From 2f06ef5d4e1187008c54bc5af1c513a5d713f3ef Mon Sep 17 00:00:00 2001 From: MerryMage Date: Sat, 27 Jul 2019 08:29:32 +0100 Subject: [PATCH] a32_emit_x64: EmitA32SetCpsr: BUGFIX: Actually set CPSR.GE Was unintentionally masking the writing of CPSR.GE due to 32-bit immediate sign extension. --- src/backend/x64/a32_emit_x64.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/backend/x64/a32_emit_x64.cpp b/src/backend/x64/a32_emit_x64.cpp index 5a54ea05..018e70ea 100644 --- a/src/backend/x64/a32_emit_x64.cpp +++ b/src/backend/x64/a32_emit_x64.cpp @@ -397,7 +397,9 @@ void A32EmitX64::EmitA32SetCpsr(A32EmitContext& ctx, IR::Inst* inst) { // cpsr_et and cpsr_ge static_assert(offsetof(A32JitState, upper_location_descriptor) + 4 == offsetof(A32JitState, cpsr_ge)); - code.and_(qword[r15 + offsetof(A32JitState, upper_location_descriptor)], u32(0xFFFF0000)); + // This mask is 0x7FFF0000, because we do not want the MSB to be sign extended to the upper dword. + static_assert((A32::LocationDescriptor::FPSCR_MODE_MASK & ~0x7FFF0000) == 0); + code.and_(qword[r15 + offsetof(A32JitState, upper_location_descriptor)], u32(0x7FFF0000)); code.mov(tmp, 0x000f0220); code.pext(cpsr, cpsr, tmp); code.mov(tmp.cvt64(), 0x01010101'00000003ull);