diff options
Diffstat (limited to 'ARMeilleure/Instructions/InstEmitFlow32.cs')
-rw-r--r-- | ARMeilleure/Instructions/InstEmitFlow32.cs | 50 |
1 files changed, 37 insertions, 13 deletions
diff --git a/ARMeilleure/Instructions/InstEmitFlow32.cs b/ARMeilleure/Instructions/InstEmitFlow32.cs index 27addc78..cbb9ad5b 100644 --- a/ARMeilleure/Instructions/InstEmitFlow32.cs +++ b/ARMeilleure/Instructions/InstEmitFlow32.cs @@ -1,7 +1,9 @@ using ARMeilleure.Decoders; +using ARMeilleure.IntermediateRepresentation; using ARMeilleure.State; using ARMeilleure.Translation; +using static ARMeilleure.Instructions.InstEmitFlowHelper; using static ARMeilleure.Instructions.InstEmitHelper; using static ARMeilleure.IntermediateRepresentation.OperandHelper; @@ -20,7 +22,6 @@ namespace ARMeilleure.Instructions else { context.StoreToContext(); - context.Return(Const(op.Immediate)); } } @@ -35,15 +36,6 @@ namespace ARMeilleure.Instructions Blx(context, x: true); } - public static void Bx(ArmEmitterContext context) - { - IOpCode32BReg op = (IOpCode32BReg)context.CurrOp; - - context.StoreToContext(); - - EmitBxWritePc(context, GetIntA32(context, op.Rm)); - } - private static void Blx(ArmEmitterContext context, bool x) { IOpCode32BImm op = (IOpCode32BImm)context.CurrOp; @@ -53,10 +45,10 @@ namespace ARMeilleure.Instructions bool isThumb = IsThumb(context.CurrOp); uint currentPc = isThumb - ? op.GetPc() | 1 - : op.GetPc() - 4; + ? pc | 1 + : pc - 4; - SetIntOrSP(context, GetBankedRegisterAlias(context.Mode, RegisterAlias.Aarch32Lr), Const(currentPc)); + SetIntA32(context, GetBankedRegisterAlias(context.Mode, RegisterAlias.Aarch32Lr), Const(currentPc)); // If x is true, then this is a branch with link and exchange. // In this case we need to swap the mode between Arm <-> Thumb. @@ -67,5 +59,37 @@ namespace ARMeilleure.Instructions InstEmitFlowHelper.EmitCall(context, (ulong)op.Immediate); } + + public static void Blxr(ArmEmitterContext context) + { + IOpCode32BReg op = (IOpCode32BReg)context.CurrOp; + + uint pc = op.GetPc(); + + Operand addr = GetIntA32(context, op.Rm); + Operand bitOne = context.BitwiseAnd(addr, Const(1)); + addr = context.BitwiseOr(addr, Const((int)CallFlag)); // Set call flag. + + bool isThumb = IsThumb(context.CurrOp); + + uint currentPc = isThumb + ? pc | 1 + : pc - 4; + + SetIntA32(context, GetBankedRegisterAlias(context.Mode, RegisterAlias.Aarch32Lr), Const(currentPc)); + + SetFlag(context, PState.TFlag, bitOne); + + context.Return(addr); // Call. + } + + public static void Bx(ArmEmitterContext context) + { + IOpCode32BReg op = (IOpCode32BReg)context.CurrOp; + + context.StoreToContext(); + + EmitBxWritePc(context, GetIntA32(context, op.Rm)); + } } }
\ No newline at end of file |