Selaa lähdekoodia

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
merry 4 vuotta sitten
vanhempi
sitoutus
497199bb50

+ 6 - 2
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;
         }

+ 15 - 6
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;
 
-        public static void Svc(ArmEmitterContext context)
-        {
-            EmitExceptionCall(context, nameof(NativeInterface.SupervisorCall));
+            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));
         }
 
-        private static void EmitExceptionCall(ArmEmitterContext context, string name)
+        public static void Svc(ArmEmitterContext context)
         {
             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));
         }
     }
 }

+ 14 - 7
ARMeilleure/Instructions/InstEmitException32.cs

@@ -10,25 +10,32 @@ namespace ARMeilleure.Instructions
     {
         public static void Svc(ArmEmitterContext context)
         {
-            EmitExceptionCall(context, nameof(NativeInterface.SupervisorCall));
-        }
+            IOpCode32Exception op = (IOpCode32Exception)context.CurrOp;
 
-        public static void Trap(ArmEmitterContext context)
-        {
-            EmitExceptionCall(context, nameof(NativeInterface.Break));
+            string name = nameof(NativeInterface.SupervisorCall);
+
+            context.StoreToContext();
+
+            context.Call(typeof(NativeInterface).GetMethod(name), Const(((IOpCode)op).Address), Const(op.Id));
+
+            context.LoadFromContext();
+
+            Translator.EmitSynchronization(context);
         }
 
-        private static void EmitExceptionCall(ArmEmitterContext context, string name)
+        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();
 
-            Translator.EmitSynchronization(context);
+            context.Return(Const(context.CurrOp.Address));
         }
     }
 }