diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2024-12-24 21:06:52 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-12-24 14:06:52 +0100 |
| commit | 05060803b243e143c1c95e4ec61be60f0e479181 (patch) | |
| tree | 1add8bd42f83978876e448cf166bf05224de5aae /src | |
| parent | e84f2e4a8beac7c781615f3b470c81e6f58f953b (diff) | |
| download | box64-05060803b243e143c1c95e4ec61be60f0e479181.tar.gz box64-05060803b243e143c1c95e4ec61be60f0e479181.zip | |
[RV64_DYNAREC] Fixed nativeflags tmp register usage (#2199)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f.c | 52 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_660f.c | 3 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 169 |
3 files changed, 117 insertions, 107 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c index 28b8fc96..22cc4029 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_0f.c @@ -100,7 +100,7 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } SRLI(xRDX, x3, 32); ZEXTW2(xRAX, x3); // wipe upper part - MV(xRCX, xZR); // IA32_TSC, 0 for now + MV(xRCX, xZR); // IA32_TSC, 0 for now break; default: DEFAULT; @@ -898,30 +898,30 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } break; -#define GO(GETFLAGS, NO, YES, NATNO, NATYES, F) \ - READFLAGS_FUSION(F, x1, x2, x3, x4, x5); \ - if (!dyn->insts[ninst].nat_flags_fusion) { \ - GETFLAGS; \ - } \ - nextop = F8; \ - GETGD; \ - if (MODREG) { \ - ed = TO_NAT((nextop & 7) + (rex.b << 3)); \ - if (dyn->insts[ninst].nat_flags_fusion) { \ - NATIVEJUMP(NATNO, 8); \ - } else { \ - B##NO(tmp1, 8); \ - } \ - MV(gd, ed); \ - } else { \ - addr = geted(dyn, addr, ninst, nextop, &ed, tmp2, tmp3, &fixedaddress, rex, NULL, 1, 0); \ - if (dyn->insts[ninst].nat_flags_fusion) { \ - NATIVEJUMP(NATNO, 8); \ - } else { \ - B##NO(tmp1, 8); \ - } \ - LDxw(gd, ed, fixedaddress); \ - } \ +#define GO(GETFLAGS, NO, YES, NATNO, NATYES, F) \ + READFLAGS_FUSION(F, x1, x2, x3, x4, x5); \ + if (!dyn->insts[ninst].nat_flags_fusion) { \ + GETFLAGS; \ + } \ + nextop = F8; \ + GETGD; \ + if (MODREG) { \ + ed = TO_NAT((nextop & 7) + (rex.b << 3)); \ + if (dyn->insts[ninst].nat_flags_fusion) { \ + NATIVEJUMP(NATNO, 8); \ + } else { \ + B##NO(tmp1, 8); \ + } \ + MV(gd, ed); \ + } else { \ + addr = geted(dyn, addr, ninst, nextop, &ed, tmp2, tmp3, &fixedaddress, rex, NULL, 1, 0); \ + if (dyn->insts[ninst].nat_flags_fusion) { \ + NATIVEJUMP(NATNO, 8); \ + } else { \ + B##NO(tmp1, 8); \ + } \ + LDxw(gd, ed, fixedaddress); \ + } \ if (!rex.w) ZEROUP(gd); GOCOND(0x40, "CMOV", "Gd, Ed"); @@ -1712,6 +1712,8 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni #define GO(GETFLAGS, NO, YES, NATNO, NATYES, F) \ READFLAGS(F); \ + tmp1 = x1; \ + tmp3 = x3; \ GETFLAGS; \ nextop = F8; \ S##YES(x3, x1); \ diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c index 2bad6621..ac6f5b24 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f.c +++ b/src/dynarec/rv64/dynarec_rv64_660f.c @@ -34,6 +34,7 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int uint8_t gd, ed; uint8_t wback, wb1, wb2, gback; uint8_t eb1, eb2; + uint8_t tmp1, tmp2, tmp3; int64_t j64; uint64_t tmp64u, tmp64u2; int v0, v1; @@ -276,6 +277,8 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int #define GO(GETFLAGS, NO, YES, NATNO, NATYES, F) \ READFLAGS(F); \ + tmp1 = x1; \ + tmp3 = x3; \ GETFLAGS; \ nextop = F8; \ GETGD; \ diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index e2b8fdc5..2a5fc687 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -1009,9 +1009,14 @@ #endif #ifndef READFLAGS_FUSION -#define READFLAGS_FUSION(A, s1, s2, s3, s4, s5) \ - if(dyn->insts[ninst].nat_flags_fusion) get_free_scratch(dyn, ninst, &tmp1, &tmp2, &tmp3, s1, s2, s3, s4, s5); \ - else { tmp1=s1; tmp2=s2; tmp3=s3; } \ +#define READFLAGS_FUSION(A, s1, s2, s3, s4, s5) \ + if (dyn->insts[ninst].nat_flags_fusion) \ + get_free_scratch(dyn, ninst, &tmp1, &tmp2, &tmp3, s1, s2, s3, s4, s5); \ + else { \ + tmp1 = s1; \ + tmp2 = s2; \ + tmp3 = s3; \ + } \ READFLAGS(A) #endif @@ -1668,85 +1673,85 @@ uintptr_t dynarec64_AVX_F3_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, #define MAYUSE(A) #endif -// GOCOND will use x1 and x3 -#define GOCOND(B, T1, T2) \ - case B + 0x0: \ - INST_NAME(T1 "O " T2); \ - GO(ANDI(x1, xFlags, 1 << F_OF2), EQZ, NEZ, _, _, X_OF) \ - break; \ - case B + 0x1: \ - INST_NAME(T1 "NO " T2); \ - GO(ANDI(x1, xFlags, 1 << F_OF2), NEZ, EQZ, _, _, X_OF) \ - break; \ - case B + 0x2: \ - INST_NAME(T1 "C " T2); \ - GO(ANDI(x1, xFlags, 1 << F_CF), EQZ, NEZ, GEU, LTU, X_CF) \ - break; \ - case B + 0x3: \ - INST_NAME(T1 "NC " T2); \ - GO(ANDI(x1, xFlags, 1 << F_CF), NEZ, EQZ, LTU, GEU, X_CF) \ - break; \ - case B + 0x4: \ - INST_NAME(T1 "Z " T2); \ - GO(ANDI(x1, xFlags, 1 << F_ZF), EQZ, NEZ, NE, EQ, X_ZF) \ - break; \ - case B + 0x5: \ - INST_NAME(T1 "NZ " T2); \ - GO(ANDI(x1, xFlags, 1 << F_ZF), NEZ, EQZ, EQ, NE, X_ZF) \ - break; \ - case B + 0x6: \ - INST_NAME(T1 "BE " T2); \ - GO(ANDI(x1, xFlags, (1 << F_CF) | (1 << F_ZF)), EQZ, NEZ, GTU, LEU, X_CF | X_ZF) \ - break; \ - case B + 0x7: \ - INST_NAME(T1 "NBE " T2); \ - GO(ANDI(x1, xFlags, (1 << F_CF) | (1 << F_ZF)), NEZ, EQZ, LEU, GTU, X_CF | X_ZF) \ - break; \ - case B + 0x8: \ - INST_NAME(T1 "S " T2); \ - GO(ANDI(x1, xFlags, 1 << F_SF), EQZ, NEZ, _, _, X_SF) \ - break; \ - case B + 0x9: \ - INST_NAME(T1 "NS " T2); \ - GO(ANDI(x1, xFlags, 1 << F_SF), NEZ, EQZ, _, _, X_SF) \ - break; \ - case B + 0xA: \ - INST_NAME(T1 "P " T2); \ - GO(ANDI(x1, xFlags, 1 << F_PF), EQZ, NEZ, _, _, X_PF) \ - break; \ - case B + 0xB: \ - INST_NAME(T1 "NP " T2); \ - GO(ANDI(x1, xFlags, 1 << F_PF), NEZ, EQZ, _, _, X_PF) \ - break; \ - case B + 0xC: \ - INST_NAME(T1 "L " T2); \ - GO(SRLI(x1, xFlags, F_SF - F_OF2); \ - XOR(x1, x1, xFlags); \ - ANDI(x1, x1, 1 << F_OF2), EQZ, NEZ, GE, LT, X_SF | X_OF) \ - break; \ - case B + 0xD: \ - INST_NAME(T1 "GE " T2); \ - GO(SRLI(x1, xFlags, F_SF - F_OF2); \ - XOR(x1, x1, xFlags); \ - ANDI(x1, x1, 1 << F_OF2), NEZ, EQZ, LT, GE, X_SF | X_OF) \ - break; \ - case B + 0xE: \ - INST_NAME(T1 "LE " T2); \ - GO(SRLI(x1, xFlags, F_SF - F_OF2); \ - XOR(x1, x1, xFlags); \ - ANDI(x1, x1, 1 << F_OF2); \ - ANDI(x3, xFlags, 1 << F_ZF); \ - OR(x1, x1, x3); \ - ANDI(x1, x1, (1 << F_OF2) | (1 << F_ZF)), EQZ, NEZ, GT, LE, X_SF | X_OF | X_ZF) \ - break; \ - case B + 0xF: \ - INST_NAME(T1 "G " T2); \ - GO(SRLI(x1, xFlags, F_SF - F_OF2); \ - XOR(x1, x1, xFlags); \ - ANDI(x1, x1, 1 << F_OF2); \ - ANDI(x3, xFlags, 1 << F_ZF); \ - OR(x1, x1, x3); \ - ANDI(x1, x1, (1 << F_OF2) | (1 << F_ZF)), NEZ, EQZ, LE, GT, X_SF | X_OF | X_ZF) \ +// GOCOND will use tmp1 and tmp3 +#define GOCOND(B, T1, T2) \ + case B + 0x0: \ + INST_NAME(T1 "O " T2); \ + GO(ANDI(tmp1, xFlags, 1 << F_OF2), EQZ, NEZ, _, _, X_OF) \ + break; \ + case B + 0x1: \ + INST_NAME(T1 "NO " T2); \ + GO(ANDI(tmp1, xFlags, 1 << F_OF2), NEZ, EQZ, _, _, X_OF) \ + break; \ + case B + 0x2: \ + INST_NAME(T1 "C " T2); \ + GO(ANDI(tmp1, xFlags, 1 << F_CF), EQZ, NEZ, GEU, LTU, X_CF) \ + break; \ + case B + 0x3: \ + INST_NAME(T1 "NC " T2); \ + GO(ANDI(tmp1, xFlags, 1 << F_CF), NEZ, EQZ, LTU, GEU, X_CF) \ + break; \ + case B + 0x4: \ + INST_NAME(T1 "Z " T2); \ + GO(ANDI(tmp1, xFlags, 1 << F_ZF), EQZ, NEZ, NE, EQ, X_ZF) \ + break; \ + case B + 0x5: \ + INST_NAME(T1 "NZ " T2); \ + GO(ANDI(tmp1, xFlags, 1 << F_ZF), NEZ, EQZ, EQ, NE, X_ZF) \ + break; \ + case B + 0x6: \ + INST_NAME(T1 "BE " T2); \ + GO(ANDI(tmp1, xFlags, (1 << F_CF) | (1 << F_ZF)), EQZ, NEZ, GTU, LEU, X_CF | X_ZF) \ + break; \ + case B + 0x7: \ + INST_NAME(T1 "NBE " T2); \ + GO(ANDI(tmp1, xFlags, (1 << F_CF) | (1 << F_ZF)), NEZ, EQZ, LEU, GTU, X_CF | X_ZF) \ + break; \ + case B + 0x8: \ + INST_NAME(T1 "S " T2); \ + GO(ANDI(tmp1, xFlags, 1 << F_SF), EQZ, NEZ, _, _, X_SF) \ + break; \ + case B + 0x9: \ + INST_NAME(T1 "NS " T2); \ + GO(ANDI(tmp1, xFlags, 1 << F_SF), NEZ, EQZ, _, _, X_SF) \ + break; \ + case B + 0xA: \ + INST_NAME(T1 "P " T2); \ + GO(ANDI(tmp1, xFlags, 1 << F_PF), EQZ, NEZ, _, _, X_PF) \ + break; \ + case B + 0xB: \ + INST_NAME(T1 "NP " T2); \ + GO(ANDI(tmp1, xFlags, 1 << F_PF), NEZ, EQZ, _, _, X_PF) \ + break; \ + case B + 0xC: \ + INST_NAME(T1 "L " T2); \ + GO(SRLI(tmp1, xFlags, F_SF - F_OF2); \ + XOR(tmp1, tmp1, xFlags); \ + ANDI(tmp1, tmp1, 1 << F_OF2), EQZ, NEZ, GE, LT, X_SF | X_OF) \ + break; \ + case B + 0xD: \ + INST_NAME(T1 "GE " T2); \ + GO(SRLI(tmp1, xFlags, F_SF - F_OF2); \ + XOR(tmp1, tmp1, xFlags); \ + ANDI(tmp1, tmp1, 1 << F_OF2), NEZ, EQZ, LT, GE, X_SF | X_OF) \ + break; \ + case B + 0xE: \ + INST_NAME(T1 "LE " T2); \ + GO(SRLI(tmp1, xFlags, F_SF - F_OF2); \ + XOR(tmp1, tmp1, xFlags); \ + ANDI(tmp1, tmp1, 1 << F_OF2); \ + ANDI(tmp3, xFlags, 1 << F_ZF); \ + OR(tmp1, tmp1, tmp3); \ + ANDI(tmp1, tmp1, (1 << F_OF2) | (1 << F_ZF)), EQZ, NEZ, GT, LE, X_SF | X_OF | X_ZF) \ + break; \ + case B + 0xF: \ + INST_NAME(T1 "G " T2); \ + GO(SRLI(tmp1, xFlags, F_SF - F_OF2); \ + XOR(tmp1, tmp1, xFlags); \ + ANDI(tmp1, tmp1, 1 << F_OF2); \ + ANDI(tmp3, xFlags, 1 << F_ZF); \ + OR(tmp1, tmp1, tmp3); \ + ANDI(tmp1, tmp1, (1 << F_OF2) | (1 << F_ZF)), NEZ, EQZ, LE, GT, X_SF | X_OF | X_ZF) \ break // Dummy macros |