A32 Support

(WIP)
This commit is contained in:
riperiperi 2020-02-05 01:56:20 +00:00
commit 16a850d588
3 changed files with 21 additions and 13 deletions

View file

@ -5,6 +5,7 @@ using ARMeilleure.Translation;
using static ARMeilleure.Instructions.InstEmitFlowHelper; using static ARMeilleure.Instructions.InstEmitFlowHelper;
using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.Instructions.InstEmitHelper;
using static ARMeilleure.Instructions.InstEmitFlowHelper;
using static ARMeilleure.IntermediateRepresentation.OperandHelper; using static ARMeilleure.IntermediateRepresentation.OperandHelper;
namespace ARMeilleure.Instructions namespace ARMeilleure.Instructions
@ -21,7 +22,6 @@ namespace ARMeilleure.Instructions
} }
else else
{ {
context.StoreToContext();
context.Return(Const(op.Immediate)); context.Return(Const(op.Immediate));
} }
} }
@ -57,7 +57,7 @@ namespace ARMeilleure.Instructions
SetFlag(context, PState.TFlag, Const(isThumb ? 0 : 1)); SetFlag(context, PState.TFlag, Const(isThumb ? 0 : 1));
} }
InstEmitFlowHelper.EmitCall(context, (ulong)op.Immediate); EmitJumpTableCall(context, Const((int)op.Immediate));
} }
public static void Blxr(ArmEmitterContext context) public static void Blxr(ArmEmitterContext context)
@ -66,9 +66,8 @@ namespace ARMeilleure.Instructions
uint pc = op.GetPc(); uint pc = op.GetPc();
Operand addr = GetIntA32(context, op.Rm); Operand addr = context.Copy(GetIntA32(context, op.Rm));
Operand bitOne = context.BitwiseAnd(addr, Const(1)); Operand bitOne = context.BitwiseAnd(addr, Const(1));
addr = context.BitwiseOr(addr, Const((int)CallFlag)); // Set call flag.
bool isThumb = IsThumb(context.CurrOp); bool isThumb = IsThumb(context.CurrOp);
@ -80,15 +79,13 @@ namespace ARMeilleure.Instructions
SetFlag(context, PState.TFlag, bitOne); SetFlag(context, PState.TFlag, bitOne);
context.Return(addr); // Call. EmitJumpTableCall(context, addr);
} }
public static void Bx(ArmEmitterContext context) public static void Bx(ArmEmitterContext context)
{ {
IOpCode32BReg op = (IOpCode32BReg)context.CurrOp; IOpCode32BReg op = (IOpCode32BReg)context.CurrOp;
context.StoreToContext();
EmitBxWritePc(context, GetIntA32(context, op.Rm)); EmitBxWritePc(context, GetIntA32(context, op.Rm));
} }
} }

View file

@ -144,22 +144,33 @@ namespace ARMeilleure.Instructions
} }
} }
public static void EmitBxWritePc(ArmEmitterContext context, Operand pc) public static void EmitBxWritePc(ArmEmitterContext context, Operand pc, int sourceRegister = 0)
{ {
bool allowRejit = sourceRegister != RegisterAlias.Aarch32Lr && context.CurrOp.Instruction.Name != InstName.Ldm;
Operand mode = context.BitwiseAnd(pc, Const(1)); Operand mode = context.BitwiseAnd(pc, Const(1));
SetFlag(context, PState.TFlag, mode); SetFlag(context, PState.TFlag, mode);
Operand lblArmMode = Label(); Operand lblArmMode = Label();
context.BranchIfTrue(lblArmMode, mode); context.BranchIfFalse(lblArmMode, mode);
// Make this count as a call, the translator will ignore the low bit for the address. Operand thumbAddr = allowRejit ? context.BitwiseOr(pc, Const((int)InstEmitFlowHelper.CallFlag)) : pc;
context.Return(context.ZeroExtend32(OperandType.I64, context.BitwiseOr(pc, Const((int)InstEmitFlowHelper.CallFlag)))); // Make this count for rejit, the translator will ignore the low bit for the address.
context.Return(context.ZeroExtend32(OperandType.I64, thumbAddr));
context.MarkLabel(lblArmMode); context.MarkLabel(lblArmMode);
context.Return(context.ZeroExtend32(OperandType.I64, context.BitwiseOr(context.BitwiseAnd(pc, Const(~3)), Const((int)InstEmitFlowHelper.CallFlag)))); Operand a32Addr = context.BitwiseAnd(pc, Const(~3));
if (allowRejit)
{
InstEmitFlowHelper.EmitJumpTableCall(context, a32Addr, true);
}
else
{
context.Return(context.ZeroExtend32(OperandType.I64, a32Addr));
}
} }
public static Operand GetIntOrZR(ArmEmitterContext context, int regIndex) public static Operand GetIntOrZR(ArmEmitterContext context, int regIndex)

View file

@ -51,7 +51,7 @@ namespace ARMeilleure.Instructions
EmitReadInt(context, address, rt, size); EmitReadInt(context, address, rt, size);
} }
if (!isSimd) if (!isSimd && !(context.CurrOp is OpCode32 && rt == State.RegisterAlias.Aarch32Pc))
{ {
Operand value = GetInt(context, rt); Operand value = GetInt(context, rt);