diff options
-rw-r--r-- | ARMeilleure/Decoders/IOpCode32MemRsImm.cs | 8 | ||||
-rw-r--r-- | ARMeilleure/Decoders/OpCode32MemMult.cs | 11 | ||||
-rw-r--r-- | ARMeilleure/Decoders/OpCode32MemRsImm.cs | 2 | ||||
-rw-r--r-- | ARMeilleure/Decoders/OpCodeT16BImmCmp.cs | 4 | ||||
-rw-r--r-- | ARMeilleure/Decoders/OpCodeT32MemImm8D.cs | 31 | ||||
-rw-r--r-- | ARMeilleure/Decoders/OpCodeT32MemLdEx.cs | 24 | ||||
-rw-r--r-- | ARMeilleure/Decoders/OpCodeT32MemMult.cs | 52 | ||||
-rw-r--r-- | ARMeilleure/Decoders/OpCodeT32MemRsImm.cs | 30 | ||||
-rw-r--r-- | ARMeilleure/Decoders/OpCodeT32MemStEx.cs | 25 | ||||
-rw-r--r-- | ARMeilleure/Decoders/OpCodeTable.cs | 10 | ||||
-rw-r--r-- | ARMeilleure/Instructions/InstEmitFlow32.cs | 2 | ||||
-rw-r--r-- | ARMeilleure/Instructions/InstEmitMemoryHelper.cs | 4 | ||||
-rw-r--r-- | ARMeilleure/Translation/ControlFlowGraph.cs | 2 |
13 files changed, 190 insertions, 15 deletions
diff --git a/ARMeilleure/Decoders/IOpCode32MemRsImm.cs b/ARMeilleure/Decoders/IOpCode32MemRsImm.cs new file mode 100644 index 00000000..65b7ee0b --- /dev/null +++ b/ARMeilleure/Decoders/IOpCode32MemRsImm.cs @@ -0,0 +1,8 @@ +namespace ARMeilleure.Decoders +{ + interface IOpCode32MemRsImm : IOpCode32Mem + { + int Rm { get; } + ShiftType ShiftType { get; } + } +}
\ No newline at end of file diff --git a/ARMeilleure/Decoders/OpCode32MemMult.cs b/ARMeilleure/Decoders/OpCode32MemMult.cs index cc726196..522b96bb 100644 --- a/ARMeilleure/Decoders/OpCode32MemMult.cs +++ b/ARMeilleure/Decoders/OpCode32MemMult.cs @@ -1,3 +1,5 @@ +using System.Numerics; + namespace ARMeilleure.Decoders { class OpCode32MemMult : OpCode32, IOpCode32MemMult @@ -23,14 +25,7 @@ namespace ARMeilleure.Decoders RegisterMask = opCode & 0xffff; - int regsSize = 0; - - for (int index = 0; index < 16; index++) - { - regsSize += (RegisterMask >> index) & 1; - } - - regsSize *= 4; + int regsSize = BitOperations.PopCount((uint)RegisterMask) * 4; if (!u) { diff --git a/ARMeilleure/Decoders/OpCode32MemRsImm.cs b/ARMeilleure/Decoders/OpCode32MemRsImm.cs index dc5f0fd3..e1284cf7 100644 --- a/ARMeilleure/Decoders/OpCode32MemRsImm.cs +++ b/ARMeilleure/Decoders/OpCode32MemRsImm.cs @@ -1,6 +1,6 @@ namespace ARMeilleure.Decoders { - class OpCode32MemRsImm : OpCode32Mem + class OpCode32MemRsImm : OpCode32Mem, IOpCode32MemRsImm { public int Rm { get; } public ShiftType ShiftType { get; } diff --git a/ARMeilleure/Decoders/OpCodeT16BImmCmp.cs b/ARMeilleure/Decoders/OpCodeT16BImmCmp.cs index ab7ae13f..68ebac75 100644 --- a/ARMeilleure/Decoders/OpCodeT16BImmCmp.cs +++ b/ARMeilleure/Decoders/OpCodeT16BImmCmp.cs @@ -1,10 +1,10 @@ namespace ARMeilleure.Decoders { - class OpCodeT16BImmCmp : OpCodeT16 + class OpCodeT16BImmCmp : OpCodeT16, IOpCode32BImm { public int Rn { get; } - public int Immediate { get; } + public long Immediate { get; } public static new OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16BImmCmp(inst, address, opCode); diff --git a/ARMeilleure/Decoders/OpCodeT32MemImm8D.cs b/ARMeilleure/Decoders/OpCodeT32MemImm8D.cs new file mode 100644 index 00000000..18eeffa4 --- /dev/null +++ b/ARMeilleure/Decoders/OpCodeT32MemImm8D.cs @@ -0,0 +1,31 @@ +namespace ARMeilleure.Decoders +{ + class OpCodeT32MemImm8D : OpCodeT32, IOpCode32Mem + { + public int Rt { get; } + public int Rt2 { get; } + public int Rn { get; } + public bool WBack { get; } + public bool IsLoad { get; } + public bool Index { get; } + public bool Add { get; } + public int Immediate { get; } + + public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32MemImm8D(inst, address, opCode); + + public OpCodeT32MemImm8D(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) + { + Rt2 = (opCode >> 8) & 0xf; + Rt = (opCode >> 12) & 0xf; + Rn = (opCode >> 16) & 0xf; + + Index = ((opCode >> 24) & 1) != 0; + Add = ((opCode >> 23) & 1) != 0; + WBack = ((opCode >> 21) & 1) != 0; + + Immediate = opCode & 0xff; + + IsLoad = ((opCode >> 20) & 1) != 0; + } + } +}
\ No newline at end of file diff --git a/ARMeilleure/Decoders/OpCodeT32MemLdEx.cs b/ARMeilleure/Decoders/OpCodeT32MemLdEx.cs new file mode 100644 index 00000000..da565f61 --- /dev/null +++ b/ARMeilleure/Decoders/OpCodeT32MemLdEx.cs @@ -0,0 +1,24 @@ +namespace ARMeilleure.Decoders +{ + class OpCodeT32MemLdEx : OpCodeT32, IOpCode32MemEx + { + public int Rd => 0; + public int Rt { get; } + public int Rn { get; } + + public bool WBack => false; + public bool IsLoad => true; + public bool Index => false; + public bool Add => false; + + public int Immediate => 0; + + public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32MemLdEx(inst, address, opCode); + + public OpCodeT32MemLdEx(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) + { + Rt = (opCode >> 12) & 0xf; + Rn = (opCode >> 16) & 0xf; + } + } +} diff --git a/ARMeilleure/Decoders/OpCodeT32MemMult.cs b/ARMeilleure/Decoders/OpCodeT32MemMult.cs new file mode 100644 index 00000000..a9ba306d --- /dev/null +++ b/ARMeilleure/Decoders/OpCodeT32MemMult.cs @@ -0,0 +1,52 @@ +using System.Numerics; + +namespace ARMeilleure.Decoders +{ + class OpCodeT32MemMult : OpCodeT32, IOpCode32MemMult + { + public int Rn { get; } + + public int RegisterMask { get; } + public int Offset { get; } + public int PostOffset { get; } + + public bool IsLoad { get; } + + public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32MemMult(inst, address, opCode); + + public OpCodeT32MemMult(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) + { + Rn = (opCode >> 16) & 0xf; + + bool isLoad = (opCode & (1 << 20)) != 0; + bool w = (opCode & (1 << 21)) != 0; + bool u = (opCode & (1 << 23)) != 0; + bool p = (opCode & (1 << 24)) != 0; + + RegisterMask = opCode & 0xffff; + + int regsSize = BitOperations.PopCount((uint)RegisterMask) * 4; + + if (!u) + { + Offset -= regsSize; + } + + if (u == p) + { + Offset += 4; + } + + if (w) + { + PostOffset = u ? regsSize : -regsSize; + } + else + { + PostOffset = 0; + } + + IsLoad = isLoad; + } + } +}
\ No newline at end of file diff --git a/ARMeilleure/Decoders/OpCodeT32MemRsImm.cs b/ARMeilleure/Decoders/OpCodeT32MemRsImm.cs new file mode 100644 index 00000000..056d3b46 --- /dev/null +++ b/ARMeilleure/Decoders/OpCodeT32MemRsImm.cs @@ -0,0 +1,30 @@ +namespace ARMeilleure.Decoders +{ + class OpCodeT32MemRsImm : OpCodeT32, IOpCode32MemRsImm + { + public int Rt { get; } + public int Rn { get; } + public int Rm { get; } + public ShiftType ShiftType => ShiftType.Lsl; + + public bool WBack => false; + public bool IsLoad { get; } + public bool Index => true; + public bool Add => true; + + public int Immediate { get; } + + public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32MemRsImm(inst, address, opCode); + + public OpCodeT32MemRsImm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) + { + Rm = (opCode >> 0) & 0xf; + Rt = (opCode >> 12) & 0xf; + Rn = (opCode >> 16) & 0xf; + + IsLoad = (opCode & (1 << 20)) != 0; + + Immediate = (opCode >> 4) & 3; + } + } +} diff --git a/ARMeilleure/Decoders/OpCodeT32MemStEx.cs b/ARMeilleure/Decoders/OpCodeT32MemStEx.cs new file mode 100644 index 00000000..8fe1950e --- /dev/null +++ b/ARMeilleure/Decoders/OpCodeT32MemStEx.cs @@ -0,0 +1,25 @@ +namespace ARMeilleure.Decoders +{ + class OpCodeT32MemStEx : OpCodeT32, IOpCode32MemEx + { + public int Rd { get; } + public int Rt { get; } + public int Rn { get; } + + public bool WBack => false; + public bool IsLoad => false; + public bool Index => false; + public bool Add => false; + + public int Immediate => 0; + + public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT32MemStEx(inst, address, opCode); + + public OpCodeT32MemStEx(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode) + { + Rd = (opCode >> 0) & 0xf; + Rt = (opCode >> 12) & 0xf; + Rn = (opCode >> 16) & 0xf; + } + } +} diff --git a/ARMeilleure/Decoders/OpCodeTable.cs b/ARMeilleure/Decoders/OpCodeTable.cs index 023b9a4a..7fee8a71 100644 --- a/ARMeilleure/Decoders/OpCodeTable.cs +++ b/ARMeilleure/Decoders/OpCodeTable.cs @@ -1070,14 +1070,19 @@ namespace ARMeilleure.Decoders SetT32("11110x011011xxxx0xxx1111xxxxxxxx", InstName.Cmp, InstEmit32.Cmp, OpCodeT32AluImm.Create); SetT32("11101010100<xxxx0xxx<<<<xxxxxxxx", InstName.Eor, InstEmit32.Eor, OpCodeT32AluRsImm.Create); SetT32("11110x00100<xxxx0xxx<<<<xxxxxxxx", InstName.Eor, InstEmit32.Eor, OpCodeT32AluImm.Create); + SetT32("111010001101xxxxxxxx111111101111", InstName.Ldaex, InstEmit32.Ldaex, 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("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("111110001001xxxxxxxxxxxxxxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT32MemImm12.Create); + SetT32("1110100>x1>1<<<<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); @@ -1102,10 +1107,15 @@ 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("111010001100xxxxxxxx11111110xxxx", InstName.Stlex, InstEmit32.Stlex, 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); SetT32("111110001100xxxxxxxxxxxxxxxxxxxx", InstName.Str, InstEmit32.Str, OpCodeT32MemImm12.Create); + 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("1110100>x1>0<<<<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("11101011101<xxxx0xxx<<<<xxxxxxxx", InstName.Sub, InstEmit32.Sub, OpCodeT32AluRsImm.Create); diff --git a/ARMeilleure/Instructions/InstEmitFlow32.cs b/ARMeilleure/Instructions/InstEmitFlow32.cs index 064aeb36..030713fb 100644 --- a/ARMeilleure/Instructions/InstEmitFlow32.cs +++ b/ARMeilleure/Instructions/InstEmitFlow32.cs @@ -88,7 +88,7 @@ namespace ARMeilleure.Instructions { OpCodeT16BImmCmp op = (OpCodeT16BImmCmp)context.CurrOp; - Operand value = GetIntOrZR(context, op.Rn); + Operand value = GetIntA32(context, op.Rn); Operand lblTarget = context.GetLabel((ulong)op.Immediate); if (onNotZero) diff --git a/ARMeilleure/Instructions/InstEmitMemoryHelper.cs b/ARMeilleure/Instructions/InstEmitMemoryHelper.cs index ecb644a2..2877d53e 100644 --- a/ARMeilleure/Instructions/InstEmitMemoryHelper.cs +++ b/ARMeilleure/Instructions/InstEmitMemoryHelper.cs @@ -547,7 +547,7 @@ namespace ARMeilleure.Instructions { switch (context.CurrOp) { - case OpCode32MemRsImm op: return GetMShiftedByImmediate(context, op, setCarry); + case IOpCode32MemRsImm op: return GetMShiftedByImmediate(context, op, setCarry); case IOpCode32MemReg op: return GetIntA32(context, op.Rm); @@ -564,7 +564,7 @@ namespace ARMeilleure.Instructions return new InvalidOperationException($"Invalid OpCode type \"{opCode?.GetType().Name ?? "null"}\"."); } - public static Operand GetMShiftedByImmediate(ArmEmitterContext context, OpCode32MemRsImm op, bool setCarry) + public static Operand GetMShiftedByImmediate(ArmEmitterContext context, IOpCode32MemRsImm op, bool setCarry) { Operand m = GetIntA32(context, op.Rm); diff --git a/ARMeilleure/Translation/ControlFlowGraph.cs b/ARMeilleure/Translation/ControlFlowGraph.cs index 77d2bc46..c935f152 100644 --- a/ARMeilleure/Translation/ControlFlowGraph.cs +++ b/ARMeilleure/Translation/ControlFlowGraph.cs @@ -14,7 +14,7 @@ namespace ARMeilleure.Translation public BasicBlock Entry { get; } public IntrusiveList<BasicBlock> Blocks { get; } public BasicBlock[] PostOrderBlocks => _postOrderBlocks; - public int[] PostOrderMap => _postOrderMap; + public int[] PostOrderMap => _postOrderMap; public ControlFlowGraph(BasicBlock entry, IntrusiveList<BasicBlock> blocks, int localsCount) { |