about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2025-02-17 20:49:12 +0800
committerGitHub <noreply@github.com>2025-02-17 13:49:12 +0100
commit26dd597a1b27fe8e3be0df1f3640428d2791e497 (patch)
treeafe05e55f11153fc0e8c1397f612be92efa1f229 /src
parent040f8d9a9f84a43bac88a7614711b442cc750519 (diff)
downloadbox64-26dd597a1b27fe8e3be0df1f3640428d2791e497.tar.gz
box64-26dd597a1b27fe8e3be0df1f3640428d2791e497.zip
[LA64_DYNAREC] Added more opcodes (#2374)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/la64/dynarec_la64_660f.c86
-rw-r--r--src/dynarec/la64/dynarec_la64_helper.h15
-rw-r--r--src/dynarec/la64/la64_emitter.h3
3 files changed, 96 insertions, 8 deletions
diff --git a/src/dynarec/la64/dynarec_la64_660f.c b/src/dynarec/la64/dynarec_la64_660f.c
index 86c37c06..0c19b1c5 100644
--- a/src/dynarec/la64/dynarec_la64_660f.c
+++ b/src/dynarec/la64/dynarec_la64_660f.c
@@ -456,6 +456,30 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
                     GETGX_empty(q0);
                     VSIGNCOV_W(q0, q1, q1);
                     break;
+                case 0x20:
+                    INST_NAME("PMOVSXBW Gx, Ex"); // SSE4 opcode!
+                    nextop = F8;
+                    GETEX64(q1, 0, 0);
+                    GETGX_empty(q0);
+                    VSLLWIL_H_B(q0, q1, 0);
+                    break;
+                case 0x21:
+                    INST_NAME("PMOVSXBD Gx, Ex"); // SSE4 opcode!
+                    nextop = F8;
+                    GETEX32(q1, 0, 0);
+                    GETGX_empty(q0);
+                    VSLLWIL_H_B(q0, q1, 0);
+                    VSLLWIL_W_H(q0, q0, 0);
+                    break;
+                case 0x22:
+                    INST_NAME("PMOVSXBQ Gx, Ex"); // SSE4 opcode!
+                    nextop = F8;
+                    GETEX16(q1, 0, 0);
+                    GETGX_empty(q0);
+                    VSLLWIL_H_B(q0, q1, 0);
+                    VSLLWIL_W_H(q0, q0, 0);
+                    VSLLWIL_D_W(q0, q0, 0);
+                    break;
                 case 0x23:
                     INST_NAME("PMOVSXWD Gx, Ex"); // SSE4 opcode!
                     nextop = F8;
@@ -464,22 +488,22 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
                     VSLLWIL_W_H(q0, q1, 0);
                     break;
                 case 0x24:
-                    INST_NAME("PMOVSXWQ Gx, Ex");
+                    INST_NAME("PMOVSXWQ Gx, Ex"); // SSE4 opcode!
                     nextop = F8;
-                    GETEXSS(q1, 0, 0);
+                    GETEX32(q1, 0, 0);
                     GETGX_empty(q0);
-                    VSLLWIL_W_H(q0, q1, 0);     // 16bits->32bits
-                    VSLLWIL_D_W(q0, q0, 0);     // 32bits->64bits
+                    VSLLWIL_W_H(q0, q1, 0);
+                    VSLLWIL_D_W(q0, q0, 0);
                     break;
                 case 0x25:
-                    INST_NAME("PMOVSXDQ Gx, Ex");
+                    INST_NAME("PMOVSXDQ Gx, Ex"); // SSE4 opcode!
                     nextop = F8;
                     GETEX64(q1, 0, 0);
                     GETGX_empty(q0);
-                    VSLLWIL_D_W(q0, q1, 0);     // 32bits->64bits
+                    VSLLWIL_D_W(q0, q1, 0);
                     break;                    
                 case 0x29:
-                    INST_NAME("PCMPEQQ Gx, Ex");  // SSE4 opcode!
+                    INST_NAME("PCMPEQQ Gx, Ex"); // SSE4 opcode!
                     nextop = F8;
                     GETEX(q1, 0, 0);
                     GETGX_empty(q0);
@@ -505,12 +529,58 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
                     }
                     break;
                 case 0x30:
-                    INST_NAME("PMOVZXBW Gx, Ex");
+                    INST_NAME("PMOVZXBW Gx, Ex"); // SSE4 opcode!
                     nextop = F8;
                     GETEX(q1, 0, 0);
                     GETGX_empty(q0);
                     VEXT2XV_HU_BU(q0, q1);
                     break;
+                case 0x31:
+                    INST_NAME("PMOVZXBD Gx, Ex"); // SSE4 opcode!
+                    nextop = F8;
+                    GETEX32(q1, 0, 0);
+                    GETGX_empty(q0);
+                    VSLLWIL_HU_BU(q0, q1, 0);
+                    VSLLWIL_WU_HU(q0, q0, 0);
+                    break;
+                case 0x32:
+                    INST_NAME("PMOVZXBQ Gx, Ex"); // SSE4 opcode!
+                    nextop = F8;
+                    GETEX16(q1, 0, 0);
+                    GETGX_empty(q0);
+                    VSLLWIL_HU_BU(q0, q1, 0);
+                    VSLLWIL_WU_HU(q0, q0, 0);
+                    VSLLWIL_DU_WU(q0, q0, 0);
+                    break;
+                case 0x33:
+                    INST_NAME("PMOVZXWD Gx, Ex"); // SSE4 opcode!
+                    nextop = F8;
+                    GETEX64(q1, 0, 0);
+                    GETGX_empty(q0);
+                    VSLLWIL_WU_HU(q0, q1, 0);
+                    break;
+                case 0x34:
+                    INST_NAME("PMOVZXWQ Gx, Ex"); // SSE4 opcode!
+                    nextop = F8;
+                    GETEX32(q1, 0, 0);
+                    GETGX_empty(q0);
+                    VSLLWIL_WU_HU(q0, q1, 0);
+                    VSLLWIL_DU_WU(q0, q0, 0);
+                    break;
+                case 0x35:
+                    INST_NAME("PMOVZXDQ Gx, Ex"); // SSE4 opcode!
+                    nextop = F8;
+                    GETEX64(q1, 0, 0);
+                    GETGX_empty(q0);
+                    VSLLWIL_DU_WU(q0, q1, 0);
+                    break;
+                case 0x39:
+                    INST_NAME("PMINSD Gx, Ex"); // SSE4 opcode!
+                    nextop = F8;
+                    GETEX(q1, 0, 0);
+                    GETGX(q0, 1);
+                    VMIN_W(q0, q0, q1);
+                    break;
                 case 0x3A:
                     INST_NAME("PMINUW Gx, Ex");  // SSE4 opcode!
                     nextop = F8;
diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h
index b912fe8a..98be10b3 100644
--- a/src/dynarec/la64/dynarec_la64_helper.h
+++ b/src/dynarec/la64/dynarec_la64_helper.h
@@ -381,6 +381,21 @@
         FLD_S(a, ed, fixedaddress);                                                          \
     }
 
+// Get Ex as 32bits, not a quad (warning, x1 get used)
+#define GETEX32(a, w, D) GETEXSS(a, w, D)
+
+// Get Ex as 16bits, not a quad (warning, x1 get used)
+#define GETEX16(a, w, D)                                                                     \
+    if (MODREG) {                                                                            \
+        a = sse_get_reg(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), w);                     \
+    } else {                                                                                 \
+        SMREAD();                                                                            \
+        a = fpu_get_scratch(dyn);                                                            \
+        addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, D); \
+        LD_HU(x2, ed, fixedaddress);                                                         \
+        MOVGR2FR_D(a, x2);                                                                   \
+    }
+
 // Write gb (gd) back to original register / memory, using s1 as scratch
 #define GBBACK() BSTRINS_D(gb1, gd, gb2 + 7, gb2);
 
diff --git a/src/dynarec/la64/la64_emitter.h b/src/dynarec/la64/la64_emitter.h
index db82087f..54240f96 100644
--- a/src/dynarec/la64/la64_emitter.h
+++ b/src/dynarec/la64/la64_emitter.h
@@ -1921,6 +1921,9 @@ LSX instruction starts with V, LASX instruction starts with XV.
 #define VSLLWIL_H_B(vd, vj, imm3)    EMIT(type_2RI3(0b0111001100001000001, imm3, vj, vd))
 #define VSLLWIL_W_H(vd, vj, imm4)    EMIT(type_2RI4(0b011100110000100001, imm4, vj, vd))
 #define VSLLWIL_D_W(vd, vj, imm5)    EMIT(type_2RI5(0b01110011000010001, imm5, vj, vd))
+#define VSLLWIL_HU_BU(vd, vj, imm3)  EMIT(type_2RI3(0b0111001100001100001, imm3, vj, vd))
+#define VSLLWIL_WU_HU(vd, vj, imm4)  EMIT(type_2RI4(0b011100110000110001, imm4, vj, vd))
+#define VSLLWIL_DU_WU(vd, vj, imm5)  EMIT(type_2RI5(0b01110011000011001, imm5, vj, vd))
 #define VNEG_B(vd, vj)               EMIT(type_2R(0b0111011010011100001100, vj, vd))
 #define VNEG_H(vd, vj)               EMIT(type_2R(0b0111011010011100001101, vj, vd))
 #define VNEG_W(vd, vj)               EMIT(type_2R(0b0111011010011100001110, vj, vd))