diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2025-03-19 20:51:04 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-19 13:51:04 +0100 |
| commit | ba630300b609cce283f2658205db4d9789fe104c (patch) | |
| tree | 22858b552741b468567c00de9fa189bd007f382c /src | |
| parent | 0e32c17076ea4377168fa3e6be0b210a7eea1634 (diff) | |
| download | box64-ba630300b609cce283f2658205db4d9789fe104c.tar.gz box64-ba630300b609cce283f2658205db4d9789fe104c.zip | |
[RV64_DYNAREC] Fixed many minor issues (#2451)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_00.c | 4 | ||||
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_helper.h | 41 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_3.c | 8 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_66.c | 6 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_emit_shift.c | 26 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 40 |
6 files changed, 65 insertions, 60 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c index 68295c71..eabb0ac1 100644 --- a/src/dynarec/la64/dynarec_la64_00.c +++ b/src/dynarec/la64/dynarec_la64_00.c @@ -2672,7 +2672,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni MOD_DU(xRDX, xRAX, ed); MV(xRAX, x2); } else { - GETEDH(x1, 0); // get edd changed addr, so cannot be called 2 times for same op... + GETEDH(x4, x1, 0); // get edd changed addr, so cannot be called 2 times for same op... BEQ_MARK(xRDX, xZR); if (ed != x1) { MV(x1, ed); } CALL(div64, -1); @@ -2710,7 +2710,7 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni MOD_D(xRDX, xRAX, ed); MV(xRAX, x2); } else { - GETEDH(x1, 0); // get edd changed addr, so cannot be called 2 times for same op... + GETEDH(x4, x1, 0); // get edd changed addr, so cannot be called 2 times for same op... // need to see if RDX == 0 and RAX not signed // or RDX == -1 and RAX signed BNE_MARK2(xRDX, xZR); diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h index 4199aef1..e3146d77 100644 --- a/src/dynarec/la64/dynarec_la64_helper.h +++ b/src/dynarec/la64/dynarec_la64_helper.h @@ -77,28 +77,27 @@ LDxw(x1, wback, fixedaddress); \ ed = x1; \ } -// GETEDH can use hint for ed, and x1 or x2 for wback (depending on hint), might also use x3. wback is 0 if ed is xEAX..xEDI -#define GETEDH(hint, D) \ - if (MODREG) { \ - ed = TO_NAT((nextop & 7) + (rex.b << 3)); \ - wback = 0; \ - } else { \ - SMREAD(); \ - addr = geted(dyn, addr, ninst, nextop, &wback, (hint == x2) ? x1 : x2, (hint == x1) ? x1 : x3, &fixedaddress, rex, NULL, 1, D); \ - LDxw(hint, wback, fixedaddress); \ - ed = hint; \ +// GETEDH can use hint for wback and ret for ed. wback is 0 if ed is xEAX..xEDI +#define GETEDH(hint, ret, D) \ + if (MODREG) { \ + ed = TO_NAT((nextop & 7) + (rex.b << 3)); \ + wback = 0; \ + } else { \ + SMREAD(); \ + addr = geted(dyn, addr, ninst, nextop, &wback, hint, ret, &fixedaddress, rex, NULL, 1, D); \ + ed = ret; \ + LDxw(ed, wback, fixedaddress); \ } -// GETEDW can use hint for wback and ret for ed. wback is 0 if ed is xEAX..xEDI -#define GETEDW(hint, ret, D) \ - if (MODREG) { \ - ed = TO_NAT((nextop & 7) + (rex.b << 3)); \ - MV(ret, ed); \ - wback = 0; \ - } else { \ - SMREAD(); \ - addr = geted(dyn, addr, ninst, nextop, &wback, (hint == x2) ? x1 : x2, (hint == x1) ? x1 : x3, &fixedaddress, rex, NULL, 0, D); \ - ed = ret; \ - LDxw(ed, wback, fixedaddress); \ +#define GETEDW(hint, ret, D) \ + if (MODREG) { \ + ed = TO_NAT((nextop & 7) + (rex.b << 3)); \ + MV(ret, ed); \ + wback = 0; \ + } else { \ + SMREAD(); \ + addr = geted(dyn, addr, ninst, nextop, &wback, hint, ret, &fixedaddress, rex, NULL, 0, D); \ + ed = ret; \ + LDxw(ed, wback, fixedaddress); \ } // GETEWW will use i for ed, and can use w for wback. #define GETEWW(w, i, D) \ diff --git a/src/dynarec/rv64/dynarec_rv64_00_3.c b/src/dynarec/rv64/dynarec_rv64_00_3.c index 81c240e4..f814a75a 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_3.c +++ b/src/dynarec/rv64/dynarec_rv64_00_3.c @@ -193,9 +193,9 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); SETFLAGS(X_OF | X_CF, SF_SET_DF, NAT_FLAGS_NOFUSION); + GETEDW(x4, x1, 0); u8 = (F8) & (rex.w ? 0x3f : 0x1f); MOV32w(x2, u8); - GETEDW(x4, x1, 0); CALL_(rex.w ? ((void*)rcl64) : ((void*)rcl32), ed, x4, x1, x2); WBACK; if (!wback && !rex.w) ZEROUP(ed); @@ -205,9 +205,9 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int MESSAGE(LOG_DUMP, "Need Optimization\n"); READFLAGS(X_CF); SETFLAGS(X_OF | X_CF, SF_SET_DF, NAT_FLAGS_NOFUSION); + GETEDW(x4, x1, 0); u8 = (F8) & (rex.w ? 0x3f : 0x1f); MOV32w(x2, u8); - GETEDW(x4, x1, 0); CALL_(rex.w ? ((void*)rcr64) : ((void*)rcr32), ed, x4, x1, x2); WBACK; if (!wback && !rex.w) ZEROUP(ed); @@ -1366,7 +1366,7 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int REMU(xRDX, xRAX, ed); MV(xRAX, x2); } else { - GETEDH(x1, 0); // get edd changed addr, so cannot be called 2 times for same op... + GETEDH(x4, x1, 0); // get edd changed addr, so cannot be called 2 times for same op... if (BOX64ENV(dynarec_div0)) { BNE_MARK3(ed, xZR); GETIP_(ip, x7); @@ -1431,7 +1431,7 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int REM(xRDX, xRAX, ed); MV(xRAX, x2); } else { - GETEDH(x1, 0); // get edd changed addr, so cannot be called 2 times for same op... + GETEDH(x4, x1, 0); // get edd changed addr, so cannot be called 2 times for same op... if (BOX64ENV(dynarec_div0)) { BNE_MARK3(ed, xZR); GETIP_(ip, x7); diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c index 9535ce8d..25e595f5 100644 --- a/src/dynarec/rv64/dynarec_rv64_66.c +++ b/src/dynarec/rv64/dynarec_rv64_66.c @@ -1398,11 +1398,12 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni GETEW(x1, 0); ZEXTH(x2, xRAX); MULW(x1, x2, x1); + ZEROUP(x1); UFLAG_RES(x1); INSHz(xRAX, x1, x4, x5, 1, 1); SRLI(xRDX, xRDX, 16); SLLI(xRDX, xRDX, 16); - SRLI(x1, x1, 48); + SRLI(x1, x1, 16); OR(xRDX, xRDX, x1); UFLAG_DF(x1, d_mul16); break; @@ -1413,11 +1414,12 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SLLI(x2, xRAX, 16); SRAIW(x2, x2, 16); MULW(x1, x2, x1); + ZEROUP(x1); UFLAG_RES(x1); INSHz(xRAX, x1, x4, x5, 1, 1); SRLI(xRDX, xRDX, 16); SLLI(xRDX, xRDX, 16); - SRLI(x1, x1, 48); + SRLI(x1, x1, 16); OR(xRDX, xRDX, x1); UFLAG_DF(x1, d_imul16); break; diff --git a/src/dynarec/rv64/dynarec_rv64_emit_shift.c b/src/dynarec/rv64/dynarec_rv64_emit_shift.c index 91c9bb6c..797c769b 100644 --- a/src/dynarec/rv64/dynarec_rv64_emit_shift.c +++ b/src/dynarec/rv64/dynarec_rv64_emit_shift.c @@ -1068,10 +1068,12 @@ void emit_rol16c(dynarec_rv64_t* dyn, int ninst, int s1, uint32_t c, int s3, int SET_DFNONE(); - SLLI(s3, s1, 48 + c); - SRLI(s3, s3, 48); - SRLI(s1, s1, 16 - c); - OR(s1, s1, s3); + if (c & 15) { + SRLI(s3, s1, 16 - (c & 15)); + SLLI(s1, s1, c & 15); + OR(s1, s1, s3); + ZEXTH(s1, s1); + } if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR); @@ -1148,10 +1150,12 @@ void emit_ror16c(dynarec_rv64_t* dyn, int ninst, int s1, uint32_t c, int s3, int SET_DFNONE(); - SRLI(s3, s1, c); - SLLI(s1, s1, 64 - c); - SRLI(s1, s1, 48); - OR(s1, s1, s3); + if (c & 15) { + SRLI(s3, s1, c & 15); + SLLI(s1, s1, 16 - (c & 15)); + OR(s1, s1, s3); + ZEXTH(s1, s1); + } if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR); @@ -1692,10 +1696,10 @@ void emit_rcr16c(dynarec_rv64_t* dyn, int ninst, int s1, uint32_t c, int s3, int OR(s1, s1, s3); // insert CF to bit 16 SRLI(s3, s1, c); - SLLI(s4, s1, 63 - c); - SLLI(s1, s4, s1); - SRLI(s1, s1, 48); + SLLI(s1, s1, 17 - c); OR(s1, s1, s3); + SLLI(s4, s1, 47); + ZEXTH(s1, s1); if (dyn->insts[ninst].nat_flags_fusion) NAT_FLAGS_OPS(s1, xZR); diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 684357bf..a519b71a 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -98,28 +98,28 @@ LDxw(x1, wback, fixedaddress); \ ed = x1; \ } -// GETEDH can use hint for ed, and x1 or x2 for wback (depending on hint), might also use x3. wback is 0 if ed is xEAX..xEDI -#define GETEDH(hint, D) \ - if (MODREG) { \ - ed = TO_NAT((nextop & 7) + (rex.b << 3)); \ - wback = 0; \ - } else { \ - SMREAD(); \ - addr = geted(dyn, addr, ninst, nextop, &wback, (hint == x2) ? x1 : x2, (hint == x1) ? x1 : x3, &fixedaddress, rex, NULL, 1, D); \ - LDxw(hint, wback, fixedaddress); \ - ed = hint; \ +// GETEDH can use hint for wback and ret for ed. wback is 0 if ed is xEAX..xEDI +#define GETEDH(hint, ret, D) \ + if (MODREG) { \ + ed = TO_NAT((nextop & 7) + (rex.b << 3)); \ + wback = 0; \ + } else { \ + SMREAD(); \ + addr = geted(dyn, addr, ninst, nextop, &wback, hint, ret, &fixedaddress, rex, NULL, 1, D); \ + ed = ret; \ + LDxw(ed, wback, fixedaddress); \ } // GETEDW can use hint for wback and ret for ed. wback is 0 if ed is xEAX..xEDI -#define GETEDW(hint, ret, D) \ - if (MODREG) { \ - ed = TO_NAT((nextop & 7) + (rex.b << 3)); \ - MV(ret, ed); \ - wback = 0; \ - } else { \ - SMREAD(); \ - addr = geted(dyn, addr, ninst, nextop, &wback, (hint == x2) ? x1 : x2, (hint == x1) ? x1 : x3, &fixedaddress, rex, NULL, 0, D); \ - ed = ret; \ - LDxw(ed, wback, fixedaddress); \ +#define GETEDW(hint, ret, D) \ + if (MODREG) { \ + ed = TO_NAT((nextop & 7) + (rex.b << 3)); \ + MV(ret, ed); \ + wback = 0; \ + } else { \ + SMREAD(); \ + addr = geted(dyn, addr, ninst, nextop, &wback, hint, ret, &fixedaddress, rex, NULL, 0, D); \ + ed = ret; \ + LDxw(ed, wback, fixedaddress); \ } // GETGW extract x64 register in gd, that is i #define GETGW(i) \ |