about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <numbksco@gmail.com>2024-05-01 17:04:50 +0800
committerGitHub <noreply@github.com>2024-05-01 11:04:50 +0200
commit0fe7e7a88df5404fbc49f0fc1e6a77fa2b20d75a (patch)
tree14794dc5f86832369ca169c26ca265b55d1e7e09 /src
parent08bc57045af7067adf3495d274a4800bb8385df0 (diff)
downloadbox64-0fe7e7a88df5404fbc49f0fc1e6a77fa2b20d75a.tar.gz
box64-0fe7e7a88df5404fbc49f0fc1e6a77fa2b20d75a.zip
[LA64_DYNAREC] Added more opcodes (#1480)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/la64/dynarec_la64_00.c51
-rw-r--r--src/dynarec/la64/dynarec_la64_660f.c302
-rw-r--r--src/dynarec/la64/dynarec_la64_helper.h7
-rw-r--r--src/dynarec/la64/la64_emitter.h22
-rw-r--r--src/dynarec/la64/la64_printer.c4
5 files changed, 384 insertions, 2 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c
index 721f3864..47a0548d 100644
--- a/src/dynarec/la64/dynarec_la64_00.c
+++ b/src/dynarec/la64/dynarec_la64_00.c
@@ -121,6 +121,15 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             emit_or32(dyn, ninst, rex, ed, gd, x3, x4);
             WBACK;
             break;
+        case 0x0A:
+            INST_NAME("OR Gb, Eb");
+            SETFLAGS(X_ALL, SF_SET_PENDING);
+            nextop = F8;
+            GETEB(x1, 0);
+            GETGB(x2);
+            emit_or8(dyn, ninst, x2, x1, x4, x5);
+            GBBACK();
+            break;
         case 0x0B:
             INST_NAME("OR Gd, Ed");
             SETFLAGS(X_ALL, SF_SET_PENDING);
@@ -553,6 +562,14 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
         case 0x80:
             nextop = F8;
             switch((nextop>>3)&7) {
+                case 0: // ADD
+                    INST_NAME("ADD Eb, Ib");
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    GETEB(x1, 1);
+                    u8 = F8;
+                    emit_add8c(dyn, ninst, x1, u8, x2, x4, x5);
+                    EBBACK();
+                    break;
                 case 1: // OR
                     INST_NAME("OR Eb, Ib");
                     SETFLAGS(X_ALL, SF_SET_PENDING);
@@ -828,6 +845,40 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 SMWRITELOCK(lock);
             }
             break;
+        case 0x8A:
+            INST_NAME("MOV Gb, Eb");
+            nextop = F8;
+            if (rex.rex) {
+                gb1 = gd = TO_LA64(((nextop & 0x38) >> 3) + (rex.r << 3));
+                gb2 = 0;
+            } else {
+                gd = (nextop & 0x38) >> 3;
+                gb1 = TO_LA64(gd & 3);
+                gb2 = ((gd & 4) << 1);
+            }
+            if (MODREG) {
+                if (rex.rex) {
+                    wback = TO_LA64((nextop & 7) + (rex.b << 3));
+                    wb2 = 0;
+                } else {
+                    wback = (nextop & 7);
+                    wb2 = (wback >> 2);
+                    wback = TO_LA64(wback & 3);
+                }
+                if (wb2) {
+                    BSTRPICK_D(x4, wback, 7 + wb2 * 8, wb2 * 8);
+                    ed = x4;
+                } else {
+                    ed = wback;
+                }
+            } else {
+                addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, &lock, 1, 0);
+                SMREADLOCK(lock);
+                LD_BU(x4, wback, fixedaddress);
+                ed = x4;
+            }
+            BSTRINS_D(gb1, ed, gb2 + 7, gb2);
+            break;
         case 0x8B:
             INST_NAME("MOV Gd, Ed");
             nextop = F8;
diff --git a/src/dynarec/la64/dynarec_la64_660f.c b/src/dynarec/la64/dynarec_la64_660f.c
index 68f277bd..487e8195 100644
--- a/src/dynarec/la64/dynarec_la64_660f.c
+++ b/src/dynarec/la64/dynarec_la64_660f.c
@@ -194,6 +194,13 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
                     DEFAULT;
             }
             break;
+        case 0x60:
+            INST_NAME("PUNPCKLBW Gx,Ex");
+            nextop = F8;
+            GETGX(v0, 1);
+            GETEX(q0, 0, 0);
+            VILVL_B(v0, q0, v0);
+            break;
         case 0x61:
             INST_NAME("PUNPCKLWD Gx,Ex");
             nextop = F8;
@@ -201,6 +208,56 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
             GETEX(q0, 0, 0);
             VILVL_H(v0, q0, v0);
             break;
+        case 0x62:
+            INST_NAME("PUNPCKLDQ Gx,Ex");
+            nextop = F8;
+            GETGX(v0, 1);
+            GETEX(q0, 0, 0);
+            VILVL_W(v0, q0, v0);
+            break;
+        case 0x64:
+            INST_NAME("PCMPGTB Gx,Ex");
+            nextop = F8;
+            GETGX(v0, 1);
+            GETEX(v1, 0, 0);
+            VSLT_B(v0, v1, v0);
+            break;
+        case 0x65:
+            INST_NAME("PCMPGTW Gx,Ex");
+            nextop = F8;
+            GETGX(v0, 1);
+            GETEX(v1, 0, 0);
+            VSLT_H(v0, v1, v0);
+            break;
+        case 0x66:
+            INST_NAME("PCMPGTD Gx,Ex");
+            nextop = F8;
+            GETGX(v0, 1);
+            GETEX(v1, 0, 0);
+            VSLT_W(v0, v1, v0);
+            break;
+        case 0x67:
+            INST_NAME("PACKUSWB Gx, Ex");
+            nextop = F8;
+            GETGX(v0, 1);
+            GETEX(v1, 0, 0);
+            if (v0 == v1) {
+                VMAXI_H(v0, v0, 0);
+                VPICKEV_B(v0, v0, v0);
+            } else {
+                q1 = fpu_get_scratch(dyn);
+                VMAXI_H(v0, v0, 0);
+                VMAXI_H(q1, v1, 0);
+                VPICKEV_B(v0, q1, v0);
+            }
+            break;
+        case 0x68:
+            INST_NAME("PUNPCKHBW Gx,Ex");
+            nextop = F8;
+            GETGX(q0, 1);
+            GETEX(q1, 0, 0);
+            VILVH_B(q0, q1, q0);
+            break;
         case 0x69:
             INST_NAME("PUNPCKHWD Gx,Ex");
             nextop = F8;
@@ -208,6 +265,13 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
             GETEX(q1, 0, 0);
             VILVH_H(q0, q1, q0);
             break;
+        case 0x6A:
+            INST_NAME("PUNPCKHDQ Gx,Ex");
+            nextop = F8;
+            GETGX(q0, 1);
+            GETEX(q1, 0, 0);
+            VILVH_W(q0, q1, q0);
+            break;
         case 0x6C:
             INST_NAME("PUNPCKLQDQ Gx,Ex");
             nextop = F8;
@@ -259,6 +323,167 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 VLD(v0, ed, fixedaddress);
             }
             break;
+        case 0x70:
+            INST_NAME("PSHUFD Gx,Ex,Ib");
+            nextop = F8;
+            GETGX(v0, 1);
+            GETEX(v1, 0, 1);
+            u8 = F8;
+            VSHUF4I_W(v0, v1, u8);
+            break;
+        case 0x71:
+            nextop = F8;
+            switch ((nextop >> 3) & 7) {
+                case 2:
+                    INST_NAME("PSRLW Ex, Ib");
+                    GETEX(q0, 1, 1);
+                    u8 = F8;
+                    if (u8) {
+                        if (u8 > 15) {
+                            VXOR_V(q0, q0, q0);
+                        } else if (u8) {
+                            VSRLI_H(q0, q0, u8);
+                        }
+                        PUTEX(q0);
+                    }
+                    break;
+                case 4:
+                    INST_NAME("PSRAW Ex, Ib");
+                    GETEX(q0, 1, 1);
+                    u8 = F8;
+                    if (u8 > 15) u8 = 15;
+                    if (u8) {
+                        VSRAI_H(q0, q0, u8);
+                    }
+                    PUTEX(q0);
+                    break;
+                case 6:
+                    INST_NAME("PSLLW Ex, Ib");
+                    GETEX(q0, 1, 1);
+                    u8 = F8;
+                    if (u8) {
+                        if (u8 > 15) {
+                            VXOR_V(q0, q0, q0);
+                        } else {
+                            VSLLI_H(q0, q0, u8);
+                        }
+                        PUTEX(q0);
+                    }
+                    break;
+                default:
+                    *ok = 0;
+                    DEFAULT;
+            }
+            break;
+        case 0x72:
+            nextop = F8;
+            switch ((nextop >> 3) & 7) {
+                case 2:
+                    INST_NAME("PSRLD Ex, Ib");
+                    GETEX(q0, 1, 1);
+                    u8 = F8;
+                    if (u8) {
+                        if (u8 > 31) {
+                            VXOR_V(q0, q0, q0);
+                        } else if (u8) {
+                            VSRLI_W(q0, q0, u8);
+                        }
+                        PUTEX(q0);
+                    }
+                    break;
+                case 4:
+                    INST_NAME("PSRAD Ex, Ib");
+                    GETEX(q0, 1, 1);
+                    u8 = F8;
+                    if (u8 > 31) u8 = 31;
+                    if (u8) {
+                        VSRAI_W(q0, q0, u8);
+                    }
+                    PUTEX(q0);
+                    break;
+                case 6:
+                    INST_NAME("PSLLD Ex, Ib");
+                    GETEX(q0, 1, 1);
+                    u8 = F8;
+                    if (u8) {
+                        if (u8 > 31) {
+                            VXOR_V(q0, q0, q0);
+                        } else {
+                            VSLLI_W(q0, q0, u8);
+                        }
+                        PUTEX(q0);
+                    }
+                    break;
+                default:
+                    DEFAULT;
+            }
+            break;
+        case 0x73:
+            nextop = F8;
+            switch ((nextop >> 3) & 7) {
+                case 2:
+                    INST_NAME("PSRLQ Ex, Ib");
+                    GETEX(q0, 1, 1);
+                    u8 = F8;
+                    if (u8) {
+                        if (u8 > 63) {
+                            VXOR_V(q0, q0, q0);
+                        } else {
+                            VSRLI_D(q0, q0, u8);
+                        }
+                        PUTEX(q0);
+                    }
+                    break;
+                case 3:
+                    INST_NAME("PSRLDQ Ex, Ib");
+                    GETEX(q0, 1, 1);
+                    u8 = F8;
+                    if (u8) {
+                        if (u8 > 15) {
+                            XVOR_V(q0, q0, q0);
+                        } else {
+                            VBSRL_V(q0, q0, u8);
+                        }
+                        PUTEX(q0);
+                    }
+                    break;
+                case 6:
+                    INST_NAME("PSLLQ Ex, Ib");
+                    GETEX(q0, 1, 1);
+                    u8 = F8;
+                    if (u8) {
+                        if (u8 > 63) {
+                            XVOR_V(q0, q0, q0);
+                        } else {
+                            VSLLI_D(q0, q0, u8);
+                        }
+                        PUTEX(q0);
+                    }
+                    break;
+                case 7:
+                    INST_NAME("PSLLDQ Ex, Ib");
+                    GETEX(q0, 1, 1);
+                    u8 = F8;
+                    if (u8) {
+                        if (u8 > 15) {
+                            VXOR_V(q0, q0, q0);
+                        } else if (u8 > 0) {
+                            VBSLL_V(q0, q0, u8);
+                        }
+                        PUTEX(q0);
+                    }
+                    break;
+                default:
+                    DEFAULT;
+            }
+            break;
+        case 0x76:
+            INST_NAME("PCMPEQD Gx,Ex");
+            nextop = F8;
+            GETGX(v0, 1);
+            GETEX(q0, 0, 0);
+            VSEQ_W(v0, v0, q0);
+            break;
         case 0x7E:
             INST_NAME("MOVD Ed,Gx");
             nextop = F8;
@@ -318,6 +543,13 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
             GETEX(q0, 0, 0);
             VADD_D(v0, v0, q0);
             break;
+        case 0xD5:
+            INST_NAME("PMULLW Gx,Ex");
+            nextop = F8;
+            GETGX(q0, 1);
+            GETEX(q1, 0, 0);
+            VMUL_H(q0, q0, q1);
+            break;
         case 0xD6:
             INST_NAME("MOVQ Ex, Gx");
             nextop = F8;
@@ -339,6 +571,27 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
             GETEX(q0, 0, 0);
             VAND_V(v0, v0, q0);
             break;
+        case 0xDF:
+            INST_NAME("PANDN Gx,Ex");
+            nextop = F8;
+            GETGX(v0, 1);
+            GETEX(q0, 0, 0);
+            VANDN_V(v0, v0, q0);
+            break;
+        case 0xE4:
+            INST_NAME("PMULHUW Gx,Ex");
+            nextop = F8;
+            GETGX(v0, 1);
+            GETEX(v1, 0, 0);
+            VMUH_HU(v0, v0, v1);
+            break;
+        case 0xEB:
+            INST_NAME("POR Gx,Ex");
+            nextop = F8;
+            GETGX(v0, 1);
+            GETEX(q0, 0, 0);
+            VOR_V(v0, v0, q0);
+            break;
         case 0xEF:
             INST_NAME("PXOR Gx,Ex");
             nextop = F8;
@@ -353,6 +606,55 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 VXOR_V(q0, q0, q1);
             }
             break;
+        case 0xF8:
+            INST_NAME("PSUBB Gx,Ex");
+            nextop = F8;
+            GETGX(v0, 1);
+            GETEX(q0, 0, 0);
+            VSUB_B(v0, v0, q0);
+            break;
+        case 0xF9:
+            INST_NAME("PSUBW Gx,Ex");
+            nextop = F8;
+            GETGX(v0, 1);
+            GETEX(q0, 0, 0);
+            VSUB_H(v0, v0, q0);
+            break;
+        case 0xFA:
+            INST_NAME("PSUBD Gx,Ex");
+            nextop = F8;
+            GETGX(v0, 1);
+            GETEX(q0, 0, 0);
+            VSUB_W(v0, v0, q0);
+            break;
+        case 0xFB:
+            INST_NAME("PSUBQ Gx,Ex");
+            nextop = F8;
+            GETGX(v0, 1);
+            GETEX(q0, 0, 0);
+            VSUB_D(v0, v0, q0);
+            break;
+        case 0xFC:
+            INST_NAME("PADDB Gx,Ex");
+            nextop = F8;
+            GETGX(v0, 1);
+            GETEX(q0, 0, 0);
+            VADD_B(v0, v0, q0);
+            break;
+        case 0xFD:
+            INST_NAME("PADDW Gx,Ex");
+            nextop = F8;
+            GETGX(v0, 1);
+            GETEX(q0, 0, 0);
+            VADD_H(v0, v0, q0);
+            break;
+        case 0xFE:
+            INST_NAME("PADDD Gx,Ex");
+            nextop = F8;
+            GETGX(v0, 1);
+            GETEX(q0, 0, 0);
+            VADD_W(v0, v0, q0);
+            break;
         default:
             DEFAULT;
     }
diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h
index a7d55077..50405c1c 100644
--- a/src/dynarec/la64/dynarec_la64_helper.h
+++ b/src/dynarec/la64/dynarec_la64_helper.h
@@ -279,6 +279,13 @@
         VLD(a, ed, fixedaddress);                                                            \
     }
 
+// Put Back EX if it was a memory and not an emm register
+#define PUTEX(a)                  \
+    if (!MODREG) {                \
+        VST(a, ed, fixedaddress); \
+        SMWRITE2();               \
+    }
+
 // Get Ex as a double, not a quad (warning, x1 get used, x2 might too)
 #define GETEXSD(a, D)                                                                        \
     if (MODREG) {                                                                            \
diff --git a/src/dynarec/la64/la64_emitter.h b/src/dynarec/la64/la64_emitter.h
index afe2f5fd..93d50b99 100644
--- a/src/dynarec/la64/la64_emitter.h
+++ b/src/dynarec/la64/la64_emitter.h
@@ -1140,6 +1140,18 @@ LSX instruction starts with V, LASX instruction starts with XV.
 #define VSRA_H(vd, vj, vk)          EMIT(type_3R(0b01110000111011001, vk, vj, vd))
 #define VSRA_W(vd, vj, vk)          EMIT(type_3R(0b01110000111011010, vk, vj, vd))
 #define VSRA_D(vd, vj, vk)          EMIT(type_3R(0b01110000111011011, vk, vj, vd))
+#define VSLLI_B(vd, vj, imm3)       EMIT(type_2RI3(0b0111001100101100001, imm3, vj, vd))
+#define VSLLI_H(vd, vj, imm4)       EMIT(type_2RI4(0b011100110010110001, imm4, vj, vd))
+#define VSLLI_W(vd, vj, imm5)       EMIT(type_2RI5(0b01110011001011001, imm5, vj, vd))
+#define VSLLI_D(vd, vj, imm6)       EMIT(type_2RI6(0b0111001100101101, imm6, vj, vd))
+#define VSRLI_B(vd, vj, imm3)       EMIT(type_2RI3(0b0111001100110000001, imm3, vj, vd))
+#define VSRLI_H(vd, vj, imm4)       EMIT(type_2RI4(0b011100110011000001, imm4, vj, vd))
+#define VSRLI_W(vd, vj, imm5)       EMIT(type_2RI5(0b01110011001100001, imm5, vj, vd))
+#define VSRLI_D(vd, vj, imm6)       EMIT(type_2RI6(0b0111001100110001, imm6, vj, vd))
+#define VSRAI_B(vd, vj, imm3)       EMIT(type_2RI3(0b0111001100110100001, imm3, vj, vd))
+#define VSRAI_H(vd, vj, imm4)       EMIT(type_2RI4(0b011100110011010001, imm4, vj, vd))
+#define VSRAI_W(vd, vj, imm5)       EMIT(type_2RI5(0b01110011001101001, imm5, vj, vd))
+#define VSRAI_D(vd, vj, imm6)       EMIT(type_2RI6(0b0111001100110101, imm6, vj, vd))
 #define VROTR_B(vd, vj, vk)         EMIT(type_3R(0b01110000111011100, vk, vj, vd))
 #define VROTR_H(vd, vj, vk)         EMIT(type_3R(0b01110000111011101, vk, vj, vd))
 #define VROTR_W(vd, vj, vk)         EMIT(type_3R(0b01110000111011110, vk, vj, vd))
@@ -1276,6 +1288,8 @@ LSX instruction starts with V, LASX instruction starts with XV.
 #define VSLT_HU(vd, vj, vk)         EMIT(type_3R(0b01110000000010001, vk, vj, vd))
 #define VSLT_WU(vd, vj, vk)         EMIT(type_3R(0b01110000000010010, vk, vj, vd))
 #define VSLT_DU(vd, vj, vk)         EMIT(type_3R(0b01110000000010011, vk, vj, vd))
+#define VBSLL_V(vd, vj, imm5)       EMIT(type_2RI5(0b01110010100011100, imm5, vj, vd))
+#define VBSRL_V(vd, vj, imm5)       EMIT(type_2RI5(0b01110010100011101, imm5, vj, vd))
 #define VPACKEV_B(vd, vj, vk)       EMIT(type_3R(0b01110001000101100, vk, vj, vd))
 #define VPACKEV_H(vd, vj, vk)       EMIT(type_3R(0b01110001000101101, vk, vj, vd))
 #define VPACKEV_W(vd, vj, vk)       EMIT(type_3R(0b01110001000101110, vk, vj, vd))
@@ -1525,6 +1539,14 @@ LSX instruction starts with V, LASX instruction starts with XV.
 #define XVMOD_HU(vd, vj, vk)         EMIT(type_3R(0b01110100111001101, vk, vj, vd))
 #define XVMOD_WU(vd, vj, vk)         EMIT(type_3R(0b01110100111001110, vk, vj, vd))
 #define XVMOD_DU(vd, vj, vk)         EMIT(type_3R(0b01110100111001111, vk, vj, vd))
+#define VSAT_B(vd, vj, imm3)         EMIT(type_2RI3(0b0111001100100100001, imm3, vj, vd))
+#define VSAT_H(vd, vj, imm4)         EMIT(type_2RI4(0b011100110010010001, imm4, vj, vd))
+#define VSAT_W(vd, vj, imm5)         EMIT(type_2RI5(0b01110011001001001, imm5, vj, vd))
+#define VSAT_D(vd, vj, imm6)         EMIT(type_2RI6(0b0111001100100101, imm6, vj, vd))
+#define VSAT_BU(vd, vj, imm3)        EMIT(type_2RI3(0b0111001100101000001, imm3, vj, vd))
+#define VSAT_HU(vd, vj, imm4)        EMIT(type_2RI4(0b011100110010100001, imm4, vj, vd))
+#define VSAT_WU(vd, vj, imm5)        EMIT(type_2RI5(0b01110011001010001, imm5, vj, vd))
+#define VSAT_DU(vd, vj, imm6)        EMIT(type_2RI6(0b0111001100101001, imm6, vj, vd))
 #define XVSIGNCOV_B(vd, vj, vk)      EMIT(type_3R(0b01110101001011100, vk, vj, vd))
 #define XVSIGNCOV_H(vd, vj, vk)      EMIT(type_3R(0b01110101001011101, vk, vj, vd))
 #define XVSIGNCOV_W(vd, vj, vk)      EMIT(type_3R(0b01110101001011110, vk, vj, vd))
diff --git a/src/dynarec/la64/la64_printer.c b/src/dynarec/la64/la64_printer.c
index 247653b4..5c58541c 100644
--- a/src/dynarec/la64/la64_printer.c
+++ b/src/dynarec/la64/la64_printer.c
@@ -2157,11 +2157,11 @@ const char* la64_print(uint32_t opcode, uintptr_t addr)
         return buff;
     }
     if (isMask(opcode, "0010110000iiiiiiiiiiiijjjjjddddd", &a)) {
-        snprintf(buff, sizeof(buff), "%-15s %s, %s, %d", "VLD.D", Vt[Rd], Xt[Rj], signExtend(imm, 12));
+        snprintf(buff, sizeof(buff), "%-15s %s, %s, %d", "VLD", Vt[Rd], Xt[Rj], signExtend(imm, 12));
         return buff;
     }
     if (isMask(opcode, "0010110001iiiiiiiiiiiijjjjjddddd", &a)) {
-        snprintf(buff, sizeof(buff), "%-15s %s, %s, %d", "VST.D", Vt[Rd], Xt[Rj], signExtend(imm, 12));
+        snprintf(buff, sizeof(buff), "%-15s %s, %s, %d", "VST", Vt[Rd], Xt[Rj], signExtend(imm, 12));
         return buff;
     }
     if (isMask(opcode, "00000000000000001000000000101000", &a)) {