diff --git a/src/backend_x64/emit_x64.cpp b/src/backend_x64/emit_x64.cpp index c991a739..085bce5a 100644 --- a/src/backend_x64/emit_x64.cpp +++ b/src/backend_x64/emit_x64.cpp @@ -325,17 +325,16 @@ void EmitX64::EmitSetVFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { } void EmitX64::EmitOrQFlag(RegAlloc& reg_alloc, IR::Block&, IR::Inst* inst) { - constexpr size_t flag_bit = 27; - constexpr u32 flag_mask = 1u << flag_bit; + using namespace Xbyak::util; + auto args = reg_alloc.GetArgumentInfo(inst); if (args[0].IsImmediate()) { if (args[0].GetImmediateU1()) - code->or_(MJitStateCpsr_other(), flag_mask); + code->mov(dword[r15 + offsetof(JitState, CPSR_q)], 1); } else { - Xbyak::Reg32 to_store = reg_alloc.UseScratchGpr(args[0]).cvt32(); + Xbyak::Reg8 to_store = reg_alloc.UseGpr(args[0]).cvt8(); - code->shl(to_store, flag_bit); - code->or_(MJitStateCpsr_other(), to_store); + code->or_(code->byte[r15 + offsetof(JitState, CPSR_q)], to_store); } } diff --git a/src/backend_x64/jitstate.cpp b/src/backend_x64/jitstate.cpp index 715f77a8..9898a3d8 100644 --- a/src/backend_x64/jitstate.cpp +++ b/src/backend_x64/jitstate.cpp @@ -47,6 +47,8 @@ namespace BackendX64 { u32 JitState::Cpsr() const { u32 cpsr = 0; + // Q flag + cpsr |= CPSR_q ? 1 << 27 : 0; // GE flags cpsr |= Common::Bit<31>(CPSR_ge) ? 1 << 19 : 0; cpsr |= Common::Bit<23>(CPSR_ge) ? 1 << 18 : 0; @@ -62,6 +64,8 @@ u32 JitState::Cpsr() const { } void JitState::SetCpsr(u32 cpsr) { + // Q flag + CPSR_q = Common::Bit<27>(cpsr) ? 1 : 0; // GE flags CPSR_ge = 0; CPSR_ge |= Common::Bit<19>(cpsr) ? 0xFF000000 : 0; @@ -73,7 +77,7 @@ void JitState::SetCpsr(u32 cpsr) { CPSR_et |= Common::Bit<9>(cpsr) ? 2 : 0; CPSR_et |= Common::Bit<5>(cpsr) ? 1 : 0; // Other flags - CPSR_other = cpsr & 0xFFF0FDDF; + CPSR_other = cpsr & 0xF7F0FDDF; } void JitState::ResetRSB() { diff --git a/src/backend_x64/jitstate.h b/src/backend_x64/jitstate.h index 911cdb2b..3695b8e8 100644 --- a/src/backend_x64/jitstate.h +++ b/src/backend_x64/jitstate.h @@ -31,6 +31,7 @@ struct JitState { u32 CPSR_other = 0; u32 CPSR_ge = 0; u32 CPSR_et = 0; + u32 CPSR_q = 0; u32 Cpsr() const; void SetCpsr(u32 cpsr);