From 52aa68c31c6eed45ff335fc314ccf89c01a1e4b5 Mon Sep 17 00:00:00 2001 From: Merry Date: Wed, 20 Jul 2022 14:58:28 +0100 Subject: [PATCH] backend/x64: Fixup NZ flag emission --- src/dynarmic/backend/x64/a32_emit_x64.cpp | 25 +++++++++++------------ src/dynarmic/backend/x64/emit_x64.cpp | 3 +++ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/dynarmic/backend/x64/a32_emit_x64.cpp b/src/dynarmic/backend/x64/a32_emit_x64.cpp index 5e68478f..214e6597 100644 --- a/src/dynarmic/backend/x64/a32_emit_x64.cpp +++ b/src/dynarmic/backend/x64/a32_emit_x64.cpp @@ -544,12 +544,13 @@ void A32EmitX64::EmitA32SetCpsrNZCVQ(A32EmitContext& ctx, IR::Inst* inst) { void A32EmitX64::EmitA32SetCpsrNZ(A32EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); - ctx.reg_alloc.Use(args[0], HostLoc::RAX); + const Xbyak::Reg32 nz = ctx.reg_alloc.UseGpr(args[0]).cvt32(); + const Xbyak::Reg32 tmp = ctx.reg_alloc.ScratchGpr().cvt32(); - code.mov(al, code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1]); - code.and_(al, 1); - code.or_(al, ah); - code.mov(code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1], al); + code.movzx(tmp, code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1]); + code.and_(tmp, 1); + code.or_(tmp, nz); + code.mov(code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1], tmp.cvt8()); } void A32EmitX64::EmitA32SetCpsrNZC(A32EmitContext& ctx, IR::Inst* inst) { @@ -566,20 +567,18 @@ void A32EmitX64::EmitA32SetCpsrNZC(A32EmitContext& ctx, IR::Inst* inst) { code.mov(code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1], c); } } else { - ctx.reg_alloc.Use(args[0], HostLoc::RAX); + const Xbyak::Reg32 nz = ctx.reg_alloc.UseScratchGpr(args[0]).cvt32(); if (args[1].IsImmediate()) { const bool c = args[1].GetImmediateU1(); - code.mov(al, ah); - code.or_(al, c); - code.mov(code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1], al); + code.or_(nz, c); + code.mov(code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1], nz.cvt8()); } else { - const Xbyak::Reg8 c = ctx.reg_alloc.UseGpr(args[1]).cvt8(); + const Xbyak::Reg32 c = ctx.reg_alloc.UseGpr(args[1]).cvt32(); - code.mov(al, ah); - code.or_(al, c); - code.mov(code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1], al); + code.or_(nz, c); + code.mov(code.byte[r15 + offsetof(A32JitState, cpsr_nzcv) + 1], nz.cvt8()); } } } diff --git a/src/dynarmic/backend/x64/emit_x64.cpp b/src/dynarmic/backend/x64/emit_x64.cpp index 286f58c5..68e65c87 100644 --- a/src/dynarmic/backend/x64/emit_x64.cpp +++ b/src/dynarmic/backend/x64/emit_x64.cpp @@ -156,6 +156,9 @@ void EmitX64::EmitGetNZFromOp(EmitContext& ctx, IR::Inst* inst) { const Xbyak::Reg value = ctx.reg_alloc.UseGpr(args[0]).changeBit(bitsize); code.cmp(value, 0); code.lahf(); + code.db(0x0f); + code.db(0xb6); + code.db(0xc4); ctx.reg_alloc.DefineValue(inst, nz); }