about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/arm64_emitter.h73
-rwxr-xr-xsrc/dynarec/arm64_printer.c30
-rwxr-xr-xsrc/dynarec/dynarec_arm64_660f.c19
3 files changed, 121 insertions, 1 deletions
diff --git a/src/dynarec/arm64_emitter.h b/src/dynarec/arm64_emitter.h
index 220d8444..0446bde6 100755
--- a/src/dynarec/arm64_emitter.h
+++ b/src/dynarec/arm64_emitter.h
@@ -1226,4 +1226,77 @@
 #define VUMULL2_16(Rd, Rn, Rm)      EMIT(MULL_vector(1, 1, 0b01, Rm, Rn, Rd))
 #define VUMULL2_32(Rd, Rn, Rm)      EMIT(MULL_vector(1, 1, 0b10, Rm, Rn, Rd))
 
+// Absolute Difference
+#define AD_vector(Q, U, size, Rm, ac, Rn, Rd)   ((Q)<<30 | (U)<<29 | 0b01110<<24 | (size)<<22 | 1<<21 | (Rm)<<16 | 0b0111<<12 | (ac)<<11 | 1<<10 | (Rn)<<5 | (Rd))
+// Signed Absolute Difference and accumulate
+#define SABAQ_8(Rd, Rn, Rm)         EMIT(AD_vector(1, 0, 0b00, Rm, 1, Rn, Rd))
+#define SABAQ_16(Rd, Rn, Rm)        EMIT(AD_vector(1, 0, 0b01, Rm, 1, Rn, Rd))
+#define SABAQ_32(Rd, Rn, Rm)        EMIT(AD_vector(1, 0, 0b10, Rm, 1, Rn, Rd))
+#define SABA_8(Rd, Rn, Rm)          EMIT(AD_vector(0, 0, 0b00, Rm, 1, Rn, Rd))
+#define SABA_16(Rd, Rn, Rm)         EMIT(AD_vector(0, 0, 0b01, Rm, 1, Rn, Rd))
+#define SABA_32(Rd, Rn, Rm)         EMIT(AD_vector(0, 0, 0b10, Rm, 1, Rn, Rd))
+// Signed Absolute Difference
+#define SABDQ_8(Rd, Rn, Rm)         EMIT(AD_vector(1, 0, 0b00, Rm, 0, Rn, Rd))
+#define SABDQ_16(Rd, Rn, Rm)        EMIT(AD_vector(1, 0, 0b01, Rm, 0, Rn, Rd))
+#define SABDQ_32(Rd, Rn, Rm)        EMIT(AD_vector(1, 0, 0b10, Rm, 0, Rn, Rd))
+#define SABD_8(Rd, Rn, Rm)          EMIT(AD_vector(0, 0, 0b00, Rm, 0, Rn, Rd))
+#define SABD_16(Rd, Rn, Rm)         EMIT(AD_vector(0, 0, 0b01, Rm, 0, Rn, Rd))
+#define SABD_32(Rd, Rn, Rm)         EMIT(AD_vector(0, 0, 0b10, Rm, 0, Rn, Rd))
+
+#define ADL_vector(Q, U, size, Rm, op, Rn, Rd)  ((Q)<<30 | (U)<<29 | 0b01110<<24 | (size)<<22 | 1<<21 | (Rm)<<16 | 0b01<<14 | (op)<<13 | 1<<12 | (Rn)<<5 | (Rd))
+#define SABAL_8(Rd, Rn, Rm)         EMIT(ADL_vector(0, 0, 0b00, Rm, 0, Rn, Rd))
+#define SABAL2_8(Rd, Rn, Rm)        EMIT(ADL_vector(1, 0, 0b00, Rm, 0, Rn, Rd))
+#define SABAL_16(Rd, Rn, Rm)        EMIT(ADL_vector(0, 0, 0b01, Rm, 0, Rn, Rd))
+#define SABAL2_16(Rd, Rn, Rm)       EMIT(ADL_vector(1, 0, 0b01, Rm, 0, Rn, Rd))
+#define SABAL_32(Rd, Rn, Rm)        EMIT(ADL_vector(0, 0, 0b10, Rm, 0, Rn, Rd))
+#define SABAL2_32(Rd, Rn, Rm)       EMIT(ADL_vector(1, 0, 0b10, Rm, 0, Rn, Rd))
+#define UABAL_8(Rd, Rn, Rm)         EMIT(ADL_vector(0, 1, 0b00, Rm, 0, Rn, Rd))
+#define UABAL2_8(Rd, Rn, Rm)        EMIT(ADL_vector(1, 1, 0b00, Rm, 0, Rn, Rd))
+#define UABAL_16(Rd, Rn, Rm)        EMIT(ADL_vector(0, 1, 0b01, Rm, 0, Rn, Rd))
+#define UABAL2_16(Rd, Rn, Rm)       EMIT(ADL_vector(1, 1, 0b01, Rm, 0, Rn, Rd))
+#define UABAL_32(Rd, Rn, Rm)        EMIT(ADL_vector(0, 1, 0b10, Rm, 0, Rn, Rd))
+#define UABAL2_32(Rd, Rn, Rm)       EMIT(ADL_vector(1, 1, 0b10, Rm, 0, Rn, Rd))
+#define SABDL_8(Rd, Rn, Rm)         EMIT(ADL_vector(0, 0, 0b00, Rm, 1, Rn, Rd))
+#define SABDL2_8(Rd, Rn, Rm)        EMIT(ADL_vector(1, 0, 0b00, Rm, 1, Rn, Rd))
+#define SABDL_16(Rd, Rn, Rm)        EMIT(ADL_vector(0, 0, 0b01, Rm, 1, Rn, Rd))
+#define SABDL2_16(Rd, Rn, Rm)       EMIT(ADL_vector(1, 0, 0b01, Rm, 1, Rn, Rd))
+#define SABDL_32(Rd, Rn, Rm)        EMIT(ADL_vector(0, 0, 0b10, Rm, 1, Rn, Rd))
+#define SABDL2_32(Rd, Rn, Rm)       EMIT(ADL_vector(1, 0, 0b10, Rm, 1, Rn, Rd))
+#define UABDL_8(Rd, Rn, Rm)         EMIT(ADL_vector(0, 1, 0b00, Rm, 1, Rn, Rd))
+#define UABDL2_8(Rd, Rn, Rm)        EMIT(ADL_vector(1, 1, 0b00, Rm, 1, Rn, Rd))
+#define UABDL_16(Rd, Rn, Rm)        EMIT(ADL_vector(0, 1, 0b01, Rm, 1, Rn, Rd))
+#define UABDL2_16(Rd, Rn, Rm)       EMIT(ADL_vector(1, 1, 0b01, Rm, 1, Rn, Rd))
+#define UABDL_32(Rd, Rn, Rm)        EMIT(ADL_vector(0, 1, 0b10, Rm, 1, Rn, Rd))
+#define UABDL2_32(Rd, Rn, Rm)       EMIT(ADL_vector(1, 1, 0b10, Rm, 1, Rn, Rd))
+
+// Add Pairwise
+#define ADDLP_vector(Q, U, size, op, Rn, Rd)    ((Q)<<30 | (U)<<29 | 0b01110<<24 | (size)<<22 | 1<<21 | (op)<<14 | 0b10<<12 | 0b10<<10 | (Rn)<<5 | (Rd))
+#define SADDLPQ_8(Rd, Rn)           EMIT(ADDLP_vector(1, 0, 0b00, 0, Rn, Rd))
+#define SADDLPQ_16(Rd, Rn)          EMIT(ADDLP_vector(1, 0, 0b01, 0, Rn, Rd))
+#define SADDLPQ_32(Rd, Rn)          EMIT(ADDLP_vector(1, 0, 0b10, 0, Rn, Rd))
+#define SADDLP_8(Rd, Rn)            EMIT(ADDLP_vector(0, 0, 0b00, 0, Rn, Rd))
+#define SADDLP_16(Rd, Rn)           EMIT(ADDLP_vector(0, 0, 0b01, 0, Rn, Rd))
+#define SADDLP_32(Rd, Rn)           EMIT(ADDLP_vector(0, 0, 0b10, 0, Rn, Rd))
+#define UADDLPQ_8(Rd, Rn)           EMIT(ADDLP_vector(1, 1, 0b00, 0, Rn, Rd))
+#define UADDLPQ_16(Rd, Rn)          EMIT(ADDLP_vector(1, 1, 0b01, 0, Rn, Rd))
+#define UADDLPQ_32(Rd, Rn)          EMIT(ADDLP_vector(1, 1, 0b10, 0, Rn, Rd))
+#define UADDLP_8(Rd, Rn)            EMIT(ADDLP_vector(0, 1, 0b00, 0, Rn, Rd))
+#define UADDLP_16(Rd, Rn)           EMIT(ADDLP_vector(0, 1, 0b01, 0, Rn, Rd))
+#define UADDLP_32(Rd, Rn)           EMIT(ADDLP_vector(0, 1, 0b10, 0, Rn, Rd))
+
+// Add accros vector
+#define ADDLV_vector(Q, U, size, Rn, Rd)    ((Q)<<30 | (U)<<29 | 0b01110<<24 | (size)<<22 | 0b11000<<17 | 0b00011<<12 | 0b10<<10 | (Rn)<<5 | (Rd))
+#define SADDLVQ_8(Rd, Rn)           EMIT(ADDLV_vector(1, 0, 0b00, Rn, Rd))
+#define SADDLVQ_16(Rd, Rn)          EMIT(ADDLV_vector(1, 0, 0b01, Rn, Rd))
+#define SADDLVQ_32(Rd, Rn)          EMIT(ADDLV_vector(1, 0, 0b10, Rn, Rd))
+#define SADDLV_8(Rd, Rn)            EMIT(ADDLV_vector(0, 0, 0b00, Rn, Rd))
+#define SADDLV_16(Rd, Rn)           EMIT(ADDLV_vector(0, 0, 0b01, Rn, Rd))
+#define SADDLV_32(Rd, Rn)           EMIT(ADDLV_vector(0, 0, 0b10, Rn, Rd))
+#define UADDLVQ_8(Rd, Rn)           EMIT(ADDLV_vector(1, 1, 0b00, Rn, Rd))
+#define UADDLVQ_16(Rd, Rn)          EMIT(ADDLV_vector(1, 1, 0b01, Rn, Rd))
+#define UADDLVQ_32(Rd, Rn)          EMIT(ADDLV_vector(1, 1, 0b10, Rn, Rd))
+#define UADDLV_8(Rd, Rn)            EMIT(ADDLV_vector(0, 1, 0b00, Rn, Rd))
+#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))
+
 #endif  //__ARM64_EMITTER_H__
diff --git a/src/dynarec/arm64_printer.c b/src/dynarec/arm64_printer.c
index d7c52e97..606271af 100755
--- a/src/dynarec/arm64_printer.c
+++ b/src/dynarec/arm64_printer.c
@@ -1137,6 +1137,36 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
         return buff;

     }

 

+    // Absolute Difference

+    // SABA / SABD / UABA / UABD

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

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

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

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

+        return buff;

+    }

+    if(isMask(opcode, "0QU01110ff1mmmmm01c100nnnnnddddd", &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 = Y[(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;

+    }

+    // Add pair / accros vector

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

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

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

+        snprintf(buff, sizeof(buff), "%cAD%cLP V%d.%s, V%d.%s", a.U?'U':'S', a.c?'A':'D', Rd, Vd, Rn, Vd);

+        return buff;

+    }

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

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

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

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

+        snprintf(buff, sizeof(buff), "%cADDLV V%d.%s, V%d.%s", a.U?'U':'S', Rd, Z[sf], Rn, Vd);

+        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 b285b9e5..f9432aaf 100755
--- a/src/dynarec/dynarec_arm64_660f.c
+++ b/src/dynarec/dynarec_arm64_660f.c
@@ -53,10 +53,11 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
     uint64_t tmp64u;

     int v0, v1;

     int q0, q1;

-    int d0;

+    int d0, d1;

     int fixedaddress;

 

     MAYUSE(d0);

+    MAYUSE(d1);

     MAYUSE(q0);

     MAYUSE(q1);

     MAYUSE(eb1);

@@ -991,6 +992,22 @@ uintptr_t dynarec64_660F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int n
             VUMULL_32(v0, q0, q1);

             break;

 

+        case 0xF6:

+            INST_NAME("PSADBW Gx, Ex");

+            nextop = F8;

+            GETGX(q0);

+            GETEX(q1, 0);

+            d0 = fpu_get_scratch(dyn);

+            d1 = fpu_get_scratch(dyn);

+            VEOR(d1, d1, d1);   // is it necessary?

+            UABDL_8(d0, q0, q1);

+            UADDLVQ_16(d1, d0);

+            VMOVeD(q0, 0, d1, 0);

+            UABDL2_8(d0, q0, q1);

+            UADDLVQ_16(d1, d0);

+            VMOVeD(q0, 1, d1, 0);

+            break;

+

         case 0xF8:

             INST_NAME("PSUBB Gx,Ex");

             nextop = F8;