aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ARMeilleure/Decoders/IOpCode32MemRsImm.cs8
-rw-r--r--ARMeilleure/Decoders/OpCode32MemMult.cs11
-rw-r--r--ARMeilleure/Decoders/OpCode32MemRsImm.cs2
-rw-r--r--ARMeilleure/Decoders/OpCodeT16BImmCmp.cs4
-rw-r--r--ARMeilleure/Decoders/OpCodeT32MemImm8D.cs31
-rw-r--r--ARMeilleure/Decoders/OpCodeT32MemLdEx.cs24
-rw-r--r--ARMeilleure/Decoders/OpCodeT32MemMult.cs52
-rw-r--r--ARMeilleure/Decoders/OpCodeT32MemRsImm.cs30
-rw-r--r--ARMeilleure/Decoders/OpCodeT32MemStEx.cs25
-rw-r--r--ARMeilleure/Decoders/OpCodeTable.cs10
-rw-r--r--ARMeilleure/Instructions/InstEmitFlow32.cs2
-rw-r--r--ARMeilleure/Instructions/InstEmitMemoryHelper.cs4
-rw-r--r--ARMeilleure/Translation/ControlFlowGraph.cs2
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)
{