about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-12-26 17:14:54 +0800
committerGitHub <noreply@github.com>2024-12-26 10:14:54 +0100
commita7ded59393ad97959b572f4c97bae6f91d318b1e (patch)
tree5f61e1f73f3c1dbfe2c91a478fe4cb60447a0471 /src
parent205ef4ddeb69fbc0a1b105b23b6d65959479bee5 (diff)
downloadbox64-a7ded59393ad97959b572f4c97bae6f91d318b1e.tar.gz
box64-a7ded59393ad97959b572f4c97bae6f91d318b1e.zip
[LA64_DYNAREC] Added more opcodes (#2214)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/la64/dynarec_la64_66.c66
-rw-r--r--src/dynarec/la64/dynarec_la64_660f.c34
2 files changed, 100 insertions, 0 deletions
diff --git a/src/dynarec/la64/dynarec_la64_66.c b/src/dynarec/la64/dynarec_la64_66.c
index 2cedcf4e..27999e66 100644
--- a/src/dynarec/la64/dynarec_la64_66.c
+++ b/src/dynarec/la64/dynarec_la64_66.c
@@ -625,6 +625,65 @@ uintptr_t dynarec64_66(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 ADD_D(xRDI, xRDI, x3);
             }
             break;
+        case 0xAF:
+            switch (rep) {
+                case 1:
+                case 2:
+                    if (rep == 1) {
+                        INST_NAME("REPNZ SCASW");
+                    } else {
+                        INST_NAME("REPZ SCASW");
+                    }
+                    MAYSETFLAGS();
+                    SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION);
+                    CBZ_NEXT(xRCX);
+                    GETDIR(x3, x1, rex.w ? 8 : 2);
+                    if (rex.w) {
+                        MARK;
+                        LD_D(x2, xRDI, 0);
+                        ADD_D(xRDI, xRDI, x3);
+                        ADDI_D(xRCX, xRCX, -1);
+                        if (rep == 1) {
+                            BEQ_MARK3(xRAX, x2);
+                        } else {
+                            BNE_MARK3(xRAX, x2);
+                        }
+                        BNE_MARK(xRCX, xZR);
+                        MARK3;
+                        emit_cmp32(dyn, ninst, rex, xRAX, x2, x3, x4, x5, x6);
+                    } else {
+                        BSTRPICK_D(x1, xRAX, 15, 0);
+                        MARK;
+                        LD_HU(x2, xRDI, 0);
+                        ADD_D(xRDI, xRDI, x3);
+                        ADDI_D(xRCX, xRCX, -1);
+                        if (rep == 1) {
+                            BEQ_MARK3(x1, x2);
+                        } else {
+                            BNE_MARK3(x1, x2);
+                        }
+                        BNE_MARK(xRCX, xZR);
+                        MARK3;
+                        emit_cmp16(dyn, ninst, x1, x2, x3, x4, x5, x6);
+                    }
+                    break;
+                default:
+                    INST_NAME("SCASW");
+                    SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION);
+                    GETDIR(x3, x1, rex.w ? 8 : 2);
+                    if (rex.w) {
+                        LD_D(x2, xRDI, 0);
+                        ADD_D(xRDI, xRDI, x3);
+                        emit_cmp32(dyn, ninst, rex, xRAX, x2, x3, x4, x5, x6);
+                    } else {
+                        BSTRPICK_D(x1, xRAX, 15, 0);
+                        LD_HU(x2, xRDI, 0);
+                        ADD_D(xRDI, xRDI, x3);
+                        emit_cmp16(dyn, ninst, x1, x2, x3, x4, x5, x6);
+                    }
+                    break;
+            }
+            break;
         case 0xB8:
         case 0xB9:
         case 0xBA:
@@ -790,6 +849,13 @@ uintptr_t dynarec64_66(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     MOV32w(x2, u16);
                     emit_test16(dyn, ninst, x1, x2, x3, x4, x5);
                     break;
+                case 2:
+                    INST_NAME("NOT Ew");
+                    GETEW(x1, 0);
+                    MOV32w(x5, 0xffff);
+                    XOR(ed, ed, x5); // No flags affected
+                    EWBACK;
+                    break;
                 case 3:
                     INST_NAME("NEG Ew");
                     SETFLAGS(X_ALL, SF_SET_PENDING, NAT_FLAGS_FUSION);
diff --git a/src/dynarec/la64/dynarec_la64_660f.c b/src/dynarec/la64/dynarec_la64_660f.c
index d2024ba3..da3bb540 100644
--- a/src/dynarec/la64/dynarec_la64_660f.c
+++ b/src/dynarec/la64/dynarec_la64_660f.c
@@ -22,6 +22,7 @@
 #include "dynarec_la64_private.h"
 #include "dynarec_la64_functions.h"
 #include "../dynarec_helper.h"
+#include "emu/x64compstrings.h"
 
 uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ninst, rex_t rex, int* ok, int* need_epilog)
 {
@@ -728,6 +729,39 @@ uintptr_t dynarec64_660F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
                     MOV32w(x4, u8);
                     CALL(native_pclmul, -1);
                     break;
+                case 0x63:
+                    INST_NAME("PCMPISTRI Gx, Ex, Ib");
+                    SETFLAGS(X_ALL, SF_SET_DF, NAT_FLAGS_NOFUSION);
+                    nextop = F8;
+                    GETG;
+                    if (gd > 7) sse_reflect_reg(dyn, ninst, gd);
+                    ADDI_D(x2, xEmu, offsetof(x64emu_t, xmm[gd]));
+                    if (MODREG) {
+                        ed = (nextop & 7) + (rex.b << 3);
+                        if (ed > 7) sse_reflect_reg(dyn, ninst, ed);
+                        ADDI_D(x1, xEmu, offsetof(x64emu_t, xmm[ed]));
+                    } else {
+                        addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 0, 1);
+                        if (ed != x1) MV(x1, ed);
+                    }
+                    u8 = F8;
+                    MOV32w(x3, u8);
+                    CALL(sse42_compare_string_implicit_len, x1);
+                    BNEZ_MARK(x1);
+                    MOV32w(xRCX, (u8 & 1) ? 8 : 16);
+                    B_NEXT_nocond;
+                    MARK;
+                    if (u8 & 0b1000000) {
+                        CLZ_W(xRCX, x1);
+                        ADDI_D(x2, xZR, 31);
+                        SUB_D(xRCX, x2, xRCX);
+                    } else {
+                        if (rex.w)
+                            CTZ_D(xRCX, x1);
+                        else
+                            CTZ_W(xRCX, x1);
+                    }
+                    break;
                 case 0xDF:
                     INST_NAME("AESKEYGENASSIST Gx, Ex, Ib"); // AES-NI
                     nextop = F8;