about summary refs log tree commit diff stats
path: root/src/dynarec
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-03-31 13:23:56 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-03-31 13:23:56 +0200
commitdc938e8a60c7a466bb8b25fc465e6dedaff4b183 (patch)
treecc0aca2073f4e208d2f57e9533ec5047f1bfe1d7 /src/dynarec
parent7dd4f1ab72b15216736c1dfc79b4d39b8152e7de (diff)
downloadbox64-dc938e8a60c7a466bb8b25fc465e6dedaff4b183.tar.gz
box64-dc938e8a60c7a466bb8b25fc465e6dedaff4b183.zip
[DYNAREC] Added 66 0F 38 00 and fixed 66 0F 67 opcodes
Diffstat (limited to 'src/dynarec')
-rwxr-xr-xsrc/dynarec/arm64_emitter.h5
-rwxr-xr-xsrc/dynarec/arm64_printer.c49
-rwxr-xr-xsrc/dynarec/dynarec_arm64_660f.c23
3 files changed, 74 insertions, 3 deletions
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h
index ea7a8ae9..364dda4d 100755
--- a/src/dynarec/arm64_emitter.h
+++ b/src/dynarec/arm64_emitter.h
@@ -1316,4 +1316,9 @@
 #define UADDLV_16(Rd, Rn)           EMIT(ADDLV_vector(0, 1, 0b01, Rn, Rd))
 #define UADDLV_32(Rd, Rn)           EMIT(ADDLV_vector(0, 1, 0b10, Rn, Rd))
 
+// MOV Immediate
+#define MOVI_vector(Q, op, abc, cmode, defgh, Rd)   ((Q)<<30 | (op)<<29 | 0b0111100000<<19 | (abc)<<16 | (cmode)<<12 | 1<<10 | (defgh)<<5 | (Rd))
+#define MOVIQ_8(Rd, imm8)           EMIT(MOVI_vector(1, 0, (((imm8)>>5)&0b111), 0b1110, ((imm8)&0b11111), Rd))
+#define MOVI_8(Rd, imm8)            EMIT(MOVI_vector(0, 0, (((imm8)>>5)&0b111), 0b1110, ((imm8)&0b11111), Rd))
+
 #endif  //__ARM64_EMITTER_H__
diff --git a/src/dynarec/arm64_printer.c b/src/dynarec/arm64_printer.c
index 606271af..fd87692d 100755
--- a/src/dynarec/arm64_printer.c
+++ b/src/dynarec/arm64_printer.c
@@ -1149,7 +1149,7 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
         const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "??", "???"};

         const char* Vd = Y[(sf<<1) | a.Q];

         const char* Z[] = {"8H", "4S", "2D", "?"};

-        const char* Va = Y[(sf<<1)];

+        const char* Va = Z[(sf<<1)];

         snprintf(buff, sizeof(buff), "%cAB%cL%s V%d.%s, V%d.%s, V%d.%s", a.U?'U':'S', a.c?'A':'D', a.Q?"2":"", Rd, Va, Rn, Vd, Rm, Vd);

         return buff;

     }

@@ -1167,6 +1167,53 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
         snprintf(buff, sizeof(buff), "%cADDLV V%d.%s, V%d.%s", a.U?'U':'S', Rd, Z[sf], Rn, Vd);

         return buff;

     }

+    

+    // MOV immediate

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

+        const char* Y[] = {"8B", "16B"};

+        const char* Vd = Y[a.Q];

+        snprintf(buff, sizeof(buff), "MOVI V%d.%s, #0x%x", Rd, Vd, imm);

+        return buff;

+    }

+

+    // LD1/ST1 single structure

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

+        int scale = a.c;

+        int idx = 0;

+        const char* Y[] = {"B", "H", "S", "D"};

+        switch(scale) {

+            case 3: scale = sf; /* rep = 1; */ break;

+            case 0: idx = (a.Q<<3) | (a.S<<2) | sf; break;

+            case 1: idx = (a.Q<<2) | (a.S<<1) | (sf>>1); break;

+            case 2: if(!(sf&1))

+                        idx = (a.Q<<1) | a.S;

+                    else {

+                        scale = 3;

+                        idx = a.Q;

+                    }

+                    break;

+        }

+        snprintf(buff, sizeof(buff), "%s1 {V%d.%s}[%d], %s", a.L?"LD":"ST", Rd, Y[scale], idx, XtSp[Rt]);

+        return buff;

+    }

+

+    // (S/U)QXT(U)N

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

+        const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "?", "??"};

+        const char* Vd = Y[(sf<<1) | a.Q];

+        const char* Z[] = {"8H", "4S", "2D", "?"};

+        const char* Va = Z[sf];

+        snprintf(buff, sizeof(buff), "SQXTUN%s V%d.%s, V%d.%s", a.Q?"2":"", Rd, Vd, Rn, Va);

+        return buff;

+    }

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

+        const char* Y[] = {"8B", "16B", "4H", "8H", "2S", "4S", "?", "??"};

+        const char* Vd = Y[(sf<<1) | a.Q];

+        const char* Z[] = {"8H", "4S", "2D", "?"};

+        const char* Va = Z[sf];

+        snprintf(buff, sizeof(buff), "%cQXTN%s V%d.%s, V%d.%s", a.U?'U':'S', a.Q?"2":"", Rd, Vd, Rn, Va);

+        return buff;

+    }

 

 

     snprintf(buff, sizeof(buff), "%08X ???", __builtin_bswap32(opcode));

diff --git a/src/dynarec/dynarec_arm64_660f.c b/src/dynarec/dynarec_arm64_660f.c
index 0d0ffdae..98f44979 100755
--- a/src/dynarec/dynarec_arm64_660f.c
+++ b/src/dynarec/dynarec_arm64_660f.c
@@ -220,6 +220,25 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             FCOMI(x1, x2);

             break;

 

+        case 0x38:  // SSSE3 opcodes

+            nextop = F8;

+            switch(nextop) {

+                case 0x00:

+                    INST_NAME("PSHUFB Gx, Ex");

+                    nextop = F8;

+                    GETGX(q0);

+                    GETEX(q1, 0);

+                    d0 = fpu_get_scratch(dyn);

+                    MOVIQ_8(d0, 0b10001111);

+                    VANDQ(d0, d0, q1);  // mask the index

+                    VTBLQ1_8(q0, q0, d0);

+                    break;

+

+                default:

+                    DEFAULT;

+            }

+            break;

+

         #define GO(GETFLAGS, NO, YES, F)            \

             READFLAGS(F);                           \

             GETFLAGS;                               \

@@ -348,11 +367,11 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             nextop = F8;

             GETGX(v0);

             GETEX(v1, 0);

-            SQXTUN_16(v0, v0);

+            SQXTUN_8(v0, v0);

             if(v0==v1) {

                 VMOVeD(v0, 1, v0, 0);

             } else {

-                SQXTUN2_16(v0, v1);

+                SQXTUN2_8(v0, v1);

             }

             break;

         case 0x68: