emit_arm64_a32: Implement A32CallSupervisor and A32ExceptionRaised
This commit is contained in:
parent
882490b372
commit
0f0744cb78
2 changed files with 41 additions and 8 deletions
|
@ -44,7 +44,11 @@ enum class LinkTarget {
|
||||||
WriteMemory16,
|
WriteMemory16,
|
||||||
WriteMemory32,
|
WriteMemory32,
|
||||||
WriteMemory64,
|
WriteMemory64,
|
||||||
|
CallSVC,
|
||||||
|
ExceptionRaised,
|
||||||
InstructionSynchronizationBarrierRaised,
|
InstructionSynchronizationBarrierRaised,
|
||||||
|
AddTicks,
|
||||||
|
GetTicksRemaining,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Relocation {
|
struct Relocation {
|
||||||
|
|
|
@ -505,18 +505,47 @@ void EmitIR<IR::Opcode::A32UpdateUpperLocationDescriptor>(oaknut::CodeGenerator&
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32CallSupervisor>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A32CallSupervisor>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
(void)code;
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
(void)ctx;
|
ctx.reg_alloc.PrepareForCall(nullptr);
|
||||||
(void)inst;
|
|
||||||
ASSERT_FALSE("Unimplemented");
|
static_assert(offsetof(StackLayout, cycles_remaining) + sizeof(u64) == offsetof(StackLayout, cycles_to_run));
|
||||||
|
|
||||||
|
if (ctx.conf.enable_cycle_counting) {
|
||||||
|
code.LDP(Xscratch0, Xscratch1, SP, offsetof(StackLayout, cycles_remaining));
|
||||||
|
code.SUB(Xscratch0, Xscratch1, Xscratch0);
|
||||||
|
EmitRelocation(code, ctx, LinkTarget::AddTicks);
|
||||||
|
}
|
||||||
|
|
||||||
|
code.MOV(W1, args[0].GetImmediateU32());
|
||||||
|
EmitRelocation(code, ctx, LinkTarget::CallSVC);
|
||||||
|
|
||||||
|
if (ctx.conf.enable_cycle_counting) {
|
||||||
|
EmitRelocation(code, ctx, LinkTarget::GetTicksRemaining);
|
||||||
|
code.STP(X0, X0, SP, offsetof(StackLayout, cycles_remaining));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
void EmitIR<IR::Opcode::A32ExceptionRaised>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
void EmitIR<IR::Opcode::A32ExceptionRaised>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
|
||||||
(void)code;
|
auto args = ctx.reg_alloc.GetArgumentInfo(inst);
|
||||||
(void)ctx;
|
ctx.reg_alloc.PrepareForCall(nullptr);
|
||||||
(void)inst;
|
|
||||||
ASSERT_FALSE("Unimplemented");
|
static_assert(offsetof(StackLayout, cycles_remaining) + sizeof(u64) == offsetof(StackLayout, cycles_to_run));
|
||||||
|
|
||||||
|
if (ctx.conf.enable_cycle_counting) {
|
||||||
|
code.LDP(Xscratch0, Xscratch1, SP, offsetof(StackLayout, cycles_remaining));
|
||||||
|
code.SUB(Xscratch0, Xscratch1, Xscratch0);
|
||||||
|
EmitRelocation(code, ctx, LinkTarget::AddTicks);
|
||||||
|
}
|
||||||
|
|
||||||
|
code.MOV(W1, args[0].GetImmediateU32());
|
||||||
|
code.MOV(W2, args[1].GetImmediateU32());
|
||||||
|
EmitRelocation(code, ctx, LinkTarget::CallSVC);
|
||||||
|
|
||||||
|
if (ctx.conf.enable_cycle_counting) {
|
||||||
|
EmitRelocation(code, ctx, LinkTarget::GetTicksRemaining);
|
||||||
|
code.STP(X0, X0, SP, offsetof(StackLayout, cycles_remaining));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template<>
|
||||||
|
|
Loading…
Reference in a new issue