diff --git a/src/dynarmic/backend/arm64/emit_arm64_a64.cpp b/src/dynarmic/backend/arm64/emit_arm64_a64.cpp index 67fd91f2..5152a54b 100644 --- a/src/dynarmic/backend/arm64/emit_arm64_a64.cpp +++ b/src/dynarmic/backend/arm64/emit_arm64_a64.cpp @@ -10,6 +10,7 @@ #include "dynarmic/backend/arm64/abi.h" #include "dynarmic/backend/arm64/emit_arm64.h" #include "dynarmic/backend/arm64/emit_context.h" +#include "dynarmic/backend/arm64/fpsr_manager.h" #include "dynarmic/backend/arm64/reg_alloc.h" #include "dynarmic/interface/halt_reason.h" #include "dynarmic/ir/basic_block.h" @@ -277,11 +278,11 @@ void EmitIR(oaknut::CodeGenerator& code, EmitContext& ct } template<> -void EmitIR(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) { +void EmitIR(oaknut::CodeGenerator&, EmitContext& ctx, IR::Inst* inst) { auto Wresult = ctx.reg_alloc.WriteW(inst); RegAlloc::Realize(Wresult); - code.LDR(Wresult, Xstate, offsetof(A64JitState, fpsr)); + ctx.fpsr.GetFpsr(Wresult); } template<> diff --git a/src/dynarmic/backend/arm64/fpsr_manager.cpp b/src/dynarmic/backend/arm64/fpsr_manager.cpp index 1a1c323e..1c614745 100644 --- a/src/dynarmic/backend/arm64/fpsr_manager.cpp +++ b/src/dynarmic/backend/arm64/fpsr_manager.cpp @@ -37,4 +37,13 @@ void FpsrManager::Load() { fpsr_loaded = true; } +void FpsrManager::GetFpsr(oaknut::WReg dest) { + code.LDR(dest, Xstate, state_fpsr_offset); + + if (fpsr_loaded) { + code.MRS(Xscratch1, oaknut::SystemReg::FPSR); + code.ORR(dest, dest, Wscratch1); + } +} + } // namespace Dynarmic::Backend::Arm64 diff --git a/src/dynarmic/backend/arm64/fpsr_manager.h b/src/dynarmic/backend/arm64/fpsr_manager.h index e003522d..9e5d68bf 100644 --- a/src/dynarmic/backend/arm64/fpsr_manager.h +++ b/src/dynarmic/backend/arm64/fpsr_manager.h @@ -9,6 +9,7 @@ namespace oaknut { struct CodeGenerator; +struct WReg; } // namespace oaknut namespace Dynarmic::Backend::Arm64 { @@ -21,6 +22,8 @@ public: void Load(); void Overwrite() { fpsr_loaded = false; } + void GetFpsr(oaknut::WReg); + private: oaknut::CodeGenerator& code; size_t state_fpsr_offset;