aboutsummaryrefslogtreecommitdiff
path: root/ARMeilleure/Decoders
diff options
context:
space:
mode:
Diffstat (limited to 'ARMeilleure/Decoders')
-rw-r--r--ARMeilleure/Decoders/Decoder.cs21
-rw-r--r--ARMeilleure/Decoders/IOpCode32Adr.cs9
-rw-r--r--ARMeilleure/Decoders/IOpCode32Alu.cs2
-rw-r--r--ARMeilleure/Decoders/IOpCode32AluImm.cs9
-rw-r--r--ARMeilleure/Decoders/IOpCode32AluRsImm.cs10
-rw-r--r--ARMeilleure/Decoders/IOpCode32AluRsReg.cs10
-rw-r--r--ARMeilleure/Decoders/IOpCode32Exception.cs6
-rw-r--r--ARMeilleure/Decoders/IOpCode32Mem.cs4
-rw-r--r--ARMeilleure/Decoders/IOpCode32MemMult.cs2
-rw-r--r--ARMeilleure/Decoders/IOpCode32MemReg.cs7
-rw-r--r--ARMeilleure/Decoders/OpCode.cs5
-rw-r--r--ARMeilleure/Decoders/OpCode32Alu.cs2
-rw-r--r--ARMeilleure/Decoders/OpCode32AluImm.cs2
-rw-r--r--ARMeilleure/Decoders/OpCode32AluMla.cs2
-rw-r--r--ARMeilleure/Decoders/OpCode32AluRsImm.cs2
-rw-r--r--ARMeilleure/Decoders/OpCode32AluRsReg.cs2
-rw-r--r--ARMeilleure/Decoders/OpCode32AluUmull.cs2
-rw-r--r--ARMeilleure/Decoders/OpCode32Exception.cs2
-rw-r--r--ARMeilleure/Decoders/OpCode32MemReg.cs2
-rw-r--r--ARMeilleure/Decoders/OpCodeT16AddSubImm3.cs24
-rw-r--r--ARMeilleure/Decoders/OpCodeT16AddSubReg.cs20
-rw-r--r--ARMeilleure/Decoders/OpCodeT16AddSubSp.cs23
-rw-r--r--ARMeilleure/Decoders/OpCodeT16Adr.cs20
-rw-r--r--ARMeilleure/Decoders/OpCodeT16AluImm8.cs22
-rw-r--r--ARMeilleure/Decoders/OpCodeT16AluImmZero.cs24
-rw-r--r--ARMeilleure/Decoders/OpCodeT16AluRegHigh.cs20
-rw-r--r--ARMeilleure/Decoders/OpCodeT16AluRegLow.cs20
-rw-r--r--ARMeilleure/Decoders/OpCodeT16AluUx.cs22
-rw-r--r--ARMeilleure/Decoders/OpCodeT16BImm11.cs15
-rw-r--r--ARMeilleure/Decoders/OpCodeT16BImm8.cs17
-rw-r--r--ARMeilleure/Decoders/OpCodeT16BImmCmp.cs19
-rw-r--r--ARMeilleure/Decoders/OpCodeT16BReg.cs4
-rw-r--r--ARMeilleure/Decoders/OpCodeT16Exception.cs14
-rw-r--r--ARMeilleure/Decoders/OpCodeT16IfThen.cs34
-rw-r--r--ARMeilleure/Decoders/OpCodeT16MemImm5.cs58
-rw-r--r--ARMeilleure/Decoders/OpCodeT16MemLit.cs26
-rw-r--r--ARMeilleure/Decoders/OpCodeT16MemMult.cs34
-rw-r--r--ARMeilleure/Decoders/OpCodeT16MemReg.cs27
-rw-r--r--ARMeilleure/Decoders/OpCodeT16MemSp.cs28
-rw-r--r--ARMeilleure/Decoders/OpCodeT16MemStack.cs42
-rw-r--r--ARMeilleure/Decoders/OpCodeT16ShiftImm.cs24
-rw-r--r--ARMeilleure/Decoders/OpCodeT16ShiftReg.cs27
-rw-r--r--ARMeilleure/Decoders/OpCodeT16SpRel.cs24
-rw-r--r--ARMeilleure/Decoders/OpCodeTable.cs134
44 files changed, 766 insertions, 57 deletions
diff --git a/ARMeilleure/Decoders/Decoder.cs b/ARMeilleure/Decoders/Decoder.cs
index eb085999..46774f41 100644
--- a/ARMeilleure/Decoders/Decoder.cs
+++ b/ARMeilleure/Decoders/Decoder.cs
@@ -195,12 +195,13 @@ namespace ARMeilleure.Decoders
ulong limitAddress)
{
ulong address = block.Address;
+ int itBlockSize = 0;
OpCode opCode;
do
{
- if (address >= limitAddress)
+ if (address >= limitAddress && itBlockSize == 0)
{
break;
}
@@ -210,6 +211,15 @@ namespace ARMeilleure.Decoders
block.OpCodes.Add(opCode);
address += (ulong)opCode.OpCodeSizeInBytes;
+
+ if (opCode is OpCodeT16IfThen it)
+ {
+ itBlockSize = it.IfThenBlockSize;
+ }
+ else if (itBlockSize > 0)
+ {
+ itBlockSize--;
+ }
}
while (!(IsBranch(opCode) || IsException(opCode)));
@@ -345,7 +355,14 @@ namespace ARMeilleure.Decoders
}
else
{
- return new OpCode(inst, address, opCode);
+ if (mode == ExecutionMode.Aarch32Thumb)
+ {
+ return new OpCodeT16(inst, address, opCode);
+ }
+ else
+ {
+ return new OpCode(inst, address, opCode);
+ }
}
}
}
diff --git a/ARMeilleure/Decoders/IOpCode32Adr.cs b/ARMeilleure/Decoders/IOpCode32Adr.cs
new file mode 100644
index 00000000..40a4f526
--- /dev/null
+++ b/ARMeilleure/Decoders/IOpCode32Adr.cs
@@ -0,0 +1,9 @@
+namespace ARMeilleure.Decoders
+{
+ interface IOpCode32Adr
+ {
+ int Rd { get; }
+
+ int Immediate { get; }
+ }
+}
diff --git a/ARMeilleure/Decoders/IOpCode32Alu.cs b/ARMeilleure/Decoders/IOpCode32Alu.cs
index 72aea30e..9876f107 100644
--- a/ARMeilleure/Decoders/IOpCode32Alu.cs
+++ b/ARMeilleure/Decoders/IOpCode32Alu.cs
@@ -5,6 +5,6 @@ namespace ARMeilleure.Decoders
int Rd { get; }
int Rn { get; }
- bool SetFlags { get; }
+ bool? SetFlags { get; }
}
} \ No newline at end of file
diff --git a/ARMeilleure/Decoders/IOpCode32AluImm.cs b/ARMeilleure/Decoders/IOpCode32AluImm.cs
new file mode 100644
index 00000000..342fb8f6
--- /dev/null
+++ b/ARMeilleure/Decoders/IOpCode32AluImm.cs
@@ -0,0 +1,9 @@
+namespace ARMeilleure.Decoders
+{
+ interface IOpCode32AluImm : IOpCode32Alu
+ {
+ int Immediate { get; }
+
+ bool IsRotated { get; }
+ }
+} \ No newline at end of file
diff --git a/ARMeilleure/Decoders/IOpCode32AluRsImm.cs b/ARMeilleure/Decoders/IOpCode32AluRsImm.cs
new file mode 100644
index 00000000..e899a659
--- /dev/null
+++ b/ARMeilleure/Decoders/IOpCode32AluRsImm.cs
@@ -0,0 +1,10 @@
+namespace ARMeilleure.Decoders
+{
+ interface IOpCode32AluRsImm : IOpCode32Alu
+ {
+ int Rm { get; }
+ int Immediate { get; }
+
+ ShiftType ShiftType { get; }
+ }
+} \ No newline at end of file
diff --git a/ARMeilleure/Decoders/IOpCode32AluRsReg.cs b/ARMeilleure/Decoders/IOpCode32AluRsReg.cs
new file mode 100644
index 00000000..879db059
--- /dev/null
+++ b/ARMeilleure/Decoders/IOpCode32AluRsReg.cs
@@ -0,0 +1,10 @@
+namespace ARMeilleure.Decoders
+{
+ interface IOpCode32AluRsReg : IOpCode32Alu
+ {
+ int Rm { get; }
+ int Rs { get; }
+
+ ShiftType ShiftType { get; }
+ }
+} \ No newline at end of file
diff --git a/ARMeilleure/Decoders/IOpCode32Exception.cs b/ARMeilleure/Decoders/IOpCode32Exception.cs
new file mode 100644
index 00000000..82819bdd
--- /dev/null
+++ b/ARMeilleure/Decoders/IOpCode32Exception.cs
@@ -0,0 +1,6 @@
+namespace ARMeilleure.Decoders;
+
+interface IOpCode32Exception
+{
+ int Id { get; }
+} \ No newline at end of file
diff --git a/ARMeilleure/Decoders/IOpCode32Mem.cs b/ARMeilleure/Decoders/IOpCode32Mem.cs
index 8fdc9dad..145bc618 100644
--- a/ARMeilleure/Decoders/IOpCode32Mem.cs
+++ b/ARMeilleure/Decoders/IOpCode32Mem.cs
@@ -7,5 +7,9 @@ namespace ARMeilleure.Decoders
bool WBack { get; }
bool IsLoad { get; }
+ bool Index { get; }
+ bool Add { get; }
+
+ int Immediate { get; }
}
} \ No newline at end of file
diff --git a/ARMeilleure/Decoders/IOpCode32MemMult.cs b/ARMeilleure/Decoders/IOpCode32MemMult.cs
index 18fd3f6b..4b891bc1 100644
--- a/ARMeilleure/Decoders/IOpCode32MemMult.cs
+++ b/ARMeilleure/Decoders/IOpCode32MemMult.cs
@@ -9,5 +9,7 @@ namespace ARMeilleure.Decoders
int PostOffset { get; }
bool IsLoad { get; }
+
+ int Offset { get; }
}
} \ No newline at end of file
diff --git a/ARMeilleure/Decoders/IOpCode32MemReg.cs b/ARMeilleure/Decoders/IOpCode32MemReg.cs
new file mode 100644
index 00000000..7fe1b022
--- /dev/null
+++ b/ARMeilleure/Decoders/IOpCode32MemReg.cs
@@ -0,0 +1,7 @@
+namespace ARMeilleure.Decoders
+{
+ interface IOpCode32MemReg : IOpCode32Mem
+ {
+ int Rm { get; }
+ }
+} \ No newline at end of file
diff --git a/ARMeilleure/Decoders/OpCode.cs b/ARMeilleure/Decoders/OpCode.cs
index e0b14e66..f9aed792 100644
--- a/ARMeilleure/Decoders/OpCode.cs
+++ b/ARMeilleure/Decoders/OpCode.cs
@@ -18,10 +18,9 @@ namespace ARMeilleure.Decoders
public OpCode(InstDescriptor inst, ulong address, int opCode)
{
- Address = address;
- RawOpCode = opCode;
-
Instruction = inst;
+ Address = address;
+ RawOpCode = opCode;
RegisterSize = RegisterSize.Int64;
}
diff --git a/ARMeilleure/Decoders/OpCode32Alu.cs b/ARMeilleure/Decoders/OpCode32Alu.cs
index 6c7723bb..1625aee0 100644
--- a/ARMeilleure/Decoders/OpCode32Alu.cs
+++ b/ARMeilleure/Decoders/OpCode32Alu.cs
@@ -5,7 +5,7 @@ namespace ARMeilleure.Decoders
public int Rd { get; }
public int Rn { get; }
- public bool SetFlags { get; }
+ public bool? SetFlags { get; }
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32Alu(inst, address, opCode);
diff --git a/ARMeilleure/Decoders/OpCode32AluImm.cs b/ARMeilleure/Decoders/OpCode32AluImm.cs
index 9d82db4b..b5435aaf 100644
--- a/ARMeilleure/Decoders/OpCode32AluImm.cs
+++ b/ARMeilleure/Decoders/OpCode32AluImm.cs
@@ -2,7 +2,7 @@ using ARMeilleure.Common;
namespace ARMeilleure.Decoders
{
- class OpCode32AluImm : OpCode32Alu
+ class OpCode32AluImm : OpCode32Alu, IOpCode32AluImm
{
public int Immediate { get; }
diff --git a/ARMeilleure/Decoders/OpCode32AluMla.cs b/ARMeilleure/Decoders/OpCode32AluMla.cs
index 4e9b25e3..74894667 100644
--- a/ARMeilleure/Decoders/OpCode32AluMla.cs
+++ b/ARMeilleure/Decoders/OpCode32AluMla.cs
@@ -10,7 +10,7 @@
public bool NHigh { get; }
public bool MHigh { get; }
public bool R { get; }
- public bool SetFlags { get; }
+ public bool? SetFlags { get; }
public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCode32AluMla(inst, address, opCode);
diff --git a/ARMeilleure/Decoders/OpCode32AluRsImm.cs b/ARMeilleure/Decoders/OpCode32AluRsImm.cs
index f24e7757..c2dee6c9 100644
--- a/ARMeilleure/Decoders/OpCode32AluRsImm.cs
+++ b/ARMeilleure/Decoders/OpCode32AluRsImm.cs
@@ -1,6 +1,6 @@
namespace ARMeilleure.Decoders
{
- class OpCode32AluRsImm : OpCode32Alu
+ class OpCode32AluRsImm : OpCode32Alu, IOpCode32AluRsImm
{
public int Rm { get; }
public int Immediate { get; }
diff --git a/ARMeilleure/Decoders/OpCode32AluRsReg.cs b/ARMeilleure/Decoders/OpCode32AluRsReg.cs
index 574588f8..04740d08 100644
--- a/ARMeilleure/Decoders/OpCode32AluRsReg.cs
+++ b/ARMeilleure/Decoders/OpCode32AluRsReg.cs
@@ -1,6 +1,6 @@
namespace ARMeilleure.Decoders
{
- class OpCode32AluRsReg : OpCode32Alu
+ class OpCode32AluRsReg : OpCode32Alu, IOpCode32AluRsReg
{
public int Rm { get; }
public int Rs { get; }
diff --git a/ARMeilleure/Decoders/OpCode32AluUmull.cs b/ARMeilleure/Decoders/OpCode32AluUmull.cs
index e4f0895b..bbdaaeae 100644
--- a/ARMeilleure/Decoders/OpCode32AluUmull.cs
+++ b/ARMeilleure/Decoders/OpCode32AluUmull.cs
@@ -10,7 +10,7 @@
public bool NHigh { get; }
public bool MHigh { get; }
- public bool SetFlags { 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);
diff --git a/ARMeilleure/Decoders/OpCode32Exception.cs b/ARMeilleure/Decoders/OpCode32Exception.cs
index e963be64..b4edcc10 100644
--- a/ARMeilleure/Decoders/OpCode32Exception.cs
+++ b/ARMeilleure/Decoders/OpCode32Exception.cs
@@ -1,6 +1,6 @@
namespace ARMeilleure.Decoders
{
- class OpCode32Exception : OpCode32
+ class OpCode32Exception : OpCode32, IOpCode32Exception
{
public int Id { get; }
diff --git a/ARMeilleure/Decoders/OpCode32MemReg.cs b/ARMeilleure/Decoders/OpCode32MemReg.cs
index c9434399..786f37fa 100644
--- a/ARMeilleure/Decoders/OpCode32MemReg.cs
+++ b/ARMeilleure/Decoders/OpCode32MemReg.cs
@@ -1,6 +1,6 @@
namespace ARMeilleure.Decoders
{
- class OpCode32MemReg : OpCode32Mem
+ class OpCode32MemReg : OpCode32Mem, IOpCode32MemReg
{
public int Rm { get; }
diff --git a/ARMeilleure/Decoders/OpCodeT16AddSubImm3.cs b/ARMeilleure/Decoders/OpCodeT16AddSubImm3.cs
new file mode 100644
index 00000000..95f18054
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeT16AddSubImm3.cs
@@ -0,0 +1,24 @@
+namespace ARMeilleure.Decoders
+{
+ class OpCodeT16AddSubImm3: OpCodeT16, IOpCode32AluImm
+ {
+ public int Rd { get; }
+ public int Rn { get; }
+
+ public bool? SetFlags => null;
+
+ public int Immediate { get; }
+
+ public bool IsRotated { get; }
+
+ public static new OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16AddSubImm3(inst, address, opCode);
+
+ public OpCodeT16AddSubImm3(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ Rd = (opCode >> 0) & 0x7;
+ Rn = (opCode >> 3) & 0x7;
+ Immediate = (opCode >> 6) & 0x7;
+ IsRotated = false;
+ }
+ }
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16AddSubReg.cs b/ARMeilleure/Decoders/OpCodeT16AddSubReg.cs
new file mode 100644
index 00000000..2a407b2d
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeT16AddSubReg.cs
@@ -0,0 +1,20 @@
+namespace ARMeilleure.Decoders
+{
+ class OpCodeT16AddSubReg : OpCodeT16, IOpCode32AluReg
+ {
+ public int Rm { get; }
+ public int Rd { get; }
+ public int Rn { get; }
+
+ public bool? SetFlags => null;
+
+ public static new OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16AddSubReg(inst, address, opCode);
+
+ public OpCodeT16AddSubReg(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ Rd = (opCode >> 0) & 0x7;
+ Rn = (opCode >> 3) & 0x7;
+ Rm = (opCode >> 6) & 0x7;
+ }
+ }
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16AddSubSp.cs b/ARMeilleure/Decoders/OpCodeT16AddSubSp.cs
new file mode 100644
index 00000000..b66fe0cd
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeT16AddSubSp.cs
@@ -0,0 +1,23 @@
+using ARMeilleure.State;
+
+namespace ARMeilleure.Decoders
+{
+ class OpCodeT16AddSubSp : OpCodeT16, IOpCode32AluImm
+ {
+ public int Rd => RegisterAlias.Aarch32Sp;
+ public int Rn => RegisterAlias.Aarch32Sp;
+
+ public bool? SetFlags => false;
+
+ public int Immediate { get; }
+
+ public bool IsRotated => false;
+
+ public static new OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16AddSubSp(inst, address, opCode);
+
+ public OpCodeT16AddSubSp(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ Immediate = ((opCode >> 0) & 0x7f) << 2;
+ }
+ }
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16Adr.cs b/ARMeilleure/Decoders/OpCodeT16Adr.cs
new file mode 100644
index 00000000..ef14791d
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeT16Adr.cs
@@ -0,0 +1,20 @@
+namespace ARMeilleure.Decoders
+{
+ class OpCodeT16Adr : OpCodeT16, IOpCode32Adr
+ {
+ public int Rd { get; }
+
+ public bool Add => true;
+ public int Immediate { get; }
+
+ public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16Adr(inst, address, opCode);
+
+ public OpCodeT16Adr(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ Rd = (opCode >> 8) & 7;
+
+ int imm = (opCode & 0xff) << 2;
+ Immediate = (int)(GetPc() & 0xfffffffc) + imm;
+ }
+ }
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16AluImm8.cs b/ARMeilleure/Decoders/OpCodeT16AluImm8.cs
index d31f37a2..673a4604 100644
--- a/ARMeilleure/Decoders/OpCodeT16AluImm8.cs
+++ b/ARMeilleure/Decoders/OpCodeT16AluImm8.cs
@@ -1,22 +1,24 @@
-namespace ARMeilleure.Decoders
+namespace ARMeilleure.Decoders
{
- class OpCodeT16AluImm8 : OpCodeT16, IOpCode32Alu
+ class OpCodeT16AluImm8 : OpCodeT16, IOpCode32AluImm
{
- private int _rdn;
+ public int Rd { get; }
+ public int Rn { get; }
- public int Rd => _rdn;
- public int Rn => _rdn;
-
- public bool SetFlags => false;
+ public bool? SetFlags => null;
public int Immediate { get; }
- public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16AluImm8(inst, address, opCode);
+ public bool IsRotated { get; }
+
+ public static new OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16AluImm8(inst, address, opCode);
public OpCodeT16AluImm8(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
{
+ Rd = (opCode >> 8) & 0x7;
+ Rn = (opCode >> 8) & 0x7;
Immediate = (opCode >> 0) & 0xff;
- _rdn = (opCode >> 8) & 0x7;
+ IsRotated = false;
}
}
-} \ No newline at end of file
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16AluImmZero.cs b/ARMeilleure/Decoders/OpCodeT16AluImmZero.cs
new file mode 100644
index 00000000..b23f8fe0
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeT16AluImmZero.cs
@@ -0,0 +1,24 @@
+namespace ARMeilleure.Decoders
+{
+ class OpCodeT16AluImmZero : OpCodeT16, IOpCode32AluImm
+ {
+ public int Rd { get; }
+ public int Rn { get; }
+
+ public bool? SetFlags => null;
+
+ public int Immediate { get; }
+
+ public bool IsRotated { get; }
+
+ public static new OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16AluImmZero(inst, address, opCode);
+
+ public OpCodeT16AluImmZero(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ Rd = (opCode >> 0) & 0x7;
+ Rn = (opCode >> 3) & 0x7;
+ Immediate = 0;
+ IsRotated = false;
+ }
+ }
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16AluRegHigh.cs b/ARMeilleure/Decoders/OpCodeT16AluRegHigh.cs
new file mode 100644
index 00000000..6d5ac8fd
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeT16AluRegHigh.cs
@@ -0,0 +1,20 @@
+namespace ARMeilleure.Decoders
+{
+ class OpCodeT16AluRegHigh : OpCodeT16, IOpCode32AluReg
+ {
+ public int Rm { get; }
+ public int Rd { get; }
+ public int Rn { get; }
+
+ public bool? SetFlags => false;
+
+ public static new OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16AluRegHigh(inst, address, opCode);
+
+ public OpCodeT16AluRegHigh(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ Rd = ((opCode >> 0) & 0x7) | ((opCode >> 4) & 0x8);
+ Rn = ((opCode >> 0) & 0x7) | ((opCode >> 4) & 0x8);
+ Rm = (opCode >> 3) & 0xf;
+ }
+ }
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16AluRegLow.cs b/ARMeilleure/Decoders/OpCodeT16AluRegLow.cs
new file mode 100644
index 00000000..b37b4f66
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeT16AluRegLow.cs
@@ -0,0 +1,20 @@
+namespace ARMeilleure.Decoders
+{
+ class OpCodeT16AluRegLow : OpCodeT16, IOpCode32AluReg
+ {
+ public int Rm { get; }
+ public int Rd { get; }
+ public int Rn { get; }
+
+ public bool? SetFlags => null;
+
+ public static new OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16AluRegLow(inst, address, opCode);
+
+ public OpCodeT16AluRegLow(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ Rd = (opCode >> 0) & 0x7;
+ Rn = (opCode >> 0) & 0x7;
+ Rm = (opCode >> 3) & 0x7;
+ }
+ }
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16AluUx.cs b/ARMeilleure/Decoders/OpCodeT16AluUx.cs
new file mode 100644
index 00000000..11d3a8fe
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeT16AluUx.cs
@@ -0,0 +1,22 @@
+namespace ARMeilleure.Decoders
+{
+ class OpCodeT16AluUx : OpCodeT16, IOpCode32AluUx
+ {
+ public int Rm { get; }
+ public int Rd { get; }
+ public int Rn { get; }
+
+ public bool? SetFlags => false;
+
+ public int RotateBits => 0;
+ public bool Add => false;
+
+ public static new OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16AluUx(inst, address, opCode);
+
+ public OpCodeT16AluUx(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ Rd = (opCode >> 0) & 0x7;
+ Rm = (opCode >> 3) & 0x7;
+ }
+ }
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16BImm11.cs b/ARMeilleure/Decoders/OpCodeT16BImm11.cs
new file mode 100644
index 00000000..42ebec4f
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeT16BImm11.cs
@@ -0,0 +1,15 @@
+namespace ARMeilleure.Decoders
+{
+ class OpCodeT16BImm11 : OpCode32, IOpCode32BImm
+ {
+ public long Immediate { get; }
+
+ public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16BImm11(inst, address, opCode);
+
+ public OpCodeT16BImm11(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ int imm = (opCode << 21) >> 20;
+ Immediate = GetPc() + imm;
+ }
+ }
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16BImm8.cs b/ARMeilleure/Decoders/OpCodeT16BImm8.cs
new file mode 100644
index 00000000..9b3a4ad1
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeT16BImm8.cs
@@ -0,0 +1,17 @@
+namespace ARMeilleure.Decoders
+{
+ class OpCodeT16BImm8 : OpCode32, IOpCode32BImm
+ {
+ public long Immediate { get; }
+
+ public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16BImm8(inst, address, opCode);
+
+ public OpCodeT16BImm8(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ Cond = (Condition)((opCode >> 8) & 0xf);
+
+ int imm = (opCode << 24) >> 23;
+ Immediate = GetPc() + imm;
+ }
+ }
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16BImmCmp.cs b/ARMeilleure/Decoders/OpCodeT16BImmCmp.cs
new file mode 100644
index 00000000..ab7ae13f
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeT16BImmCmp.cs
@@ -0,0 +1,19 @@
+namespace ARMeilleure.Decoders
+{
+ class OpCodeT16BImmCmp : OpCodeT16
+ {
+ public int Rn { get; }
+
+ public int Immediate { get; }
+
+ public static new OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16BImmCmp(inst, address, opCode);
+
+ public OpCodeT16BImmCmp(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ Rn = (opCode >> 0) & 0x7;
+
+ int imm = ((opCode >> 2) & 0x3e) | ((opCode >> 3) & 0x40);
+ Immediate = (int)GetPc() + imm;
+ }
+ }
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16BReg.cs b/ARMeilleure/Decoders/OpCodeT16BReg.cs
index 38c07480..3122cd07 100644
--- a/ARMeilleure/Decoders/OpCodeT16BReg.cs
+++ b/ARMeilleure/Decoders/OpCodeT16BReg.cs
@@ -1,4 +1,4 @@
-namespace ARMeilleure.Decoders
+namespace ARMeilleure.Decoders
{
class OpCodeT16BReg : OpCodeT16, IOpCode32BReg
{
@@ -11,4 +11,4 @@ namespace ARMeilleure.Decoders
Rm = (opCode >> 3) & 0xf;
}
}
-} \ No newline at end of file
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16Exception.cs b/ARMeilleure/Decoders/OpCodeT16Exception.cs
new file mode 100644
index 00000000..bb005083
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeT16Exception.cs
@@ -0,0 +1,14 @@
+namespace ARMeilleure.Decoders
+{
+ class OpCodeT16Exception : OpCodeT16, IOpCode32Exception
+ {
+ public int Id { get; }
+
+ public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16Exception(inst, address, opCode);
+
+ public OpCodeT16Exception(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ Id = opCode & 0xFF;
+ }
+ }
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16IfThen.cs b/ARMeilleure/Decoders/OpCodeT16IfThen.cs
new file mode 100644
index 00000000..bf84d1d3
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeT16IfThen.cs
@@ -0,0 +1,34 @@
+using System.Collections.Generic;
+using System.Reflection.Emit;
+
+namespace ARMeilleure.Decoders
+{
+ class OpCodeT16IfThen : OpCodeT16
+ {
+ public Condition[] IfThenBlockConds { get; }
+
+ public int IfThenBlockSize { get { return IfThenBlockConds.Length; } }
+
+ public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16IfThen(inst, address, opCode);
+
+ public OpCodeT16IfThen(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ List<Condition> conds = new();
+
+ int cond = (opCode >> 4) & 0xf;
+ int mask = opCode & 0xf;
+
+ conds.Add((Condition)cond);
+
+ while ((mask & 7) != 0)
+ {
+ int newLsb = (mask >> 3) & 1;
+ cond = (cond & 0xe) | newLsb;
+ mask <<= 1;
+ conds.Add((Condition)cond);
+ }
+
+ IfThenBlockConds = conds.ToArray();
+ }
+ }
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16MemImm5.cs b/ARMeilleure/Decoders/OpCodeT16MemImm5.cs
new file mode 100644
index 00000000..20ef31e2
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeT16MemImm5.cs
@@ -0,0 +1,58 @@
+using ARMeilleure.Instructions;
+using System;
+
+namespace ARMeilleure.Decoders
+{
+ class OpCodeT16MemImm5 : OpCodeT16, IOpCode32Mem
+ {
+ public int Rt { get; }
+ public int Rn { get; }
+
+ 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 OpCodeT16MemImm5(inst, address, opCode);
+
+ public OpCodeT16MemImm5(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ Rt = (opCode >> 0) & 7;
+ Rn = (opCode >> 3) & 7;
+
+ switch (inst.Name)
+ {
+ case InstName.Ldr:
+ case InstName.Ldrb:
+ case InstName.Ldrh:
+ IsLoad = true;
+ break;
+ case InstName.Str:
+ case InstName.Strb:
+ case InstName.Strh:
+ IsLoad = false;
+ break;
+ }
+
+ switch (inst.Name)
+ {
+ case InstName.Str:
+ case InstName.Ldr:
+ Immediate = ((opCode >> 6) & 0x1f) << 2;
+ break;
+ case InstName.Strb:
+ case InstName.Ldrb:
+ Immediate = ((opCode >> 6) & 0x1f);
+ break;
+ case InstName.Strh:
+ case InstName.Ldrh:
+ Immediate = ((opCode >> 6) & 0x1f) << 1;
+ break;
+ default:
+ throw new InvalidOperationException();
+ }
+ }
+ }
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16MemLit.cs b/ARMeilleure/Decoders/OpCodeT16MemLit.cs
new file mode 100644
index 00000000..f8c16e29
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeT16MemLit.cs
@@ -0,0 +1,26 @@
+using ARMeilleure.State;
+
+namespace ARMeilleure.Decoders
+{
+ class OpCodeT16MemLit : OpCodeT16, IOpCode32Mem
+ {
+ public int Rt { get; }
+ public int Rn => RegisterAlias.Aarch32Pc;
+
+ public bool WBack => false;
+ public bool IsLoad => true;
+ public bool Index => true;
+ public bool Add => true;
+
+ public int Immediate { get; }
+
+ public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16MemLit(inst, address, opCode);
+
+ public OpCodeT16MemLit(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ Rt = (opCode >> 8) & 7;
+
+ Immediate = (opCode & 0xff) << 2;
+ }
+ }
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16MemMult.cs b/ARMeilleure/Decoders/OpCodeT16MemMult.cs
new file mode 100644
index 00000000..f4185cfc
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeT16MemMult.cs
@@ -0,0 +1,34 @@
+using ARMeilleure.Instructions;
+using System;
+using System.Numerics;
+
+namespace ARMeilleure.Decoders
+{
+ class OpCodeT16MemMult : OpCodeT16, IOpCode32MemMult
+ {
+ public int Rn { get; }
+ public int RegisterMask { get; }
+ public int PostOffset { get; }
+ public bool IsLoad { get; }
+ public int Offset { get; }
+
+ public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16MemMult(inst, address, opCode);
+
+ public OpCodeT16MemMult(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ RegisterMask = opCode & 0xff;
+ Rn = (opCode >> 8) & 7;
+
+ int regCount = BitOperations.PopCount((uint)RegisterMask);
+
+ Offset = 0;
+ PostOffset = 4 * regCount;
+ IsLoad = inst.Name switch
+ {
+ InstName.Ldm => true,
+ InstName.Stm => false,
+ _ => throw new InvalidOperationException()
+ };
+ }
+ }
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16MemReg.cs b/ARMeilleure/Decoders/OpCodeT16MemReg.cs
new file mode 100644
index 00000000..71100112
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeT16MemReg.cs
@@ -0,0 +1,27 @@
+namespace ARMeilleure.Decoders
+{
+ class OpCodeT16MemReg : OpCodeT16, IOpCode32MemReg
+ {
+ public int Rm { get; }
+ public int Rt { get; }
+ public int Rn { get; }
+
+ public bool WBack => false;
+ public bool IsLoad { get; }
+ public bool Index => true;
+ public bool Add => true;
+
+ public int Immediate => throw new System.InvalidOperationException();
+
+ public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16MemReg(inst, address, opCode);
+
+ public OpCodeT16MemReg(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ Rt = (opCode >> 0) & 7;
+ Rn = (opCode >> 3) & 7;
+ Rm = (opCode >> 6) & 7;
+
+ IsLoad = ((opCode >> 9) & 7) >= 3;
+ }
+ }
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16MemSp.cs b/ARMeilleure/Decoders/OpCodeT16MemSp.cs
new file mode 100644
index 00000000..a038b915
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeT16MemSp.cs
@@ -0,0 +1,28 @@
+using ARMeilleure.State;
+
+namespace ARMeilleure.Decoders
+{
+ class OpCodeT16MemSp : OpCodeT16, IOpCode32Mem
+ {
+ public int Rt { get; }
+ public int Rn => RegisterAlias.Aarch32Sp;
+
+ 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 OpCodeT16MemSp(inst, address, opCode);
+
+ public OpCodeT16MemSp(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ Rt = (opCode >> 8) & 7;
+
+ IsLoad = ((opCode >> 11) & 1) != 0;
+
+ Immediate = ((opCode >> 0) & 0xff) << 2;
+ }
+ }
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16MemStack.cs b/ARMeilleure/Decoders/OpCodeT16MemStack.cs
new file mode 100644
index 00000000..9d7b0d20
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeT16MemStack.cs
@@ -0,0 +1,42 @@
+using ARMeilleure.Instructions;
+using ARMeilleure.State;
+using System;
+using System.Numerics;
+
+namespace ARMeilleure.Decoders
+{
+ class OpCodeT16MemStack : OpCodeT16, IOpCode32MemMult
+ {
+ public int Rn => RegisterAlias.Aarch32Sp;
+ public int RegisterMask { get; }
+ public int PostOffset { get; }
+ public bool IsLoad { get; }
+ public int Offset { get; }
+
+ public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16MemStack(inst, address, opCode);
+
+ public OpCodeT16MemStack(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ int extra = (opCode >> 8) & 1;
+ int regCount = BitOperations.PopCount((uint)opCode & 0x1ff);
+
+ switch (inst.Name)
+ {
+ case InstName.Push:
+ RegisterMask = (opCode & 0xff) | (extra << 14);
+ IsLoad = false;
+ Offset = -4 * regCount;
+ PostOffset = -4 * regCount;
+ break;
+ case InstName.Pop:
+ RegisterMask = (opCode & 0xff) | (extra << 15);
+ IsLoad = true;
+ Offset = 0;
+ PostOffset = 4 * regCount;
+ break;
+ default:
+ throw new InvalidOperationException();
+ }
+ }
+ }
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16ShiftImm.cs b/ARMeilleure/Decoders/OpCodeT16ShiftImm.cs
new file mode 100644
index 00000000..a540026e
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeT16ShiftImm.cs
@@ -0,0 +1,24 @@
+namespace ARMeilleure.Decoders
+{
+ class OpCodeT16ShiftImm : OpCodeT16, IOpCode32AluRsImm
+ {
+ public int Rd { get; }
+ public int Rn { get; }
+ public int Rm { get; }
+
+ public int Immediate { get; }
+ public ShiftType ShiftType { get; }
+
+ public bool? SetFlags => null;
+
+ public static new OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16ShiftImm(inst, address, opCode);
+
+ public OpCodeT16ShiftImm(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ Rd = (opCode >> 0) & 0x7;
+ Rm = (opCode >> 3) & 0x7;
+ Immediate = (opCode >> 6) & 0x1F;
+ ShiftType = (ShiftType)((opCode >> 11) & 3);
+ }
+ }
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16ShiftReg.cs b/ARMeilleure/Decoders/OpCodeT16ShiftReg.cs
new file mode 100644
index 00000000..9f898281
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeT16ShiftReg.cs
@@ -0,0 +1,27 @@
+namespace ARMeilleure.Decoders
+{
+ class OpCodeT16ShiftReg : OpCodeT16, IOpCode32AluRsReg
+ {
+ public int Rm { get; }
+ public int Rs { get; }
+ public int Rd { get; }
+
+ public int Rn { get; }
+
+ public ShiftType ShiftType { get; }
+
+ public bool? SetFlags => null;
+
+ public new static OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16ShiftReg(inst, address, opCode);
+
+ public OpCodeT16ShiftReg(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ Rd = (opCode >> 0) & 7;
+ Rm = (opCode >> 0) & 7;
+ Rn = (opCode >> 3) & 7;
+ Rs = (opCode >> 3) & 7;
+
+ ShiftType = (ShiftType)(((opCode >> 6) & 1) | ((opCode >> 7) & 2));
+ }
+ }
+}
diff --git a/ARMeilleure/Decoders/OpCodeT16SpRel.cs b/ARMeilleure/Decoders/OpCodeT16SpRel.cs
new file mode 100644
index 00000000..d737f5bd
--- /dev/null
+++ b/ARMeilleure/Decoders/OpCodeT16SpRel.cs
@@ -0,0 +1,24 @@
+using ARMeilleure.State;
+
+namespace ARMeilleure.Decoders
+{
+ class OpCodeT16SpRel : OpCodeT16, IOpCode32AluImm
+ {
+ public int Rd { get; }
+ public int Rn => RegisterAlias.Aarch32Sp;
+
+ public bool? SetFlags => false;
+
+ public int Immediate { get; }
+
+ public bool IsRotated => false;
+
+ public static new OpCode Create(InstDescriptor inst, ulong address, int opCode) => new OpCodeT16SpRel(inst, address, opCode);
+
+ public OpCodeT16SpRel(InstDescriptor inst, ulong address, int opCode) : base(inst, address, opCode)
+ {
+ Rd = (opCode >> 8) & 0x7;
+ Immediate = ((opCode >> 0) & 0xff) << 2;
+ }
+ }
+}
diff --git a/ARMeilleure/Decoders/OpCodeTable.cs b/ARMeilleure/Decoders/OpCodeTable.cs
index 53328a73..1ea8885b 100644
--- a/ARMeilleure/Decoders/OpCodeTable.cs
+++ b/ARMeilleure/Decoders/OpCodeTable.cs
@@ -1,5 +1,4 @@
using ARMeilleure.Instructions;
-using ARMeilleure.State;
using System;
using System.Collections.Generic;
@@ -29,9 +28,9 @@ namespace ARMeilleure.Decoders
}
}
- private static List<InstInfo> AllInstA32 = new List<InstInfo>();
- private static List<InstInfo> AllInstT32 = new List<InstInfo>();
- private static List<InstInfo> AllInstA64 = new List<InstInfo>();
+ private static List<InstInfo> AllInstA32 = new();
+ private static List<InstInfo> AllInstT32 = new();
+ private static List<InstInfo> AllInstA64 = new();
private static InstInfo[][] InstA32FastLookup = new InstInfo[FastLookupSize][];
private static InstInfo[][] InstT32FastLookup = new InstInfo[FastLookupSize][];
@@ -628,7 +627,7 @@ namespace ARMeilleure.Decoders
SetA64("0>001110<<0xxxxx011110xxxxxxxxxx", InstName.Zip2_V, InstEmit.Zip2_V, OpCodeSimdReg.Create);
#endregion
-#region "OpCode Table (AArch32)"
+#region "OpCode Table (AArch32, A32)"
// Base
SetA32("<<<<0010101xxxxxxxxxxxxxxxxxxxxx", InstName.Adc, InstEmit32.Adc, OpCode32AluImm.Create);
SetA32("<<<<0000101xxxxxxxxxxxxxxxx0xxxx", InstName.Adc, InstEmit32.Adc, OpCode32AluRsImm.Create);
@@ -649,7 +648,6 @@ namespace ARMeilleure.Decoders
SetA32("1111101xxxxxxxxxxxxxxxxxxxxxxxxx", InstName.Blx, InstEmit32.Blx, OpCode32BImm.Create);
SetA32("<<<<000100101111111111110011xxxx", InstName.Blx, InstEmit32.Blxr, OpCode32BReg.Create);
SetA32("<<<<000100101111111111110001xxxx", InstName.Bx, InstEmit32.Bx, OpCode32BReg.Create);
- SetT32("xxxxxxxxxxxxxxxx010001110xxxx000", InstName.Bx, InstEmit32.Bx, OpCodeT16BReg.Create);
SetA32("11110101011111111111000000011111", InstName.Clrex, InstEmit32.Clrex, OpCode32.Create);
SetA32("<<<<000101101111xxxx11110001xxxx", InstName.Clz, InstEmit32.Clz, OpCode32AluReg.Create);
SetA32("<<<<00110111xxxx0000xxxxxxxxxxxx", InstName.Cmn, InstEmit32.Cmn, OpCode32AluImm.Create);
@@ -702,7 +700,6 @@ namespace ARMeilleure.Decoders
SetA32("<<<<0001101x0000xxxxxxxxxxx0xxxx", InstName.Mov, InstEmit32.Mov, OpCode32AluRsImm.Create);
SetA32("<<<<0001101x0000xxxxxxxx0xx1xxxx", InstName.Mov, InstEmit32.Mov, OpCode32AluRsReg.Create);
SetA32("<<<<00110000xxxxxxxxxxxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, OpCode32AluImm16.Create);
- SetT32("xxxxxxxxxxxxxxxx00100xxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, OpCodeT16AluImm8.Create);
SetA32("<<<<00110100xxxxxxxxxxxxxxxxxxxx", InstName.Movt, InstEmit32.Movt, OpCode32AluImm16.Create);
SetA32("<<<<1110xxx1xxxxxxxx111xxxx1xxxx", InstName.Mrc, InstEmit32.Mrc, OpCode32System.Create);
SetA32("<<<<11000101xxxxxxxx111xxxxxxxxx", InstName.Mrrc, InstEmit32.Mrrc, OpCode32System.Create);
@@ -975,12 +972,85 @@ namespace ARMeilleure.Decoders
SetA32("111100111x11<<10xxxx00011xx0xxxx", InstName.Vzip, InstEmit32.Vzip, OpCode32SimdCmpZ.Create);
#endregion
- FillFastLookupTable(InstA32FastLookup, AllInstA32);
- FillFastLookupTable(InstT32FastLookup, AllInstT32);
- FillFastLookupTable(InstA64FastLookup, AllInstA64);
+#region "OpCode Table (AArch32, T16/T32)"
+ // T16
+ SetT16("000<<xxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, OpCodeT16ShiftImm.Create);
+ SetT16("0001100xxxxxxxxx", InstName.Add, InstEmit32.Add, OpCodeT16AddSubReg.Create);
+ SetT16("0001101xxxxxxxxx", InstName.Sub, InstEmit32.Sub, OpCodeT16AddSubReg.Create);
+ SetT16("0001110xxxxxxxxx", InstName.Add, InstEmit32.Add, OpCodeT16AddSubImm3.Create);
+ SetT16("0001111xxxxxxxxx", InstName.Sub, InstEmit32.Sub, OpCodeT16AddSubImm3.Create);
+ SetT16("00100xxxxxxxxxxx", InstName.Mov, InstEmit32.Mov, OpCodeT16AluImm8.Create);
+ SetT16("00101xxxxxxxxxxx", InstName.Cmp, InstEmit32.Cmp, OpCodeT16AluImm8.Create);
+ SetT16("00110xxxxxxxxxxx", InstName.Add, InstEmit32.Add, OpCodeT16AluImm8.Create);
+ SetT16("00111xxxxxxxxxxx", InstName.Sub, InstEmit32.Sub, OpCodeT16AluImm8.Create);
+ SetT16("0100000000xxxxxx", InstName.And, InstEmit32.And, OpCodeT16AluRegLow.Create);
+ SetT16("0100000001xxxxxx", InstName.Eor, InstEmit32.Eor, OpCodeT16AluRegLow.Create);
+ SetT16("0100000010xxxxxx", InstName.Mov, InstEmit32.Mov, OpCodeT16ShiftReg.Create);
+ SetT16("0100000011xxxxxx", InstName.Mov, InstEmit32.Mov, OpCodeT16ShiftReg.Create);
+ SetT16("0100000100xxxxxx", InstName.Mov, InstEmit32.Mov, OpCodeT16ShiftReg.Create);
+ SetT16("0100000101xxxxxx", InstName.Adc, InstEmit32.Adc, OpCodeT16AluRegLow.Create);
+ SetT16("0100000110xxxxxx", InstName.Sbc, InstEmit32.Sbc, OpCodeT16AluRegLow.Create);
+ SetT16("0100000111xxxxxx", InstName.Mov, InstEmit32.Mov, OpCodeT16ShiftReg.Create);
+ SetT16("0100001000xxxxxx", InstName.Tst, InstEmit32.Tst, OpCodeT16AluRegLow.Create);
+ SetT16("0100001001xxxxxx", InstName.Rsb, InstEmit32.Rsb, OpCodeT16AluImmZero.Create);
+ SetT16("0100001010xxxxxx", InstName.Cmp, InstEmit32.Cmp, OpCodeT16AluRegLow.Create);
+ SetT16("0100001011xxxxxx", InstName.Cmn, InstEmit32.Cmn, OpCodeT16AluRegLow.Create);
+ SetT16("0100001100xxxxxx", InstName.Orr, InstEmit32.Orr, OpCodeT16AluRegLow.Create);
+ SetT16("0100001101xxxxxx", InstName.Mul, InstEmit32.Mul, OpCodeT16AluRegLow.Create);
+ SetT16("0100001110xxxxxx", InstName.Bic, InstEmit32.Bic, OpCodeT16AluRegLow.Create);
+ SetT16("0100001111xxxxxx", InstName.Mvn, InstEmit32.Mvn, OpCodeT16AluRegLow.Create);
+ SetT16("01000100xxxxxxxx", InstName.Add, InstEmit32.Add, OpCodeT16AluRegHigh.Create);
+ SetT16("01000101xxxxxxxx", InstName.Cmp, InstEmit32.Cmp, OpCodeT16AluRegHigh.Create);
+ SetT16("01000110xxxxxxxx", InstName.Mov, InstEmit32.Mov, OpCodeT16AluRegHigh.Create);
+ SetT16("010001110xxxx000", InstName.Bx, InstEmit32.Bx, OpCodeT16BReg.Create);
+ SetT16("010001111xxxx000", InstName.Blx, InstEmit32.Blx, OpCodeT16BReg.Create);
+ SetT16("01001xxxxxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT16MemLit.Create);
+ SetT16("0101000xxxxxxxxx", InstName.Str, InstEmit32.Str, OpCodeT16MemReg.Create);
+ SetT16("0101001xxxxxxxxx", InstName.Strh, InstEmit32.Strh, OpCodeT16MemReg.Create);
+ SetT16("0101010xxxxxxxxx", InstName.Strb, InstEmit32.Strb, OpCodeT16MemReg.Create);
+ SetT16("0101011xxxxxxxxx", InstName.Ldrsb, InstEmit32.Ldrsb, OpCodeT16MemReg.Create);
+ SetT16("0101100xxxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT16MemReg.Create);
+ SetT16("0101101xxxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT16MemReg.Create);
+ SetT16("0101110xxxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT16MemReg.Create);
+ SetT16("0101111xxxxxxxxx", InstName.Ldrsh, InstEmit32.Ldrsh, OpCodeT16MemReg.Create);
+ SetT16("01100xxxxxxxxxxx", InstName.Str, InstEmit32.Str, OpCodeT16MemImm5.Create);
+ SetT16("01101xxxxxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT16MemImm5.Create);
+ SetT16("01110xxxxxxxxxxx", InstName.Strb, InstEmit32.Strb, OpCodeT16MemImm5.Create);
+ SetT16("01111xxxxxxxxxxx", InstName.Ldrb, InstEmit32.Ldrb, OpCodeT16MemImm5.Create);
+ SetT16("10000xxxxxxxxxxx", InstName.Strh, InstEmit32.Strh, OpCodeT16MemImm5.Create);
+ SetT16("10001xxxxxxxxxxx", InstName.Ldrh, InstEmit32.Ldrh, OpCodeT16MemImm5.Create);
+ SetT16("10010xxxxxxxxxxx", InstName.Str, InstEmit32.Str, OpCodeT16MemSp.Create);
+ SetT16("10011xxxxxxxxxxx", InstName.Ldr, InstEmit32.Ldr, OpCodeT16MemSp.Create);
+ SetT16("10100xxxxxxxxxxx", InstName.Adr, InstEmit32.Adr, OpCodeT16Adr.Create);
+ SetT16("10101xxxxxxxxxxx", InstName.Add, InstEmit32.Add, OpCodeT16SpRel.Create);
+ SetT16("101100000xxxxxxx", InstName.Add, InstEmit32.Add, OpCodeT16AddSubSp.Create);
+ SetT16("101100001xxxxxxx", InstName.Sub, InstEmit32.Sub, OpCodeT16AddSubSp.Create);
+ SetT16("1011001000xxxxxx", InstName.Sxth, InstEmit32.Sxth, OpCodeT16AluUx.Create);
+ SetT16("1011001001xxxxxx", InstName.Sxtb, InstEmit32.Sxtb, OpCodeT16AluUx.Create);
+ SetT16("1011001010xxxxxx", InstName.Uxth, InstEmit32.Uxth, OpCodeT16AluUx.Create);
+ SetT16("1011001011xxxxxx", InstName.Uxtb, InstEmit32.Uxtb, OpCodeT16AluUx.Create);
+ SetT16("101100x1xxxxxxxx", InstName.Cbz, InstEmit32.Cbz, OpCodeT16BImmCmp.Create);
+ SetT16("1011010xxxxxxxxx", InstName.Push, InstEmit32.Stm, OpCodeT16MemStack.Create);
+ SetT16("1011101000xxxxxx", InstName.Rev, InstEmit32.Rev, OpCodeT16AluRegLow.Create);
+ SetT16("1011101001xxxxxx", InstName.Rev16, InstEmit32.Rev16, OpCodeT16AluRegLow.Create);
+ SetT16("1011101011xxxxxx", InstName.Revsh, InstEmit32.Revsh, OpCodeT16AluRegLow.Create);
+ SetT16("101110x1xxxxxxxx", InstName.Cbnz, InstEmit32.Cbnz, OpCodeT16BImmCmp.Create);
+ SetT16("1011110xxxxxxxxx", InstName.Pop, InstEmit32.Ldm, OpCodeT16MemStack.Create);
+ SetT16("10111111xxxx0000", InstName.Nop, InstEmit32.Nop, OpCodeT16.Create);
+ SetT16("10111111xxxx>>>>", InstName.It, InstEmit32.It, OpCodeT16IfThen.Create);
+ SetT16("11000xxxxxxxxxxx", InstName.Stm, InstEmit32.Stm, OpCodeT16MemMult.Create);
+ SetT16("11001xxxxxxxxxxx", InstName.Ldm, InstEmit32.Ldm, OpCodeT16MemMult.Create);
+ SetT16("1101<<<xxxxxxxxx", InstName.B, InstEmit32.B, OpCodeT16BImm8.Create);
+ SetT16("11011111xxxxxxxx", InstName.Svc, InstEmit32.Svc, OpCodeT16Exception.Create);
+ SetT16("11100xxxxxxxxxxx", InstName.B, InstEmit32.B, OpCodeT16BImm11.Create);
+#endregion
+
+ FillFastLookupTable(InstA32FastLookup, AllInstA32, ToFastLookupIndexA);
+ FillFastLookupTable(InstT32FastLookup, AllInstT32, ToFastLookupIndexT);
+ FillFastLookupTable(InstA64FastLookup, AllInstA64, ToFastLookupIndexA);
}
- private static void FillFastLookupTable(InstInfo[][] table, List<InstInfo> allInsts)
+ private static void FillFastLookupTable(InstInfo[][] table, List<InstInfo> allInsts, Func<int, int> ToFastLookupIndex)
{
List<InstInfo>[] temp = new List<InstInfo>[FastLookupSize];
@@ -1011,20 +1081,27 @@ namespace ARMeilleure.Decoders
private static void SetA32(string encoding, InstName name, InstEmitter emitter, MakeOp makeOp)
{
- Set(encoding, ExecutionMode.Aarch32Arm, new InstDescriptor(name, emitter), makeOp);
+ Set(encoding, AllInstA32, new InstDescriptor(name, emitter), makeOp);
+ }
+
+ private static void SetT16(string encoding, InstName name, InstEmitter emitter, MakeOp makeOp)
+ {
+ encoding = "xxxxxxxxxxxxxxxx" + encoding;
+ Set(encoding, AllInstT32, new InstDescriptor(name, emitter), makeOp);
}
private static void SetT32(string encoding, InstName name, InstEmitter emitter, MakeOp makeOp)
{
- Set(encoding, ExecutionMode.Aarch32Thumb, new InstDescriptor(name, emitter), makeOp);
+ encoding = encoding.Substring(16) + encoding.Substring(0, 16);
+ Set(encoding, AllInstT32, new InstDescriptor(name, emitter), makeOp);
}
private static void SetA64(string encoding, InstName name, InstEmitter emitter, MakeOp makeOp)
{
- Set(encoding, ExecutionMode.Aarch64, new InstDescriptor(name, emitter), makeOp);
+ Set(encoding, AllInstA64, new InstDescriptor(name, emitter), makeOp);
}
- private static void Set(string encoding, ExecutionMode mode, InstDescriptor inst, MakeOp makeOp)
+ private static void Set(string encoding, List<InstInfo> list, InstDescriptor inst, MakeOp makeOp)
{
int bit = encoding.Length - 1;
int value = 0;
@@ -1073,7 +1150,7 @@ namespace ARMeilleure.Decoders
if (xBits == 0)
{
- InsertInst(new InstInfo(xMask, value, inst, makeOp), mode);
+ list.Add(new InstInfo(xMask, value, inst, makeOp));
return;
}
@@ -1089,34 +1166,24 @@ namespace ARMeilleure.Decoders
if (mask != blacklisted)
{
- InsertInst(new InstInfo(xMask, value | mask, inst, makeOp), mode);
+ list.Add(new InstInfo(xMask, value | mask, inst, makeOp));
}
}
}
- private static void InsertInst(InstInfo info, ExecutionMode mode)
- {
- switch (mode)
- {
- case ExecutionMode.Aarch32Arm: AllInstA32.Add(info); break;
- case ExecutionMode.Aarch32Thumb: AllInstT32.Add(info); break;
- case ExecutionMode.Aarch64: AllInstA64.Add(info); break;
- }
- }
-
public static (InstDescriptor inst, MakeOp makeOp) GetInstA32(int opCode)
{
- return GetInstFromList(InstA32FastLookup[ToFastLookupIndex(opCode)], opCode);
+ return GetInstFromList(InstA32FastLookup[ToFastLookupIndexA(opCode)], opCode);
}
public static (InstDescriptor inst, MakeOp makeOp) GetInstT32(int opCode)
{
- return GetInstFromList(InstT32FastLookup[ToFastLookupIndex(opCode)], opCode);
+ return GetInstFromList(InstT32FastLookup[ToFastLookupIndexT(opCode)], opCode);
}
public static (InstDescriptor inst, MakeOp makeOp) GetInstA64(int opCode)
{
- return GetInstFromList(InstA64FastLookup[ToFastLookupIndex(opCode)], opCode);
+ return GetInstFromList(InstA64FastLookup[ToFastLookupIndexA(opCode)], opCode);
}
private static (InstDescriptor inst, MakeOp makeOp) GetInstFromList(InstInfo[] insts, int opCode)
@@ -1132,9 +1199,14 @@ namespace ARMeilleure.Decoders
return (new InstDescriptor(InstName.Und, InstEmit.Und), null);
}
- private static int ToFastLookupIndex(int value)
+ private static int ToFastLookupIndexA(int value)
{
return ((value >> 10) & 0x00F) | ((value >> 18) & 0xFF0);
}
+
+ private static int ToFastLookupIndexT(int value)
+ {
+ return (value >> 4) & 0xFFF;
+ }
}
}