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 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