diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2025-10-12 02:15:10 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-10-11 20:15:10 +0200 |
| commit | 494428dbbe1309ecc19a5b9862b0cd2ab02c501d (patch) | |
| tree | 69e7bd81a8bc5923054362453af3120c12899ffc | |
| parent | a40b6d49cb19134386b56648be43b8ccdd2b6c7a (diff) | |
| download | box64-494428dbbe1309ecc19a5b9862b0cd2ab02c501d.tar.gz box64-494428dbbe1309ecc19a5b9862b0cd2ab02c501d.zip | |
[DYNAREC] Fixed negative issues with 0F/F0 A3/AB/B3/BB opcodes (#3057)
| -rw-r--r-- | src/dynarec/la64/dynarec_la64_0f.c | 20 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f.c | 20 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_f0.c | 10 |
3 files changed, 40 insertions, 10 deletions
diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c index e07d650d..39f1ac74 100644 --- a/src/dynarec/la64/dynarec_la64_0f.c +++ b/src/dynarec/la64/dynarec_la64_0f.c @@ -1387,7 +1387,10 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { SMREAD(); addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, NULL, 1, 0); - SRAIxw(x1, gd, 5 + rex.w); // r1 = (gd>>5) + if (rex.w) + SRAI_D(x1, gd, 6); + else + SRAI_W(x1, gd, 5); ALSL_D(x3, x1, wback, 2 + rex.w); // (&ed) += r1*4; LDxw(x1, x3, fixedaddress); ed = x1; @@ -1429,7 +1432,10 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { SMREAD(); addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, NULL, 1, 0); - SRAI_D(x1, gd, 5 + rex.w); + if (rex.w) + SRAI_D(x1, gd, 6); + else + SRAI_W(x1, gd, 5); ALSL_D(x3, x1, wback, 2 + rex.w); LDxw(x1, x3, fixedaddress); ed = x1; @@ -1672,7 +1678,10 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { SMREAD(); addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 0); - SRAIxw(x1, gd, 5 + rex.w); + if (rex.w) + SRAI_D(x1, gd, 6); + else + SRAI_W(x1, gd, 5); ADDSL(x3, wback, x1, 2 + rex.w, x1); LDxw(x1, x3, fixedaddress); ed = x1; @@ -1827,7 +1836,10 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { SMREAD(); addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, NULL, 1, 0); - SRAIxw(x1, gd, 5 + rex.w); + if (rex.w) + SRAI_D(x1, gd, 6); + else + SRAI_W(x1, gd, 5); ADDSL(x3, wback, x1, 2 + rex.w, x1); LDxw(x1, x3, fixedaddress); ed = x1; diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c index 31cfd7ea..8039a8fc 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_0f.c @@ -1861,7 +1861,10 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { SMREAD(); addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, NULL, 1, 0); - SRAIxw(x1, gd, 5 + rex.w); // r1 = (gd>>5) + if (rex.w) + SRAI(x1, gd, 6); + else + SRAIW(x1, gd, 5); ADDSL(x3, wback, x1, 2 + rex.w, x1); LDxw(x1, x3, fixedaddress); ed = x1; @@ -1914,7 +1917,10 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { SMREAD(); addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, NULL, 1, 0); - SRAIxw(x1, gd, 5 + rex.w); + if (rex.w) + SRAI(x1, gd, 6); + else + SRAIW(x1, gd, 5); ADDSL(x3, wback, x1, 2 + rex.w, x1); LDxw(x1, x3, fixedaddress); ed = x1; @@ -2142,7 +2148,10 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { SMREAD(); addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 0); - SRAIxw(x1, gd, 5 + rex.w); + if (rex.w) + SRAI(x1, gd, 6); + else + SRAIW(x1, gd, 5); ADDSL(x3, wback, x1, 2 + rex.w, x1); LDxw(x1, x3, fixedaddress); ed = x1; @@ -2312,7 +2321,10 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { SMREAD(); addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, NULL, 1, 0); - SRAIxw(x1, gd, 5 + rex.w); + if (rex.w) + SRAI(x1, gd, 6); + else + SRAIW(x1, gd, 5); ADDSL(x3, wback, x1, 2 + rex.w, x1); LDxw(x1, x3, fixedaddress); ed = x1; diff --git a/src/dynarec/rv64/dynarec_rv64_f0.c b/src/dynarec/rv64/dynarec_rv64_f0.c index 544a8c11..2a3f93c0 100644 --- a/src/dynarec/rv64/dynarec_rv64_f0.c +++ b/src/dynarec/rv64/dynarec_rv64_f0.c @@ -130,7 +130,10 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni if (!rex.w) ZEROUP(ed); } else { addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0); - SRAIxw(x1, gd, 5 + rex.w); + if (rex.w) + SRAI(x1, gd, 6); + else + SRAIW(x1, gd, 5); ADDSL(x3, wback, x1, 2 + rex.w, x1); ed = x1; wback = x3; @@ -310,7 +313,10 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni if (!rex.w) ZEROUP(ed); } else { addr = geted(dyn, addr, ninst, nextop, &wback, x3, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0); - SRAIxw(x1, gd, 5 + rex.w); + if (rex.w) + SRAI(x1, gd, 6); + else + SRAIW(x1, gd, 5); ADDSL(x3, wback, x1, 2 + rex.w, x1); LDxw(x1, x3, fixedaddress); ed = x1; |