Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
95dca6f
fix when STR LDR V0 Register this immediate must << 4 ins : E0 0B 8…
IIIImmmyyy Apr 30, 2025
d9591ef
fix movz when shift is not zero and this result is int64 , it can cha…
IIIImmmyyy May 8, 2025
336dab3
fix FCVT
IIIImmmyyy May 15, 2025
63356b9
fix E8 07 45 FC LDR D8, [SP+0x50+var_5…
IIIImmmyyy May 29, 2025
3488c81
rollback
IIIImmmyyy May 29, 2025
b6a4431
bug fix
IIIImmmyyy May 29, 2025
093ccea
fix D0 parser v0
IIIImmmyyy Jun 3, 2025
723623d
fix MOVK!
IIIImmmyyy Jun 9, 2025
6f852a1
support fcvt
IIIImmmyyy Jun 13, 2025
d875ce3
fix s0 parser error to v0
IIIImmmyyy Jun 13, 2025
6df0faa
support more ins
IIIImmmyyy Jun 14, 2025
72a9e18
修复指令
IIIImmmyyy Jun 14, 2025
7d82bda
fix SIMD DUP ins
IIIImmmyyy Jun 14, 2025
cd0877f
fix REV64
IIIImmmyyy Jun 14, 2025
742ea72
1
IIIImmmyyy Jun 14, 2025
1c2721a
bug fix
IIIImmmyyy Jun 16, 2025
0692f00
support more aliases
IIIImmmyyy Jun 17, 2025
8c6e5ec
bug fix
IIIImmmyyy Jun 18, 2025
a98e4dd
fix FMOV with immdata
IIIImmmyyy Jun 18, 2025
23c398f
UDP INS is better
IIIImmmyyy Jun 19, 2025
2162858
support more alia
IIIImmmyyy Jun 24, 2025
3d6961c
add BFM to BFI alias conversion
IIIImmmyyy Jul 16, 2025
8cc4324
enhance BFM to BFXIL and BFI conversion logic
IIIImmmyyy Jul 21, 2025
d18c557
refactor SMADDL instruction handling for optimized operand management
IIIImmmyyy Jul 22, 2025
c756c21
refactor SMADDL and UMADDL instruction handling for proper aliasing t…
IIIImmmyyy Jul 23, 2025
9dbe694
refactor variable shift instruction handling for improved alias reada…
IIIImmmyyy Jul 23, 2025
598dae6
update EXT Ins
IIIImmmyyy Jul 23, 2025
5cbdb5b
refactor Arm64Branches to improve bit testing logic and register sele…
IIIImmmyyy Sep 11, 2025
fe87a0d
Add support for conditional field access and improve load/store handling
Jun 14, 2026
a309067
Refactor MOVN and MOVZ handling to use MOV aliases and add correspond…
Jul 3, 2026
7eb1c15
Add support for FNEG instruction and corresponding test case
Jul 9, 2026
6612560
Remove unused compiler optimization stages
Jul 10, 2026
1a10198
继续修正
Jul 28, 2026
89d8e33
细节修复 以及快照更新
Jul 30, 2026
1d4df8f
底层逻辑修复
Jul 30, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions Disarm.Tests/DataProcessingTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,71 @@ public void DataProcessing1Source()
Assert.Equal(Arm64Register.W20, DisassembleAndCheckMnemonic(0x5AC00114, Arm64Mnemonic.RBIT).Op0Reg);
}

[Fact]
public void MoveWideMovnIsDecodedAsMovAlias()
{
var xMovn = DisassembleAndCheckMnemonic(0x928003F8, Arm64Mnemonic.MOV);
Assert.Equal(Arm64Register.X24, xMovn.Op0Reg);
Assert.Equal(Arm64OperandKind.Immediate, xMovn.Op1Kind);
Assert.Equal(-32, xMovn.Op1Imm);

var wMovn = DisassembleAndCheckMnemonic(0x12800000, Arm64Mnemonic.MOV);
Assert.Equal(Arm64Register.W0, wMovn.Op0Reg);
Assert.Equal(Arm64OperandKind.Immediate, wMovn.Op1Kind);
Assert.Equal(0xFFFFFFFFL, wMovn.Op1Imm);
}

[Fact]
public void AdrExposesPositivePcRelativeTarget()
{
var instruction = Disassembler
.Disassemble(new byte[] { 0x8A, 0x00, 0x00, 0x10 }, 0x1C73FA0)
.Single();

Assert.Equal(Arm64Mnemonic.ADR, instruction.Mnemonic);
Assert.Equal(Arm64Register.X10, instruction.Op0Reg);
Assert.Equal(Arm64OperandKind.ImmediatePcRelative, instruction.Op1Kind);
Assert.Equal(0x10, instruction.Op1Imm);
Assert.Equal(0x1C73FB0UL, instruction.Op1PcRelImm);
Assert.Equal("0x01C73FA0 ADR X10, 0x1C73FB0", instruction.ToString());
}

[Fact]
public void AdrExposesNegativePcRelativeTarget()
{
var instruction = Disassembler
.Disassemble(new byte[] { 0xA0, 0xFE, 0xFF, 0x10 }, 0x1C67FA4)
.Single();

Assert.Equal(Arm64Mnemonic.ADR, instruction.Mnemonic);
Assert.Equal(Arm64Register.X0, instruction.Op0Reg);
Assert.Equal(Arm64OperandKind.ImmediatePcRelative, instruction.Op1Kind);
Assert.Equal(-0x2C, instruction.Op1Imm);
Assert.Equal(0x1C67F78UL, instruction.Op1PcRelImm);
Assert.Equal("0x01C67FA4 ADR X0, 0x1C67F78", instruction.ToString());
}

[Fact]
public void DataProcessing2Source()
=> DisassembleAndCheckMnemonic(0x1AC80D2AU, Arm64Mnemonic.SDIV);

[Fact]
public void LogicalShiftedRegisterPreservesShiftMetadata()
{
var shifted = DisassembleAndCheckMnemonic(0x0AA87D08U, Arm64Mnemonic.BIC);
Assert.Equal(Arm64Register.W8, shifted.Op0Reg);
Assert.Equal(Arm64Register.W8, shifted.Op1Reg);
Assert.Equal(Arm64Register.W8, shifted.Op2Reg);
Assert.Equal(Arm64OperandKind.Immediate, shifted.Op3Kind);
Assert.Equal(31, shifted.Op3Imm);
Assert.Equal(Arm64ShiftType.ASR, shifted.FinalOpShiftType);

var unshifted = DisassembleAndCheckMnemonic(0x0A280108U, Arm64Mnemonic.BIC);
Assert.Equal(Arm64OperandKind.Immediate, unshifted.Op3Kind);
Assert.Equal(0, unshifted.Op3Imm);
Assert.Equal(Arm64ShiftType.NONE, unshifted.FinalOpShiftType);
}

[Fact]
public void ConditionalCompareImmediate()
{
Expand Down
62 changes: 1 addition & 61 deletions Disarm.Tests/FloatingPointTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,34 +9,6 @@ public FloatingPointTests(ITestOutputHelper outputHelper) : base(outputHelper)
{
}

[Fact]
public void FloatingToFromFixedTests()
{
var insn = DisassembleAndCheckMnemonic(0x1E02C060, Arm64Mnemonic.SCVTF);

Assert.Equal(Arm64OperandKind.Register, insn.Op0Kind);
Assert.Equal(Arm64OperandKind.Register, insn.Op1Kind);
Assert.Equal(Arm64OperandKind.Immediate, insn.Op2Kind);

Assert.Equal(Arm64Register.S0, insn.Op0Reg);
Assert.Equal(Arm64Register.W3, insn.Op1Reg);
Assert.Equal(16, insn.Op2Imm);

Assert.Equal("0x00000000 SCVTF S0, W3, 0x10", insn.ToString());

insn = DisassembleAndCheckMnemonic(0x1E18C060, Arm64Mnemonic.FCVTZS);

Assert.Equal(Arm64OperandKind.Register, insn.Op0Kind);
Assert.Equal(Arm64OperandKind.Register, insn.Op1Kind);
Assert.Equal(Arm64OperandKind.Immediate, insn.Op2Kind);

Assert.Equal(Arm64Register.W0, insn.Op0Reg);
Assert.Equal(Arm64Register.S3, insn.Op1Reg);
Assert.Equal(16, insn.Op2Imm);

Assert.Equal("0x00000000 FCVTZS W0, S3, 0x10", insn.ToString());
}

[Fact]
public void DataProcessingThreeSourceTests()
{
Expand Down Expand Up @@ -71,36 +43,4 @@ public void DataProcessingThreeSourceTests()
DisassembleAndCheckMnemonic(0x1F228C20, Arm64Mnemonic.FNMSUB);
}

[Fact]
public void ConditionalCompareTests()
{
var insn = DisassembleAndCheckMnemonic(0x1E210401, Arm64Mnemonic.FCCMP);

Assert.Equal(Arm64OperandKind.Register, insn.Op0Kind);
Assert.Equal(Arm64OperandKind.Register, insn.Op1Kind);
Assert.Equal(Arm64OperandKind.Immediate, insn.Op2Kind);

Assert.Equal(Arm64Register.S0, insn.Op0Reg);
Assert.Equal(Arm64Register.S1, insn.Op1Reg);
Assert.Equal(1, insn.Op2Imm);

Assert.Equal(Arm64ConditionCode.EQ, insn.FinalOpConditionCode);

Assert.Equal("0x00000000 FCCMP S0, S1, 0x1, EQ", insn.ToString());

insn = DisassembleAndCheckMnemonic(0x1E614411, Arm64Mnemonic.FCCMPE);

Assert.Equal(Arm64Register.D0, insn.Op0Reg);
Assert.Equal(Arm64Register.D1, insn.Op1Reg);
Assert.Equal(1, insn.Op2Imm);

Assert.Equal(Arm64ConditionCode.MI, insn.FinalOpConditionCode);

Assert.Equal("0x00000000 FCCMPE D0, D1, 0x1, MI", insn.ToString());

insn = DisassembleAndCheckMnemonic(0x1EE10401, Arm64Mnemonic.FCCMP);

Assert.Equal(Arm64Register.H0, insn.Op0Reg);
Assert.Equal(Arm64Register.H1, insn.Op1Reg);
}
}
}
32 changes: 32 additions & 0 deletions Disarm.Tests/LoadStoreTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,38 @@ public void LoadStoreRegFromRegOffset()
Assert.Equal("0x00000000 LDR W9, [X10, X9, LSL #2]", instruction.ToString());
}

[Fact]
public void LoadStoreRegFromRegOffsetPreservesExtendedRegisterScale()
{
// SXTW 与访问宽度缩放是同一条寻址语义,不能因为它不是 LSL 形式就丢掉 S 位表达的 #2。
var instruction = DisassembleAndCheckMnemonic(0xBC60D900U, Arm64Mnemonic.LDR);

Assert.Equal(Arm64Register.S0, instruction.Op0Reg);
Assert.Equal(Arm64OperandKind.Memory, instruction.Op1Kind);
Assert.Equal(Arm64Register.X8, instruction.MemBase);
Assert.Equal(Arm64Register.W0, instruction.MemAddendReg);
Assert.Equal(Arm64ExtendType.SXTW, instruction.MemExtendType);
Assert.Equal(Arm64ShiftType.NONE, instruction.MemShiftType);
Assert.Equal(2, instruction.MemExtendOrShiftAmount);

Assert.Equal("0x00000000 LDR S0, [X8, W0, SXTW #2]", instruction.ToString());
}

[Fact]
public void LoadStoreRegFromRegOffsetOmitsNoOpLsl()
{
var instruction = DisassembleAndCheckMnemonic(0xBC686A6AU, Arm64Mnemonic.LDR);

Assert.Equal(Arm64Register.S10, instruction.Op0Reg);
Assert.Equal(Arm64OperandKind.Memory, instruction.Op1Kind);
Assert.Equal(Arm64Register.X19, instruction.MemBase);
Assert.Equal(Arm64Register.X8, instruction.MemAddendReg);
Assert.Equal(Arm64ShiftType.NONE, instruction.MemShiftType);
Assert.Equal(0, instruction.MemExtendOrShiftAmount);

Assert.Equal("0x00000000 LDR S10, [X19, X8]", instruction.ToString());
}

[Fact]
public void LoadRegFromMemImmPostIndex()
{
Expand Down
126 changes: 3 additions & 123 deletions Disarm.Tests/SimdTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,33 +60,6 @@ public void TestMovi()
Assert.Equal(0, result.Op1Imm);
}

[Fact]
public void TestAdvancedSimdCopy()
{
//MOV V0.S[1], V1.S[0]
var result = DisassembleAndCheckMnemonic(0x6E0C0420U, Arm64Mnemonic.MOV);
Assert.Equal(Arm64OperandKind.VectorRegisterElement, result.Op0Kind);
Assert.Equal(Arm64OperandKind.VectorRegisterElement, result.Op1Kind);
Assert.Equal(Arm64Register.V0, result.Op0Reg);
Assert.Equal(Arm64Register.V1, result.Op1Reg);
Assert.Equal(1, result.Op0VectorElement.Index);
Assert.Equal(0, result.Op1VectorElement.Index);
Assert.Equal(Arm64VectorElementWidth.S, result.Op0VectorElement.Width);
Assert.Equal(Arm64VectorElementWidth.S, result.Op1VectorElement.Width);
}

[Fact]
public void TestMixedVectorElementToRegMov()
{
var result = DisassembleAndCheckMnemonic(0x5E0C0401, Arm64Mnemonic.MOV);
Assert.Equal(Arm64OperandKind.Register, result.Op0Kind);
Assert.Equal(Arm64OperandKind.VectorRegisterElement, result.Op1Kind);
Assert.Equal(Arm64Register.S1, result.Op0Reg);
Assert.Equal(Arm64Register.V0, result.Op1Reg);
Assert.Equal(Arm64VectorElementWidth.S, result.Op1VectorElement.Width);
Assert.Equal(1, result.Op1VectorElement.Index);
}

[Fact]
public void TestFmovImmediateToScalar()
{
Expand Down Expand Up @@ -227,103 +200,10 @@ public void TestAdvancedSimdThreeSame()
}

[Fact]
public void TestScalarAdvancedSimdShiftByImmediate()
public void TestAdvancedSimdTwoRegisterMiscFneg2S()
{
Arm64Instruction inst;
inst = DisassembleAndCheckMnemonic(0x7F40060A, Arm64Mnemonic.USHR);
Assert.Equal("0x00000000 USHR D10, D16, 0x40", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F40171D, Arm64Mnemonic.USRA);
Assert.Equal("0x00000000 USRA D29, D24, 0x40", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F402491, Arm64Mnemonic.URSHR);
Assert.Equal("0x00000000 URSHR D17, D4, 0x40", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F4035AA, Arm64Mnemonic.URSRA);
Assert.Equal("0x00000000 URSRA D10, D13, 0x40", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F404693, Arm64Mnemonic.SRI);
Assert.Equal("0x00000000 SRI D19, D20, 0x40", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F405591, Arm64Mnemonic.SLI);
Assert.Equal("0x00000000 SLI D17, D12, 0x0", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F086526, Arm64Mnemonic.SQSHLU);
Assert.Equal("0x00000000 SQSHLU B6, B9, 0x0", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F106526, Arm64Mnemonic.SQSHLU);
Assert.Equal("0x00000000 SQSHLU H6, H9, 0x0", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F206526, Arm64Mnemonic.SQSHLU);
Assert.Equal("0x00000000 SQSHLU S6, S9, 0x0", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F406526, Arm64Mnemonic.SQSHLU);
Assert.Equal("0x00000000 SQSHLU D6, D9, 0x0", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F08766F, Arm64Mnemonic.UQSHL);
Assert.Equal("0x00000000 UQSHL B15, B19, 0x0", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F10766F, Arm64Mnemonic.UQSHL);
Assert.Equal("0x00000000 UQSHL H15, H19, 0x0", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F20766F, Arm64Mnemonic.UQSHL);
Assert.Equal("0x00000000 UQSHL S15, S19, 0x0", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F40766F, Arm64Mnemonic.UQSHL);
Assert.Equal("0x00000000 UQSHL D15, D19, 0x0", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F10867C, Arm64Mnemonic.SQSHRUN);
Assert.Equal("0x00000000 SQSHRUN H28, S19, 0x10", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F20867C, Arm64Mnemonic.SQSHRUN);
Assert.Equal("0x00000000 SQSHRUN S28, D19, 0x20", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F108C56, Arm64Mnemonic.SQRSHRUN);
Assert.Equal("0x00000000 SQRSHRUN H22, S2, 0x10", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F208C56, Arm64Mnemonic.SQRSHRUN);
Assert.Equal("0x00000000 SQRSHRUN S22, D2, 0x20", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F109429, Arm64Mnemonic.UQSHRN);
Assert.Equal("0x00000000 UQSHRN H9, S1, 0x10", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F3F9429, Arm64Mnemonic.UQSHRN);
Assert.Equal("0x00000000 UQSHRN S9, D1, 0x1", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F109DEE, Arm64Mnemonic.UQRSHRN);
Assert.Equal("0x00000000 UQRSHRN H14, S15, 0x10", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F209DEE, Arm64Mnemonic.UQRSHRN);
Assert.Equal("0x00000000 UQRSHRN S14, D15, 0x20", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F10E492, Arm64Mnemonic.UCVTF);
Assert.Equal("0x00000000 UCVTF H18, H4, 0x10", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F20E492, Arm64Mnemonic.UCVTF);
Assert.Equal("0x00000000 UCVTF S18, S4, 0x20", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F40E492, Arm64Mnemonic.UCVTF);
Assert.Equal("0x00000000 UCVTF D18, D4, 0x40", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F10FDCF, Arm64Mnemonic.FCVTZU);
Assert.Equal("0x00000000 FCVTZU H15, H14, 0x10", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F20FDCF, Arm64Mnemonic.FCVTZU);
Assert.Equal("0x00000000 FCVTZU S15, S14, 0x20", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x7F40FDCF, Arm64Mnemonic.FCVTZU);
Assert.Equal("0x00000000 FCVTZU D15, D14, 0x40", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x5F400797, Arm64Mnemonic.SSHR);
Assert.Equal("0x00000000 SSHR D23, D28, 0x40", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x5F401559, Arm64Mnemonic.SSRA);
Assert.Equal("0x00000000 SSRA D25, D10, 0x40", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x5F402697, Arm64Mnemonic.SRSHR);
Assert.Equal("0x00000000 SRSHR D23, D20, 0x40", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x5F40357D, Arm64Mnemonic.SRSRA);
Assert.Equal("0x00000000 SRSRA D29, D11, 0x40", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x5F40569A, Arm64Mnemonic.SHL);
Assert.Equal("0x00000000 SHL D26, D20, 0x0", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x5F087668, Arm64Mnemonic.SQSHL);
Assert.Equal("0x00000000 SQSHL B8, B19, 0x0", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x5F107668, Arm64Mnemonic.SQSHL);
Assert.Equal("0x00000000 SQSHL H8, H19, 0x0", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x5F207668, Arm64Mnemonic.SQSHL);
Assert.Equal("0x00000000 SQSHL S8, S19, 0x0", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x5F407668, Arm64Mnemonic.SQSHL);
Assert.Equal("0x00000000 SQSHL D8, D19, 0x0", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x5F1095A0, Arm64Mnemonic.SQSHRN);
Assert.Equal("0x00000000 SQSHRN H0, S13, 0x10", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x5F2095A0, Arm64Mnemonic.SQSHRN);
Assert.Equal("0x00000000 SQSHRN S0, D13, 0x20", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x5F109F2B, Arm64Mnemonic.SQRSHRN);
Assert.Equal("0x00000000 SQRSHRN H11, S25, 0x10", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x5F209F2B, Arm64Mnemonic.SQRSHRN);
Assert.Equal("0x00000000 SQRSHRN S11, D25, 0x20", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x5F10E533, Arm64Mnemonic.SCVTF);
Assert.Equal("0x00000000 SCVTF H19, H9, 0x10", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x5F20E533, Arm64Mnemonic.SCVTF);
Assert.Equal("0x00000000 SCVTF S19, S9, 0x20", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x5F40E533, Arm64Mnemonic.SCVTF);
Assert.Equal("0x00000000 SCVTF D19, D9, 0x40", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x5F10FDBA, Arm64Mnemonic.FCVTZS);
Assert.Equal("0x00000000 FCVTZS H26, H13, 0x10", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x5F20FDBA, Arm64Mnemonic.FCVTZS);
Assert.Equal("0x00000000 FCVTZS S26, S13, 0x20", inst.ToString());
inst = DisassembleAndCheckMnemonic(0x5F40FDBA, Arm64Mnemonic.FCVTZS);
Assert.Equal("0x00000000 FCVTZS D26, D13, 0x40", inst.ToString());
var inst = DisassembleAndCheckMnemonic(0x2EA0F8A7, Arm64Mnemonic.FNEG);
Assert.Equal("0x00000000 FNEG V7.2S, V5.2S", inst.ToString());
}

[Fact]
Expand Down
29 changes: 28 additions & 1 deletion Disarm.Tests/SystemTests.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Xunit.Abstractions;
using Disarm.InternalDisassembly;

namespace Disarm.Tests;

Expand All @@ -16,4 +17,30 @@ public void TestMnemonics()
DisassembleAndCheckMnemonic(0xD5300000, Arm64Mnemonic.MRS);
DisassembleAndCheckMnemonic(0xD5100000, Arm64Mnemonic.MSR);
}
}

[Fact]
public void RegisterMovePreservesEncodingAndFormatsKnownSystemRegisterName()
{
var mrs = DisassembleAndCheckMnemonic(0xD53BD055, Arm64Mnemonic.MRS);
Assert.Equal(Arm64Register.X21, mrs.Op0Reg);
Assert.Equal(Arm64OperandKind.Immediate, mrs.Op1Kind);
Assert.Equal(0xDE82L, mrs.Op1Imm);
Assert.Equal("0x00000000 MRS X21, TPIDR_EL0", mrs.ToString());

var msr = DisassembleAndCheckMnemonic(0xD51BD055, Arm64Mnemonic.MSR);
Assert.Equal(Arm64OperandKind.Immediate, msr.Op0Kind);
Assert.Equal(0xDE82L, msr.Op0Imm);
Assert.Equal(Arm64Register.X21, msr.Op1Reg);
Assert.Equal("0x00000000 MSR TPIDR_EL0, X21", msr.ToString());
}

[Fact]
public void UnmappedSystemRegisterKeepsImmediateFormatting()
{
var mrs = DisassembleAndCheckMnemonic(0xD5300000, Arm64Mnemonic.MRS);

Assert.Equal(Arm64OperandKind.Immediate, mrs.Op1Kind);
Assert.Equal(0x8000L, mrs.Op1Imm);
Assert.Equal("0x00000000 MRS X0, #0x8000", mrs.ToString());
}
}
Loading