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
This commit is contained in:
merry 2022-03-04 22:16:58 +00:00 committed by GitHub
parent bd9ac0fdaa
commit 497199bb50
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 38 additions and 18 deletions

View file

@ -121,7 +121,7 @@ namespace ARMeilleure.Decoders
currBlock.Branch = GetBlock((ulong)op.Immediate); currBlock.Branch = GetBlock((ulong)op.Immediate);
} }
if (!IsUnconditionalBranch(lastOp) || isCall) if (isCall || !(IsUnconditionalBranch(lastOp) || IsTrap(lastOp)))
{ {
currBlock.Next = GetBlock(currBlock.EndAddress); currBlock.Next = GetBlock(currBlock.EndAddress);
} }
@ -329,9 +329,13 @@ namespace ARMeilleure.Decoders
} }
private static bool IsException(OpCode opCode) 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 || return opCode.Instruction.Name == InstName.Brk ||
opCode.Instruction.Name == InstName.Svc ||
opCode.Instruction.Name == InstName.Trap || opCode.Instruction.Name == InstName.Trap ||
opCode.Instruction.Name == InstName.Und; opCode.Instruction.Name == InstName.Und;
} }

View file

@ -9,18 +9,25 @@ namespace ARMeilleure.Instructions
{ {
public static void Brk(ArmEmitterContext context) 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) public static void Svc(ArmEmitterContext context)
{
EmitExceptionCall(context, nameof(NativeInterface.SupervisorCall));
}
private static void EmitExceptionCall(ArmEmitterContext context, string name)
{ {
OpCodeException op = (OpCodeException)context.CurrOp; OpCodeException op = (OpCodeException)context.CurrOp;
string name = nameof(NativeInterface.SupervisorCall);
context.StoreToContext(); context.StoreToContext();
context.Call(typeof(NativeInterface).GetMethod(name), Const(op.Address), Const(op.Id)); 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.Call(typeof(NativeInterface).GetMethod(name), Const(op.Address), Const(op.RawOpCode));
context.LoadFromContext(); context.LoadFromContext();
context.Return(Const(op.Address));
} }
} }
} }

View file

@ -9,19 +9,11 @@ namespace ARMeilleure.Instructions
static partial class InstEmit32 static partial class InstEmit32
{ {
public static void Svc(ArmEmitterContext context) 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; IOpCode32Exception op = (IOpCode32Exception)context.CurrOp;
string name = nameof(NativeInterface.SupervisorCall);
context.StoreToContext(); context.StoreToContext();
context.Call(typeof(NativeInterface).GetMethod(name), Const(((IOpCode)op).Address), Const(op.Id)); context.Call(typeof(NativeInterface).GetMethod(name), Const(((IOpCode)op).Address), Const(op.Id));
@ -30,5 +22,20 @@ namespace ARMeilleure.Instructions
Translator.EmitSynchronization(context); 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));
}
} }
} }