about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-06-01 09:02:54 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-06-01 09:02:54 +0200
commit453003da23af2abfd6f6f42e5909675ac7c28cb8 (patch)
treeda728aa97bc743b9adf7ba9978ef9a13ee3edee5 /src
parenteec08973bfeafb7cef08310e99d0e57a46620b87 (diff)
downloadbox64-453003da23af2abfd6f6f42e5909675ac7c28cb8.tar.gz
box64-453003da23af2abfd6f6f42e5909675ac7c28cb8.zip
[ARM64_DYNAREC] Added some AVX.66.0F opcodes
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_avx_66_0f.c304
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h5
2 files changed, 308 insertions, 1 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c b/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c
index 649cf797..bb23bba8 100644
--- a/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c
+++ b/src/dynarec/arm64/dynarec_arm64_avx_66_0f.c
@@ -174,7 +174,77 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
             } 
             if(!vex.l) YMM0(gd);
             break;
-
+        case 0x6C:
+            INST_NAME("VPUNPCKLQDQ Gx, Vx, Ex");
+            nextop = F8;
+            if(MODREG) {
+                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);
+                    }
+                    VMOVeD(v0, 1, v1, 0);
+                    if(v0!=v2) VMOVeD(v0, 0, v2, 0);
+                }
+            } else {
+                for(int l=0; l<1+vex.l; ++l) {
+                    if(!l) {
+                        GETGX_empty_VX(v0, v2, 0);
+                        addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
+                    } else {
+                        GETGY_empty_VY(v0, v2, 0, -1, -1);
+                        ADDx_U12(x3, ed, 16);
+                        ed = x3;
+                    }
+                    VLD1_64(v0, 1, ed);
+                    if(v0!=v2) VMOVeD(v0, 0, v2, 0);
+                }
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+        case 0x6D:
+            INST_NAME("VPUNPCKHQDQ Gx, Vx, Ex");
+            nextop = F8;
+            if(MODREG) {
+                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);
+                    }
+                    VMOVeD(v0, 0, v2, 1);
+                    if(v0!=v1) VMOVeD(v0, 1, v1, 1);
+                }
+            } else {
+                for(int l=0; l<1+vex.l; ++l) {
+                    if(!l) {
+                        GETGX_empty_VX(v0, v2, 0);
+                        addr = geted(dyn, addr, ninst, nextop, &ed, x3, &fixedaddress, NULL, 0, 0, rex, NULL, 0, 0);
+                        ADDx_U12(x1, ed, 8);
+                    } else {
+                        GETGY_empty_VY(v0, v2, -1, -1, -1);
+                        ADDx_U12(x1, ed, 16+8);
+                    }
+                    VMOVeD(v0, 0, v2, 1);
+                    VLD1_64(v0, 1, x1);
+                }
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+        case 0x6E:
+            INST_NAME("VMOVD Gx, Ed");
+            nextop = F8;
+            GETGX_empty(v0);
+            GETED(0);
+            if(rex.w) {
+                FMOVDx(v0, ed);
+            } else {
+                VEORQ(v0, v0, v0); // RAZ vector
+                VMOVQSfrom(v0, 0, ed);
+            }
+            YMM0(gd);
+            break;
         case 0x6F:
             INST_NAME("MOVDQA Gx,Ex");
             nextop = F8;
@@ -385,6 +455,238 @@ uintptr_t dynarec64_AVX_66_0F(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip,
             }
             break;
 
+        case 0xD8:
+            INST_NAME("VPSUBUSB 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);
+                }
+                UQSUBQ_8(v0, v2, v1);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+        case 0xD9:
+            INST_NAME("VPSUBUSW 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);
+                }
+                UQSUBQ_16(v0, v2, v1);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+        case 0xDA:
+            INST_NAME("VPMINUB 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);
+                }
+                UMINQ_8(v0, v2, v1);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+        case 0xDB:
+            INST_NAME("VPAND 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);
+                }
+                VANDQ(v0, v2, v1);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+        case 0xDC:
+            INST_NAME("VPADDUSB 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);
+                }
+                UQADDQ_8(v0, v2, v1);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+        case 0xDD:
+            INST_NAME("VPADDUSW 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);
+                }
+                UQADDQ_16(v0, v2, v1);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+        case 0xDE:
+            INST_NAME("VPMAXUB 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);
+                }
+                UMAXQ_8(v0, v2, v1);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+        case 0xDF:
+            INST_NAME("VPANDN 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);
+                }
+                VBICQ(v0, v1, v2);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+         case 0xE0:
+            INST_NAME("VPAVGB 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);
+                }
+                URHADDQ_8(v0, v2, v1);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+
+        case 0xE8:
+            INST_NAME("VPSUBSB 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);
+                }
+                SQSUBQ_8(v0, v2, v1);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+        case 0xE9:
+            INST_NAME("VPSUBSW 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);
+                }
+                SQSUBQ_16(v0, v2, v1);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+        case 0xEA:
+            INST_NAME("VPMINSW 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);
+                }
+                SMINQ_16(v0, v2, v1);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+        case 0xEB:
+            INST_NAME("VPOR 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);
+                }
+                VORRQ(v0, v2, v1);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+        case 0xEC:
+            INST_NAME("VPADDSB 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);
+                }
+                SQADDQ_8(v0, v2, v1);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+        case 0xED:
+            INST_NAME("VPADDSW 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);
+                }
+                SQADDQ_16(v0, v2, v1);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+        case 0xEE:
+            INST_NAME("VPMAXSW 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);
+                }
+                SMAXQ_16(v0, v2, v1);
+            }
+            if(!vex.l) YMM0(gd);
+            break;
+        case 0xEF:
+            INST_NAME("VPXOR Gx, Vx, Ex");
+            nextop = F8;
+            GETG;
+            if(MODREG && ((nextop&7)+(rex.b<<3)==vex.v)) {
+                // special case for PXOR Gx, Gx
+                q0 = sse_get_reg_empty(dyn, ninst, x1, gd);
+                VEORQ(q0, q0, q0);
+                if(vex.l) {
+                    q0 = ymm_get_reg_empty(dyn, ninst, x1, gd, -1, -1,-1);
+                    VEORQ(q0, q0, q0);
+                }
+            } else {
+                GETGX_empty_VXEX(v0, v2, v1, 0);
+                VEORQ(v0, v1, v2);
+                if(vex.l) {
+                    GETGY_empty_VYEY(v0, v2,v1);
+                    VEORQ(v0, v1, v2);
+                }
+            }
+            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 cc4ef30a..e328d255 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -480,6 +480,11 @@
     GETEX_Y(ex, 0, D);                      \
     GETGX_empty(gx)
 
+// Get empty GX, and non-writen VX
+#define GETGX_empty_VX(gx, vx, D)           \
+    GETVX(vx, 0);                           \
+    GETGX_empty(gx)
+
 // Get EX and and non-writen VX and GX
 #define GETGXVXEX(gx, vx, ex, D)            \
     GETVX(vx, 0);                           \