From c832cec96d413ed6e640431234bc39a0e8912843 Mon Sep 17 00:00:00 2001
From: MerryMage <MerryMage@users.noreply.github.com>
Date: Tue, 20 Feb 2018 20:29:15 +0000
Subject: [PATCH] Correct FPSR and FPCR

---
 src/backend_x64/a64_emit_x64.cpp           | 4 ++--
 src/backend_x64/a64_jitstate.cpp           | 4 +++-
 src/frontend/A64/translate/impl/system.cpp | 1 +
 3 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/src/backend_x64/a64_emit_x64.cpp b/src/backend_x64/a64_emit_x64.cpp
index fea42c9f..006c18fa 100644
--- a/src/backend_x64/a64_emit_x64.cpp
+++ b/src/backend_x64/a64_emit_x64.cpp
@@ -348,8 +348,8 @@ void A64EmitX64::EmitA64GetSP(A64EmitContext& ctx, IR::Inst* inst) {
 }
 
 void A64EmitX64::EmitA64GetFPCR(A64EmitContext& ctx, IR::Inst* inst) {
-    Xbyak::Reg64 result = ctx.reg_alloc.ScratchGpr();
-    code.mov(result, qword[r15 + offsetof(A64JitState, fpcr)]);
+    Xbyak::Reg32 result = ctx.reg_alloc.ScratchGpr().cvt32();
+    code.mov(result, dword[r15 + offsetof(A64JitState, fpcr)]);
     ctx.reg_alloc.DefineValue(inst, result);
 }
 
diff --git a/src/backend_x64/a64_jitstate.cpp b/src/backend_x64/a64_jitstate.cpp
index d9106e0f..efc8d167 100644
--- a/src/backend_x64/a64_jitstate.cpp
+++ b/src/backend_x64/a64_jitstate.cpp
@@ -62,7 +62,8 @@ u32 A64JitState::GetFpcr() const {
 void A64JitState::SetFpcr(u32 value) {
     fpcr = value & FPCR_MASK;
 
-    guest_MXCSR = 0x00001f80; // Mask all exceptions
+    guest_MXCSR &= 0x0000003D;
+    guest_MXCSR |= 0x00001f80; // Mask all exceptions
 
     // RMode
     const std::array<u32, 4> MXCSR_RMode {0x0, 0x4000, 0x2000, 0x6000};
@@ -108,6 +109,7 @@ u32 A64JitState::GetFpsr() const {
 }
 
 void A64JitState::SetFpsr(u32 value) {
+    guest_MXCSR &= ~0x0000003D;
     guest_MXCSR |= ( value     ) & 0b0000000000001;  // IE = IOC
     guest_MXCSR |= ( value << 1) & 0b0000000111100;  // PE, UE, OE, ZE = IXC, UFC, OFC, DZC
 
diff --git a/src/frontend/A64/translate/impl/system.cpp b/src/frontend/A64/translate/impl/system.cpp
index b8a3dc03..bab196a2 100644
--- a/src/frontend/A64/translate/impl/system.cpp
+++ b/src/frontend/A64/translate/impl/system.cpp
@@ -59,6 +59,7 @@ bool TranslatorVisitor::MSR_reg(Imm<1> o0, Imm<3> op1, Imm<4> CRn, Imm<4> CRm, I
         return true;
     case 0b11'011'0100'0100'000: // FPCR
         ir.SetFPCR(X(32, Rt));
+        ir.SetPC(ir.Imm64(ir.current_location->PC() + 4));
         ir.SetTerm(IR::Term::ReturnToDispatch{});
         return false;
     case 0b11'011'0100'0100'001: // FPSR