From 497199bb50af98a73e0862107f408757a6e8da31 Mon Sep 17 00:00:00 2001 From: merry Date: Fri, 4 Mar 2022 22:16:58 +0000 Subject: [PATCH] Decoder: Exit on trapping instructions, and resume execution at trapping instruction (#3153) * Decoder: Exit on trapping instructions, and resume execution at trapping instruction * Resume at trapping address * remove mustExit --- ARMeilleure/Decoders/Decoder.cs | 8 ++++-- ARMeilleure/Instructions/InstEmitException.cs | 21 ++++++++++----- .../Instructions/InstEmitException32.cs | 27 ++++++++++++------- 3 files changed, 38 insertions(+), 18 deletions(-) diff --git a/ARMeilleure/Decoders/Decoder.cs b/ARMeilleure/Decoders/Decoder.cs index af3b0629..4dd8742c 100644 --- a/ARMeilleure/Decoders/Decoder.cs +++ b/ARMeilleure/Decoders/Decoder.cs @@ -121,7 +121,7 @@ namespace ARMeilleure.Decoders currBlock.Branch = GetBlock((ulong)op.Immediate); } - if (!IsUnconditionalBranch(lastOp) || isCall) + if (isCall || !(IsUnconditionalBranch(lastOp) || IsTrap(lastOp))) { currBlock.Next = GetBlock(currBlock.EndAddress); } @@ -329,9 +329,13 @@ namespace ARMeilleure.Decoders } private static bool IsException(OpCode opCode) + { + return IsTrap(opCode) || opCode.Instruction.Name == InstName.Svc; + } + + private static bool IsTrap(OpCode opCode) { return opCode.Instruction.Name == InstName.Brk || - opCode.Instruction.Name == InstName.Svc || opCode.Instruction.Name == InstName.Trap || opCode.Instruction.Name == InstName.Und; } diff --git a/ARMeilleure/Instructions/InstEmitException.cs b/ARMeilleure/Instructions/InstEmitException.cs index 8819824b..0baaa87d 100644 --- a/ARMeilleure/Instructions/InstEmitException.cs +++ b/ARMeilleure/Instructions/InstEmitException.cs @@ -9,18 +9,25 @@ namespace ARMeilleure.Instructions { public static void Brk(ArmEmitterContext context) { - EmitExceptionCall(context, nameof(NativeInterface.Break)); + OpCodeException op = (OpCodeException)context.CurrOp; + + string name = nameof(NativeInterface.Break); + + context.StoreToContext(); + + context.Call(typeof(NativeInterface).GetMethod(name), Const(op.Address), Const(op.Id)); + + context.LoadFromContext(); + + context.Return(Const(op.Address)); } public static void Svc(ArmEmitterContext context) - { - EmitExceptionCall(context, nameof(NativeInterface.SupervisorCall)); - } - - private static void EmitExceptionCall(ArmEmitterContext context, string name) { OpCodeException op = (OpCodeException)context.CurrOp; + string name = nameof(NativeInterface.SupervisorCall); + context.StoreToContext(); context.Call(typeof(NativeInterface).GetMethod(name), Const(op.Address), Const(op.Id)); @@ -41,6 +48,8 @@ namespace ARMeilleure.Instructions context.Call(typeof(NativeInterface).GetMethod(name), Const(op.Address), Const(op.RawOpCode)); context.LoadFromContext(); + + context.Return(Const(op.Address)); } } } \ No newline at end of file diff --git a/ARMeilleure/Instructions/InstEmitException32.cs b/ARMeilleure/Instructions/InstEmitException32.cs index 0b3d28d9..a2a3869f 100644 --- a/ARMeilleure/Instructions/InstEmitException32.cs +++ b/ARMeilleure/Instructions/InstEmitException32.cs @@ -9,19 +9,11 @@ namespace ARMeilleure.Instructions static partial class InstEmit32 { public static void Svc(ArmEmitterContext context) - { - EmitExceptionCall(context, nameof(NativeInterface.SupervisorCall)); - } - - public static void Trap(ArmEmitterContext context) - { - EmitExceptionCall(context, nameof(NativeInterface.Break)); - } - - private static void EmitExceptionCall(ArmEmitterContext context, string name) { IOpCode32Exception op = (IOpCode32Exception)context.CurrOp; + string name = nameof(NativeInterface.SupervisorCall); + context.StoreToContext(); context.Call(typeof(NativeInterface).GetMethod(name), Const(((IOpCode)op).Address), Const(op.Id)); @@ -30,5 +22,20 @@ namespace ARMeilleure.Instructions Translator.EmitSynchronization(context); } + + public static void Trap(ArmEmitterContext context) + { + IOpCode32Exception op = (IOpCode32Exception)context.CurrOp; + + string name = nameof(NativeInterface.Break); + + context.StoreToContext(); + + context.Call(typeof(NativeInterface).GetMethod(name), Const(((IOpCode)op).Address), Const(op.Id)); + + context.LoadFromContext(); + + context.Return(Const(context.CurrOp.Address)); + } } }