[DYNAREC] Fixed negative issues with 0F/F0 A3/AB/B3/BB opcodes (#3057)

This commit is contained in:
Yang Liu
2025-10-12 02:15:10 +08:00
committed by GitHub
parent a40b6d49cb
commit 494428dbbe
3 changed files with 40 additions and 10 deletions

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;