Add ARM32 support on the translator (#561)
* Remove ARM32 interpreter and add ARM32 support on the translator * Nits. * Rename Cond -> Condition * Align code again * Rename Data to Alu * Enable ARM32 support and handle undefined instructions * Use the IsThumb method to check if its a thumb opcode * Remove another 32-bits check
This commit is contained in:
parent
72157e03eb
commit
36b9ab0e48
57 changed files with 1274 additions and 495 deletions
59
ChocolArm64/Decoders/BitUtils.cs
Normal file
59
ChocolArm64/Decoders/BitUtils.cs
Normal file
|
@ -0,0 +1,59 @@
|
|||
namespace ChocolArm64.Decoders
|
||||
{
|
||||
static class BitUtils
|
||||
{
|
||||
public static int HighestBitSet32(int value)
|
||||
{
|
||||
for (int bit = 31; bit >= 0; bit--)
|
||||
{
|
||||
if (((value >> bit) & 1) != 0)
|
||||
{
|
||||
return bit;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static readonly sbyte[] HbsNibbleTbl = { -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3 };
|
||||
|
||||
public static int HighestBitSetNibble(int value) => HbsNibbleTbl[value & 0b1111];
|
||||
|
||||
public static long Replicate(long bits, int size)
|
||||
{
|
||||
long output = 0;
|
||||
|
||||
for (int bit = 0; bit < 64; bit += size)
|
||||
{
|
||||
output |= bits << bit;
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
public static long FillWithOnes(int bits)
|
||||
{
|
||||
return bits == 64 ? -1L : (1L << bits) - 1;
|
||||
}
|
||||
|
||||
public static int RotateRight(int bits, int shift, int size)
|
||||
{
|
||||
return (int)RotateRight((uint)bits, shift, size);
|
||||
}
|
||||
|
||||
public static uint RotateRight(uint bits, int shift, int size)
|
||||
{
|
||||
return (bits >> shift) | (bits << (size - shift));
|
||||
}
|
||||
|
||||
public static long RotateRight(long bits, int shift, int size)
|
||||
{
|
||||
return (long)RotateRight((ulong)bits, shift, size);
|
||||
}
|
||||
|
||||
public static ulong RotateRight(ulong bits, int shift, int size)
|
||||
{
|
||||
return (bits >> shift) | (bits << (size - shift));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
namespace ChocolArm64.Decoders
|
||||
{
|
||||
enum Cond
|
||||
enum Condition
|
||||
{
|
||||
Eq = 0,
|
||||
Ne = 1,
|
|
@ -19,20 +19,20 @@ namespace ChocolArm64.Decoders
|
|||
_opActivators = new ConcurrentDictionary<Type, OpActivator>();
|
||||
}
|
||||
|
||||
public static Block DecodeBasicBlock(CpuThreadState state, MemoryManager memory, long start)
|
||||
public static Block DecodeBasicBlock(MemoryManager memory, long start, ExecutionMode mode)
|
||||
{
|
||||
Block block = new Block(start);
|
||||
|
||||
FillBlock(state, memory, block);
|
||||
FillBlock(memory, mode, block);
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
public static Block DecodeSubroutine(
|
||||
TranslatorCache cache,
|
||||
CpuThreadState state,
|
||||
MemoryManager memory,
|
||||
long start)
|
||||
long start,
|
||||
ExecutionMode mode)
|
||||
{
|
||||
Dictionary<long, Block> visited = new Dictionary<long, Block>();
|
||||
Dictionary<long, Block> visitedEnd = new Dictionary<long, Block>();
|
||||
|
@ -59,7 +59,7 @@ namespace ChocolArm64.Decoders
|
|||
{
|
||||
Block current = blocks.Dequeue();
|
||||
|
||||
FillBlock(state, memory, current);
|
||||
FillBlock(memory, mode, current);
|
||||
|
||||
//Set child blocks. "Branch" is the block the branch instruction
|
||||
//points to (when taken), "Next" is the block at the next address,
|
||||
|
@ -71,7 +71,7 @@ namespace ChocolArm64.Decoders
|
|||
|
||||
OpCode64 lastOp = current.GetLastOp();
|
||||
|
||||
if (lastOp is OpCodeBImm64 op)
|
||||
if (lastOp is IOpCodeBImm op)
|
||||
{
|
||||
if (op.Emitter == InstEmit.Bl)
|
||||
{
|
||||
|
@ -83,8 +83,7 @@ namespace ChocolArm64.Decoders
|
|||
}
|
||||
}
|
||||
|
||||
if (!((lastOp is OpCodeBImmAl64) ||
|
||||
(lastOp is OpCodeBReg64)) || hasCachedSub)
|
||||
if (!IsUnconditionalBranch(lastOp) || hasCachedSub)
|
||||
{
|
||||
current.Next = Enqueue(current.EndPosition);
|
||||
}
|
||||
|
@ -121,7 +120,7 @@ namespace ChocolArm64.Decoders
|
|||
return entry;
|
||||
}
|
||||
|
||||
private static void FillBlock(CpuThreadState state, MemoryManager memory, Block block)
|
||||
private static void FillBlock(MemoryManager memory, ExecutionMode mode, Block block)
|
||||
{
|
||||
long position = block.Position;
|
||||
|
||||
|
@ -129,13 +128,11 @@ namespace ChocolArm64.Decoders
|
|||
|
||||
do
|
||||
{
|
||||
//TODO: This needs to be changed to support both AArch32 and AArch64,
|
||||
//once JIT support is introduced on AArch32 aswell.
|
||||
opCode = DecodeOpCode(state, memory, position);
|
||||
opCode = DecodeOpCode(memory, position, mode);
|
||||
|
||||
block.OpCodes.Add(opCode);
|
||||
|
||||
position += 4;
|
||||
position += opCode.OpCodeSizeInBytes;
|
||||
}
|
||||
while (!(IsBranch(opCode) || IsException(opCode)));
|
||||
|
||||
|
@ -145,7 +142,35 @@ namespace ChocolArm64.Decoders
|
|||
private static bool IsBranch(OpCode64 opCode)
|
||||
{
|
||||
return opCode is OpCodeBImm64 ||
|
||||
opCode is OpCodeBReg64;
|
||||
opCode is OpCodeBReg64 || IsAarch32Branch(opCode);
|
||||
}
|
||||
|
||||
private static bool IsUnconditionalBranch(OpCode64 opCode)
|
||||
{
|
||||
return opCode is OpCodeBImmAl64 ||
|
||||
opCode is OpCodeBReg64 || IsAarch32UnconditionalBranch(opCode);
|
||||
}
|
||||
|
||||
private static bool IsAarch32UnconditionalBranch(OpCode64 opCode)
|
||||
{
|
||||
if (!(opCode is OpCode32 op))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//Note: On ARM32, most instructions have conditional execution,
|
||||
//so there's no "Always" (unconditional) branch like on ARM64.
|
||||
//We need to check if the condition is "Always" instead.
|
||||
return IsAarch32Branch(op) && op.Cond >= Condition.Al;
|
||||
}
|
||||
|
||||
private static bool IsAarch32Branch(OpCode64 opCode)
|
||||
{
|
||||
//Note: On ARM32, most ALU operations can write to R15 (PC),
|
||||
//so we must consider such operations as a branch in potential aswell.
|
||||
return opCode is IOpCodeBImm32 ||
|
||||
opCode is IOpCodeBReg32 ||
|
||||
(opCode is IOpCodeAlu32 op && op.Rd == RegisterAlias.Aarch32Pc);
|
||||
}
|
||||
|
||||
private static bool IsException(OpCode64 opCode)
|
||||
|
@ -155,20 +180,26 @@ namespace ChocolArm64.Decoders
|
|||
opCode.Emitter == InstEmit.Und;
|
||||
}
|
||||
|
||||
public static OpCode64 DecodeOpCode(CpuThreadState state, MemoryManager memory, long position)
|
||||
public static OpCode64 DecodeOpCode(MemoryManager memory, long position, ExecutionMode mode)
|
||||
{
|
||||
int opCode = memory.ReadInt32(position);
|
||||
|
||||
Inst inst;
|
||||
|
||||
if (state.ExecutionMode == ExecutionMode.AArch64)
|
||||
if (mode == ExecutionMode.Aarch64)
|
||||
{
|
||||
inst = OpCodeTable.GetInstA64(opCode);
|
||||
}
|
||||
else
|
||||
{
|
||||
//TODO: Thumb support.
|
||||
inst = OpCodeTable.GetInstA32(opCode);
|
||||
if (mode == ExecutionMode.Aarch32Arm)
|
||||
{
|
||||
inst = OpCodeTable.GetInstA32(opCode);
|
||||
}
|
||||
else /* if (mode == ExecutionMode.Aarch32Thumb) */
|
||||
{
|
||||
inst = OpCodeTable.GetInstT32(opCode);
|
||||
}
|
||||
}
|
||||
|
||||
OpCode64 decodedOpCode = new OpCode64(Inst.Undefined, position, opCode);
|
||||
|
|
|
@ -89,6 +89,11 @@ namespace ChocolArm64.Decoders
|
|||
return value;
|
||||
}
|
||||
|
||||
public static long DecodeImm24_2(int opCode)
|
||||
{
|
||||
return ((long)opCode << 40) >> 38;
|
||||
}
|
||||
|
||||
public static long DecodeImm26_2(int opCode)
|
||||
{
|
||||
return ((long)opCode << 38) >> 36;
|
||||
|
|
9
ChocolArm64/Decoders/IOpCode32.cs
Normal file
9
ChocolArm64/Decoders/IOpCode32.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
namespace ChocolArm64.Decoders
|
||||
{
|
||||
interface IOpCode32 : IOpCode64
|
||||
{
|
||||
Condition Cond { get; }
|
||||
|
||||
uint GetPc();
|
||||
}
|
||||
}
|
10
ChocolArm64/Decoders/IOpCodeAlu32.cs
Normal file
10
ChocolArm64/Decoders/IOpCodeAlu32.cs
Normal file
|
@ -0,0 +1,10 @@
|
|||
namespace ChocolArm64.Decoders
|
||||
{
|
||||
interface IOpCodeAlu32 : IOpCode32
|
||||
{
|
||||
int Rd { get; }
|
||||
int Rn { get; }
|
||||
|
||||
bool SetFlags { get; }
|
||||
}
|
||||
}
|
7
ChocolArm64/Decoders/IOpCodeBImm.cs
Normal file
7
ChocolArm64/Decoders/IOpCodeBImm.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace ChocolArm64.Decoders
|
||||
{
|
||||
interface IOpCodeBImm : IOpCode64
|
||||
{
|
||||
long Imm { get; }
|
||||
}
|
||||
}
|
4
ChocolArm64/Decoders/IOpCodeBImm32.cs
Normal file
4
ChocolArm64/Decoders/IOpCodeBImm32.cs
Normal file
|
@ -0,0 +1,4 @@
|
|||
namespace ChocolArm64.Decoders
|
||||
{
|
||||
interface IOpCodeBImm32 : IOpCode32, IOpCodeBImm { }
|
||||
}
|
7
ChocolArm64/Decoders/IOpCodeBReg32.cs
Normal file
7
ChocolArm64/Decoders/IOpCodeBReg32.cs
Normal file
|
@ -0,0 +1,7 @@
|
|||
namespace ChocolArm64.Decoders
|
||||
{
|
||||
interface IOpCodeBReg32 : IOpCode32
|
||||
{
|
||||
int Rm { get; }
|
||||
}
|
||||
}
|
|
@ -2,6 +2,6 @@ namespace ChocolArm64.Decoders
|
|||
{
|
||||
interface IOpCodeCond64 : IOpCode64
|
||||
{
|
||||
Cond Cond { get; }
|
||||
Condition Cond { get; }
|
||||
}
|
||||
}
|
24
ChocolArm64/Decoders/OpCode32.cs
Normal file
24
ChocolArm64/Decoders/OpCode32.cs
Normal file
|
@ -0,0 +1,24 @@
|
|||
using ChocolArm64.Instructions;
|
||||
using ChocolArm64.State;
|
||||
|
||||
namespace ChocolArm64.Decoders
|
||||
{
|
||||
class OpCode32 : OpCode64
|
||||
{
|
||||
public Condition Cond { get; protected set; }
|
||||
|
||||
public OpCode32(Inst inst, long position, int opCode) : base(inst, position, opCode)
|
||||
{
|
||||
RegisterSize = RegisterSize.Int32;
|
||||
|
||||
Cond = (Condition)((uint)opCode >> 28);
|
||||
}
|
||||
|
||||
public uint GetPc()
|
||||
{
|
||||
//Due to backwards compatibility and legacy behavior of ARMv4 CPUs pipeline,
|
||||
//the PC actually points 2 instructions ahead.
|
||||
return (uint)Position + (uint)OpCodeSizeInBytes * 2;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -9,9 +9,10 @@ namespace ChocolArm64.Decoders
|
|||
public long Position { get; private set; }
|
||||
public int RawOpCode { get; private set; }
|
||||
|
||||
public InstEmitter Emitter { get; protected set; }
|
||||
public InstInterpreter Interpreter { get; protected set; }
|
||||
public RegisterSize RegisterSize { get; protected set; }
|
||||
public int OpCodeSizeInBytes { get; protected set; } = 4;
|
||||
|
||||
public InstEmitter Emitter { get; protected set; }
|
||||
public RegisterSize RegisterSize { get; protected set; }
|
||||
|
||||
public OpCode64(Inst inst, long position, int opCode)
|
||||
{
|
||||
|
@ -20,8 +21,7 @@ namespace ChocolArm64.Decoders
|
|||
|
||||
RegisterSize = RegisterSize.Int64;
|
||||
|
||||
Emitter = inst.Emitter;
|
||||
Interpreter = inst.Interpreter;
|
||||
Emitter = inst.Emitter;
|
||||
}
|
||||
|
||||
public int GetBitsCount()
|
||||
|
|
20
ChocolArm64/Decoders/OpCodeAlu32.cs
Normal file
20
ChocolArm64/Decoders/OpCodeAlu32.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using ChocolArm64.Instructions;
|
||||
|
||||
namespace ChocolArm64.Decoders
|
||||
{
|
||||
class OpCodeAlu32 : OpCode32, IOpCodeAlu32
|
||||
{
|
||||
public int Rd { get; private set; }
|
||||
public int Rn { get; private set; }
|
||||
|
||||
public bool SetFlags { get; private set; }
|
||||
|
||||
public OpCodeAlu32(Inst inst, long position, int opCode) : base(inst, position, opCode)
|
||||
{
|
||||
Rd = (opCode >> 12) & 0xf;
|
||||
Rn = (opCode >> 16) & 0xf;
|
||||
|
||||
SetFlags = ((opCode >> 20) & 1) != 0;
|
||||
}
|
||||
}
|
||||
}
|
21
ChocolArm64/Decoders/OpCodeAluImm32.cs
Normal file
21
ChocolArm64/Decoders/OpCodeAluImm32.cs
Normal file
|
@ -0,0 +1,21 @@
|
|||
using ChocolArm64.Instructions;
|
||||
|
||||
namespace ChocolArm64.Decoders
|
||||
{
|
||||
class OpCodeAluImm32 : OpCodeAlu32
|
||||
{
|
||||
public int Imm { get; private set; }
|
||||
|
||||
public bool IsRotated { get; private set; }
|
||||
|
||||
public OpCodeAluImm32(Inst inst, long position, int opCode) : base(inst, position, opCode)
|
||||
{
|
||||
int value = (opCode >> 0) & 0xff;
|
||||
int shift = (opCode >> 8) & 0xf;
|
||||
|
||||
Imm = BitUtils.RotateRight(value, shift * 2, 32);
|
||||
|
||||
IsRotated = shift != 0;
|
||||
}
|
||||
}
|
||||
}
|
22
ChocolArm64/Decoders/OpCodeAluImm8T16.cs
Normal file
22
ChocolArm64/Decoders/OpCodeAluImm8T16.cs
Normal file
|
@ -0,0 +1,22 @@
|
|||
using ChocolArm64.Instructions;
|
||||
|
||||
namespace ChocolArm64.Decoders
|
||||
{
|
||||
class OpCodeAluImm8T16 : OpCodeT16, IOpCodeAlu32
|
||||
{
|
||||
private int _rdn;
|
||||
|
||||
public int Rd => _rdn;
|
||||
public int Rn => _rdn;
|
||||
|
||||
public bool SetFlags => false;
|
||||
|
||||
public int Imm { get; private set; }
|
||||
|
||||
public OpCodeAluImm8T16(Inst inst, long position, int opCode) : base(inst, position, opCode)
|
||||
{
|
||||
Imm = (opCode >> 0) & 0xff;
|
||||
_rdn = (opCode >> 8) & 0x7;
|
||||
}
|
||||
}
|
||||
}
|
20
ChocolArm64/Decoders/OpCodeAluRsImm32.cs
Normal file
20
ChocolArm64/Decoders/OpCodeAluRsImm32.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
using ChocolArm64.Instructions;
|
||||
|
||||
namespace ChocolArm64.Decoders
|
||||
{
|
||||
class OpCodeAluRsImm32 : OpCodeAlu32
|
||||
{
|
||||
public int Rm { get; private set; }
|
||||
public int Imm { get; private set; }
|
||||
|
||||
public ShiftType ShiftType { get; private set; }
|
||||
|
||||
public OpCodeAluRsImm32(Inst inst, long position, int opCode) : base(inst, position, opCode)
|
||||
{
|
||||
Rm = (opCode >> 0) & 0xf;
|
||||
Imm = (opCode >> 7) & 0x1f;
|
||||
|
||||
ShiftType = (ShiftType)((opCode >> 5) & 3);
|
||||
}
|
||||
}
|
||||
}
|
29
ChocolArm64/Decoders/OpCodeBImm32.cs
Normal file
29
ChocolArm64/Decoders/OpCodeBImm32.cs
Normal file
|
@ -0,0 +1,29 @@
|
|||
using ChocolArm64.Instructions;
|
||||
|
||||
namespace ChocolArm64.Decoders
|
||||
{
|
||||
class OpCodeBImm32 : OpCode32, IOpCodeBImm32
|
||||
{
|
||||
public long Imm { get; private set; }
|
||||
|
||||
public OpCodeBImm32(Inst inst, long position, int opCode) : base(inst, position, opCode)
|
||||
{
|
||||
uint pc = GetPc();
|
||||
|
||||
//When the codition is never, the instruction is BLX to Thumb mode.
|
||||
if (Cond != Condition.Nv)
|
||||
{
|
||||
pc &= ~3u;
|
||||
}
|
||||
|
||||
Imm = pc + DecoderHelper.DecodeImm24_2(opCode);
|
||||
|
||||
if (Cond == Condition.Nv)
|
||||
{
|
||||
long H = (opCode >> 23) & 2;
|
||||
|
||||
Imm |= H;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@ using ChocolArm64.Instructions;
|
|||
|
||||
namespace ChocolArm64.Decoders
|
||||
{
|
||||
class OpCodeBImm64 : OpCode64
|
||||
class OpCodeBImm64 : OpCode64, IOpCodeBImm
|
||||
{
|
||||
public long Imm { get; protected set; }
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ namespace ChocolArm64.Decoders
|
|||
{
|
||||
class OpCodeBImmCond64 : OpCodeBImm64, IOpCodeCond64
|
||||
{
|
||||
public Cond Cond { get; private set; }
|
||||
public Condition Cond { get; private set; }
|
||||
|
||||
public OpCodeBImmCond64(Inst inst, long position, int opCode) : base(inst, position, opCode)
|
||||
{
|
||||
|
@ -17,7 +17,7 @@ namespace ChocolArm64.Decoders
|
|||
return;
|
||||
}
|
||||
|
||||
Cond = (Cond)(opCode & 0xf);
|
||||
Cond = (Condition)(opCode & 0xf);
|
||||
|
||||
Imm = position + DecoderHelper.DecodeImmS19_2(opCode);
|
||||
}
|
||||
|
|
14
ChocolArm64/Decoders/OpCodeBReg32.cs
Normal file
14
ChocolArm64/Decoders/OpCodeBReg32.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using ChocolArm64.Instructions;
|
||||
|
||||
namespace ChocolArm64.Decoders
|
||||
{
|
||||
class OpCodeBReg32 : OpCode32, IOpCodeBReg32
|
||||
{
|
||||
public int Rm { get; private set; }
|
||||
|
||||
public OpCodeBReg32(Inst inst, long position, int opCode) : base(inst, position, opCode)
|
||||
{
|
||||
Rm = opCode & 0xf;
|
||||
}
|
||||
}
|
||||
}
|
14
ChocolArm64/Decoders/OpCodeBRegT16.cs
Normal file
14
ChocolArm64/Decoders/OpCodeBRegT16.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using ChocolArm64.Instructions;
|
||||
|
||||
namespace ChocolArm64.Decoders
|
||||
{
|
||||
class OpCodeBRegT16 : OpCodeT16, IOpCodeBReg32
|
||||
{
|
||||
public int Rm { get; private set; }
|
||||
|
||||
public OpCodeBRegT16(Inst inst, long position, int opCode) : base(inst, position, opCode)
|
||||
{
|
||||
Rm = (opCode >> 3) & 0xf;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,7 +8,7 @@ namespace ChocolArm64.Decoders
|
|||
public int Nzcv { get; private set; }
|
||||
protected int RmImm;
|
||||
|
||||
public Cond Cond { get; private set; }
|
||||
public Condition Cond { get; private set; }
|
||||
|
||||
public OpCodeCcmp64(Inst inst, long position, int opCode) : base(inst, position, opCode)
|
||||
{
|
||||
|
@ -21,11 +21,11 @@ namespace ChocolArm64.Decoders
|
|||
return;
|
||||
}
|
||||
|
||||
Nzcv = (opCode >> 0) & 0xf;
|
||||
Cond = (Cond)((opCode >> 12) & 0xf);
|
||||
RmImm = (opCode >> 16) & 0x1f;
|
||||
Nzcv = (opCode >> 0) & 0xf;
|
||||
Cond = (Condition)((opCode >> 12) & 0xf);
|
||||
RmImm = (opCode >> 16) & 0x1f;
|
||||
|
||||
Rd = CpuThreadState.ZrIndex;
|
||||
Rd = RegisterAlias.Zr;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,12 +6,12 @@ namespace ChocolArm64.Decoders
|
|||
{
|
||||
public int Rm { get; private set; }
|
||||
|
||||
public Cond Cond { get; private set; }
|
||||
public Condition Cond { get; private set; }
|
||||
|
||||
public OpCodeCsel64(Inst inst, long position, int opCode) : base(inst, position, opCode)
|
||||
{
|
||||
Rm = (opCode >> 16) & 0x1f;
|
||||
Cond = (Cond)((opCode >> 12) & 0xf);
|
||||
Rm = (opCode >> 16) & 0x1f;
|
||||
Cond = (Condition)((opCode >> 12) & 0xf);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -6,12 +6,12 @@ namespace ChocolArm64.Decoders
|
|||
{
|
||||
public int Nzcv { get; private set; }
|
||||
|
||||
public Cond Cond { get; private set; }
|
||||
public Condition Cond { get; private set; }
|
||||
|
||||
public OpCodeSimdFcond64(Inst inst, long position, int opCode) : base(inst, position, opCode)
|
||||
{
|
||||
Nzcv = (opCode >> 0) & 0xf;
|
||||
Cond = (Cond)((opCode >> 12) & 0xf);
|
||||
Nzcv = (opCode >> 0) & 0xf;
|
||||
Cond = (Condition)((opCode >> 12) & 0xf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
14
ChocolArm64/Decoders/OpCodeT16.cs
Normal file
14
ChocolArm64/Decoders/OpCodeT16.cs
Normal file
|
@ -0,0 +1,14 @@
|
|||
using ChocolArm64.Instructions;
|
||||
|
||||
namespace ChocolArm64.Decoders
|
||||
{
|
||||
class OpCodeT16 : OpCode32
|
||||
{
|
||||
public OpCodeT16(Inst inst, long position, int opCode) : base(inst, position, opCode)
|
||||
{
|
||||
Cond = Condition.Al;
|
||||
|
||||
OpCodeSizeInBytes = 2;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue