From 60a56fa893be1e0d238b66935cab5c899e5da1ea Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Mon, 13 Jul 2026 14:41:46 +0800 Subject: [PATCH] [LA64_DYNAREC] Fixed gpr upper tracking non-lbt path --- src/dynarec/la64/dynarec_la64_emit_logic.c | 16 ++++------ src/dynarec/la64/dynarec_la64_emit_math.c | 18 +++++------ src/dynarec/la64/dynarec_la64_emit_shift.c | 35 ++++++++++------------ 3 files changed, 31 insertions(+), 38 deletions(-) diff --git a/src/dynarec/la64/dynarec_la64_emit_logic.c b/src/dynarec/la64/dynarec_la64_emit_logic.c index 4bd3de3390..3200e96a6f 100644 --- a/src/dynarec/la64/dynarec_la64_emit_logic.c +++ b/src/dynarec/la64/dynarec_la64_emit_logic.c @@ -185,9 +185,7 @@ void emit_xor32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s BGE(s1, xZR, 8); ORI(xFlags, xFlags, 1 << F_SF); } - if (s1 != s2 && NEED_ZEROUP(s1)) { - ZEROUP(s1); - } + if (!rex.w && s1 != s2) ZEROUP(s1); IFX(X_PEND) { SDxw(s1, xEmu, offsetof(x64emu_t, res)); @@ -252,7 +250,7 @@ void emit_xor32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i BGE(s1, xZR, 8); ORI(xFlags, xFlags, 1 << F_SF); } - if (NEED_ZEROUP(s1)) ZEROUP(s1); + if (!rex.w) ZEROUP(s1); IFX (X_PEND) { SDxw(s1, xEmu, offsetof(x64emu_t, res)); @@ -408,16 +406,16 @@ void emit_and32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s } AND(s1, s1, s2); // res = s1 & s2 - if (NEED_ZEROUP(s1)) ZEROUP(s1); IFX(X_PEND) { SDxw(s1, xEmu, offsetof(x64emu_t, res)); } if (cpuext.lbt) { + if (NEED_ZEROUP(s1)) ZEROUP(s1); if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR, s3, xZR); return; - } + } else if (!rex.w) ZEROUP(s1); CLEAR_FLAGS(s3); IFX(X_SF) { @@ -563,7 +561,7 @@ void emit_or32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s3 ORI(xFlags, xFlags, 1 << F_SF); } - if (NEED_ZEROUP(s1)) ZEROUP(s1); + if (!rex.w) ZEROUP(s1); IFX(X_ZF) { BNEZ(s1, 8); ORI(xFlags, xFlags, 1 << F_ZF); @@ -615,9 +613,7 @@ void emit_or32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, in BGE(s1, xZR, 8); ORI(xFlags, xFlags, 1 << F_SF); } - if (NEED_ZEROUP(s1)) { - ZEROUP(s1); - } + if (!rex.w) ZEROUP(s1); IFX(X_ZF) { BNEZ(s1, 8); diff --git a/src/dynarec/la64/dynarec_la64_emit_math.c b/src/dynarec/la64/dynarec_la64_emit_math.c index d8c7a59ce7..88f1e8b2d8 100644 --- a/src/dynarec/la64/dynarec_la64_emit_math.c +++ b/src/dynarec/la64/dynarec_la64_emit_math.c @@ -105,7 +105,7 @@ void emit_add32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s BGE(s1, xZR, 8); ORI(xFlags, xFlags, 1 << F_SF); } - if (NEED_ZEROUP(s1)) ZEROUP(s1); + if (!rex.w) ZEROUP(s1); IFX (X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -221,7 +221,7 @@ void emit_add32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i BGE(s1, xZR, 8); ORI(xFlags, xFlags, 1 << F_SF); } - if (NEED_ZEROUP(s1)) ZEROUP(s1); + if (!rex.w) ZEROUP(s1); IFX (X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -606,7 +606,7 @@ void emit_sub32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s BGE(s1, xZR, 8); ORI(xFlags, xFlags, 1 << F_SF); } - if (NEED_ZEROUP(s1)) ZEROUP(s1); + if (!rex.w) ZEROUP(s1); CALC_SUB_FLAGS(s5, s2, s1, s3, s4, rex.w ? 64 : 32); IFX (X_ZF) { BNEZ(s1, 8); @@ -687,7 +687,7 @@ void emit_sub32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i BGE(s1, xZR, 8); ORI(xFlags, xFlags, 1 << F_SF); } - if (NEED_ZEROUP(s1)) ZEROUP(s1); + if (!rex.w) ZEROUP(s1); CALC_SUB_FLAGS(s5, s2, s1, s3, s4, rex.w ? 64 : 32); IFX (X_ZF) { BNEZ(s1, 8); @@ -896,7 +896,7 @@ void emit_sbb32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s BGE(s1, xZR, 8); ORI(xFlags, xFlags, 1 << F_SF); } - if (NEED_ZEROUP(s1)) ZEROUP(s1); + if (!rex.w) ZEROUP(s1); IFX (X_PEND) { SDxw(s1, xEmu, offsetof(x64emu_t, res)); } @@ -1040,7 +1040,7 @@ void emit_neg32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s BGE(s1, xZR, 8); ORI(xFlags, xFlags, 1 << F_SF); } - if (NEED_ZEROUP(s1)) ZEROUP(s1); + if (!rex.w) ZEROUP(s1); IFX (X_PF) { emit_pf(dyn, ninst, s1, s3, s2); } @@ -1310,7 +1310,7 @@ void emit_adc32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s BGE(s1, xZR, 8); ORI(xFlags, xFlags, 1 << F_SF); } - if (NEED_ZEROUP(s1)) ZEROUP(s1); + if (!rex.w) ZEROUP(s1); IFX (X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } @@ -1489,7 +1489,7 @@ void emit_inc32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s BGE(s1, xZR, 8); ORI(xFlags, xFlags, 1 << F_SF); } - if (NEED_ZEROUP(s1)) ZEROUP(s1); + if (!rex.w) ZEROUP(s1); IFX (X_PF) { emit_pf(dyn, ninst, s1, s3, s2); } @@ -1666,7 +1666,7 @@ void emit_dec32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s BSTRPICK_D(s5, s1, rex.w ? 63 : 31, rex.w ? 63 : 31); BSTRINS_D(xFlags, s5, F_SF, F_SF); } - if (NEED_ZEROUP(s1)) ZEROUP(s1); + if (!rex.w) ZEROUP(s1); IFX (X_PF) { emit_pf(dyn, ninst, s1, s3, s2); } diff --git a/src/dynarec/la64/dynarec_la64_emit_shift.c b/src/dynarec/la64/dynarec_la64_emit_shift.c index bb09bbcdd9..97771b8152 100644 --- a/src/dynarec/la64/dynarec_la64_emit_shift.c +++ b/src/dynarec/la64/dynarec_la64_emit_shift.c @@ -252,7 +252,7 @@ void emit_shl32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s SLTI(s3, s1, 0); BSTRINS_D(xFlags, s3, F_SF, F_SF); } - if (NEED_ZEROUP(s1)) ZEROUP(s1); + if (!rex.w) ZEROUP(s1); IFX (X_PEND) { SDxw(s1, xEmu, offsetof(x64emu_t, res)); } @@ -336,7 +336,7 @@ void emit_shl32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, SLTI(s3, s1, 0); BSTRINS_D(xFlags, s3, F_SF, F_SF); } - if (NEED_ZEROUP(s1)) ZEROUP(s1); + if (!rex.w) ZEROUP(s1); IFX (X_PEND) { SDxw(s1, xEmu, offsetof(x64emu_t, res)); } @@ -853,7 +853,7 @@ void emit_shr32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s BGE(s1, xZR, 8); ORI(xFlags, xFlags, 1 << F_SF); } - if (NEED_ZEROUP(s1)) ZEROUP(s1); + if (!rex.w) ZEROUP(s1); IFX (X_PEND) { SDxw(s1, xEmu, offsetof(x64emu_t, res)); } @@ -1148,7 +1148,7 @@ void emit_sar32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, BGE(s1, xZR, 8); ORI(xFlags, xFlags, 1 << F_SF); } - if (NEED_ZEROUP(s1)) ZEROUP(s1); + if (!rex.w) ZEROUP(s1); IFX (X_PEND) { SDxw(s1, xEmu, offsetof(x64emu_t, res)); } @@ -1209,7 +1209,7 @@ void emit_sar32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s BGE(s1, xZR, 8); ORI(xFlags, xFlags, 1 << F_SF); } - if (NEED_ZEROUP(s1)) ZEROUP(s1); + if (!rex.w) ZEROUP(s1); IFX (X_PEND) { SDxw(s1, xEmu, offsetof(x64emu_t, res)); } @@ -1270,7 +1270,7 @@ void emit_ror32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, ROTRI_D(s1, s1, c); else ROTRI_W(s1, s1, c); - if (NEED_ZEROUP(s1)) ZEROUP(s1); + if (!rex.w) ZEROUP(s1); IFX (X_CF) { SRLIxw(s3, s1, rex.w ? 63 : 31); @@ -1419,8 +1419,7 @@ void emit_rol32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s } else { ROTR_W(s1, s1, s3); } - if (NEED_ZEROUP(s1)) ZEROUP(s1); - + if (!rex.w) ZEROUP(s1); if (cpuext.lbt) { if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR, s3, xZR); return; @@ -1463,12 +1462,12 @@ void emit_ror32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s } else { ROTR_W(s1, s1, s2); } - if (NEED_ZEROUP(s1)) ZEROUP(s1); if (cpuext.lbt) { + if (NEED_ZEROUP(s1)) ZEROUP(s1); if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR, s3, xZR); return; - } + } else if (!rex.w) ZEROUP(s1); IFX (X_CF) { SRLIxw(s3, s1, rex.w ? 63 : 31); @@ -1525,7 +1524,7 @@ void emit_rol32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, ROTRI_D(s1, s1, (rex.w ? 64 : 32) - c); else ROTRI_W(s1, s1, (rex.w ? 64 : 32) - c); - if (NEED_ZEROUP(s1)) ZEROUP(s1); + if (!rex.w) ZEROUP(s1); IFX (X_CF) { ANDI(s4, s1, 1 << F_CF); @@ -1566,7 +1565,7 @@ void emit_shld32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, uin SRLIxw(s1, s2, (rex.w ? 64 : 32) - c); OR(s1, s1, s3); - if (NEED_ZEROUP(s1)) ZEROUP(s1); + if (!rex.w) ZEROUP(s1); IFX (X_SF) { SRLIxw(s3, s1, rex.w ? 63 : 31); BEQZ(s3, 8); @@ -1623,7 +1622,7 @@ void emit_shrd32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, uin SLLIxw(s1, s2, (rex.w ? 64 : 32) - c); OR(s1, s1, s3); - if (NEED_ZEROUP(s1)) ZEROUP(s1); + if (!rex.w) ZEROUP(s1); IFX (X_SF) { SRLIxw(s3, s1, rex.w ? 63 : 31); BEQZ(s3, 8); @@ -1675,7 +1674,7 @@ void emit_shrd32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int IFX (X_PEND) { SDxw(s1, xEmu, offsetof(x64emu_t, res)); } - if (NEED_ZEROUP(s1)) ZEROUP(s1); + if (!rex.w) ZEROUP(s1); IFX (X_ZF) { BNEZ(s1, 8); ORI(xFlags, xFlags, 1 << F_ZF); @@ -1724,7 +1723,7 @@ void emit_shld32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int IFX (X_PEND) { SDxw(s1, xEmu, offsetof(x64emu_t, res)); } - if (NEED_ZEROUP(s1)) ZEROUP(s1); + if (!rex.w) ZEROUP(s1); IFX (X_ZF) { BNEZ(s1, 8); ORI(xFlags, xFlags, 1 << F_ZF); @@ -1903,8 +1902,7 @@ void emit_rcl32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, SRLI_W(s5, s1, 33 - c); OR(s1, s5, s4); } - if (NEED_ZEROUP(s1)) ZEROUP(s1); - + if (!rex.w) ZEROUP(s1); IFX (X_CF) { BSTRINS_D(xFlags, s3, F_CF, F_CF); } @@ -2061,8 +2059,7 @@ void emit_rcr32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, uint32_t c, SLLI_D(s3, s1, (rex.w ? 65 : 33) - c); OR(s1, s3, s4); } - if (NEED_ZEROUP(s1)) ZEROUP(s1); - + if (!rex.w) ZEROUP(s1); IFX (X_CF) { BSTRINS_D(xFlags, s5, F_CF, F_CF); }