A32: Add ExceptionRaised IR instruction and use it
This commit is contained in:
parent
7ffbebf290
commit
f023bbb893
7 changed files with 32 additions and 2 deletions
|
@ -584,6 +584,18 @@ void A32EmitX64::EmitA32CallSupervisor(A32EmitContext& ctx, IR::Inst* inst) {
|
||||||
code->SwitchMxcsrOnEntry();
|
code->SwitchMxcsrOnEntry();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void A32EmitX64::EmitA32ExceptionRaised(A32EmitContext& ctx, IR::Inst* inst) {
|
||||||
|
ctx.reg_alloc.HostCall(nullptr);
|
||||||
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
|
ASSERT(args[0].IsImmediate() && args[1].IsImmediate());
|
||||||
|
u32 pc = args[0].GetImmediateU32();
|
||||||
|
u64 exception = args[1].GetImmediateU64();
|
||||||
|
DEVIRT(config.callbacks, &A32::UserCallbacks::ExceptionRaised).EmitCall(code, [&](Xbyak::Reg64 param1, Xbyak::Reg64 param2) {
|
||||||
|
code->mov(param1, pc);
|
||||||
|
code->mov(param2, exception);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static u32 GetFpscrImpl(A32JitState* jit_state) {
|
static u32 GetFpscrImpl(A32JitState* jit_state) {
|
||||||
return jit_state->Fpscr();
|
return jit_state->Fpscr();
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,6 +86,10 @@ void IREmitter::CallSupervisor(const IR::U32& value) {
|
||||||
Inst(Opcode::A32CallSupervisor, value);
|
Inst(Opcode::A32CallSupervisor, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void IREmitter::ExceptionRaised(const Exception exception) {
|
||||||
|
Inst(Opcode::A64ExceptionRaised, Imm32(PC()), Imm64(static_cast<u64>(exception)));
|
||||||
|
}
|
||||||
|
|
||||||
IR::U32 IREmitter::GetCpsr() {
|
IR::U32 IREmitter::GetCpsr() {
|
||||||
return Inst<IR::U32>(Opcode::A32GetCpsr);
|
return Inst<IR::U32>(Opcode::A32GetCpsr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
|
|
||||||
namespace Dynarmic::A32 {
|
namespace Dynarmic::A32 {
|
||||||
|
|
||||||
|
enum class Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience class to construct a basic block of the intermediate representation.
|
* Convenience class to construct a basic block of the intermediate representation.
|
||||||
* `block` is the resulting block.
|
* `block` is the resulting block.
|
||||||
|
@ -41,7 +43,9 @@ public:
|
||||||
void BranchWritePC(const IR::U32& value);
|
void BranchWritePC(const IR::U32& value);
|
||||||
void BXWritePC(const IR::U32& value);
|
void BXWritePC(const IR::U32& value);
|
||||||
void LoadWritePC(const IR::U32& value);
|
void LoadWritePC(const IR::U32& value);
|
||||||
|
|
||||||
void CallSupervisor(const IR::U32& value);
|
void CallSupervisor(const IR::U32& value);
|
||||||
|
void ExceptionRaised(Exception exception);
|
||||||
|
|
||||||
IR::U32 GetCpsr();
|
IR::U32 GetCpsr();
|
||||||
void SetCpsr(const IR::U32& value);
|
void SetCpsr(const IR::U32& value);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
|
#include "dynarmic/A32/config.h"
|
||||||
#include "frontend/A32/decoder/arm.h"
|
#include "frontend/A32/decoder/arm.h"
|
||||||
#include "frontend/A32/decoder/vfp2.h"
|
#include "frontend/A32/decoder/vfp2.h"
|
||||||
#include "frontend/A32/location_descriptor.h"
|
#include "frontend/A32/location_descriptor.h"
|
||||||
|
@ -117,7 +118,14 @@ bool ArmTranslatorVisitor::InterpretThisInstruction() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArmTranslatorVisitor::UnpredictableInstruction() {
|
bool ArmTranslatorVisitor::UnpredictableInstruction() {
|
||||||
ASSERT_MSG(false, "UNPREDICTABLE");
|
ir.ExceptionRaised(Exception::UnpredictableInstruction);
|
||||||
|
ir.SetTerm(IR::Term::CheckHalt{IR::Term::ReturnToDispatch{}});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ArmTranslatorVisitor::UndefinedInstruction() {
|
||||||
|
ir.ExceptionRaised(Exception::UndefinedInstruction);
|
||||||
|
ir.SetTerm(IR::Term::CheckHalt{IR::Term::ReturnToDispatch{}});
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ bool ArmTranslatorVisitor::arm_SVC(Cond cond, Imm24 imm24) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ArmTranslatorVisitor::arm_UDF() {
|
bool ArmTranslatorVisitor::arm_UDF() {
|
||||||
return InterpretThisInstruction();
|
return UndefinedInstruction();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::A32
|
} // namespace Dynarmic::A32
|
||||||
|
|
|
@ -35,6 +35,7 @@ struct ArmTranslatorVisitor final {
|
||||||
bool ConditionPassed(Cond cond);
|
bool ConditionPassed(Cond cond);
|
||||||
bool InterpretThisInstruction();
|
bool InterpretThisInstruction();
|
||||||
bool UnpredictableInstruction();
|
bool UnpredictableInstruction();
|
||||||
|
bool UndefinedInstruction();
|
||||||
|
|
||||||
static u32 rotr(u32 x, int shift) {
|
static u32 rotr(u32 x, int shift) {
|
||||||
shift &= 31;
|
shift &= 31;
|
||||||
|
|
|
@ -29,6 +29,7 @@ A32OPC(SetGEFlags, T::Void, T::U32
|
||||||
A32OPC(SetGEFlagsCompressed, T::Void, T::U32 )
|
A32OPC(SetGEFlagsCompressed, T::Void, T::U32 )
|
||||||
A32OPC(BXWritePC, T::Void, T::U32 )
|
A32OPC(BXWritePC, T::Void, T::U32 )
|
||||||
A32OPC(CallSupervisor, T::Void, T::U32 )
|
A32OPC(CallSupervisor, T::Void, T::U32 )
|
||||||
|
A32OPC(ExceptionRaised, T::Void, T::U32, T::U64 )
|
||||||
A32OPC(GetFpscr, T::U32, )
|
A32OPC(GetFpscr, T::U32, )
|
||||||
A32OPC(SetFpscr, T::Void, T::U32, )
|
A32OPC(SetFpscr, T::Void, T::U32, )
|
||||||
A32OPC(GetFpscrNZCV, T::U32, )
|
A32OPC(GetFpscrNZCV, T::U32, )
|
||||||
|
|
Loading…
Add table
Reference in a new issue