about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-05-30 21:26:10 +0200
committerptitSeb <sebastien.chev@gmail.com>2024-05-30 21:26:10 +0200
commit7eb24ff51407562fe29fc1259cd3a8ce47f143e8 (patch)
tree54abb8744d320aa639bbe692ff97d94c5b842cad /src
parente367a2bcc95a8ad1f292a231bffe12a8d2dcea84 (diff)
downloadbox64-7eb24ff51407562fe29fc1259cd3a8ce47f143e8.tar.gz
box64-7eb24ff51407562fe29fc1259cd3a8ce47f143e8.zip
[ARM64_DYNBAREC] Added AVX.66.0F38 2C-2F opcodes
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/arm64_emitter.h2
-rw-r--r--src/dynarec/arm64/arm64_printer.c6
-rw-r--r--src/dynarec/arm64/dynarec_arm64_avx_66_0f38.c65
-rw-r--r--src/dynarec/arm64/dynarec_arm64_helper.h15
4 files changed, 87 insertions, 1 deletions
diff --git a/src/dynarec/arm64/arm64_emitter.h b/src/dynarec/arm64/arm64_emitter.h
index 464693ba..9552f5de 100644
--- a/src/dynarec/arm64/arm64_emitter.h
+++ b/src/dynarec/arm64/arm64_emitter.h
@@ -1483,7 +1483,7 @@ int convert_bitmask(uint64_t bitmask);
 #define VUZP1Q_64(Rt, Rn, Rm)       EMIT(UZP_gen(1, 0b11, Rm, 0, Rn, Rt))
 #define VUZP2Q_64(Rt, Rn, Rm)       EMIT(UZP_gen(1, 0b11, Rm, 1, Rn, Rt))
 
-#define BITBIF_gen(Q, opc2, Rm, Rn, Rd) ((Q)<<30 | 0b101110101<<21 | (Rm)<<16 | 0b000111<<10 | (Rn)<<4 | (Rd))
+#define BITBIF_gen(Q, opc2, Rm, Rn, Rd) ((Q)<<30 | 0b101110101<<21 | (Rm)<<16 | 0b000111<<10 | (Rn)<<5 | (Rd))
 // Bitwise insert Vn in Vd if Vm is "0"
 #define VBIF(Vd, Vn,Vm)             EMIT(BITBIF_gen(0, 0b11, Vm, Vn, Vd))
 // Bitwise insert Vn in Vd if Vm is "0"
diff --git a/src/dynarec/arm64/arm64_printer.c b/src/dynarec/arm64/arm64_printer.c
index 8e975c63..98bbcc98 100644
--- a/src/dynarec/arm64/arm64_printer.c
+++ b/src/dynarec/arm64/arm64_printer.c
@@ -952,6 +952,12 @@ const char* arm64_print(uint32_t opcode, uintptr_t addr)
         snprintf(buff, sizeof(buff), "VMUL V%d.%s, V%d.%s, V%d.%s", Rd, Vd, Rn, Vd, Rm, Vd);

         return buff;

     }

+    // VBIT / VBIF

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

+        char q = a.Q?'Q':'D';

+        snprintf(buff, sizeof(buff), "VBI%c %c%d, %c%d, %c%d", a.o?'F':'T', q, Rd, q, Rn, q, Rm);

+        return buff;

+    }

     // CMP

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

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

diff --git a/src/dynarec/arm64/dynarec_arm64_avx_66_0f38.c b/src/dynarec/arm64/dynarec_arm64_avx_66_0f38.c
index 74e8a20c..14dfd263 100644
--- a/src/dynarec/arm64/dynarec_arm64_avx_66_0f38.c
+++ b/src/dynarec/arm64/dynarec_arm64_avx_66_0f38.c
@@ -79,6 +79,71 @@ uintptr_t dynarec64_AVX_66_0F38(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip
             } else YMM0(gd);
             break;
 
+        case 0x2C:
+            INST_NAME("VMASKMOVPS Gx, Vx, Ex");
+            nextop = F8;
+            GETGX_empty_VXEX(v0, v2, v1, 0);
+            q0 = fpu_get_scratch(dyn, ninst);
+            // create mask
+            VSSHRQ_32(q0, v2, 31);
+            VANDQ(v0, v1, q0);
+            if(vex.l) {
+                GETGY_empty_VYEY(v0, v2, v1);
+                VSSHRQ_32(q0, v2, 31);
+                VANDQ(v0, v1, q0);
+            } else YMM0(gd);
+            break;
+        case 0x2D:
+            INST_NAME("VMASKMOVPD Gx, Vx, Ex");
+            nextop = F8;
+            GETGX_empty_VXEX(v0, v2, v1, 0);
+            q0 = fpu_get_scratch(dyn, ninst);
+            // create mask
+            VSSHRQ_64(q0, v2, 63);
+            VANDQ(v0, v1, q0);
+            if(vex.l) {
+                GETGY_empty_VYEY(v0, v2, v1);
+                VSSHRQ_64(q0, v2, 63);
+                VANDQ(v0, v1, q0);
+            } else YMM0(gd);
+            break;
+        case 0x2E:
+            INST_NAME("VMASKMOVPS Ex, Gx, Vx");
+            nextop = F8;
+            GETGXVXEX(v0, v2, v1, 0);
+            q0 = fpu_get_scratch(dyn, ninst);
+            // create mask
+            VSSHRQ_32(q0, v2, 31);
+            VBITQ(v1, v0, q0);
+            if(!MODREG)
+                VST128(v1, ed, fixedaddress);
+            if(vex.l) {
+                GETGYVYEY(v0, v2, v1);
+                VSSHRQ_32(q0, v2, 31);
+                VBITQ(v1, v0, q0);
+                if(!MODREG)
+                    VST128(v1, ed, fixedaddress+16);
+            }
+            break;
+        case 0x2F:
+            INST_NAME("VMASKMOVPD Ex, Gx, Vx");
+            nextop = F8;
+            GETGXVXEX(v0, v2, v1, 0);
+            q0 = fpu_get_scratch(dyn, ninst);
+            // create mask
+            VSSHRQ_64(q0, v2, 63);
+            VBITQ(v1, v0, q0);
+            if(!MODREG)
+                VST128(v1, ed, fixedaddress);
+            if(vex.l) {
+                GETGYVYEY(v0, v2, v1);
+                VSSHRQ_64(q0, v2, 63);
+                VBITQ(v1, v0, q0);
+                if(!MODREG)
+                    VST128(v1, ed, fixedaddress+16);
+            }
+            break;
+
         default:
             DEFAULT;
     }
diff --git a/src/dynarec/arm64/dynarec_arm64_helper.h b/src/dynarec/arm64/dynarec_arm64_helper.h
index 6349054b..e455acda 100644
--- a/src/dynarec/arm64/dynarec_arm64_helper.h
+++ b/src/dynarec/arm64/dynarec_arm64_helper.h
@@ -478,6 +478,12 @@
     GETEX_Y(ex, 0, D);                      \
     GETGX_empty(gx)
 
+// Get EX and and non-writen VX and GX
+#define GETGXVXEX(gx, vx, ex, D)            \
+    GETVX(vx, 0);                           \
+    GETEX_Y(ex, 1, D);                      \
+    GETGX(gx, 0)
+
 // Get empty GY, and non-writen VY and EY
 #define GETGY_empty_VYEY(gy, vy, ey)                                                            \
     vy = ymm_get_reg(dyn, ninst, x1, vex.v, 0, gd, (MODREG)?((nextop&7)+(rex.b<<3)):-1, -1);    \
@@ -487,6 +493,15 @@
         VLD128(ey, ed, fixedaddress+16);                                                        \
     gy = ymm_get_reg_empty(dyn, ninst, x1, gd, vex.v, (MODREG)?((nextop&7)+(rex.b<<3)):-1, -1)
 
+// Get EY and non-writen VY and GY
+#define GETGYVYEY(gy, vy, ey)                                                                   \
+    vy = ymm_get_reg(dyn, ninst, x1, vex.v, 0, gd, (MODREG)?((nextop&7)+(rex.b<<3)):-1, -1);    \
+    if(MODREG)                                                                                  \
+        ey = ymm_get_reg(dyn, ninst, x1, (nextop&7)+(rex.b<<3), 1, gd, vex.v, -1);              \
+    else                                                                                        \
+        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 empty GY, and non-writen EY
 #define GETGY_empty_EY(gy, ey)                                                      \
     if(MODREG)                                                                      \