diff options
| author | gdkchan <gab.dark.100@gmail.com> | 2019-01-24 23:59:53 -0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-01-24 23:59:53 -0200 |
| commit | 36b9ab0e48b6893c057a954e1ef3181b452add1c (patch) | |
| tree | 16a4ae56019b55d0cb61f1aa105481933ada733e /ChocolArm64/Instructions/InstEmitFlow32.cs | |
| parent | 72157e03eb09d4fb5d6d004efc2d13d3194e8c90 (diff) | |
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
Diffstat (limited to 'ChocolArm64/Instructions/InstEmitFlow32.cs')
| -rw-r--r-- | ChocolArm64/Instructions/InstEmitFlow32.cs | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/ChocolArm64/Instructions/InstEmitFlow32.cs b/ChocolArm64/Instructions/InstEmitFlow32.cs new file mode 100644 index 00000000..03b39936 --- /dev/null +++ b/ChocolArm64/Instructions/InstEmitFlow32.cs @@ -0,0 +1,99 @@ +using ChocolArm64.Decoders; +using ChocolArm64.State; +using ChocolArm64.Translation; +using System.Reflection.Emit; + +using static ChocolArm64.Instructions.InstEmit32Helper; + +namespace ChocolArm64.Instructions +{ + static partial class InstEmit32 + { + public static void B(ILEmitterCtx context) + { + IOpCodeBImm32 op = (IOpCodeBImm32)context.CurrOp; + + if (context.CurrBlock.Branch != null) + { + context.Emit(OpCodes.Br, context.GetLabel(op.Imm)); + } + else + { + context.EmitStoreState(); + context.EmitLdc_I8(op.Imm); + + context.Emit(OpCodes.Ret); + } + } + + public static void Bl(ILEmitterCtx context) + { + Blx(context, x: false); + } + + public static void Blx(ILEmitterCtx context) + { + Blx(context, x: true); + } + + public static void Bx(ILEmitterCtx context) + { + IOpCodeBReg32 op = (IOpCodeBReg32)context.CurrOp; + + context.EmitStoreState(); + + EmitLoadFromRegister(context, op.Rm); + + EmitBxWritePc(context); + } + + private static void Blx(ILEmitterCtx context, bool x) + { + IOpCodeBImm32 op = (IOpCodeBImm32)context.CurrOp; + + uint pc = op.GetPc(); + + bool isThumb = IsThumb(context.CurrOp); + + if (!isThumb) + { + context.EmitLdc_I(op.GetPc() - 4); + } + else + { + context.EmitLdc_I(op.GetPc() | 1); + } + + context.EmitStint(GetBankedRegisterAlias(context.Mode, RegisterAlias.Aarch32Lr)); + context.EmitStoreState(); + + //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. + if (x) + { + context.EmitLdc_I4(isThumb ? 0 : 1); + + context.EmitStflg((int)PState.TBit); + } + + InstEmitFlowHelper.EmitCall(context, op.Imm); + } + + private static void EmitBxWritePc(ILEmitterCtx context) + { + context.Emit(OpCodes.Dup); + + context.EmitLdc_I4(1); + + context.Emit(OpCodes.And); + + context.EmitStflg((int)PState.TBit); + + context.EmitLdc_I4(~1); + + context.Emit(OpCodes.And); + context.Emit(OpCodes.Conv_U8); + context.Emit(OpCodes.Ret); + } + } +}
\ No newline at end of file |
