Correct FPSR and FPCR

This commit is contained in:
MerryMage 2018-02-20 20:29:15 +00:00
parent 147284427b
commit c832cec96d
3 changed files with 6 additions and 3 deletions

View file

@ -348,8 +348,8 @@ void A64EmitX64::EmitA64GetSP(A64EmitContext& ctx, IR::Inst* inst) {
} }
void A64EmitX64::EmitA64GetFPCR(A64EmitContext& ctx, IR::Inst* inst) { void A64EmitX64::EmitA64GetFPCR(A64EmitContext& ctx, IR::Inst* inst) {
Xbyak::Reg64 result = ctx.reg_alloc.ScratchGpr(); Xbyak::Reg32 result = ctx.reg_alloc.ScratchGpr().cvt32();
code.mov(result, qword[r15 + offsetof(A64JitState, fpcr)]); code.mov(result, dword[r15 + offsetof(A64JitState, fpcr)]);
ctx.reg_alloc.DefineValue(inst, result); ctx.reg_alloc.DefineValue(inst, result);
} }

View file

@ -62,7 +62,8 @@ u32 A64JitState::GetFpcr() const {
void A64JitState::SetFpcr(u32 value) { void A64JitState::SetFpcr(u32 value) {
fpcr = value & FPCR_MASK; fpcr = value & FPCR_MASK;
guest_MXCSR = 0x00001f80; // Mask all exceptions guest_MXCSR &= 0x0000003D;
guest_MXCSR |= 0x00001f80; // Mask all exceptions
// RMode // RMode
const std::array<u32, 4> MXCSR_RMode {0x0, 0x4000, 0x2000, 0x6000}; const std::array<u32, 4> MXCSR_RMode {0x0, 0x4000, 0x2000, 0x6000};
@ -108,6 +109,7 @@ u32 A64JitState::GetFpsr() const {
} }
void A64JitState::SetFpsr(u32 value) { void A64JitState::SetFpsr(u32 value) {
guest_MXCSR &= ~0x0000003D;
guest_MXCSR |= ( value ) & 0b0000000000001; // IE = IOC guest_MXCSR |= ( value ) & 0b0000000000001; // IE = IOC
guest_MXCSR |= ( value << 1) & 0b0000000111100; // PE, UE, OE, ZE = IXC, UFC, OFC, DZC guest_MXCSR |= ( value << 1) & 0b0000000111100; // PE, UE, OE, ZE = IXC, UFC, OFC, DZC

View file

@ -59,6 +59,7 @@ bool TranslatorVisitor::MSR_reg(Imm<1> o0, Imm<3> op1, Imm<4> CRn, Imm<4> CRm, I
return true; return true;
case 0b11'011'0100'0100'000: // FPCR case 0b11'011'0100'0100'000: // FPCR
ir.SetFPCR(X(32, Rt)); ir.SetFPCR(X(32, Rt));
ir.SetPC(ir.Imm64(ir.current_location->PC() + 4));
ir.SetTerm(IR::Term::ReturnToDispatch{}); ir.SetTerm(IR::Term::ReturnToDispatch{});
return false; return false;
case 0b11'011'0100'0100'001: // FPSR case 0b11'011'0100'0100'001: // FPSR