about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorLeslie Zhai <zhaixiang@loongson.cn>2024-11-26 15:27:13 +0800
committerGitHub <noreply@github.com>2024-11-26 08:27:13 +0100
commitb207ecad6a35b43649496db5ea6e3042c773f1ac (patch)
tree03487af1e9411cdac866c35ea5cb8e71a2aa9845 /src
parent48461001d2ecf5f7f5c99a8c2be414761e298841 (diff)
downloadbox64-b207ecad6a35b43649496db5ea6e3042c773f1ac.tar.gz
box64-b207ecad6a35b43649496db5ea6e3042c773f1ac.zip
[LA64_DYNAREC] Added SBB opcodes (#2076)
* [LA64_DYNAREC] Added SBB opcodes

* [LA64_DYNAREC] clang-format and fix LOCK ADC wrong ed
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/la64/dynarec_la64_00.c18
-rw-r--r--src/dynarec/la64/dynarec_la64_66.c37
-rw-r--r--src/dynarec/la64/dynarec_la64_67.c37
-rw-r--r--src/dynarec/la64/dynarec_la64_f0.c2
-rw-r--r--src/dynarec/la64/dynarec_la64_helper.h22
5 files changed, 115 insertions, 1 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c
index c1ac8fa0..ab786d7b 100644
--- a/src/dynarec/la64/dynarec_la64_00.c
+++ b/src/dynarec/la64/dynarec_la64_00.c
@@ -243,6 +243,16 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             emit_sbb32(dyn, ninst, rex, ed, gd, x3, x4, x5);
             WBACK;
             break;
+        case 0x1A:
+            INST_NAME("SBB Gb, Eb");
+            READFLAGS(X_CF);
+            SETFLAGS(X_ALL, SF_SET_PENDING);
+            nextop = F8;
+            GETEB(x2, 0);
+            GETGB(x1);
+            emit_sbb8(dyn, ninst, x1, x2, x6, x4, x5);
+            GBBACK();
+            break;
         case 0x1B:
             INST_NAME("SBB Gd, Ed");
             READFLAGS(X_CF);
@@ -261,6 +271,14 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             emit_sbb8c(dyn, ninst, x1, u8, x3, x4, x5, x6);
             BSTRINS_D(xRAX, x1, 7, 0);
             break;
+        case 0x1D:
+            INST_NAME("SBB EAX, Id");
+            READFLAGS(X_CF);
+            SETFLAGS(X_ALL, SF_SET_PENDING);
+            i64 = F32S;
+            MOV64xw(x2, i64);
+            emit_sbb32(dyn, ninst, rex, xRAX, x2, x3, x4, x5);
+            break;
         case 0x20:
             INST_NAME("AND Eb, Gb");
             SETFLAGS(X_ALL, SF_SET_PENDING);
diff --git a/src/dynarec/la64/dynarec_la64_66.c b/src/dynarec/la64/dynarec_la64_66.c
index d720b4cf..b23a13ac 100644
--- a/src/dynarec/la64/dynarec_la64_66.c
+++ b/src/dynarec/la64/dynarec_la64_66.c
@@ -159,6 +159,26 @@ uintptr_t dynarec64_66(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             emit_sbb16(dyn, ninst, x1, x2, x4, x5, x6);
             EWBACK;
             break;
+        case 0x1B:
+            INST_NAME("SBB Gw, Ew");
+            READFLAGS(X_CF);
+            SETFLAGS(X_ALL, SF_SET_PENDING);
+            nextop = F8;
+            GETGW(x1);
+            GETEW(x2, 0);
+            emit_sbb16(dyn, ninst, x1, x2, x6, x4, x5);
+            GWBACK;
+            break;
+        case 0x1D:
+            INST_NAME("SBB AX, Iw");
+            READFLAGS(X_CF);
+            SETFLAGS(X_ALL, SF_SET_PENDING);
+            BSTRPICK_D(x1, xRAX, 15, 0);
+            u64 = F16;
+            MOV64x(x2, u64);
+            emit_sbb16(dyn, ninst, x1, x2, x3, x4, x5);
+            BSTRINSz(xRAX, x1, 15, 0);
+            break;
         case 0x21:
             INST_NAME("AND Ew, Gw");
             SETFLAGS(X_ALL, SF_SET_PENDING);
@@ -342,6 +362,23 @@ uintptr_t dynarec64_66(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     emit_adc16(dyn, ninst, x1, x5, x2, x4, x6);
                     EWBACK;
                     break;
+                case 3: // SBB
+                    if (opcode == 0x81) {
+                        INST_NAME("SBB Ew, Iw");
+                    } else {
+                        INST_NAME("SBB Ew, Ib");
+                    }
+                    READFLAGS(X_CF);
+                    SETFLAGS(X_ALL, SF_SET_PENDING);
+                    GETEW(x1, (opcode == 0x81) ? 2 : 1);
+                    if (opcode == 0x81)
+                        u64 = F16;
+                    else
+                        u64 = (uint16_t)(int16_t)F8S;
+                    MOV64x(x5, u64);
+                    emit_sbb16(dyn, ninst, x1, x5, x2, x4, x6);
+                    EWBACK;
+                    break;
                 case 4: // AND
                     if (opcode == 0x81) {
                         INST_NAME("AND Ew, Iw");
diff --git a/src/dynarec/la64/dynarec_la64_67.c b/src/dynarec/la64/dynarec_la64_67.c
index 0d69d45a..969c448b 100644
--- a/src/dynarec/la64/dynarec_la64_67.c
+++ b/src/dynarec/la64/dynarec_la64_67.c
@@ -62,6 +62,43 @@ uintptr_t dynarec64_67(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
     }
 
     switch(opcode) {
+        case 0x19:
+            INST_NAME("SBB Ed, Gd");
+            READFLAGS(X_CF);
+            SETFLAGS(X_ALL, SF_SET_PENDING);
+            nextop = F8;
+            GETGD;
+            GETED32(0);
+            emit_sbb32(dyn, ninst, rex, ed, gd, x3, x4, x5);
+            WBACK;
+            break;
+        case 0x1A:
+            INST_NAME("SBB Gb, Eb");
+            READFLAGS(X_CF);
+            SETFLAGS(X_ALL, SF_SET_PENDING);
+            nextop = F8;
+            GETEB32(x2, 0);
+            GETGB(x1);
+            emit_sbb8(dyn, ninst, x1, x2, x3, x4, x5);
+            GBBACK();
+            break;
+        case 0x1B:
+            INST_NAME("SBB Gd, Ed");
+            READFLAGS(X_CF);
+            SETFLAGS(X_ALL, SF_SET_PENDING);
+            nextop = F8;
+            GETGD;
+            GETED32(0);
+            emit_sbb32(dyn, ninst, rex, gd, ed, x3, x4, x5);
+            break;
+        case 0x1D:
+            INST_NAME("SBB EAX, Id");
+            READFLAGS(X_CF);
+            SETFLAGS(X_ALL, SF_SET_PENDING);
+            i64 = F32S;
+            MOV64xw(x2, i64);
+            emit_sbb32(dyn, ninst, rex, xRAX, x2, x3, x4, x5);
+            break;
         case 0x88:
             INST_NAME("MOV Eb, Gb");
             nextop = F8;
diff --git a/src/dynarec/la64/dynarec_la64_f0.c b/src/dynarec/la64/dynarec_la64_f0.c
index c92e9406..994cd0b5 100644
--- a/src/dynarec/la64/dynarec_la64_f0.c
+++ b/src/dynarec/la64/dynarec_la64_f0.c
@@ -410,7 +410,7 @@ uintptr_t dynarec64_F0(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             GETGD;
             SMDMB();
             if (MODREG) {
-                ed = xRAX + (nextop & 7) + (rex.b << 3);
+                ed = TO_LA64((nextop & 7) + (rex.b << 3));
                 emit_adc32(dyn, ninst, rex, ed, gd, x3, x4, x5, x6);
             } else {
                 addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0);
diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h
index 12ebe679..d66b6be8 100644
--- a/src/dynarec/la64/dynarec_la64_helper.h
+++ b/src/dynarec/la64/dynarec_la64_helper.h
@@ -250,6 +250,28 @@
         wb1 = 1;                                                                                \
         ed = i;                                                                                 \
     }
+// GETEB32 will use i for ed, and can use r3 for wback.
+#define GETEB32(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 = geted32(dyn, addr, ninst, nextop, &wback, x3, x2, &fixedaddress, rex, NULL, 1, D); \
+        LD_BU(i, wback, fixedaddress);                                                            \
+        wb1 = 1;                                                                                  \
+        ed = i;                                                                                   \
+    }
+
 // GETGB will use i for gd
 #define GETGB(i)                                              \
     if (rex.rex) {                                            \