diff --git a/src/dynarmic/backend/arm64/emit_arm64_a32_coprocessor.cpp b/src/dynarmic/backend/arm64/emit_arm64_a32_coprocessor.cpp index 746757e9..629c381c 100644 --- a/src/dynarmic/backend/arm64/emit_arm64_a32_coprocessor.cpp +++ b/src/dynarmic/backend/arm64/emit_arm64_a32_coprocessor.cpp @@ -24,7 +24,20 @@ static void EmitCoprocessorException() { } static void CallCoprocCallback(oaknut::CodeGenerator& code, EmitContext& ctx, A32::Coprocessor::Callback callback, IR::Inst* inst = nullptr, std::optional arg0 = {}, std::optional arg1 = {}) { - const auto Xresult = ctx.reg_alloc.PrepareForCallReg(inst, {}, arg0, arg1); + if (inst) { + const auto Xresult = ctx.reg_alloc.PrepareForCallReg(inst, {}, arg0, arg1); + + if (callback.user_arg) { + code.MOV(X0, reinterpret_cast(*callback.user_arg)); + } + + code.MOV(Xscratch0, reinterpret_cast(callback.function)); + code.BLR(Xscratch0); + code.MOV(Xresult, X0); + return; + } + + ctx.reg_alloc.PrepareForCall({}, arg0, arg1); if (callback.user_arg) { code.MOV(X0, reinterpret_cast(*callback.user_arg)); @@ -32,7 +45,6 @@ static void CallCoprocCallback(oaknut::CodeGenerator& code, EmitContext& ctx, A3 code.MOV(Xscratch0, reinterpret_cast(callback.function)); code.BLR(Xscratch0); - code.MOV(Xresult, X0); } template<>