about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorYang Liu <numbksco@gmail.com>2024-07-08 20:26:28 +0800
committerGitHub <noreply@github.com>2024-07-08 14:26:28 +0200
commita7b912393c9bb865a18d8f95d42c14099ed10504 (patch)
treee7deccb49bb774d3ef2f0abf80da6b56337687f5
parente82f17842edaf1664795f414042b154704b4569d (diff)
downloadbox64-a7b912393c9bb865a18d8f95d42c14099ed10504.tar.gz
box64-a7b912393c9bb865a18d8f95d42c14099ed10504.zip
[LA64_DYNAREC] Added more opcodes (#1654)
-rw-r--r--src/dynarec/la64/dynarec_la64_00.c9
-rw-r--r--src/dynarec/la64/dynarec_la64_64.c103
-rw-r--r--src/dynarec/la64/dynarec_la64_f30f.c9
-rw-r--r--src/dynarec/la64/dynarec_la64_helper.h24
4 files changed, 145 insertions, 0 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c
index ba441913..e7904928 100644
--- a/src/dynarec/la64/dynarec_la64_00.c
+++ b/src/dynarec/la64/dynarec_la64_00.c
@@ -641,6 +641,15 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     emit_or8c(dyn, ninst, x1, u8, x2, x4, x5);
                     EBBACK();
                     break;
+                case 3: // SBB
+                    INST_NAME("SBB Eb, Ib");
+                    READFLAGS(X_CF);
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    GETEB(x1, 1);
+                    u8 = F8;
+                    emit_sbb8c(dyn, ninst, x1, u8, x2, x4, x5, x6);
+                    EBBACK();
+                    break;
                 case 4: // AND
                     INST_NAME("AND Eb, Ib");
                     SETFLAGS(X_ALL, SF_SET_PENDING);
diff --git a/src/dynarec/la64/dynarec_la64_64.c b/src/dynarec/la64/dynarec_la64_64.c
index 0e7b96d6..892d3290 100644
--- a/src/dynarec/la64/dynarec_la64_64.c
+++ b/src/dynarec/la64/dynarec_la64_64.c
@@ -88,6 +88,81 @@ uintptr_t dynarec64_64(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
         case 0x66:
             addr = dynarec64_6664(dyn, addr, ip, ninst, rex, seg, ok, need_epilog);
             break;
+        case 0x80:
+            nextop = F8;
+            switch ((nextop >> 3) & 7) {
+                case 0: // ADD
+                    INST_NAME("ADD Eb, Ib");
+                    grab_segdata(dyn, addr, ninst, x1, seg);
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    GETEBO(x1, 1);
+                    u8 = F8;
+                    emit_add8c(dyn, ninst, x1, u8, x2, x4, x5);
+                    EBBACK();
+                    break;
+                case 1: // OR
+                    INST_NAME("OR Eb, Ib");
+                    grab_segdata(dyn, addr, ninst, x1, seg);
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    GETEBO(x1, 1);
+                    u8 = F8;
+                    emit_or8c(dyn, ninst, x1, u8, x2, x4, x5);
+                    EBBACK();
+                    break;
+                case 3: // SBB
+                    INST_NAME("SBB Eb, Ib");
+                    grab_segdata(dyn, addr, ninst, x1, seg);
+                    READFLAGS(X_CF);
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    GETEBO(x1, 1);
+                    u8 = F8;
+                    emit_sbb8c(dyn, ninst, x1, u8, x2, x4, x5, x6);
+                    EBBACK();
+                    break;
+                case 4: // AND
+                    INST_NAME("AND Eb, Ib");
+                    grab_segdata(dyn, addr, ninst, x1, seg);
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    GETEBO(x1, 1);
+                    u8 = F8;
+                    emit_and8c(dyn, ninst, x1, u8, x2, x4);
+                    EBBACK();
+                    break;
+                case 5: // SUB
+                    INST_NAME("SUB Eb, Ib");
+                    grab_segdata(dyn, addr, ninst, x1, seg);
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    GETEBO(x1, 1);
+                    u8 = F8;
+                    emit_sub8c(dyn, ninst, x1, u8, x2, x4, x5, x6);
+                    EBBACK();
+                    break;
+                case 6: // XOR
+                    INST_NAME("XOR Eb, Ib");
+                    grab_segdata(dyn, addr, ninst, x1, seg);
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    GETEBO(x1, 1);
+                    u8 = F8;
+                    emit_xor8c(dyn, ninst, x1, u8, x2, x4);
+                    EBBACK();
+                    break;
+                case 7: // CMP
+                    INST_NAME("CMP Eb, Ib");
+                    grab_segdata(dyn, addr, ninst, x1, seg);
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    GETEBO(x1, 1);
+                    u8 = F8;
+                    if (u8) {
+                        MOV32w(x2, u8);
+                        emit_cmp8(dyn, ninst, x1, x2, x3, x4, x5, x6);
+                    } else {
+                        emit_cmp8_0(dyn, ninst, x1, x3, x4);
+                    }
+                    break;
+                default:
+                    DEFAULT;
+            }
+            break;
         case 0x81:
         case 0x83:
             nextop = F8;
@@ -262,6 +337,34 @@ uintptr_t dynarec64_64(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 LDxw(gd, x4, fixedaddress);
             }
             break;
+        case 0xC6:
+            INST_NAME("MOV Seg:Eb, Ib");
+            grab_segdata(dyn, addr, ninst, x4, seg);
+            nextop = F8;
+            if (MODREG) { // reg <= u8
+                u8 = F8;
+                if (!rex.rex) {
+                    ed = (nextop & 7);
+                    eb1 = TO_LA64(ed & 3); // Ax, Cx, Dx or Bx
+                    eb2 = (ed & 4) >> 2;   // L or H
+                } else {
+                    eb1 = TO_LA64((nextop & 7) + (rex.b << 3));
+                    eb2 = 0;
+                }
+                MOV32w(x3, u8);
+                BSTRINS_D(eb1, x3, eb2 * 8 + 7, eb2 * 8);
+            } else { // mem <= u8
+                addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 1);
+                u8 = F8;
+                if (u8) {
+                    ADDI_D(x3, xZR, u8);
+                    ed = x3;
+                } else
+                    ed = xZR;
+                STX_B(x3, wback, x4);
+                SMWRITE2();
+            }
+            break;
         case 0xC7:
             INST_NAME("MOV Seg:Ed, Id");
             grab_segdata(dyn, addr, ninst, x4, seg);
diff --git a/src/dynarec/la64/dynarec_la64_f30f.c b/src/dynarec/la64/dynarec_la64_f30f.c
index 196e386f..333c7b62 100644
--- a/src/dynarec/la64/dynarec_la64_f30f.c
+++ b/src/dynarec/la64/dynarec_la64_f30f.c
@@ -248,6 +248,15 @@ uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
                 VLD(v0, ed, fixedaddress);
             }
             break;
+        case 0x70:
+            INST_NAME("PSHUFHW Gx, Ex, Ib");
+            nextop = F8;
+            GETEX(v1, 0, 1);
+            GETGX(v0, 1);
+            u8 = F8;
+            VSHUF4I_H(v0, v1, u8);
+            VEXTRINS_D(v0, v1, 0); // v0[63:0] = v1[63:0]
+            break;
         case 0x7E:
             INST_NAME("MOVQ Gx, Ex");
             nextop = F8;
diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h
index dd961740..6ebfed29 100644
--- a/src/dynarec/la64/dynarec_la64_helper.h
+++ b/src/dynarec/la64/dynarec_la64_helper.h
@@ -297,6 +297,30 @@
     gd = i;                                                   \
     BSTRPICK_D(gd, gb1, gb2 + 7, gb2);
 
+// GETEBO will use i for ed, i is also Offset, and can use r3 for wback.
+#define GETEBO(i, D)                                                                            \
+    if (MODREG) {                                                                               \
+        if (rex.rex) {                                                                          \
+            wback = TO_LA64((nextop & 7) + (rex.b << 3));                                       \
+            wb2 = 0;                                                                            \
+        } else {                                                                                \
+            wback = (nextop & 7);                                                               \
+            wb2 = (wback >> 2) * 8;                                                             \
+            wback = TO_LA64(wback & 3);                                                         \
+        }                                                                                       \
+        BSTRPICK_D(i, wback, wb2 + 7, wb2);                                                     \
+        wb1 = 0;                                                                                \
+        ed = i;                                                                                 \
+    } else {                                                                                    \
+        SMREAD();                                                                               \
+        addr = geted(dyn, addr, ninst, nextop, &wback, x3, x2, &fixedaddress, rex, NULL, 1, D); \
+        ADD_D(x3, wback, i);                                                                    \
+        if (wback != x3) wback = x3;                                                            \
+        LD_B(i, wback, fixedaddress);                                                           \
+        wb1 = 1;                                                                                \
+        ed = i;                                                                                 \
+    }
+
 // Get GX as a quad (might use x1)
 #define GETGX(a, w)                             \
     gd = ((nextop & 0x38) >> 3) + (rex.r << 3); \