diff options
| author | xctan <xctan@cirno.icu> | 2024-07-16 14:15:33 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-16 08:15:33 +0200 |
| commit | 9fe450f2dc220bfa9c09c3963c53284772f9c745 (patch) | |
| tree | 91c0e167bdc9e865b3b2f901fc5cddfb09b49735 /src | |
| parent | b84e5f25f2d62ebe2877a5be61656cd73a9c0da2 (diff) | |
| download | box64-9fe450f2dc220bfa9c09c3963c53284772f9c745.tar.gz box64-9fe450f2dc220bfa9c09c3963c53284772f9c745.zip | |
[RV64_DYNAREC] Fixed some bugs for VMP (#1679)
* [RV64_DYNAREC] Fixed reg x3 conflict with the GETEW macro * [RV64_DYNAREC] Fixed (LOCK) XCHG Eb, Gb again * [RV64_DYNAREC] Fixed register conflict in (LOCK) XCHG Eb, Gb
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_2.c | 30 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_66.c | 38 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_660f.c | 14 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_66f20f.c | 4 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 4 |
5 files changed, 41 insertions, 49 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00_2.c b/src/dynarec/rv64/dynarec_rv64_00_2.c index 7bf4a342..f2f7d232 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_2.c +++ b/src/dynarec/rv64/dynarec_rv64_00_2.c @@ -246,35 +246,27 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int SLLI(x1, x1, 3); // align address to 4-bytes to use ll.w/sc.w - ADDI(x4, xZR, 0xffc); - AND(x6, ed, x4); + ANDI(x6, ed, ~3); - // load aligned data - LWU(x5, x6, 0); - - // insert gd byte into the aligned data + // prepare mask ADDI(x4, xZR, 0xff); SLL(x4, x4, x1); NOT(x4, x4); - AND(x4, x5, x4); - SLL(x5, gd, x1); - OR(x4, x4, x5); + SLL(x9, gd, x1); - // do aligned ll/sc sequence + // do aligned ll/sc sequence, reusing x2 (ed might be x2 but is no longer needed) MARKLOCK; - LR_W(x1, x6, 1, 1); - SC_W(x5, x4, x6, 1, 1); + LR_W(x2, x6, 1, 1); + AND(x5, x2, x4); + OR(x5, x5, x9); + SC_W(x5, x5, x6, 1, 1); BNEZ_MARKLOCK(x5); - // calculate shift amount again - ANDI(x4, ed, 0x3); - SLLI(x4, x4, 3); - // extract loaded byte - SRL(x1, x1, x4); + SRL(gd, x2, x1); + ANDI(gd, gd, 0xff); - gd = x1; - GBBACK(x3); + GBBACK(x5); } break; case 0x87: diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c index e786da98..0f101d16 100644 --- a/src/dynarec/rv64/dynarec_rv64_66.c +++ b/src/dynarec/rv64/dynarec_rv64_66.c @@ -74,7 +74,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni nextop = F8; GETGW(x1); GETEW(x2, 0); - emit_add16(dyn, ninst, x1, x2, x3, x4, x6); + emit_add16(dyn, ninst, x1, x2, x5, x4, x6); GWBACK; break; case 0x05: @@ -103,7 +103,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni nextop = F8; GETGW(x2); GETEW(x1, 0); - emit_or16(dyn, ninst, x1, x2, x4, x2); + emit_or16(dyn, ninst, x1, x2, x4, x5); EWBACK; break; case 0x0B: @@ -145,7 +145,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni nextop = F8; GETGW(x2); GETEW(x1, 0); - emit_adc16(dyn, ninst, x1, x2, x4, x3, x5); + emit_adc16(dyn, ninst, x1, x2, x4, x6, x5); EWBACK; break; case 0x13: @@ -155,7 +155,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni nextop = F8; GETGW(x1); GETEW(x2, 0); - emit_adc16(dyn, ninst, x1, x2, x4, x3, x5); + emit_adc16(dyn, ninst, x1, x2, x4, x6, x5); GWBACK; break; case 0x15: @@ -185,7 +185,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni nextop = F8; GETGW(x1); GETEW(x2, 0); - emit_sbb16(dyn, ninst, x1, x2, x3, x4, x5); + emit_sbb16(dyn, ninst, x1, x2, x6, x4, x5); GWBACK; break; case 0x1D: @@ -251,7 +251,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni nextop = F8; GETGW(x1); GETEW(x2, 0); - emit_sub16(dyn, ninst, x1, x2, x3, x4, x5); + emit_sub16(dyn, ninst, x1, x2, x6, x4, x5); GWBACK; break; case 0x2D: @@ -350,7 +350,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni nextop = F8; GETGW(x2); GETEW(x1, 0); - emit_cmp16(dyn, ninst, x1, x2, x3, x4, x5, x6); + emit_cmp16(dyn, ninst, x1, x2, x9, x4, x5, x6); break; case 0x3B: INST_NAME("CMP Gw, Ew"); @@ -358,7 +358,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni nextop = F8; GETGW(x1); GETEW(x2, 0); - emit_cmp16(dyn, ninst, x1, x2, x3, x4, x5, x6); + emit_cmp16(dyn, ninst, x1, x2, x9, x4, x5, x6); break; case 0x3D: INST_NAME("CMP AX, Iw"); @@ -531,9 +531,9 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni if(opcode==0x81) u64 = F16; else u64 = (uint16_t)(int16_t)F8S; if(u64) { MOV64x(x2, u64); - emit_cmp16(dyn, ninst, x1, x2, x3, x4, x5, x6); + emit_cmp16(dyn, ninst, x1, x2, x9, x4, x5, x6); } else - emit_cmp16_0(dyn, ninst, x1, x3, x4); + emit_cmp16_0(dyn, ninst, x1, x9, x4); break; default: DEFAULT; @@ -545,7 +545,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni nextop = F8; GETEW(x1, 0); GETGW(x2); - emit_test16(dyn, ninst, x1, x2, x3, x4, x5); + emit_test16(dyn, ninst, x1, x2, x6, x4, x5); break; case 0x87: INST_NAME("(LOCK)XCHG Ew, Gw"); @@ -1170,13 +1170,13 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni GETEW(x1, 2); u16 = F16; MOV32w(x2, u16); - emit_test16(dyn, ninst, x1, x2, x3, x4, x5); + emit_test16(dyn, ninst, x1, x2, x6, x4, x5); break; case 2: INST_NAME("NOT Ew"); GETEW(x1, 0); - MOV32w(x3, 0xffff); - XOR(ed, ed, x3); // No flags affected + MOV32w(x5, 0xffff); + XOR(ed, ed, x5); // No flags affected EWBACK; break; case 3: @@ -1192,9 +1192,9 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SET_DFNONE(); GETEW(x1, 0); ZEXTH(x2, xRAX); - SLLI(x3, xRDX, 48); - SRLI(x3, x3, 32); - OR(x2, x2, x3); + SLLI(x9, xRDX, 48); + SRLI(x9, x9, 32); + OR(x2, x2, x9); if(box64_dynarec_div0) { BNE_MARK3(ed, xZR); GETIP_(ip); @@ -1205,9 +1205,9 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni jump_to_epilog(dyn, 0, xRIP, ninst); MARK3; } - DIVUW(x3, x2, ed); + DIVUW(x9, x2, ed); REMUW(x4, x2, ed); - INSH(xRAX, x3, x5, x6, 1, 1); + INSH(xRAX, x9, x5, x6, 1, 1); INSH(xRDX, x4, x5, x6, 0, 1); break; case 7: diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c index c5cc9781..d2610cf4 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f.c +++ b/src/dynarec/rv64/dynarec_rv64_660f.c @@ -2276,7 +2276,7 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int GETEW(x1, 0); GETGW(x2); u8 = F8; - emit_shld16c(dyn, ninst, rex, ed, gd, u8, x3, x4, x5); + emit_shld16c(dyn, ninst, rex, ed, gd, u8, x6, x4, x5); EWBACK; break; case 0xAB: @@ -2302,7 +2302,7 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int GETEW(x1, 0); GETGW(x2); u8 = F8; - emit_shrd16c(dyn, ninst, rex, ed, gd, u8, x3, x4, x5); + emit_shrd16c(dyn, ninst, rex, ed, gd, u8, x6, x4, x5); EWBACK; break; case 0xAF: @@ -2430,14 +2430,14 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int GETEW(x1, 1); u8 = F8; u8 &= rex.w ? 0x3f : 15; - BEXTI(x3, ed, u8); // F_CF is 1 + BEXTI(x6, ed, u8); // F_CF is 1 ANDI(xFlags, xFlags, ~1); - OR(xFlags, xFlags, x3); + OR(xFlags, xFlags, x6); if (u8 <= 10) { XORI(ed, ed, (1LL << u8)); } else { - MOV64xw(x3, (1LL << u8)); - XOR(ed, ed, x3); + MOV64xw(x6, (1LL << u8)); + XOR(ed, ed, x6); } EWBACK; break; @@ -2514,7 +2514,7 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int B_NEXT_nocond; MARK; ANDI(xFlags, xFlags, ~(1 << F_ZF)); - CLZxw(gd, ed, 0, x1, x2, x3); + CLZxw(gd, ed, 0, x1, x2, x6); ADDI(x1, xZR, rex.w ? 63 : 31); SUB(gd, x1, gd); GWBACK; diff --git a/src/dynarec/rv64/dynarec_rv64_66f20f.c b/src/dynarec/rv64/dynarec_rv64_66f20f.c index 949270b3..a11dde1c 100644 --- a/src/dynarec/rv64/dynarec_rv64_66f20f.c +++ b/src/dynarec/rv64/dynarec_rv64_66f20f.c @@ -62,8 +62,8 @@ uintptr_t dynarec64_66F20F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, in MOV32w(x2, 0x82f63b78); for(int j=0; j<2; ++j) { SRLI(x5, ed, 8*j); - ANDI(x3, x5, 0xFF); - XOR(gd, gd, x3); + ANDI(x6, x5, 0xFF); + XOR(gd, gd, x6); for (int i = 0; i < 8; i++) { SRLI((i&1)?gd:x4, (i&1)?x4:gd, 1); ANDI(x6, (i&1)?x4:gd, 1); diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 9e9d14f5..515170be 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -168,9 +168,9 @@ ed = i; \ wb1 = 1; \ } -// GETEW will use i for ed, and can use r3 for wback. +// GETEW will use i for ed, and *may* use x3 for wback. #define GETEW(i, D) GETEWW(x3, i, D) -// GETSEW will use i for ed, and can use r3 for wback. This is the Signed version +// GETSEW will use i for ed, and *may* use x3 for wback. This is the Signed version #define GETSEW(i, D) \ if (MODREG) { \ wback = xRAX + (nextop & 7) + (rex.b << 3); \ |