about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/dynarec/arm64/arm64_emitter.h9
-rw-r--r--src/dynarec/arm64/arm64_printer.c16
-rw-r--r--src/dynarec/arm64/dynarec_arm64_0f.c39
3 files changed, 64 insertions, 0 deletions
diff --git a/src/dynarec/arm64/arm64_emitter.h b/src/dynarec/arm64/arm64_emitter.h
index e27011db..16cca694 100644
--- a/src/dynarec/arm64/arm64_emitter.h
+++ b/src/dynarec/arm64/arm64_emitter.h
@@ -1600,6 +1600,15 @@
 #define CMEQQ_0_16(Rd, Rn)          EMIT(CMEQ_0_vector(1, 0b01, Rn, Rd))
 #define CMEQQ_0_32(Rd, Rn)          EMIT(CMEQ_0_vector(1, 0b10, Rn, Rd))
 #define CMEQQ_0_64(Rd, Rn)          EMIT(CMEQ_0_vector(1, 0b11, Rn, Rd))
+// Greater Than 0
+#define CMCond_0_vector(Q, U, size, op, Rn, Rd) ((Q)<<30 | (U)<<29 | 0b01110<<24 | (size)<<22 | 0b10000<<17 | 0b0100<<13 | (op)<<12 | 0b10<<10 | (Rn)<<5 | (Rd))
+#define CMGT_0_8(Rd, Rn)            EMIT(CMCond_0_vector(0, 0, 0b00, 0, Rn, Rd))
+#define CMGT_0_16(Rd, Rn)           EMIT(CMCond_0_vector(0, 0, 0b01, 0, Rn, Rd))
+#define CMGT_0_32(Rd, Rn)           EMIT(CMCond_0_vector(0, 0, 0b10, 0, Rn, Rd))
+#define CMGTQ_0_8(Rd, Rn)           EMIT(CMCond_0_vector(1, 0, 0b00, 0, Rn, Rd))
+#define CMGTQ_0_16(Rd, Rn)          EMIT(CMCond_0_vector(1, 0, 0b01, 0, Rn, Rd))
+#define CMGTQ_0_32(Rd, Rn)          EMIT(CMCond_0_vector(1, 0, 0b10, 0, Rn, Rd))
+#define CMGTQ_0_64(Rd, Rn)          EMIT(CMCond_0_vector(1, 0, 0b11, 0, Rn, Rd))
 
 // Vector Float CMP
 // EQual
diff --git a/src/dynarec/arm64/arm64_printer.c b/src/dynarec/arm64/arm64_printer.c
index 705314df..973255f8 100644
--- a/src/dynarec/arm64/arm64_printer.c
+++ b/src/dynarec/arm64/arm64_printer.c
@@ -950,6 +950,22 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
         snprintf(buff, sizeof(buff), "VCMEQ V%d.%s, V%d.%s, V%d.%s", Rd, Vd, Rn, Vd, Rm, Vd);

         return buff;

     }

+    // CMP zero

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

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

+        const char* Z[] = {"GT", "GE", "EQ", "LE"};

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

+        const char* Cond = Z[(a.o << 1 | a.U)];

+        snprintf(buff, sizeof(buff), "VCM%s V%d.%s, V%d.%s, #0", Cond, Rd, Vd, Rn, Vd);

+        return buff;

+    }

+    // CMPLT zero

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

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

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

+        snprintf(buff, sizeof(buff), "VCMLT V%d.%s, V%d.%s, #0", Rd, Vd, Rn, Vd);

+        return buff;

+    }

     // MIN/MAX

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

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

diff --git a/src/dynarec/arm64/dynarec_arm64_0f.c b/src/dynarec/arm64/dynarec_arm64_0f.c
index 0ede6e3b..fe39a5e6 100644
--- a/src/dynarec/arm64/dynarec_arm64_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_0f.c
@@ -492,6 +492,45 @@ uintptr_t dynarec64_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin
                     VUZP2_16(q0, q0, q1);

                     SQSUB_16(q0, v0, q0);

                     break;

+                case 0x08:

+                    INST_NAME("PSIGNB Gm,Em");

+                    nextop = F8;

+                    GETGM(q0);

+                    GETEM(q1, 0);

+                    v0 = fpu_get_scratch(dyn);

+                    v1 = fpu_get_scratch(dyn);

+                    CMGT_0_8(v0, q1);

+                    VAND(v0, v0, q0);

+                    CMLT_0_8(v1, q1);

+                    VMUL_8(q0, q0, v1);

+                    VORR(q0, q0, v0);

+                    break;

+                case 0x09:

+                    INST_NAME("PSIGNW Gm,Em");

+                    nextop = F8;

+                    GETGM(q0);

+                    GETEM(q1, 0);

+                    v0 = fpu_get_scratch(dyn);

+                    v1 = fpu_get_scratch(dyn);

+                    CMGT_0_16(v0, q1);

+                    VAND(v0, v0, q0);

+                    CMLT_0_16(v1, q1);

+                    VMUL_16(q0, q0, v1);

+                    VORR(q0, q0, v0);

+                    break;

+                case 0x0A:

+                    INST_NAME("PSIGND Gm,Em");

+                    nextop = F8;

+                    GETGM(q0);

+                    GETEM(q1, 0);

+                    v0 = fpu_get_scratch(dyn);

+                    v1 = fpu_get_scratch(dyn);

+                    CMGT_0_32(v0, q1);

+                    VAND(v0, v0, q0);

+                    CMLT_0_32(v1, q1);

+                    VMUL_32(q0, q0, v1);

+                    VORR(q0, q0, v0);

+                    break;

                 case 0x0B:

                     INST_NAME("PMULHRSW Gm,Em");

                     nextop = F8;