diff --git a/ARMeilleure/Decoders/IOpCode32AluBf.cs b/ARMeilleure/Decoders/IOpCode32AluBf.cs index 18de3eb652..206c2965e6 100644 --- a/ARMeilleure/Decoders/IOpCode32AluBf.cs +++ b/ARMeilleure/Decoders/IOpCode32AluBf.cs @@ -7,5 +7,8 @@ int Msb { get; } int Lsb { get; } + + int SourceMask => (int)(0xFFFFFFFF >> (31 - Msb)); + int DestMask => SourceMask & (int)(0xFFFFFFFF << Lsb); } } diff --git a/ARMeilleure/Decoders/IOpCode32AluImm16.cs b/ARMeilleure/Decoders/IOpCode32AluImm16.cs new file mode 100644 index 0000000000..cd128f657c --- /dev/null +++ b/ARMeilleure/Decoders/IOpCode32AluImm16.cs @@ -0,0 +1,7 @@ +namespace ARMeilleure.Decoders +{ + interface IOpCode32AluImm16 : IOpCode32Alu + { + int Immediate { get; } + } +} \ No newline at end of file diff --git a/ARMeilleure/Decoders/IOpCode32AluMla.cs b/ARMeilleure/Decoders/IOpCode32AluMla.cs new file mode 100644 index 0000000000..79b1642575 --- /dev/null +++ b/ARMeilleure/Decoders/IOpCode32AluMla.cs @@ -0,0 +1,11 @@ +namespace ARMeilleure.Decoders +{ + interface IOpCode32AluMla : IOpCode32AluReg + { + int Ra { get; } + + bool NHigh { get; } + bool MHigh { get; } + bool R { get; } + } +} diff --git a/ARMeilleure/Decoders/IOpCode32AluUmull.cs b/ARMeilleure/Decoders/IOpCode32AluUmull.cs new file mode 100644 index 0000000000..79d2bb9ba7 --- /dev/null +++ b/ARMeilleure/Decoders/IOpCode32AluUmull.cs @@ -0,0 +1,13 @@ +namespace ARMeilleure.Decoders +{ + interface IOpCode32AluUmull : IOpCode32, IOpCode32HasSetFlags + { + int RdLo { get; } + int RdHi { get; } + int Rn { get; } + int Rm { get; } + + bool NHigh { get; } + bool MHigh { get; } + } +} diff --git a/ARMeilleure/Decoders/OpCode32AluBf.cs b/ARMeilleure/Decoders/OpCode32AluBf.cs index f8dc6db0d4..0cee34e6dd 100644 --- a/ARMeilleure/Decoders/OpCode32AluBf.cs +++ b/ARMeilleure/Decoders/OpCode32AluBf.cs @@ -6,12 +6,8 @@ public int Rn { get; } public int Msb { get; } - public int Lsb { get; } - public int SourceMask => (int)(0xFFFFFFFF >> (31 - Msb)); - public int DestMask => SourceMask & (int)(0xFFFFFFFF << Lsb); - public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32AluBf(inst, address, opCode); public OpCode32AluBf(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) diff --git a/ARMeilleure/Decoders/OpCode32AluImm16.cs b/ARMeilleure/Decoders/OpCode32AluImm16.cs index 662482719c..e24edeb411 100644 --- a/ARMeilleure/Decoders/OpCode32AluImm16.cs +++ b/ARMeilleure/Decoders/OpCode32AluImm16.cs @@ -1,6 +1,6 @@ namespace ARMeilleure.Decoders { - class OpCode32AluImm16 : OpCode32Alu + class OpCode32AluImm16 : OpCode32Alu, IOpCode32AluImm16 { public int Immediate { get; } diff --git a/ARMeilleure/Decoders/OpCode32AluMla.cs b/ARMeilleure/Decoders/OpCode32AluMla.cs index 7489466761..2cd2b9dcc9 100644 --- a/ARMeilleure/Decoders/OpCode32AluMla.cs +++ b/ARMeilleure/Decoders/OpCode32AluMla.cs @@ -1,6 +1,6 @@ namespace ARMeilleure.Decoders { - class OpCode32AluMla : OpCode32, IOpCode32AluReg + class OpCode32AluMla : OpCode32, IOpCode32AluMla { public int Rn { get; } public int Rm { get; } diff --git a/ARMeilleure/Decoders/OpCode32AluUmull.cs b/ARMeilleure/Decoders/OpCode32AluUmull.cs index 1b31239be0..bf80df3ffa 100644 --- a/ARMeilleure/Decoders/OpCode32AluUmull.cs +++ b/ARMeilleure/Decoders/OpCode32AluUmull.cs @@ -1,6 +1,6 @@ namespace ARMeilleure.Decoders { - class OpCode32AluUmull : OpCode32, IOpCode32HasSetFlags + class OpCode32AluUmull : OpCode32, IOpCode32AluUmull { public int RdLo { get; } public int RdHi { get; } @@ -11,7 +11,6 @@ public bool MHigh { get; } public bool? SetFlags { get; } - public DataOp DataOp { get; } public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32AluUmull(inst, address, opCode); @@ -26,7 +25,6 @@ MHigh = ((opCode >> 6) & 0x1) == 1; SetFlags = ((opCode >> 20) & 0x1) != 0; - DataOp = DataOp.Arithmetic; } } } diff --git a/ARMeilleure/Decoders/OpCodeT32AluBf.cs b/ARMeilleure/Decoders/OpCodeT32AluBf.cs new file mode 100644 index 0000000000..57ad422fdb --- /dev/null +++ b/ARMeilleure/Decoders/OpCodeT32AluBf.cs @@ -0,0 +1,22 @@ +namespace ARMeilleure.Decoders +{ + class OpCodeT32AluBf : OpCodeT32, IOpCode32AluBf + { + public int Rd { get; } + public int Rn { get; } + + public int Msb { get; } + public int Lsb { get; } + + public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32AluBf(inst, address, opCode); + + public OpCodeT32AluBf(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) + { + Rd = (opCode >> 8) & 0xf; + Rn = (opCode >> 16) & 0xf; + + Msb = (opCode >> 0) & 0x1f; + Lsb = ((opCode >> 6) & 0x3) | ((opCode >> 10) & 0x1c); + } + } +} diff --git a/ARMeilleure/Decoders/OpCodeT32AluMla.cs b/ARMeilleure/Decoders/OpCodeT32AluMla.cs new file mode 100644 index 0000000000..6cb604da6d --- /dev/null +++ b/ARMeilleure/Decoders/OpCodeT32AluMla.cs @@ -0,0 +1,29 @@ +namespace ARMeilleure.Decoders +{ + class OpCodeT32AluMla : OpCodeT32, IOpCode32AluMla + { + public int Rn { get; } + public int Rm { get; } + public int Ra { get; } + public int Rd { get; } + + public bool NHigh { get; } + public bool MHigh { get; } + public bool R { get; } + public bool? SetFlags => false; + + public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32AluMla(inst, address, opCode); + + public OpCodeT32AluMla(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) + { + Rm = (opCode >> 0) & 0xf; + Rd = (opCode >> 8) & 0xf; + Ra = (opCode >> 12) & 0xf; + Rn = (opCode >> 16) & 0xf; + R = (opCode & (1 << 4)) != 0; + + MHigh = ((opCode >> 4) & 0x1) == 1; + NHigh = ((opCode >> 5) & 0x1) == 1; + } + } +} diff --git a/ARMeilleure/Decoders/OpCodeT32AluUmull.cs b/ARMeilleure/Decoders/OpCodeT32AluUmull.cs new file mode 100644 index 0000000000..a1b2e61203 --- /dev/null +++ b/ARMeilleure/Decoders/OpCodeT32AluUmull.cs @@ -0,0 +1,28 @@ +namespace ARMeilleure.Decoders +{ + class OpCodeT32AluUmull : OpCodeT32, IOpCode32AluUmull + { + public int RdLo { get; } + public int RdHi { get; } + public int Rn { get; } + public int Rm { get; } + + public bool NHigh { get; } + public bool MHigh { get; } + + public bool? SetFlags => false; + + public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32AluUmull(inst, address, opCode); + + public OpCodeT32AluUmull(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) + { + Rm = (opCode >> 0) & 0xf; + RdHi = (opCode >> 8) & 0xf; + RdLo = (opCode >> 12) & 0xf; + Rn = (opCode >> 16) & 0xf; + + MHigh = ((opCode >> 4) & 0x1) == 1; + NHigh = ((opCode >> 5) & 0x1) == 1; + } + } +} diff --git a/ARMeilleure/Decoders/OpCodeT32AluUx.cs b/ARMeilleure/Decoders/OpCodeT32AluUx.cs new file mode 100644 index 0000000000..861dc904ab --- /dev/null +++ b/ARMeilleure/Decoders/OpCodeT32AluUx.cs @@ -0,0 +1,18 @@ +using ARMeilleure.State; + +namespace ARMeilleure.Decoders +{ + class OpCodeT32AluUx : OpCodeT32AluReg, IOpCode32AluUx + { + public int Rotate { get; } + public int RotateBits => Rotate * 8; + public bool Add => Rn != RegisterAlias.Aarch32Pc; + + public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32AluUx(inst, address, opCode); + + public OpCodeT32AluUx(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) + { + Rotate = (opCode >> 4) & 0x3; + } + } +} diff --git a/ARMeilleure/Decoders/OpCodeT32BImm24.cs b/ARMeilleure/Decoders/OpCodeT32BImm24.cs index 4381be4779..774ec3a641 100644 --- a/ARMeilleure/Decoders/OpCodeT32BImm24.cs +++ b/ARMeilleure/Decoders/OpCodeT32BImm24.cs @@ -27,7 +27,7 @@ namespace ARMeilleure.Decoders int i2 = j2 ^ s ^ 1; int imm32 = imm11 | (imm10 << 11) | (i2 << 21) | (i1 << 22) | (s << 23); - imm32 = (imm32 << 9) >> 8; + imm32 = (imm32 << 8) >> 7; Immediate = pc + imm32; } diff --git a/ARMeilleure/Decoders/OpCodeT32MemLdEx.cs b/ARMeilleure/Decoders/OpCodeT32MemLdEx.cs index da565f61d8..c8eb36b3ee 100644 --- a/ARMeilleure/Decoders/OpCodeT32MemLdEx.cs +++ b/ARMeilleure/Decoders/OpCodeT32MemLdEx.cs @@ -4,6 +4,7 @@ namespace ARMeilleure.Decoders { public int Rd => 0; public int Rt { get; } + public int Rt2 { get; } public int Rn { get; } public bool WBack => false; @@ -17,6 +18,7 @@ namespace ARMeilleure.Decoders public OpCodeT32MemLdEx(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { + Rt2 = (opCode >> 8) & 0xf; Rt = (opCode >> 12) & 0xf; Rn = (opCode >> 16) & 0xf; } diff --git a/ARMeilleure/Decoders/OpCodeT32MemStEx.cs b/ARMeilleure/Decoders/OpCodeT32MemStEx.cs index 8fe1950ed9..6a0a6bb134 100644 --- a/ARMeilleure/Decoders/OpCodeT32MemStEx.cs +++ b/ARMeilleure/Decoders/OpCodeT32MemStEx.cs @@ -4,6 +4,7 @@ namespace ARMeilleure.Decoders { public int Rd { get; } public int Rt { get; } + public int Rt2 { get; } public int Rn { get; } public bool WBack => false; @@ -18,6 +19,7 @@ namespace ARMeilleure.Decoders public OpCodeT32MemStEx(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) { Rd = (opCode >> 0) & 0xf; + Rt2 = (opCode >> 8) & 0xf; Rt = (opCode >> 12) & 0xf; Rn = (opCode >> 16) & 0xf; } diff --git a/ARMeilleure/Decoders/OpCodeT32MovImm16.cs b/ARMeilleure/Decoders/OpCodeT32MovImm16.cs index 55db012ca7..5161892bb4 100644 --- a/ARMeilleure/Decoders/OpCodeT32MovImm16.cs +++ b/ARMeilleure/Decoders/OpCodeT32MovImm16.cs @@ -1,9 +1,6 @@ -using ARMeilleure.Common; -using System.Runtime.Intrinsics; - namespace ARMeilleure.Decoders { - class OpCodeT32MovImm16 : OpCodeT32Alu, IOpCode32AluImm + class OpCodeT32MovImm16 : OpCodeT32Alu, IOpCode32AluImm16 { public int Immediate { get; } diff --git a/ARMeilleure/Decoders/OpCodeTable.cs b/ARMeilleure/Decoders/OpCodeTable.cs index a7793681de..034707b9d8 100644 --- a/ARMeilleure/Decoders/OpCodeTable.cs +++ b/ARMeilleure/Decoders/OpCodeTable.cs @@ -1074,6 +1074,8 @@ namespace ARMeilleure.Decoders SetT32("11110x00000<xxxx0xxx<<<<xxxxxxxx", InstName.And, InstEmit32.And, OpCodeT32AluImm.Create); SetT32("11110x<<<xxxxxxx10x0xxxxxxxxxxxx", InstName.B, InstEmit32.B, OpCodeT32BImm20.Create); SetT32("11110xxxxxxxxxxx10x1xxxxxxxxxxxx", InstName.B, InstEmit32.B, OpCodeT32BImm24.Create); + SetT32("11110011011011110xxxxxxxxx0xxxxx", InstName.Bfc, InstEmit32.Bfc, OpCodeT32AluBf.Create); + SetT32("111100110110<<<<0xxxxxxxxx0xxxxx", InstName.Bfi, InstEmit32.Bfi, OpCodeT32AluBf.Create); SetT32("11101010001xxxxx0xxxxxxxxxxxxxxx", InstName.Bic, InstEmit32.Bic, OpCodeT32AluRsImm.Create); SetT32("11110x00001xxxxx0xxxxxxxxxxxxxxx", InstName.Bic, InstEmit32.Bic, OpCodeT32AluImm.Create); SetT32("11110xxxxxxxxxxx11x1xxxxxxxxxxxx", InstName.Bl, InstEmit32.Bl, OpCodeT32BImm24.Create); @@ -1086,36 +1088,49 @@ namespace ARMeilleure.Decoders SetT32("11101010100<xxxx0xxx<<<<xxxxxxxx", InstName.Eor, InstEmit32.Eor, OpCodeT32AluRsImm.Create); SetT32("11110x00100<xxxx0xxx<<<<xxxxxxxx", InstName.Eor, InstEmit32.Eor, OpCodeT32AluImm.Create); SetT32("111010001101xxxxxxxx111110101111", InstName.Lda, InstEmit32.Lda, OpCodeT32MemLdEx.Create); + SetT32("111010001101xxxxxxxx111110001111", InstName.Ldab, InstEmit32.Ldab, OpCodeT32MemLdEx.Create); SetT32("111010001101xxxxxxxx111111101111", InstName.Ldaex, InstEmit32.Ldaex, OpCodeT32MemLdEx.Create); + SetT32("111010001101xxxxxxxx111111001111", InstName.Ldaexb, InstEmit32.Ldaexb, OpCodeT32MemLdEx.Create); + SetT32("111010001101xxxxxxxxxxxx11111111", InstName.Ldaexd, InstEmit32.Ldaexd, OpCodeT32MemLdEx.Create); + SetT32("111010001101xxxxxxxx111111011111", InstName.Ldaexh, InstEmit32.Ldaexh, OpCodeT32MemLdEx.Create); + SetT32("111010001101xxxxxxxx111110011111", InstName.Ldah, InstEmit32.Ldah, OpCodeT32MemLdEx.Create); SetT32("1110100010x1xxxxxxxxxxxxxxxxxxxx", InstName.Ldm, InstEmit32.Ldm, OpCodeT32MemMult.Create); SetT32("1110100100x1xxxxxxxxxxxxxxxxxxxx", InstName.Ldm, InstEmit32.Ldm, OpCodeT32MemMult.Create); - SetT32("111110000101xxxx<<<<10x1xxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm8.Create); - SetT32("111110000101xxxx<<<<1100xxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm8.Create); - SetT32("111110000101xxxx<<<<11x1xxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm8.Create); + SetT32("111110000101xxxxxxxx10x1xxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm8.Create); + SetT32("111110000101xxxxxxxx1100xxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm8.Create); + SetT32("111110000101xxxxxxxx11x1xxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm8.Create); SetT32("111110001101xxxxxxxxxxxxxxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemImm12.Create); SetT32("111110000101<<<<xxxx000000xxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT32MemRsImm.Create); - SetT32("111110000001xxxx<<<<10x1xxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm8.Create); - SetT32("111110000001xxxx<<<<1100xxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm8.Create); - SetT32("111110000001xxxx<<<<11x1xxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm8.Create); + SetT32("111110000001xxxxxxxx10x1xxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm8.Create); + SetT32("111110000001xxxxxxxx1100xxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm8.Create); + SetT32("111110000001xxxxxxxx11x1xxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm8.Create); SetT32("111110001001xxxxxxxxxxxxxxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm12.Create); + SetT32("111110000001xxxx<<<<000000xxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemRsImm.Create); SetT32("11101000x111<<<<xxxxxxxxxxxxxxxx", InstName.Ldrd, InstEmit32.Ldrd, OpCodeT32MemImm8D.Create); SetT32("11101001x1x1<<<<xxxxxxxxxxxxxxxx", InstName.Ldrd, InstEmit32.Ldrd, OpCodeT32MemImm8D.Create); - SetT32("111110000011xxxx<<<<10x1xxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm8.Create); - SetT32("111110000011xxxx<<<<1100xxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm8.Create); - SetT32("111110000011xxxx<<<<11x1xxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm8.Create); + SetT32("111110000011xxxxxxxx10x1xxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm8.Create); + SetT32("111110000011xxxxxxxx1100xxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm8.Create); + SetT32("111110000011xxxxxxxx11x1xxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm8.Create); SetT32("111110001011xxxxxxxxxxxxxxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemImm12.Create); - SetT32("111110010001xxxx<<<<10x1xxxxxxxx", InstName.Ldrsb, InstEmit32.Ldrsb, OpCodeT32MemImm8.Create); - SetT32("111110010001xxxx<<<<1100xxxxxxxx", InstName.Ldrsb, InstEmit32.Ldrsb, OpCodeT32MemImm8.Create); - SetT32("111110010001xxxx<<<<11x1xxxxxxxx", InstName.Ldrsb, InstEmit32.Ldrsb, OpCodeT32MemImm8.Create); + SetT32("111110000011xxxx<<<<000000xxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT32MemRsImm.Create); + SetT32("111110010001xxxxxxxx10x1xxxxxxxx", InstName.Ldrsb, InstEmit32.Ldrsb, OpCodeT32MemImm8.Create); + SetT32("111110010001xxxxxxxx1100xxxxxxxx", InstName.Ldrsb, InstEmit32.Ldrsb, OpCodeT32MemImm8.Create); + SetT32("111110010001xxxxxxxx11x1xxxxxxxx", InstName.Ldrsb, InstEmit32.Ldrsb, OpCodeT32MemImm8.Create); SetT32("111110011001xxxxxxxxxxxxxxxxxxxx", InstName.Ldrsb, InstEmit32.Ldrsb, OpCodeT32MemImm12.Create); - SetT32("111110010011xxxx<<<<10x1xxxxxxxx", InstName.Ldrsh, InstEmit32.Ldrsh, OpCodeT32MemImm8.Create); - SetT32("111110010011xxxx<<<<1100xxxxxxxx", InstName.Ldrsh, InstEmit32.Ldrsh, OpCodeT32MemImm8.Create); - SetT32("111110010011xxxx<<<<11x1xxxxxxxx", InstName.Ldrsh, InstEmit32.Ldrsh, OpCodeT32MemImm8.Create); + SetT32("111110010001xxxx<<<<000000xxxxxx", InstName.Ldrsb, InstEmit32.Ldrsb, OpCodeT32MemRsImm.Create); + SetT32("111110010011xxxxxxxx10x1xxxxxxxx", InstName.Ldrsh, InstEmit32.Ldrsh, OpCodeT32MemImm8.Create); + SetT32("111110010011xxxxxxxx1100xxxxxxxx", InstName.Ldrsh, InstEmit32.Ldrsh, OpCodeT32MemImm8.Create); + SetT32("111110010011xxxxxxxx11x1xxxxxxxx", InstName.Ldrsh, InstEmit32.Ldrsh, OpCodeT32MemImm8.Create); SetT32("111110011011xxxxxxxxxxxxxxxxxxxx", InstName.Ldrsh, InstEmit32.Ldrsh, OpCodeT32MemImm12.Create); + SetT32("111110010011xxxx<<<<000000xxxxxx", InstName.Ldrsh, InstEmit32.Ldrsh, OpCodeT32MemRsImm.Create); + SetT32("111110110000xxxx<<<<xxxx0000xxxx", InstName.Mla, InstEmit32.Mla, OpCodeT32AluMla.Create); + SetT32("111110110000xxxxxxxxxxxx0001xxxx", InstName.Mls, InstEmit32.Mls, OpCodeT32AluMla.Create); SetT32("11101010010x11110xxxxxxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, OpCodeT32AluRsImm.Create); SetT32("111110100xxxxxxx1111xxxx0000xxxx", InstName.Mov, InstEmit32.Mov, OpCodeT32ShiftReg.Create); SetT32("11110x00010x11110xxxxxxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, OpCodeT32AluImm.Create); SetT32("11110x100100xxxx0xxxxxxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, OpCodeT32MovImm16.Create); + SetT32("11110x101100xxxx0xxxxxxxxxxxxxxx", InstName.Movt, InstEmit32.Movt, OpCodeT32MovImm16.Create); + SetT32("111110110000xxxx1111xxxx0000xxxx", InstName.Mul, InstEmit32.Mul, OpCodeT32AluMla.Create); SetT32("11101010011x11110xxxxxxxxxxxxxxx", InstName.Mvn, InstEmit32.Mvn, OpCodeT32AluRsImm.Create); SetT32("11110x00011x11110xxxxxxxxxxxxxxx", InstName.Mvn, InstEmit32.Mvn, OpCodeT32AluImm.Create); SetT32("11110011101011111000000000000000", InstName.Nop, InstEmit32.Nop, OpCodeT32.Create); @@ -1127,7 +1142,24 @@ namespace ARMeilleure.Decoders SetT32("11110x01110xxxxx0xxxxxxxxxxxxxxx", InstName.Rsb, InstEmit32.Rsb, OpCodeT32AluImm.Create); SetT32("11101011011xxxxx0xxxxxxxxxxxxxxx", InstName.Sbc, InstEmit32.Sbc, OpCodeT32AluRsImm.Create); SetT32("11110x01011xxxxx0xxxxxxxxxxxxxxx", InstName.Sbc, InstEmit32.Sbc, OpCodeT32AluImm.Create); + SetT32("111100110100xxxx0xxxxxxxxx0xxxxx", InstName.Sbfx, InstEmit32.Sbfx, OpCodeT32AluBf.Create); + SetT32("111110111001xxxx1111xxxx1111xxxx", InstName.Sdiv, InstEmit32.Sdiv, OpCodeT32AluMla.Create); + SetT32("111110110001xxxx<<<<xxxx00xxxxxx", InstName.Smla__, InstEmit32.Smla__, OpCodeT32AluMla.Create); + SetT32("111110111100xxxxxxxxxxxx0000xxxx", InstName.Smlal, InstEmit32.Smlal, OpCodeT32AluUmull.Create); + SetT32("111110111100xxxxxxxxxxxx10xxxxxx", InstName.Smlal__, InstEmit32.Smlal__, OpCodeT32AluUmull.Create); + SetT32("111110110011xxxx<<<<xxxx000xxxxx", InstName.Smlaw_, InstEmit32.Smlaw_, OpCodeT32AluMla.Create); + SetT32("111110110101xxxx<<<<xxxx000xxxxx", InstName.Smmla, InstEmit32.Smmla, OpCodeT32AluMla.Create); + SetT32("111110110110xxxxxxxxxxxx000xxxxx", InstName.Smmls, InstEmit32.Smmls, OpCodeT32AluMla.Create); + SetT32("111110110001xxxx1111xxxx00xxxxxx", InstName.Smul__, InstEmit32.Smul__, OpCodeT32AluMla.Create); + SetT32("111110111000xxxxxxxxxxxx0000xxxx", InstName.Smull, InstEmit32.Smull, OpCodeT32AluUmull.Create); + SetT32("111110110011xxxx1111xxxx000xxxxx", InstName.Smulw_, InstEmit32.Smulw_, OpCodeT32AluMla.Create); + SetT32("111010001100xxxxxxxx111110101111", InstName.Stl, InstEmit32.Stl, OpCodeT32MemStEx.Create); + SetT32("111010001100xxxxxxxx111110001111", InstName.Stlb, InstEmit32.Stlb, OpCodeT32MemStEx.Create); SetT32("111010001100xxxxxxxx11111110xxxx", InstName.Stlex, InstEmit32.Stlex, OpCodeT32MemStEx.Create); + SetT32("111010001100xxxxxxxx11111100xxxx", InstName.Stlexb, InstEmit32.Stlexb, OpCodeT32MemStEx.Create); + SetT32("111010001100xxxxxxxxxxxx1111xxxx", InstName.Stlexd, InstEmit32.Stlexd, OpCodeT32MemStEx.Create); + SetT32("111010001100xxxxxxxx11111101xxxx", InstName.Stlexh, InstEmit32.Stlexh, OpCodeT32MemStEx.Create); + SetT32("111010001100xxxxxxxx111110011111", InstName.Stlh, InstEmit32.Stlh, OpCodeT32MemStEx.Create); SetT32("1110100010x0xxxx0xxxxxxxxxxxxxxx", InstName.Stm, InstEmit32.Stm, OpCodeT32MemMult.Create); SetT32("1110100100x0xxxx0xxxxxxxxxxxxxxx", InstName.Stm, InstEmit32.Stm, OpCodeT32MemMult.Create); SetT32("111110000100xxxxxxxx1<<>xxxxxxxx", InstName.Str, InstEmit32.Str, OpCodeT32MemImm8.Create); @@ -1135,18 +1167,31 @@ namespace ARMeilleure.Decoders SetT32("111110000100<<<<xxxx000000xxxxxx", InstName.Str, InstEmit32.Str, OpCodeT32MemRsImm.Create); SetT32("111110000000xxxxxxxx1<<>xxxxxxxx", InstName.Strb, InstEmit32.Strb, OpCodeT32MemImm8.Create); SetT32("111110001000xxxxxxxxxxxxxxxxxxxx", InstName.Strb, InstEmit32.Strb, OpCodeT32MemImm12.Create); + SetT32("111110000000<<<<xxxx000000xxxxxx", InstName.Strb, InstEmit32.Strb, OpCodeT32MemRsImm.Create); SetT32("11101000x110<<<<xxxxxxxxxxxxxxxx", InstName.Strd, InstEmit32.Strd, OpCodeT32MemImm8D.Create); SetT32("11101001x1x0<<<<xxxxxxxxxxxxxxxx", InstName.Strd, InstEmit32.Strd, OpCodeT32MemImm8D.Create); SetT32("111110000010xxxxxxxx1<<>xxxxxxxx", InstName.Strh, InstEmit32.Strh, OpCodeT32MemImm8.Create); SetT32("111110001010xxxxxxxxxxxxxxxxxxxx", InstName.Strh, InstEmit32.Strh, OpCodeT32MemImm12.Create); + SetT32("111110000010<<<<xxxx000000xxxxxx", InstName.Strh, InstEmit32.Strh, OpCodeT32MemRsImm.Create); SetT32("11101011101<xxxx0xxx<<<<xxxxxxxx", InstName.Sub, InstEmit32.Sub, OpCodeT32AluRsImm.Create); SetT32("11110x01101<xxxx0xxx<<<<xxxxxxxx", InstName.Sub, InstEmit32.Sub, OpCodeT32AluImm.Create); + SetT32("111110100100xxxx1111xxxx10xxxxxx", InstName.Sxtb, InstEmit32.Sxtb, OpCodeT32AluUx.Create); + SetT32("111110100010xxxx1111xxxx10xxxxxx", InstName.Sxtb16, InstEmit32.Sxtb16, OpCodeT32AluUx.Create); + SetT32("111110100000xxxx1111xxxx10xxxxxx", InstName.Sxth, InstEmit32.Sxth, OpCodeT32AluUx.Create); SetT32("111010001101xxxx111100000000xxxx", InstName.Tbb, InstEmit32.Tbb, OpCodeT32Tb.Create); SetT32("111010001101xxxx111100000001xxxx", InstName.Tbh, InstEmit32.Tbh, OpCodeT32Tb.Create); SetT32("111010101001xxxx0xxx1111xxxxxxxx", InstName.Teq, InstEmit32.Teq, OpCodeT32AluRsImm.Create); SetT32("11110x001001xxxx0xxx1111xxxxxxxx", InstName.Teq, InstEmit32.Teq, OpCodeT32AluImm.Create); SetT32("111010100001xxxx0xxx1111xxxxxxxx", InstName.Tst, InstEmit32.Tst, OpCodeT32AluRsImm.Create); SetT32("11110x000001xxxx0xxx1111xxxxxxxx", InstName.Tst, InstEmit32.Tst, OpCodeT32AluImm.Create); + SetT32("111100111100xxxx0xxxxxxxxx0xxxxx", InstName.Ubfx, InstEmit32.Ubfx, OpCodeT32AluBf.Create); + SetT32("111110111011xxxx1111xxxx1111xxxx", InstName.Udiv, InstEmit32.Udiv, OpCodeT32AluMla.Create); + SetT32("111110111110xxxxxxxxxxxx0110xxxx", InstName.Umaal, InstEmit32.Umaal, OpCodeT32AluUmull.Create); + SetT32("111110111110xxxxxxxxxxxx0000xxxx", InstName.Umlal, InstEmit32.Umlal, OpCodeT32AluUmull.Create); + SetT32("111110111010xxxxxxxxxxxx0000xxxx", InstName.Umull, InstEmit32.Umull, OpCodeT32AluUmull.Create); + SetT32("111110100101xxxx1111xxxx10xxxxxx", InstName.Uxtb, InstEmit32.Uxtb, OpCodeT32AluUx.Create); + SetT32("111110100011xxxx1111xxxx10xxxxxx", InstName.Uxtb16, InstEmit32.Uxtb16, OpCodeT32AluUx.Create); + SetT32("111110100001xxxx1111xxxx10xxxxxx", InstName.Uxth, InstEmit32.Uxth, OpCodeT32AluUx.Create); #endregion FillFastLookupTable(InstA32FastLookup, AllInstA32, ToFastLookupIndexA); diff --git a/ARMeilleure/Instructions/InstEmitAlu32.cs b/ARMeilleure/Instructions/InstEmitAlu32.cs index a612bdf202..31d8a02cc8 100644 --- a/ARMeilleure/Instructions/InstEmitAlu32.cs +++ b/ARMeilleure/Instructions/InstEmitAlu32.cs @@ -74,7 +74,7 @@ namespace ARMeilleure.Instructions public static void Bfc(ArmEmitterContext context) { - OpCode32AluBf op = (OpCode32AluBf)context.CurrOp; + IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp; Operand d = GetIntA32(context, op.Rd); Operand res = context.BitwiseAnd(d, Const(~op.DestMask)); @@ -84,7 +84,7 @@ namespace ARMeilleure.Instructions public static void Bfi(ArmEmitterContext context) { - OpCode32AluBf op = (OpCode32AluBf)context.CurrOp; + IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp; Operand n = GetIntA32(context, op.Rn); Operand d = GetIntA32(context, op.Rd); @@ -185,7 +185,7 @@ namespace ARMeilleure.Instructions public static void Movt(ArmEmitterContext context) { - OpCode32AluImm16 op = (OpCode32AluImm16)context.CurrOp; + IOpCode32AluImm16 op = (IOpCode32AluImm16)context.CurrOp; Operand d = GetIntA32(context, op.Rd); Operand imm = Const(op.Immediate << 16); // Immeditate value as top halfword. @@ -389,7 +389,7 @@ namespace ARMeilleure.Instructions public static void Sbfx(ArmEmitterContext context) { - OpCode32AluBf op = (OpCode32AluBf)context.CurrOp; + IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp; var msb = op.Lsb + op.Msb; // For this instruction, the msb is actually a width. @@ -484,7 +484,7 @@ namespace ARMeilleure.Instructions public static void Ubfx(ArmEmitterContext context) { - OpCode32AluBf op = (OpCode32AluBf)context.CurrOp; + IOpCode32AluBf op = (IOpCode32AluBf)context.CurrOp; var msb = op.Lsb + op.Msb; // For this instruction, the msb is actually a width. diff --git a/ARMeilleure/Instructions/InstEmitAluHelper.cs b/ARMeilleure/Instructions/InstEmitAluHelper.cs index a487895bac..88991f7d57 100644 --- a/ARMeilleure/Instructions/InstEmitAluHelper.cs +++ b/ARMeilleure/Instructions/InstEmitAluHelper.cs @@ -205,7 +205,7 @@ namespace ARMeilleure.Instructions return Const(op.Immediate); } - case OpCode32AluImm16 op: return Const(op.Immediate); + case IOpCode32AluImm16 op: return Const(op.Immediate); case IOpCode32AluRsImm op: return GetMShiftedByImmediate(context, op, setCarry); case IOpCode32AluRsReg op: return GetMShiftedByReg(context, op, setCarry); diff --git a/ARMeilleure/Instructions/InstEmitMemoryEx32.cs b/ARMeilleure/Instructions/InstEmitMemoryEx32.cs index c2326cde7e..c0b6fc39de 100644 --- a/ARMeilleure/Instructions/InstEmitMemoryEx32.cs +++ b/ARMeilleure/Instructions/InstEmitMemoryEx32.cs @@ -172,13 +172,13 @@ namespace ARMeilleure.Instructions context.BranchIfTrue(lblBigEndian, GetFlag(PState.EFlag)); SetIntA32(context, op.Rt, valueLow); - SetIntA32(context, op.Rt | 1, valueHigh); + SetIntA32(context, op.Rt2, valueHigh); context.Branch(lblEnd); context.MarkLabel(lblBigEndian); - SetIntA32(context, op.Rt | 1, valueLow); + SetIntA32(context, op.Rt2, valueLow); SetIntA32(context, op.Rt, valueHigh); context.MarkLabel(lblEnd); @@ -195,7 +195,7 @@ namespace ARMeilleure.Instructions // Split the result into 2 words (based on endianness) Operand lo = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rt)); - Operand hi = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rt | 1)); + Operand hi = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rt2)); Operand lblBigEndian = Label(); Operand lblEnd = Label(); diff --git a/ARMeilleure/Instructions/InstEmitMul32.cs b/ARMeilleure/Instructions/InstEmitMul32.cs index 868a1f4217..0822f92c30 100644 --- a/ARMeilleure/Instructions/InstEmitMul32.cs +++ b/ARMeilleure/Instructions/InstEmitMul32.cs @@ -25,7 +25,7 @@ namespace ARMeilleure.Instructions public static void Mla(ArmEmitterContext context) { - OpCode32AluMla op = (OpCode32AluMla)context.CurrOp; + IOpCode32AluMla op = (IOpCode32AluMla)context.CurrOp; Operand n = GetAluN(context); Operand m = GetAluM(context); @@ -43,7 +43,7 @@ namespace ARMeilleure.Instructions public static void Mls(ArmEmitterContext context) { - OpCode32AluMla op = (OpCode32AluMla)context.CurrOp; + IOpCode32AluMla op = (IOpCode32AluMla)context.CurrOp; Operand n = GetAluN(context); Operand m = GetAluM(context); @@ -71,7 +71,7 @@ namespace ARMeilleure.Instructions private static void EmitSmmul(ArmEmitterContext context, MullFlags flags) { - OpCode32AluMla op = (OpCode32AluMla)context.CurrOp; + IOpCode32AluMla op = (IOpCode32AluMla)context.CurrOp; Operand n = context.SignExtend32(OperandType.I64, GetIntA32(context, op.Rn)); Operand m = context.SignExtend32(OperandType.I64, GetIntA32(context, op.Rm)); @@ -99,7 +99,7 @@ namespace ARMeilleure.Instructions public static void Smla__(ArmEmitterContext context) { - OpCode32AluMla op = (OpCode32AluMla)context.CurrOp; + IOpCode32AluMla op = (IOpCode32AluMla)context.CurrOp; Operand n = GetIntA32(context, op.Rn); Operand m = GetIntA32(context, op.Rm); @@ -142,7 +142,7 @@ namespace ARMeilleure.Instructions public static void Smlal__(ArmEmitterContext context) { - OpCode32AluUmull op = (OpCode32AluUmull)context.CurrOp; + IOpCode32AluUmull op = (IOpCode32AluUmull)context.CurrOp; Operand n = GetIntA32(context, op.Rn); Operand m = GetIntA32(context, op.Rm); @@ -180,7 +180,7 @@ namespace ARMeilleure.Instructions public static void Smlaw_(ArmEmitterContext context) { - OpCode32AluMla op = (OpCode32AluMla)context.CurrOp; + IOpCode32AluMla op = (IOpCode32AluMla)context.CurrOp; Operand n = GetIntA32(context, op.Rn); Operand m = GetIntA32(context, op.Rm); @@ -210,7 +210,7 @@ namespace ARMeilleure.Instructions public static void Smul__(ArmEmitterContext context) { - OpCode32AluMla op = (OpCode32AluMla)context.CurrOp; + IOpCode32AluMla op = (IOpCode32AluMla)context.CurrOp; Operand n = GetIntA32(context, op.Rn); Operand m = GetIntA32(context, op.Rm); @@ -240,7 +240,7 @@ namespace ARMeilleure.Instructions public static void Smull(ArmEmitterContext context) { - OpCode32AluUmull op = (OpCode32AluUmull)context.CurrOp; + IOpCode32AluUmull op = (IOpCode32AluUmull)context.CurrOp; Operand n = context.SignExtend32(OperandType.I64, GetIntA32(context, op.Rn)); Operand m = context.SignExtend32(OperandType.I64, GetIntA32(context, op.Rm)); @@ -261,7 +261,7 @@ namespace ARMeilleure.Instructions public static void Smulw_(ArmEmitterContext context) { - OpCode32AluMla op = (OpCode32AluMla)context.CurrOp; + IOpCode32AluMla op = (IOpCode32AluMla)context.CurrOp; Operand n = GetIntA32(context, op.Rn); Operand m = GetIntA32(context, op.Rm); @@ -285,7 +285,7 @@ namespace ARMeilleure.Instructions public static void Umaal(ArmEmitterContext context) { - OpCode32AluUmull op = (OpCode32AluUmull)context.CurrOp; + IOpCode32AluUmull op = (IOpCode32AluUmull)context.CurrOp; Operand n = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rn)); Operand m = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rm)); @@ -310,7 +310,7 @@ namespace ARMeilleure.Instructions public static void Umull(ArmEmitterContext context) { - OpCode32AluUmull op = (OpCode32AluUmull)context.CurrOp; + IOpCode32AluUmull op = (IOpCode32AluUmull)context.CurrOp; Operand n = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rn)); Operand m = context.ZeroExtend32(OperandType.I64, GetIntA32(context, op.Rm)); @@ -331,7 +331,7 @@ namespace ARMeilleure.Instructions private static void EmitMlal(ArmEmitterContext context, bool signed) { - OpCode32AluUmull op = (OpCode32AluUmull)context.CurrOp; + IOpCode32AluUmull op = (IOpCode32AluUmull)context.CurrOp; Operand n = GetIntA32(context, op.Rn); Operand m = GetIntA32(context, op.Rm);