about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-11-23 18:19:59 +0100
committerptitSeb <sebastien.chev@gmail.com>2023-11-23 18:19:59 +0100
commitba80b40e9eb0412816d1270d57a0eb300844f476 (patch)
treea01d511936211a31d0362e854e95734e45f2a3b4 /src
parentb0fe7ecf8c5590b35a5eadfd1f15a27e3e192464 (diff)
downloadbox64-ba80b40e9eb0412816d1270d57a0eb300844f476.tar.gz
box64-ba80b40e9eb0412816d1270d57a0eb300844f476.zip
[ARM64_DYNAREC] Some fixes and improvment to various opcodes
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/arm64_emitter.h1
-rw-r--r--src/dynarec/arm64/dynarec_arm64_00.c8
-rw-r--r--src/dynarec/arm64/dynarec_arm64_0f.c3
-rw-r--r--src/dynarec/arm64/dynarec_arm64_660f.c30
-rw-r--r--src/dynarec/arm64/dynarec_arm64_f0.c36
5 files changed, 31 insertions, 47 deletions
diff --git a/src/dynarec/arm64/arm64_emitter.h b/src/dynarec/arm64/arm64_emitter.h
index 8a828d00..794a066b 100644
--- a/src/dynarec/arm64/arm64_emitter.h
+++ b/src/dynarec/arm64/arm64_emitter.h
@@ -2091,6 +2091,7 @@
 #define STUMINH(Rs, Rn)                  EMIT(ATOMIC_gen(0b01, 0, 0, Rs, 0b111, Rn, 0b11111))
 #define STUMINLH(Rs, Rn)                 EMIT(ATOMIC_gen(0b01, 0, 1, Rs, 0b111, Rn, 0b11111))
 
+// SWAPxx(Xs, Xt, Xn) : [Xn] => Xt, Xs => [Xn]
 #define SWAP_gen(size, A, R, Rs, Rn, Rt)    ((size)<<30 | 0b111<<27 | (A)<<23 | (R)<<22 | 1<<21 | (Rs)<<16 | 1<<15 | (Rn)<<5 | (Rt))
 #define SWPxw(Rs, Rt, Rn)               EMIT(SWAP_gen(0b10+rex.w, 0, 0, Rs, Rn, Rt))
 #define SWPAxw(Rs, Rt, Rn)              EMIT(SWAP_gen(0b10+rex.w, 1, 0, Rs, Rn, Rt))
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c
index 622269b9..2f05ee1f 100644
--- a/src/dynarec/arm64/dynarec_arm64_00.c
+++ b/src/dynarec/arm64/dynarec_arm64_00.c
@@ -1039,8 +1039,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             INST_NAME("(LOCK)XCHG Eb, Gb");
             // Do the swap
             nextop = F8;
+            GETGB(x4);
             if(MODREG) {
-                GETGB(x4);
                 if(rex.rex) {
                     ed = xRAX+(nextop&7)+(rex.b<<3);
                     eb1 = ed;
@@ -1052,10 +1052,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 }
                 UBFXw(x1, eb1, eb2, 8);
                 // do the swap 14 -> ed, 1 -> gd
-                BFIx(gb1, x1, gb2, 8);
                 BFIx(eb1, x4, eb2, 8);
             } else {
-                GETGB(x4);
                 addr = geted(dyn, addr, ninst, nextop, &ed, x2, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                 if(arm64_atomics) {
                     SWPALB(x4, x1, ed);
@@ -1067,8 +1065,8 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     STLXRB(x3, x4, ed);
                     CBNZx_MARKLOCK(x3);
                 }
-                BFIx(gb1, x1, gb2, 8);
             }
+            BFIx(gb1, x1, gb2, 8);
             break;
         case 0x87:
             INST_NAME("(LOCK)XCHG Ed, Gd");
@@ -2088,7 +2086,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                 SETFLAGS(X_ALL, SF_SET);    // Hack to set flags in "don't care" state
                 GETIP(ip);
                 STORE_XEMU_CALL(xRIP);
-                CALL(native_priv, -1);
+                CALL(native_int, -1);
                 LOAD_XEMU_CALL(xRIP);
                 jump_to_epilog(dyn, 0, xRIP, ninst);
                 *need_epilog = 0;
diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c
index ae874bb0..87ca717f 100644
--- a/src/dynarec/arm64/dynarec_arm64_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_0f.c
@@ -1882,8 +1882,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     IFX(X_CF) {

                         BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)

                     }

-                    MOV32w(x4, 1);

-                    BICxw_REG_LSL(ed, ed, x4, u8);

+                    BFCxw(ed, u8, 1);

                     if(wback) {

                         STxw(ed, wback, fixedaddress);

                         SMWRITE();

diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c
index 7e9d73a6..57ebe1f7 100644
--- a/src/dynarec/arm64/dynarec_arm64_660f.c
+++ b/src/dynarec/arm64/dynarec_arm64_660f.c
@@ -2272,8 +2272,6 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             ANDw_mask(x2, gd, 0, 0b000011);  // mask=0x0f

             LSRw_REG(x1, ed, x2);

             BFIw(xFlags, x1, F_CF, 1);

-            ANDSw_mask(x1, x1, 0, 0);  //mask=1

-            B_NEXT(cEQ);

             MOV32w(x1, 1);

             LSLxw_REG(x1, x1, x2);

             BICx_REG(ed, ed, x1);

@@ -2340,12 +2338,12 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     GETEW(x1, 1);

                     u8 = F8;

                     u8&=(rex.w?0x3f:0x0f);

-                    BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)

-                    TBNZ_MARK3(xFlags, 0); // bit already set, jump to next instruction

+                    IFX(X_CF) {

+                        BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)

+                    }

                     MOV32w(x4, 1);

-                    ORRxw_REG_LSL(ed, ed, x4, u8);

+                    BFIxw(ed, x4, u8, 1);

                     EWBACK(x1);

-                    MARK3;

                     break;

                 case 6:

                     INST_NAME("BTR Ew, Ib");

@@ -2354,12 +2352,11 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     GETEW(x1, 1);

                     u8 = F8;

                     u8&=(rex.w?0x3f:0x0f);

-                    BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)

-                    TBZ_MARK3(xFlags, 0); // bit already clear, jump to next instruction

-                    MOV32w(x4, 1);

-                    BICxw_REG_LSL(ed, ed, x4, u8);

+                    IFX(X_CF) {

+                        BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)

+                    }

+                    BFCxw(ed, u8, 1);

                     EWBACK(x1);

-                    MARK3;

                     break;

                 case 7:

                     INST_NAME("BTC Ew, Ib");

@@ -2368,7 +2365,9 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     GETEW(x1, 1);

                     u8 = F8;

                     u8&=(rex.w?0x3f:0x0f);

-                    BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)

+                    IFX(X_CF) {

+                        BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)

+                    }

                     MOV32w(x4, 1);

                     EORxw_REG_LSL(ed, ed, x4, u8);

                     EWBACK(x1);

@@ -2396,9 +2395,10 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                 ed = x4;

             }

             ANDw_mask(x2, gd, 0, 0b000011);  // mask=0x0f

-            LSRw_REG(x1, ed, x2);

-            BFIw(xFlags, x1, F_CF, 1);

-            ANDw_mask(x1, x1, 0, 0);  //mask=1

+            IFX(X_CF) {

+                LSRw_REG(x1, ed, x2);

+                BFIw(xFlags, x1, F_CF, 1);

+            }

             MOV32w(x1, 1);

             LSLxw_REG(x1, x1, x2);

             EORx_REG(ed, ed, x1);

diff --git a/src/dynarec/arm64/dynarec_arm64_f0.c b/src/dynarec/arm64/dynarec_arm64_f0.c
index 8d435761..384b5772 100644
--- a/src/dynarec/arm64/dynarec_arm64_f0.c
+++ b/src/dynarec/arm64/dynarec_arm64_f0.c
@@ -399,7 +399,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         BFIw(xFlags, x4, F_CF, 1);
                         MOV32w(x4, 1);
                         LSLw_REG(x4, x4, x2);
-                        ORRw_REG(ed, ed, x4);
+                        BICw_REG(ed, ed, x4);
                         STLXRB(x4, ed, wback);
                         CBNZw_MARKLOCK(x4);
                     }
@@ -446,10 +446,6 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             TBNZ_NEXT(xFlags, 0); // bit already set, jump to next instruction
                             MOV32w(x4, 1);
                             ORRxw_REG_LSL(ed, ed, x4, u8);
-                            if(wback) {
-                                STxw(ed, wback, fixedaddress);
-                                SMWRITE();
-                            }
                         } else {
                             // Will fetch only 1 byte, to avoid alignment issue
                             addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
@@ -461,17 +457,15 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             ed = x1;
                             MARKLOCK;
                             LDAXRB(ed, wback);
-                            UBFXw(x4, ed, u8&7, 1);
-                            BFIw(xFlags, x4, F_CF, 1);
+                            BFXILw(xFlags, ed, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
                             MOV32w(x4, 1);
-                            LSLw_IMM(x4, x4, u8&7);
-                            ORRw_REG(ed, ed, x4);
+                            BFIw(ed, x4, u8&7, 1);
                             STLXRB(x4, ed, wback);
                             CBNZw_MARKLOCK(x4);
                         }
                         break;
                     case 6:
-                        INST_NAME("BTR Ed, Ib");
+                        INST_NAME("LOCK BTR Ed, Ib");
                         SETFLAGS(X_CF, SF_SUBSET);
                         SET_DFNONE(x1);
                         if(MODREG) {
@@ -481,8 +475,7 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             u8&=(rex.w?0x3f:0x1f);
                             BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)
                             TBZ_NEXT(xFlags, 0); // bit already clear, jump to next instruction
-                            MOV32w(x4, 1);
-                            BICxw_REG_LSL(ed, ed, x4, u8);
+                            BFCxw(ed, u8, 1);
                         } else {
                             addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                             u8 = F8;
@@ -493,17 +486,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             ed = x1;
                             MARKLOCK;
                             LDAXRB(ed, wback);
-                            UBFXw(x4, ed, u8&7, 1);
-                            BFIw(xFlags, x4, F_CF, 1);
-                            MOV32w(x4, 1);
-                            LSLw_IMM(x4, x4, u8&7);
-                            ORRw_REG(ed, ed, x4);
+                            BFXILw(xFlags, ed, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
+                            BFCw(ed, u8&7, 1);
                             STLXRB(x4, ed, wback);
                             CBNZw_MARKLOCK(x4);
                         }
                         break;
                     case 7:
-                        INST_NAME("BTC Ed, Ib");
+                        INST_NAME("LOCK BTC Ed, Ib");
                         SETFLAGS(X_CF, SF_SUBSET);
                         SET_DFNONE(x1);
                         if(MODREG) {
@@ -514,10 +504,6 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             BFXILxw(xFlags, ed, u8, 1);  // inject 1 bit from u8 to F_CF (i.e. pos 0)
                             MOV32w(x4, 1);
                             EORxw_REG_LSL(ed, ed, x4, u8);
-                            if(wback) {
-                                STxw(ed, wback, fixedaddress);
-                                SMWRITE();
-                            }
                         } else {
                             addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
                             u8 = F8;
@@ -528,9 +514,9 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                             ed = x1;
                             MARKLOCK;
                             LDAXRB(ed, wback);
-                            UBFXw(x4, ed, u8&7, 1);
-                            BFIw(xFlags, x4, F_CF, 1);
-                            BFCw(ed, u8&7, 1);
+                            BFXILw(xFlags, ed, u8&7, 1); // inject 1 bit from u8 to F_CF (i.e. pos 0)
+                            MOV32w(x4, 1);
+                            EORw_REG_LSL(ed, ed, x4, u8&7);
                             STLXRB(x4, ed, wback);
                             CBNZw_MARKLOCK(x4);
                         }