aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--src/dynarmic/backend/arm64/emit_arm64_a64.cpp5
-rw-r--r--src/dynarmic/backend/arm64/fpsr_manager.cpp9
-rw-r--r--src/dynarmic/backend/arm64/fpsr_manager.h3
3 files changed, 15 insertions, 2 deletions
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<IR::Opcode::A64GetFPCR>(oaknut::CodeGenerator& code, EmitContext& ct
}
template<>
-void EmitIR<IR::Opcode::A64GetFPSR>(oaknut::CodeGenerator& code, EmitContext& ctx, IR::Inst* inst) {
+void EmitIR<IR::Opcode::A64GetFPSR>(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;