about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/dynarec/arm64/dynarec_arm64_avx_66_0f.c149
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h13
2 files changed, 162 insertions, 0 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c b/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c
index bb23bba8..871fefd7 100644
--- a/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c
@@ -359,6 +359,70 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
             if(!vex.l)  YMM0(gd);
             break;
 
+        case 0x72:
+            nextop = F8;
+            switch((nextop>>3)&7) {
+                case 2:
+                    INST_NAME("VPSRLD Vx, Ex, Ib");
+                    for(int l=0; l<1+vex.l; ++l) {
+                        if(!l) {
+                            GETVX_empty_EX(v0, v1,  1);
+                            u8 = F8;
+                        } else {
+                            GETVY_empty_EY(v0, v1);
+                        }
+                        if(u8) {
+                            if (u8>31) {
+                                VEORQ(v0, v0, v0);
+                            } else if(u8) {
+                                VSHRQ_32(v0, v1, u8);
+                            }
+                        } else if(v0!=v1)
+                            VMOVQ(v0, v1);
+                    }
+                    if(!vex.l) YMM0(vex.v);
+                    break;
+                case 4:
+                    INST_NAME("VPSRAD Vx, Ex, Ib");
+                    for(int l=0; l<1+vex.l; ++l) {
+                        if(!l) {
+                            GETVX_empty_EX(v0, v1, 1);
+                            u8 = F8;
+                        } else {
+                            GETVY_empty_EY(v0, v1);
+                        }
+                        if(u8>31) u8=31;
+                        if(u8) {
+                            VSSHRQ_32(v0, v1, u8);
+                        } else if(v0!=v1)
+                            VMOVQ(v0, v1);
+                    }
+                    if(!vex.l) YMM0(vex.v);
+                    break;
+                case 6:
+                    INST_NAME("VPSLLD Vx, Ex, Ib");
+                    for(int l=0; l<1+vex.l; ++l) {
+                        if(!l) {
+                            GETVX_empty_EX(v0, v1, 1);
+                            u8 = F8;
+                        } else {
+                            GETVY_empty_EY(v0, v1);
+                        }
+                        if(u8) {
+                            if (u8>31) {
+                                VEORQ(v0, v0, v0);
+                            } else {
+                                VSHLQ_32(v0, v1, u8);
+                            }
+                        } else if(v0!=v1)
+                            VMOVQ(v0, v1);
+                    }
+                    if(!vex.l) YMM0(vex.v);
+                    break;
+                default:
+                    DEFAULT;
+            }
+            break;
         case 0x73:
             nextop = F8;
             switch((nextop>>3)&7) {
@@ -455,6 +519,28 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
             }
             break;
 
+        case 0x7F:
+            INST_NAME("MOVDQA Ex,Gx");
+            nextop = F8;
+            GETGX(v0, 0);
+            if(MODREG) {
+                v1 = sse_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 1);
+                VMOVQ(v1, v0);
+                if(vex.l) {
+                    GETGYEY(v1, v0);
+                    VMOVQ(v1, v0);
+                }
+            } else {
+                addr = geted(dyn, addr, ninst, nextop, &ed, x1, &fixedaddress, NULL, 0xffe<<4, 15, rex, NULL, 0, 0);
+                VSTR128_U12(v0, ed, fixedaddress);
+                if(vex.l) {
+                    GETGY(v0, 0, -1, -1, -1);
+                    VSTR128_U12(v0, ed, fixedaddress+16);
+                }
+                SMWRITE2();
+            }
+            break;
+
         case 0xD8:
             INST_NAME("VPSUBUSB Gx, Vx, Ex");
             nextop = F8;
@@ -686,6 +772,69 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
             }
             if(!vex.l) YMM0(gd);
             break;
+        case 0xF8:
+            INST_NAME("VPSUBB Gx, Vx, Ex");
+            nextop = F8;
+            for(int l=0; l<1+vex.l; ++l) {
+                if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
+                VSUBQ_8(v0, v2, v1);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+        case 0xF9:
+            INST_NAME("VPSUBW Gx, Vx, Ex");
+            nextop = F8;
+            for(int l=0; l<1+vex.l; ++l) {
+                if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
+                VSUBQ_16(v0, v2, v1);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+        case 0xFA:
+            INST_NAME("VPSUBD Gx, Vx, Ex");
+            nextop = F8;
+            for(int l=0; l<1+vex.l; ++l) {
+                if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
+                VSUBQ_32(v0, v2, v1);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+        case 0xFB:
+            INST_NAME("VPSUBQ Gx, Vx, Ex");
+            nextop = F8;
+            for(int l=0; l<1+vex.l; ++l) {
+                if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
+                VSUBQ_64(v0, v2, v1);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+        case 0xFC:
+            INST_NAME("VPADDB Gx, Vx, Ex");
+            nextop = F8;
+            for(int l=0; l<1+vex.l; ++l) {
+                if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
+                VADDQ_8(v0, v2, v1);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+        case 0xFD:
+            INST_NAME("VPADDW Gx, Vx, Ex");
+            nextop = F8;
+            for(int l=0; l<1+vex.l; ++l) {
+                if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
+                VADDQ_16(v0, v2, v1);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+        case 0xFE:
+            INST_NAME("VPADDD Gx, Vx, Ex");
+            nextop = F8;
+            for(int l=0; l<1+vex.l; ++l) {
+                if(!l) { GETGX_empty_VXEX(v0, v2, v1, 0); } else { GETGY_empty_VYEY(v0, v2, v1); }
+                VADDQ_32(v0, v2, v1);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
 
         default:
             DEFAULT;
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index 872a86fb..8d7c09cc 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -459,6 +459,11 @@
 #define GETVX_empty(a)                  \
     a = sse_get_reg_empty(dyn, ninst, x1, vex.v)
 
+// Get empty VX, and non-writen  EX
+#define GETVX_empty_EX(vx, ex, D)           \
+    GETEX_Y(ex, 0, D);                      \
+    GETVX_empty(vx)
+
 #define GETGY_VY(a, w1, b, w2, k1, k2)                      \
     if(w2) b = ymm_get_reg(dyn, ninst, x1, vex.v, w2, gd, k1, k2); \
     a = ymm_get_reg(dyn, ninst, x1, gd, w1, vex.v, k1, k2); \
@@ -509,6 +514,14 @@
         VLD128(ey, ed, fixedaddress+16);                                                        \
     gy = ymm_get_reg(dyn, ninst, x1, gd, 0, vex.v, (MODREG)?((nextop&7)+(rex.b<<3)):-1, -1)
 
+// Get EY and non-writen GY
+#define GETGYEY(gy, ey)                                                                         \
+    if(MODREG)                                                                                  \
+        ey = ymm_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 1, gd, -1, -1);                 \
+    else                                                                                        \
+        VLD128(ey, ed, fixedaddress+16);                                                        \
+    gy = ymm_get_reg(dyn, ninst, x1, gd, 0, (MODREG)?((nextop&7)+(rex.b<<3)):-1, -1, -1)
+
 // Get empty GY, and non-writen EY
 #define GETGY_empty_EY(gy, ey)                                                      \
     if(MODREG)                                                                      \