about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2025-02-08 22:45:21 +0800
committerGitHub <noreply@github.com>2025-02-08 15:45:21 +0100
commit58b24c85a2407a6c2ab6dfc2f18555dd929ad7e1 (patch)
tree1ac38a6cdbd07097cc6141dc4a0749aac5a37248 /src
parent28ebc1a0b779d6fca2f0b7e45291df6795be6c0a (diff)
downloadbox64-58b24c85a2407a6c2ab6dfc2f18555dd929ad7e1.tar.gz
box64-58b24c85a2407a6c2ab6dfc2f18555dd929ad7e1.zip
[LA64_DYNAREC] Added more opcodes (#2328)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/la64/dynarec_la64_660f.c25
-rw-r--r--src/dynarec/la64/dynarec_la64_helper.h3
-rw-r--r--src/dynarec/la64/la64_emitter.h7
3 files changed, 35 insertions, 0 deletions
diff --git a/src/dynarec/la64/dynarec_la64_660f.c b/src/dynarec/la64/dynarec_la64_660f.c
index ccb36ad6..b5fbce5b 100644
--- a/src/dynarec/la64/dynarec_la64_660f.c
+++ b/src/dynarec/la64/dynarec_la64_660f.c
@@ -456,6 +456,13 @@ 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 0x23:
+                    INST_NAME("PMOVSXWD Gx, Ex"); // SSE4 opcode!
+                    nextop = F8;
+                    GETEX64(q1, 0, 0);
+                    GETGX_empty(q0);
+                    VSLLWIL_W_H(q0, q1, 0);
+                    break;
                 case 0x2B:
                     INST_NAME("PACKUSDW Gx, Ex"); // SSE4 opcode!
                     nextop = F8;
@@ -840,6 +847,24 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
             GOCOND(0x40, "CMOV", "Gd, Ed");
         #undef GO
 
+        case 0x51:
+            INST_NAME("SQRTPD Gx, Ex");
+            nextop = F8;
+            GETEX(q0, 0, 0);
+            GETGX_empty(q1);
+            if (!BOX64ENV(dynarec_fastnan)) {
+                v0 = fpu_get_scratch(dyn);
+                v1 = fpu_get_scratch(dyn);
+                VFCMP_D(v0, q0, q0, cEQ);
+                VFSQRT_D(q1, q0);
+                VFCMP_D(v1, q1, q1, cEQ);
+                VANDN_V(v1, v1, v0);
+                VSLLI_D(v1, v1, 63);
+                VOR_V(q1, q1, v1);
+            } else {
+                VFSQRT_D(q1, q0);
+            }
+            break;
         case 0x54:
             INST_NAME("ANDPD Gx, Ex");
             nextop = F8;
diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h
index 495fa44e..4653759d 100644
--- a/src/dynarec/la64/dynarec_la64_helper.h
+++ b/src/dynarec/la64/dynarec_la64_helper.h
@@ -355,6 +355,9 @@
         FLD_D(a, ed, fixedaddress);                                                          \
     }
 
+// Get Ex as 64bits, not a quad (warning, x1 get used, x2 might too)
+#define GETEX64(a, w, D) GETEXSD(a, w, D)
+
 // Get Ex as a single, not a quad (warning, x1 get used)
 #define GETEXSS(a, w, D)                                                                     \
     if (MODREG) {                                                                            \
diff --git a/src/dynarec/la64/la64_emitter.h b/src/dynarec/la64/la64_emitter.h
index 257fcae6..2a59c5ed 100644
--- a/src/dynarec/la64/la64_emitter.h
+++ b/src/dynarec/la64/la64_emitter.h
@@ -1908,6 +1908,13 @@ LSX instruction starts with V, LASX instruction starts with XV.
 #define VREPLGR2VR_H(vd, rj)         EMIT(type_2R(0b0111001010011111000001, rj, vd))
 #define VREPLGR2VR_W(vd, rj)         EMIT(type_2R(0b0111001010011111000010, rj, vd))
 #define VREPLGR2VR_D(vd, rj)         EMIT(type_2R(0b0111001010011111000011, rj, vd))
+#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 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))
+#define VNEG_D(vd, vj)               EMIT(type_2R(0b0111011010011100001111, vj, vd))
 
 ////////////////////////////////////////////////////////////////////////////////
 // (undocumented) LBT extension instructions