about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <numbksco@gmail.com>2024-07-17 14:15:41 +0800
committerGitHub <noreply@github.com>2024-07-17 08:15:41 +0200
commitabb2cbeeaa98b80bf8066300d62dfc5272035389 (patch)
tree8fc4b2d33d08007a6a5367dea64aa1413e045a26 /src
parent33381857ff133918a56e3afdded4ac5eefff9f9d (diff)
downloadbox64-abb2cbeeaa98b80bf8066300d62dfc5272035389.tar.gz
box64-abb2cbeeaa98b80bf8066300d62dfc5272035389.zip
[LA64_DYNAREC] Added more opcodes (#1690)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/la64/dynarec_la64_66.c9
-rw-r--r--src/dynarec/la64/dynarec_la64_660f.c89
2 files changed, 95 insertions, 3 deletions
diff --git a/src/dynarec/la64/dynarec_la64_66.c b/src/dynarec/la64/dynarec_la64_66.c
index 6432dc0e..d2d7e075 100644
--- a/src/dynarec/la64/dynarec_la64_66.c
+++ b/src/dynarec/la64/dynarec_la64_66.c
@@ -192,6 +192,15 @@ uintptr_t dynarec64_66(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             emit_xor16(dyn, ninst, x1, x2, x4, x5, x6);
             EWBACK;
             break;
+        case 0x33:
+            INST_NAME("XOR Gw, Ew");
+            SETFLAGS(X_ALL, SF_SET_PENDING);
+            nextop = F8;
+            GETGW(x1);
+            GETEW(x2, 0);
+            emit_xor16(dyn, ninst, x1, x2, x3, x4, x5);
+            GWBACK;
+            break;
         case 0x39:
             INST_NAME("CMP Ew, Gw");
             SETFLAGS(X_ALL, SF_SET_PENDING);
diff --git a/src/dynarec/la64/dynarec_la64_660f.c b/src/dynarec/la64/dynarec_la64_660f.c
index 5ced23af..02354595 100644
--- a/src/dynarec/la64/dynarec_la64_660f.c
+++ b/src/dynarec/la64/dynarec_la64_660f.c
@@ -441,8 +441,42 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
             nextop = F8;
             GETEX(q0, 0, 0);
             GETGX(q1, 1);
-            // TODO: fastnan handling
+            if (!box64_dynarec_fastnan) {
+                v0 = fpu_get_scratch(dyn);
+                v1 = fpu_get_scratch(dyn);
+                VFCMP_D(v0, q0, q1, cUN);
+            }
             VFADD_D(q1, q1, q0);
+            if (!box64_dynarec_fastnan) {
+                VFCMP_D(v1, q1, q1, cUN);
+                VANDN_V(v0, v0, v1);
+                VLDI(v1, 0b011111111000); // broadcast 0xFFFFFFFFFFFFFFF8
+                VSLLI_D(v1, v1, 48);
+                VAND_V(v1, v0, v1);
+                VANDN_V(v0, v0, q1);
+                VOR_V(q1, v0, v1);
+            }
+            break;
+        case 0x59:
+            INST_NAME("MULPD Gx, Ex");
+            nextop = F8;
+            GETEX(q0, 0, 0);
+            GETGX(q1, 1);
+            if (!box64_dynarec_fastnan) {
+                v0 = fpu_get_scratch(dyn);
+                v1 = fpu_get_scratch(dyn);
+                VFCMP_D(v0, q0, q1, cUN);
+            }
+            VFMUL_D(q1, q1, q0);
+            if (!box64_dynarec_fastnan) {
+                VFCMP_D(v1, q1, q1, cUN);
+                VANDN_V(v0, v0, v1);
+                VLDI(v1, 0b011111111000); // broadcast 0xFFFFFFFFFFFFFFF8
+                VSLLI_D(v1, v1, 48);
+                VAND_V(v1, v0, v1);
+                VANDN_V(v0, v0, q1);
+                VOR_V(q1, v0, v1);
+            }
             break;
         case 0x5A:
             INST_NAME("CVTPD2PS Gx, Ex");
@@ -483,8 +517,42 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
             nextop = F8;
             GETEX(q0, 0, 0);
             GETGX(q1, 1);
-            // TODO: fastnan handling
+            if (!box64_dynarec_fastnan) {
+                v0 = fpu_get_scratch(dyn);
+                v1 = fpu_get_scratch(dyn);
+                VFCMP_D(v0, q0, q1, cUN);
+            }
             VFSUB_D(q1, q1, q0);
+            if (!box64_dynarec_fastnan) {
+                VFCMP_D(v1, q1, q1, cUN);
+                VANDN_V(v0, v0, v1);
+                VLDI(v1, 0b011111111000); // broadcast 0xFFFFFFFFFFFFFFF8
+                VSLLI_D(v1, v1, 48);
+                VAND_V(v1, v0, v1);
+                VANDN_V(v0, v0, q1);
+                VOR_V(q1, v0, v1);
+            }
+            break;
+        case 0x5E:
+            INST_NAME("DIVPD Gx, Ex");
+            nextop = F8;
+            GETEX(q0, 0, 0);
+            GETGX(q1, 1);
+            if (!box64_dynarec_fastnan) {
+                v0 = fpu_get_scratch(dyn);
+                v1 = fpu_get_scratch(dyn);
+                VFCMP_D(v0, q0, q1, cUN);
+            }
+            VFDIV_D(q1, q1, q0);
+            if (!box64_dynarec_fastnan) {
+                VFCMP_D(v1, q1, q1, cUN);
+                VANDN_V(v0, v0, v1);
+                VLDI(v1, 0b011111111000); // broadcast 0xFFFFFFFFFFFFFFF8
+                VSLLI_D(v1, v1, 48);
+                VAND_V(v1, v0, v1);
+                VANDN_V(v0, v0, q1);
+                VOR_V(q1, v0, v1);
+            }
             break;
         case 0x60:
             INST_NAME("PUNPCKLBW Gx,Ex");
@@ -507,6 +575,21 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
             GETEX(q0, 0, 0);
             VILVL_W(v0, q0, v0);
             break;
+        case 0x63:
+            INST_NAME("PACKSSWB Gx,Ex");
+            nextop = F8;
+            GETGX(v0, 1);
+            GETEX(v1, 0, 0);
+            q0 = fpu_get_scratch(dyn);
+            if (v0 == v1) {
+                VSAT_H(v0, v0, 7);
+                VPICKEV_B(v0, v0, v0);
+            } else {
+                VSAT_H(v0, v0, 7);
+                VSAT_H(q0, v1, 7);
+                VPICKEV_B(v0, q0, v0);
+            }
+            break;
         case 0x64:
             INST_NAME("PCMPGTB Gx,Ex");
             nextop = F8;
@@ -938,7 +1021,7 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
             GETGX(v0, 1);
             GETEX(v1, 0, 1);
             u8 = F8;
-            VSHUF4I_D(v0, v1, (u8 & 1) | ((u8 & 2) << 1));
+            VSHUF4I_D(v0, v1, 0x8 | (u8 & 1) | ((u8 & 2) << 1));
             break;
         case 0xD4:
             INST_NAME("PADDQ Gx, Ex");