about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorxctan <xctan@cirno.icu>2024-07-16 14:15:33 +0800
committerGitHub <noreply@github.com>2024-07-16 08:15:33 +0200
commit9fe450f2dc220bfa9c09c3963c53284772f9c745 (patch)
tree91c0e167bdc9e865b3b2f901fc5cddfb09b49735 /src
parentb84e5f25f2d62ebe2877a5be61656cd73a9c0da2 (diff)
downloadbox64-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.c30
-rw-r--r--src/dynarec/rv64/dynarec_rv64_66.c38
-rw-r--r--src/dynarec/rv64/dynarec_rv64_660f.c14
-rw-r--r--src/dynarec/rv64/dynarec_rv64_66f20f.c4
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h4
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);                                            \