ARMeilleure: Thumb support (All T16 instructions) (#3105)

* Decoders: Add InITBlock argument

* OpCodeTable: Minor cleanup

* OpCodeTable: Remove existing thumb instruction implementations

* OpCodeTable: Prepare for thumb instructions

* OpCodeTables: Improve thumb fast lookup

* Tests: Prepare for thumb tests

* T16: Implement BX

* T16: Implement LSL/LSR/ASR (imm)

* T16: Implement ADDS, SUBS (reg)

* T16: Implement ADDS, SUBS (3-bit immediate)

* T16: Implement MOVS, CMP, ADDS, SUBS (8-bit immediate)

* T16: Implement ANDS, EORS, LSLS, LSRS, ASRS, ADCS, SBCS, RORS, TST, NEGS, CMP, CMN, ORRS, MULS, BICS, MVNS (low registers)

* T16: Implement ADD, CMP, MOV (high reg)

* T16: Implement BLX (reg)

* T16: Implement LDR (literal)

* T16: Implement {LDR,STR}{,H,B,SB,SH} (register)

* T16: Implement {LDR,STR}{,B,H} (immediate)

* T16: Implement LDR/STR (SP)

* T16: Implement ADR

* T16: Implement Add to SP (immediate)

* T16: Implement ADD/SUB (SP)

* T16: Implement SXTH, SXTB, UXTH, UTXB

* T16: Implement CBZ, CBNZ

* T16: Implement PUSH, POP

* T16: Implement REV, REV16, REVSH

* T16: Implement NOP

* T16: Implement LDM, STM

* T16: Implement SVC

* T16: Implement B (conditional)

* T16: Implement B (unconditional)

* T16: Implement IT

* fixup! T16: Implement ADD/SUB (SP)

* fixup! T16: Implement Add to SP (immediate)

* fixup! T16: Implement IT

* CpuTestThumb: Add randomized tests

* Remove inITBlock argument

* Address nits

* Use index to handle IfThenBlockState

* Reduce line noise

* fixup

* nit
This commit is contained in:
merry 2022-02-17 22:39:45 +00:00 committed by GitHub
parent 868919e101
commit 98e05ee4b7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
57 changed files with 1852 additions and 102 deletions

View file

@ -12,6 +12,18 @@ namespace ARMeilleure.Instructions
{
static class InstEmitAluHelper
{
public static bool ShouldSetFlags(ArmEmitterContext context)
{
IOpCode32Alu op = (IOpCode32Alu)context.CurrOp;
if (op.SetFlags == null)
{
return !context.IsInIfThenBlock;
}
return op.SetFlags.Value;
}
public static void EmitNZFlagsCheck(ArmEmitterContext context, Operand d)
{
SetFlag(context, PState.NFlag, context.ICompareLess (d, Const(d.Type, 0)));
@ -183,9 +195,9 @@ namespace ARMeilleure.Instructions
switch (context.CurrOp)
{
// ARM32.
case OpCode32AluImm op:
case IOpCode32AluImm op:
{
if (op.SetFlags && op.IsRotated)
if (ShouldSetFlags(context) && op.IsRotated)
{
SetFlag(context, PState.CFlag, Const((uint)op.Immediate >> 31));
}
@ -195,10 +207,8 @@ namespace ARMeilleure.Instructions
case OpCode32AluImm16 op: return Const(op.Immediate);
case OpCode32AluRsImm op: return GetMShiftedByImmediate(context, op, setCarry);
case OpCode32AluRsReg op: return GetMShiftedByReg(context, op, setCarry);
case OpCodeT16AluImm8 op: return Const(op.Immediate);
case IOpCode32AluRsImm op: return GetMShiftedByImmediate(context, op, setCarry);
case IOpCode32AluRsReg op: return GetMShiftedByReg(context, op, setCarry);
case IOpCode32AluReg op: return GetIntA32(context, op.Rm);
@ -249,7 +259,7 @@ namespace ARMeilleure.Instructions
}
// ARM32 helpers.
public static Operand GetMShiftedByImmediate(ArmEmitterContext context, OpCode32AluRsImm op, bool setCarry)
public static Operand GetMShiftedByImmediate(ArmEmitterContext context, IOpCode32AluRsImm op, bool setCarry)
{
Operand m = GetIntA32(context, op.Rm);
@ -267,7 +277,7 @@ namespace ARMeilleure.Instructions
if (shift != 0)
{
setCarry &= op.SetFlags;
setCarry &= ShouldSetFlags(context);
switch (op.ShiftType)
{
@ -305,7 +315,7 @@ namespace ARMeilleure.Instructions
return shift;
}
public static Operand GetMShiftedByReg(ArmEmitterContext context, OpCode32AluRsReg op, bool setCarry)
public static Operand GetMShiftedByReg(ArmEmitterContext context, IOpCode32AluRsReg op, bool setCarry)
{
Operand m = GetIntA32(context, op.Rm);
Operand s = context.ZeroExtend8(OperandType.I32, GetIntA32(context, op.Rs));
@ -314,7 +324,7 @@ namespace ARMeilleure.Instructions
Operand zeroResult = m;
Operand shiftResult = m;
setCarry &= op.SetFlags;
setCarry &= ShouldSetFlags(context);
switch (op.ShiftType)
{