about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-08-04 12:09:49 +0200
committerGitHub <noreply@github.com>2023-08-04 12:09:49 +0200
commit0f7b23148f614b23d58736b95337a5b8f6ecd638 (patch)
treed390aaddb858f9f166f7cd296712519f586b6233 /src
parent0edf24ae977d812386bf6bc0b5d41b7ab3900a05 (diff)
parenta46923e4949864da2f505b701bc4f0541b076481 (diff)
downloadbox64-0f7b23148f614b23d58736b95337a5b8f6ecd638.tar.gz
box64-0f7b23148f614b23d58736b95337a5b8f6ecd638.zip
Merge pull request #922 from wannacu/main
[ARM64_DYNAREC] Fixed BT/BTC/BTR/BTS opcodes
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/arm64_emitter.h15
-rw-r--r--src/dynarec/arm64/arm64_printer.c14
-rw-r--r--src/dynarec/arm64/dynarec_arm64_0f.c19
-rw-r--r--src/dynarec/arm64/dynarec_arm64_660f.c17
-rw-r--r--src/dynarec/arm64/dynarec_arm64_f0.c22
5 files changed, 55 insertions, 32 deletions
diff --git a/src/dynarec/arm64/arm64_emitter.h b/src/dynarec/arm64/arm64_emitter.h
index 7ebc0208..98708b1a 100644
--- a/src/dynarec/arm64/arm64_emitter.h
+++ b/src/dynarec/arm64/arm64_emitter.h
@@ -537,6 +537,15 @@
 #define EORx_REG_LSR(Rd, Rn, Rm, lsr)   EMIT(LOGIC_REG_gen(1, 0b10, 0b01, 0, Rm, lsr, Rn, Rd))
 #define EORw_REG_LSR(Rd, Rn, Rm, lsr)   EMIT(LOGIC_REG_gen(0, 0b10, 0b01, 0, Rm, lsr, Rn, Rd))
 #define EORxw_REG_LSR(Rd, Rn, Rm, lsr)  EMIT(LOGIC_REG_gen(rex.w, 0b10, 0b01, 0, Rm, lsr, Rn, Rd))
+#define EONx_REG(Rd, Rn, Rm)            EMIT(LOGIC_REG_gen(1, 0b10, 0b00, 1, Rm, 0, Rn, Rd))
+#define EONw_REG(Rd, Rn, Rm)            EMIT(LOGIC_REG_gen(0, 0b10, 0b00, 1, Rm, 0, Rn, Rd))
+#define EONxw_REG(Rd, Rn, Rm)           EMIT(LOGIC_REG_gen(rex.w, 0b10, 0b00, 1, Rm, 0, Rn, Rd))
+#define EONx_REG_LSL(Rd, Rn, Rm, lsl)   EMIT(LOGIC_REG_gen(1, 0b10, 0b00, 1, Rm, lsl, Rn, Rd))
+#define EONw_REG_LSL(Rd, Rn, Rm, lsl)   EMIT(LOGIC_REG_gen(0, 0b10, 0b00, 1, Rm, lsl, Rn, Rd))
+#define EONxw_REG_LSL(Rd, Rn, Rm, lsl)  EMIT(LOGIC_REG_gen(rex.w, 0b10, 0b00, 1, Rm, lsl, Rn, Rd))
+#define EONx_REG_LSR(Rd, Rn, Rm, lsr)   EMIT(LOGIC_REG_gen(1, 0b10, 0b01, 1, Rm, lsr, Rn, Rd))
+#define EONw_REG_LSR(Rd, Rn, Rm, lsr)   EMIT(LOGIC_REG_gen(0, 0b10, 0b01, 1, Rm, lsr, Rn, Rd))
+#define EONxw_REG_LSR(Rd, Rn, Rm, lsr)  EMIT(LOGIC_REG_gen(rex.w, 0b10, 0b01, 1, Rm, lsr, Rn, Rd))
 #define MOVx_REG(Rd, Rm)                ORRx_REG(Rd, xZR, Rm)
 #define MOVw_REG(Rd, Rm)                ORRw_REG(Rd, xZR, Rm)
 #define MOVxw_REG(Rd, Rm)               ORRxw_REG(Rd, xZR, Rm)
@@ -563,6 +572,12 @@
 #define BICx_REG    BICx
 #define BICw_REG    BICw
 #define BICxw_REG   BICxw
+#define BICx_REG_LSL(Rd, Rn, Rm, lsl)   EMIT(LOGIC_REG_gen(1, 0b00, 0b00, 1, Rm, lsl, Rn, Rd))
+#define BICw_REG_LSL(Rd, Rn, Rm, lsl)   EMIT(LOGIC_REG_gen(0, 0b00, 0b00, 1, Rm, lsl, Rn, Rd))
+#define BICxw_REG_LSL(Rd, Rn, Rm, lsl)  EMIT(LOGIC_REG_gen(rex.w, 0b00, 0b00, 1, Rm, lsl, Rn, Rd))
+#define BICx_REG_LSR(Rd, Rn, Rm, lsl)   EMIT(LOGIC_REG_gen(1, 0b00, 0b01, 1, Rm, lsl, Rn, Rd))
+#define BICw_REG_LSR(Rd, Rn, Rm, lsl)   EMIT(LOGIC_REG_gen(0, 0b00, 0b01, 1, Rm, lsl, Rn, Rd))
+#define BICxw_REG_LSR(Rd, Rn, Rm, lsl)  EMIT(LOGIC_REG_gen(rex.w, 0b00, 0b01, 1, Rm, lsl, Rn, Rd))
 #define TSTx_REG(Rn, Rm)                ANDSx_REG(xZR, Rn, Rm)
 #define TSTw_REG(Rn, Rm)                ANDSw_REG(wZR, Rn, Rm)
 #define TSTxw_REG(Rn, Rm)               ANDSxw_REG(xZR, Rn, Rm)
diff --git a/src/dynarec/arm64/arm64_printer.c b/src/dynarec/arm64/arm64_printer.c
index ead54a61..2c134dee 100644
--- a/src/dynarec/arm64/arm64_printer.c
+++ b/src/dynarec/arm64/arm64_printer.c
@@ -1107,7 +1107,19 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
         snprintf(buff, sizeof(buff), "FSQRT %c%d, %c%d", s, Rd, s, Rn);

         return buff;

     }

-

+    // FPRINTX

+    if(isMask(opcode, "0Q1011100f100001100110nnnnnddddd", &a)) {

+        char s = a.Q?'V':'D';

+        char d = sf?'D':'S';

+        int n = (a.Q && !sf)?4:2;

+        snprintf(buff, sizeof(buff), "VFRINTX %c%d.%d%c, %c%d.%d%c", s, Rd, n, d, s, Rn, n, d);

+        return buff;

+    }

+    if (isMask(opcode, "00011110ff100111010000nnnnnddddd", &a)) {

+        char s = (sf==0)?'S':((sf==1)?'D':'?');

+        snprintf(buff, sizeof(buff), "FRINTX %c%d, %c%d", s, Rd, s, Rn);

+        return buff;

+    }

     // FRINTI

     if(isMask(opcode, "0Q1011101f100001100110nnnnnddddd", &a)) {

         char s = a.Q?'V':'D';

diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c
index 00aa61be..ea976365 100644
--- a/src/dynarec/arm64/dynarec_arm64_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_0f.c
@@ -1104,7 +1104,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             } else {

                 SMREAD();

                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, NULL, 0, 0);

-                ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5)

+                ASRx(x1, gd, 5+rex.w); // r1 = (gd>>5)

                 ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4;

                 LDxw(x1, x3, fixedaddress);

                 ed = x1;

@@ -1152,7 +1152,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             } else {

                 SMREAD();

                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, NULL, 0, 0);

-                ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5)

+                ASRx(x1, gd, 5+rex.w); // r1 = (gd>>5)

                 ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4;

                 LDxw(x1, x3, fixedaddress);

                 ed = x1;

@@ -1318,7 +1318,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             } else {

                 SMREAD();

                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, NULL, 0, 0);

-                ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5)

+                ASRx(x1, gd, 5+rex.w); // r1 = (gd>>5)

                 ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4;

                 LDxw(x1, x3, fixedaddress);

                 ed = x1;

@@ -1331,15 +1331,14 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             }

             LSRxw_REG(x4, ed, x2);

             if(rex.w) {

-                ANDSx_mask(x4, x4, 1, 0, 0);  //mask=1

+                ANDx_mask(x4, x4, 1, 0, 0);  //mask=1

             } else {

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

+                ANDw_mask(x4, x4, 0, 0);  //mask=1

             }

             BFIw(xFlags, x4, F_CF, 1);

             MOV32w(x4, 1);

             LSLxw_REG(x4, x4, x2);

-            EORxw_REG(x4, ed, x4);

-            CSELxw(ed, ed, x4, cEQ);

+            BICxw_REG(ed, ed, x4);

             if(wback) {

                 STRxw_U12(ed, wback, fixedaddress);

                 SMWRITE();

@@ -1418,7 +1417,7 @@ uintptr_t dynarec64_0F(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)

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

                     MOV32w(x4, 1);

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

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

                     if(wback) {

                         STxw(ed, wback, fixedaddress);

                         SMWRITE();

@@ -1443,7 +1442,7 @@ uintptr_t dynarec64_0F(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)

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

                     MOV32w(x4, 1);

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

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

                     if(wback) {

                         STxw(ed, wback, fixedaddress);

                         SMWRITE();

@@ -1490,7 +1489,7 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
             } else {

                 SMREAD();

                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<(2+rex.w), (1<<(2+rex.w))-1, rex, NULL, 0, 0);

-                ASRxw(x1, gd, 5+rex.w); // r1 = (gd>>5)

+                ASRx(x1, gd, 5+rex.w); // r1 = (gd>>5)

                 ADDx_REG_LSL(x3, wback, x1, 2+rex.w); //(&ed)+=r1*4;

                 LDxw(x1, x3, fixedaddress);

                 ed = x1;

diff --git a/src/dynarec/arm64/dynarec_arm64_660f.c b/src/dynarec/arm64/dynarec_arm64_660f.c
index 509263fb..b4aa13fa 100644
--- a/src/dynarec/arm64/dynarec_arm64_660f.c
+++ b/src/dynarec/arm64/dynarec_arm64_660f.c
@@ -1756,7 +1756,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             } else {

                 SMREAD();

                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<2, (1<<2)-1, rex, NULL, 0, 0);

-                SBFXw(x1, gd, 4, 12);   // r1 = (gw>>4)

+                SBFXx(x1, gd, 4, 12);   // r1 = (gw>>4)

                 ADDx_REG_LSL(x3, wback, x1, 1); //(&ed)+=r1*2;

                 LDH(x1, x3, fixedaddress);

                 ed = x1;

@@ -1797,9 +1797,10 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                 wback = 0;

             } else {

                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<2, (1<<2)-1, rex, NULL, 0, 0);

-                SBFXw(x4, gd, 4, 12);   // r1 = (gw>>4)

+                SBFXx(x4, gd, 4, 12);   // r1 = (gw>>4)

                 ADDx_REG_LSL(x3, wback, x4, 1); //(&ed)+=r1*2;

                 LDH(x4, x3, fixedaddress);

+                wback = x3;

                 ed = x4;

             }

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

@@ -1809,7 +1810,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             B_NEXT(cNE);

             MOV32w(x1, 1);

             LSLxw_REG(x1, x1, x2);

-            EORx_REG(ed, ed, x1);

+            ORRx_REG(ed, ed, x1);

             if(wback) {

                 STRH_U12(ed, wback, fixedaddress);

             }

@@ -1859,7 +1860,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             } else {

                 SMREAD();

                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<2, (1<<2)-1, rex, NULL, 0, 0);

-                SBFXw(x4, gd, 4, 12);   // r1 = (gw>>4)

+                SBFXx(x4, gd, 4, 12);   // r1 = (gw>>4)

                 ADDx_REG_LSL(x3, wback, x4, 1); //(&ed)+=r1*2;

                 LDH(x4, x3, fixedaddress);

                 wback = x3;

@@ -1872,7 +1873,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             B_NEXT(cEQ);

             MOV32w(x1, 1);

             LSLxw_REG(x1, x1, x2);

-            EORx_REG(ed, ed, x1);

+            BICx_REG(ed, ed, x1);

             if(wback) {

                 STH(ed, wback, fixedaddress);

                 SMWRITE();

@@ -1939,7 +1940,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     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

                     MOV32w(x4, 1);

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

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

                     EWBACK(x1);

                     MARK3;

                     break;

@@ -1953,7 +1954,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
                     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);

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

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

                     EWBACK(x1);

                     MARK3;

                     break;

@@ -1985,7 +1986,7 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             } else {

                 SMREAD();

                 addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, &unscaled, 0xfff<<2, (1<<2)-1, rex, NULL, 0, 0);

-                SBFXw(x4, gd, 4, 12);   // r1 = (gw>>4)

+                SBFXx(x4, gd, 4, 12);   // r1 = (gw>>4)

                 ADDx_REG_LSL(x3, wback, x4, 1); //(&ed)+=r1*2;

                 LDH(x4, x3, fixedaddress);

                 wback = x3;

diff --git a/src/dynarec/arm64/dynarec_arm64_f0.c b/src/dynarec/arm64/dynarec_arm64_f0.c
index 4a1421cc..da747204 100644
--- a/src/dynarec/arm64/dynarec_arm64_f0.c
+++ b/src/dynarec/arm64/dynarec_arm64_f0.c
@@ -173,8 +173,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);
                         LSLxw_REG(x4, x4, x2);
-                        EORxw_REG(x4, ed, x4);
-                        CSELxw(ed, ed, x4, cNE);
+                        ORRxw_REG(ed, ed, x4);
                     } else {
                         // Will fetch only 1 byte, to avoid alignment issue
                         if(rex.w) {
@@ -191,12 +190,11 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         ed = x1;
                         wback = x3;
                         LSRw_REG(x4, ed, x2);
-                        ANDSw_mask(x4, x4, 0, 0);  //mask=1
+                        ANDw_mask(x4, x4, 0, 0);  //mask=1
                         BFIw(xFlags, x4, F_CF, 1);
                         MOV32w(x4, 1);
                         LSLw_REG(x4, x4, x2);
-                        EORw_REG(x4, ed, x4);
-                        CSELw(ed, ed, x4, cNE);
+                        ORRw_REG(ed, ed, x4);
                         STLXRB(x4, ed, wback);
                         CBNZw_MARKLOCK(x4);
                         SMDMB();
@@ -322,15 +320,14 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         }
                         LSRxw_REG(x4, ed, x2);
                         if(rex.w) {
-                            ANDSx_mask(x4, x4, 1, 0, 0);  //mask=1
+                            ANDx_mask(x4, x4, 1, 0, 0);  //mask=1
                         } else {
-                            ANDSw_mask(x4, x4, 0, 0);  //mask=1
+                            ANDw_mask(x4, x4, 0, 0);  //mask=1
                         }
                         BFIw(xFlags, x4, F_CF, 1);
                         MOV32w(x4, 1);
                         LSLxw_REG(x4, x4, x2);
-                        EORxw_REG(x4, ed, x4);
-                        CSELxw(ed, ed, x4, cEQ);
+                        BICxw_REG(ed, ed, x4);
                     } else {
                         // Will fetch only 1 byte, to avoid alignment issue
                         if(rex.w) {
@@ -340,19 +337,18 @@ uintptr_t dynarec64_F0(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                         }
                         SMDMB();
                         addr = geted(dyn, addr, ninst, nextop, &wback, x3, &fixedaddress, NULL, 0, 0, rex, LOCK_LOCK, 0, 0);
-                        ASRxw(x1, gd, 3); // r1 = (gd>>3)
+                        ASRx(x1, gd, 3); // r1 = (gd>>3)
                         ADDx_REG_LSL(x3, wback, x1, 0); //(&ed)+=r1;
                         MARKLOCK;
                         LDAXRB(x1, wback);
                         ed = x1;
                         wback = x3;
                         LSRw_REG(x4, ed, x2);
-                        ANDSw_mask(x4, x4, 0, 0);  //mask=1
+                        ANDw_mask(x4, x4, 0, 0);  //mask=1
                         BFIw(xFlags, x4, F_CF, 1);
                         MOV32w(x4, 1);
                         LSLw_REG(x4, x4, x2);
-                        EORw_REG(x4, ed, x4);
-                        CSELw(ed, ed, x4, cEQ);
+                        ORRw_REG(ed, ed, x4);
                         STLXRB(x4, ed, wback);
                         CBNZw_MARKLOCK(x4);
                         SMDMB();