diff options
| author | xctan <xctan@cirno.icu> | 2024-02-27 22:13:00 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-27 15:13:00 +0100 |
| commit | d8affd85642d03b21b871243831667089b9057ad (patch) | |
| tree | 1e449555ca693bfb4f8ddc0ef0c7bb6c72cf4b4d /src | |
| parent | f3d4a1e1c3d470fe6be4a02d9a1929738e9b5055 (diff) | |
| download | box64-d8affd85642d03b21b871243831667089b9057ad.tar.gz box64-d8affd85642d03b21b871243831667089b9057ad.zip | |
[RV64_DYNAREC] Optimized XOR Ew, Gw when Ew == Gw (#1289)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_66.c | 70 |
1 files changed, 62 insertions, 8 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c index 59350bcb..419df8ff 100644 --- a/src/dynarec/rv64/dynarec_rv64_66.c +++ b/src/dynarec/rv64/dynarec_rv64_66.c @@ -253,19 +253,73 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni INST_NAME("XOR Ew, Gw"); SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETGW(x2); - GETEW(x1, 0); - emit_xor16(dyn, ninst, x1, x2, x4, x5, x6); - EWBACK; + // try to determine ed and gd + ed = 0; + GETGD; + if (MODREG) { + GETED(0); + } + if (ed == gd) { + // optimize XOR Gw, Gw + CLEAR_FLAGS(); + IFX(X_PEND) { + SET_DF(x6, d_xor16); + } else IFX(X_ALL) { + SET_DFNONE(); + } + SRLI(ed, ed, 16); + SLLI(ed, ed, 16); + IFX(X_PEND) { + SH(ed, xEmu, offsetof(x64emu_t, res)); + } + IFX(X_ZF) { + ORI(xFlags, xFlags, 1 << F_ZF); + } + IFX(X_PF) { + ORI(xFlags, xFlags, 1 << F_PF); + } + } else { + GETGW(x2); + GETEW(x1, 0); + emit_xor16(dyn, ninst, x1, x2, x4, x5, x6); + EWBACK; + } break; case 0x33: INST_NAME("XOR Gw, Ew"); SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; - GETGW(x1); - GETEW(x2, 0); - emit_xor16(dyn, ninst, x1, x2, x4, x5, x6); - GWBACK; + // try to determine ed and gd + ed = 0; + GETGD; + if (MODREG) { + GETED(0); + } + if (ed == gd) { + // optimize XOR Gw, Gw + CLEAR_FLAGS(); + IFX(X_PEND) { + SET_DF(x6, d_xor16); + } else IFX(X_ALL) { + SET_DFNONE(); + } + SRLI(ed, ed, 16); + SLLI(ed, ed, 16); + IFX(X_PEND) { + SH(ed, xEmu, offsetof(x64emu_t, res)); + } + IFX(X_ZF) { + ORI(xFlags, xFlags, 1 << F_ZF); + } + IFX(X_PF) { + ORI(xFlags, xFlags, 1 << F_PF); + } + } else { + GETGW(x1); + GETEW(x2, 0); + emit_xor16(dyn, ninst, x1, x2, x4, x5, x6); + GWBACK; + } break; case 0x35: INST_NAME("XOR AX, Iw"); |