Skip to content

Commit e85f190

Browse files
authored
[LA64_DYNAREC] Fixed and refined 66F30F opcodes (#3441)
1 parent 8f8aa39 commit e85f190

File tree

1 file changed

+38
-39
lines changed

1 file changed

+38
-39
lines changed

src/dynarec/la64/dynarec_la64_66f30f.c

Lines changed: 38 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -60,64 +60,63 @@ uintptr_t dynarec64_66F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, in
6060
VPICKVE2GR_HU(x2, v0, 0);
6161
BSTRINS_D(gd, x2, 15, 0);
6262
IFX (X_ALL) {
63-
if (cpuext.lbt) {
64-
X64_SET_EFLAGS(xZR, X_ALL);
65-
BNEZ_MARK(x2);
66-
ADDI_D(x5, xZR, 1 << F_ZF);
67-
X64_SET_EFLAGS(x5, X_ZF);
68-
} else {
69-
CLEAR_FLAGS(x5);
70-
BNEZ_MARK(x2);
71-
ORI(xFlags, xFlags, 1 << F_ZF);
72-
}
63+
CLEAR_FLAGS(x5);
64+
BNEZ_MARK(x2);
65+
ORI(xFlags, xFlags, 1 << F_ZF);
7366
MARK;
67+
SPILL_EFLAGS();
7468
}
7569
break;
7670
case 0xBC:
7771
INST_NAME("TZCNT Gw, Ew");
78-
SETFLAGS(X_ZF, SF_SUBSET, NAT_FLAGS_NOFUSION);
72+
if (!BOX64DRENV(dynarec_safeflags)) {
73+
SETFLAGS(X_CF | X_ZF, SF_SUBSET, NAT_FLAGS_NOFUSION);
74+
} else {
75+
SETFLAGS(X_ALL, SF_SET, NAT_FLAGS_NOFUSION);
76+
}
7977
SET_DFNONE();
8078
nextop = F8;
81-
GETEW(x5, 0);
82-
GETGD;
83-
RESTORE_EFLAGS(x1);
84-
/*
85-
ZF is set if gd is zero, unset non-zero.
86-
CF is set if ed is zero, unset non-zero.
87-
OF, SF, PF, and AF flags are undefined
88-
*/
79+
GETEW(x1, 0);
80+
GETGW(x2);
8981
CLEAR_FLAGS(x2);
82+
IFX (X_CF) {
83+
SEQZ(x3, ed);
84+
BSTRINS_D(xFlags, x3, F_CF, F_CF);
85+
}
9086
ADDI_D(x4, xZR, -1);
9187
BSTRINS_D(x4, ed, 15, 0);
9288
CTZ_W(gd, x4);
93-
BNE(gd, xZR, 4 + 4);
94-
ORI(xFlags, xFlags, 1 << F_ZF);
95-
SRLI_W(x5, gd, 4); // maximum value is 16, F_CF = 0
96-
OR(xFlags, xFlags, x5);
89+
IFX (X_ZF) {
90+
SEQZ(x3, gd);
91+
BSTRINS_D(xFlags, x3, F_ZF, F_ZF);
92+
}
9793
SPILL_EFLAGS();
94+
GWBACK;
9895
break;
9996
case 0xBD:
10097
INST_NAME("LZCNT Gw, Ew");
101-
SETFLAGS(X_ZF, SF_SUBSET, NAT_FLAGS_NOFUSION);
98+
if (!BOX64DRENV(dynarec_safeflags)) {
99+
SETFLAGS(X_CF | X_ZF, SF_SUBSET, NAT_FLAGS_NOFUSION);
100+
} else {
101+
SETFLAGS(X_ALL, SF_SET, NAT_FLAGS_NOFUSION);
102+
}
102103
SET_DFNONE();
103104
nextop = F8;
104-
GETEW(x5, 0);
105-
GETGD;
106-
RESTORE_EFLAGS(x1);
107-
/*
108-
ZF is set if gd is zero, unset non-zero.
109-
CF is set if ed is zero, unset non-zero.
110-
OF, SF, PF, and AF flags are undefined
111-
*/
105+
GETEW(x1, 0);
106+
GETGW(x2);
112107
CLEAR_FLAGS(x2);
113-
ADDI_D(x4, xZR, -1);
114-
BSTRINS_D(x4, ed, 31, 16);
115-
CLZ_W(gd, x4);
116-
BNE(gd, xZR, 4 + 4);
117-
ORI(xFlags, xFlags, 1 << F_ZF);
118-
SRLI_W(x5, gd, 4); // maximum value is 16, F_CF = 0
119-
OR(xFlags, xFlags, x5);
108+
IFX (X_CF) {
109+
SEQZ(x3, ed);
110+
BSTRINS_D(xFlags, x3, F_CF, F_CF);
111+
}
112+
CLZ_W(gd, ed);
113+
ADDI_D(gd, gd, -16);
114+
IFX (X_ZF) {
115+
SEQZ(x3, gd);
116+
BSTRINS_D(xFlags, x3, F_ZF, F_ZF);
117+
}
120118
SPILL_EFLAGS();
119+
GWBACK;
121120
break;
122121
default:
123122
DEFAULT;

0 commit comments

Comments
 (0)