diff options
| author | Yang Liu <numbksco@gmail.com> | 2024-03-21 00:32:28 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-03-20 17:32:28 +0100 |
| commit | 14cf474167cae762fcdfa5a4f8acd7f71fd0c673 (patch) | |
| tree | 8533a6fd345851cb7c78ff2f69d1c02e5392460e | |
| parent | 47b120380583ee3f23e4826dd0a887c2c18dd990 (diff) | |
| download | box64-14cf474167cae762fcdfa5a4f8acd7f71fd0c673.tar.gz box64-14cf474167cae762fcdfa5a4f8acd7f71fd0c673.zip | |
[LA64_DYNAREC] Added CMOVcc opcodes and some fixes too (#1375)
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_0f.c | 30 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_emit_math.c | 31 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.h | 6 |
3 files changed, 44 insertions, 23 deletions
diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c index 49119328..5566183d 100644 --- a/src/dynarec/la64/dynarec_la64_0f.c +++ b/src/dynarec/la64/dynarec_la64_0f.c @@ -109,6 +109,36 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni FAKEED; break; + #define GO(GETFLAGS, NO, YES, F, I) \ + READFLAGS(F); \ + if (la64_lbt) { \ + X64_SETJ(x1, I); \ + } else { \ + GETFLAGS; \ + } \ + nextop = F8; \ + GETGD; \ + if (MODREG) { \ + ed = TO_LA64((nextop & 7) + (rex.b << 3)); \ + if (la64_lbt) \ + BEQZ(x1, 8); \ + else \ + B##NO(x1, 8); \ + MV(gd, ed); \ + } else { \ + addr = geted(dyn, addr, ninst, nextop, &ed, x2, x4, &fixedaddress, rex, NULL, 1, 0); \ + if (la64_lbt) \ + BEQZ(x1, 8); \ + else \ + B##NO(x1, 8); \ + LDxw(gd, ed, fixedaddress); \ + } \ + if (!rex.w) ZEROUP(gd); + + GOCOND(0x40, "CMOV", "Gd, Ed"); + + #undef GO + #define GO(GETFLAGS, NO, YES, F, I) \ READFLAGS(F); \ i32_ = F32S; \ diff --git a/src/dynarec/la64/dynarec_la64_emit_math.c b/src/dynarec/la64/dynarec_la64_emit_math.c index 1cd1fc16..600c8c49 100644 --- a/src/dynarec/la64/dynarec_la64_emit_math.c +++ b/src/dynarec/la64/dynarec_la64_emit_math.c @@ -260,33 +260,29 @@ void emit_add8(dynarec_la64_t* dyn, int ninst, int s1, int s2, int s3, int s4) X64_ADD_B(s1, s2); } ADD_D(s1, s1, s2); - ANDI(s1, s1, 0xff); - IFX(X_PEND) ST_H(s1, xEmu, offsetof(x64emu_t, res)); + + ANDI(s1, s1, 0xff); return; } CLEAR_FLAGS(s3); - IFX(X_AF | X_OF) - { + IFX(X_AF | X_OF) { OR(s3, s1, s2); // s3 = op1 | op2 AND(s4, s1, s2); // s4 = op1 & op2 } ADD_D(s1, s1, s2); - IFX(X_AF | X_OF) - { + IFX(X_AF | X_OF) { ANDN(s3, s3, s1); // s3 = ~res & (op1 | op2) OR(s3, s3, s2); // cc = (~res & (op1 | op2)) | (op1 & op2) - IFX(X_AF) - { + IFX(X_AF) { ANDI(s4, s3, 0x08); // AF: cc & 0x08 BEQZ(s4, 8); ORI(xFlags, xFlags, 1 << F_AF); } - IFX(X_OF) - { + IFX(X_OF) { SRLI_D(s3, s3, 6); SRLI_D(s4, s3, 1); XOR(s3, s3, s4); @@ -295,30 +291,25 @@ void emit_add8(dynarec_la64_t* dyn, int ninst, int s1, int s2, int s3, int s4) ORI(xFlags, xFlags, 1 << F_OF); } } - IFX(X_CF) - { + IFX(X_CF) { SRLI_D(s3, s1, 8); BEQZ(s3, 8); ORI(xFlags, xFlags, 1 << F_CF); } - IFX(X_PEND) - { + IFX(X_PEND) { ST_H(s1, xEmu, offsetof(x64emu_t, res)); } ANDI(s1, s1, 0xff); - IFX(X_ZF) - { + IFX(X_ZF) { BNEZ(s1, 8); ORI(xFlags, xFlags, 1 << F_ZF); } - IFX(X_SF) - { + IFX(X_SF) { SRLI_D(s3, s1, 7); BEQZ(s3, 8); ORI(xFlags, xFlags, 1 << F_SF); } - IFX(X_PF) - { + IFX(X_PF) { emit_pf(dyn, ninst, s1, s3, s4); } } diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h index db980487..f26dfba7 100644 --- a/src/dynarec/la64/dynarec_la64_helper.h +++ b/src/dynarec/la64/dynarec_la64_helper.h @@ -732,9 +732,9 @@ uintptr_t dynarec64_F0(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni #define RESTORE_EFLAGS(s) \ do { \ if (la64_lbt) { \ - CLEAR_FLAGS_(reg); \ - X64_GET_EFLAGS(reg, X_ALL); \ - OR(xFlags, xFlags, reg); \ + CLEAR_FLAGS_(s); \ + X64_GET_EFLAGS(s, X_ALL); \ + OR(xFlags, xFlags, s); \ } \ } while (0) |