about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <numbksco@gmail.com>2024-09-25 03:10:10 +0800
committerGitHub <noreply@github.com>2024-09-24 21:10:10 +0200
commitc795faf167c5fc455e54228294eb9a38dc0b93e9 (patch)
tree3c617f2b77d59862674f51326716f96a916cb34a /src
parentdad0913dcbe7fd754b7d48dd06af8b93b78e95d1 (diff)
downloadbox64-c795faf167c5fc455e54228294eb9a38dc0b93e9.tar.gz
box64-c795faf167c5fc455e54228294eb9a38dc0b93e9.zip
[LA64_DYNAREC][BOX32] Added more opcodes (#1864)
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/la64/dynarec_la64_00.c97
-rw-r--r--src/dynarec/la64/dynarec_la64_64.c14
2 files changed, 99 insertions, 12 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c
index abbca1e9..3003829f 100644
--- a/src/dynarec/la64/dynarec_la64_00.c
+++ b/src/dynarec/la64/dynarec_la64_00.c
@@ -427,6 +427,32 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             } else
                 emit_cmp32_0(dyn, ninst, rex, xRAX, x3, x4);
             break;
+        case 0x40:
+        case 0x41:
+        case 0x42:
+        case 0x43:
+        case 0x44:
+        case 0x45:
+        case 0x46:
+        case 0x47:
+            INST_NAME("INC Reg (32bits)");
+            SETFLAGS(X_ALL & ~X_CF, SF_SUBSET_PENDING);
+            gd = TO_LA64(opcode & 7);
+            emit_inc32(dyn, ninst, rex, gd, x1, x2, x3, x4);
+            break;
+        case 0x48:
+        case 0x49:
+        case 0x4A:
+        case 0x4B:
+        case 0x4C:
+        case 0x4D:
+        case 0x4E:
+        case 0x4F:
+            INST_NAME("DEC Reg (32bits)");
+            SETFLAGS(X_ALL & ~X_CF, SF_SUBSET_PENDING);
+            gd = TO_LA64(opcode & 7);
+            emit_dec32(dyn, ninst, rex, gd, x1, x2, x3, x4);
+            break;
         case 0x50:
         case 0x51:
         case 0x52:
@@ -740,36 +766,36 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     emit_adc32(dyn, ninst, rex, ed, x5, x3, x4, x6, x1);
                     WBACK;
                     break;
-                case 4: // AND
+                case 3: // SBB
                     if (opcode == 0x81) {
-                        INST_NAME("AND Ed, Id");
+                        INST_NAME("SBB Ed, Id");
                     } else {
-                        INST_NAME("AND Ed, Ib");
+                        INST_NAME("SBB Ed, Ib");
                     }
+                    READFLAGS(X_CF);
                     SETFLAGS(X_ALL, SF_SET_PENDING);
                     GETED((opcode == 0x81) ? 4 : 1);
                     if (opcode == 0x81)
                         i64 = F32S;
                     else
                         i64 = F8S;
-                    emit_and32c(dyn, ninst, rex, ed, i64, x3, x4);
+                    MOV64xw(x5, i64);
+                    emit_sbb32(dyn, ninst, rex, ed, x5, x3, x4, x6);
                     WBACK;
                     break;
-                case 3: // SBB
+                case 4: // AND
                     if (opcode == 0x81) {
-                        INST_NAME("SBB Ed, Id");
+                        INST_NAME("AND Ed, Id");
                     } else {
-                        INST_NAME("SBB Ed, Ib");
+                        INST_NAME("AND Ed, Ib");
                     }
-                    READFLAGS(X_CF);
                     SETFLAGS(X_ALL, SF_SET_PENDING);
                     GETED((opcode == 0x81) ? 4 : 1);
                     if (opcode == 0x81)
                         i64 = F32S;
                     else
                         i64 = F8S;
-                    MOV64xw(x5, i64);
-                    emit_sbb32(dyn, ninst, rex, ed, x5, x3, x4, x6);
+                    emit_and32c(dyn, ninst, rex, ed, i64, x3, x4);
                     WBACK;
                     break;
                 case 5: // SUB
@@ -825,8 +851,6 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         emit_cmp32_0(dyn, ninst, rex, ed, x3, x4);
                     }
                     break;
-                default:
-                    DEFAULT;
             }
             break;
         case 0x84:
@@ -1065,6 +1089,26 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 BSTRPICK_D(xRDX, xRDX, 31, 0);
             }
             break;
+        case 0x9C:
+            INST_NAME("PUSHF");
+            READFLAGS(X_ALL);
+            PUSH1z(xFlags);
+            break;
+        case 0x9D:
+            INST_NAME("POPF");
+            SETFLAGS(X_ALL, SF_SET);
+            POP1z(xFlags);
+            MOV32w(x1, 0x3F7FD7);
+            AND(xFlags, xFlags, x1);
+            ORI(xFlags, xFlags, 0x202);
+            SET_DFNONE();
+            if (box64_wine) { // should this be done all the time?
+                ANDI(x1, xFlags, 1 << F_TF);
+                CBZ_NEXT(x1);
+                // go to epilog, TF should trigger at end of next opcode, so using Interpreter only
+                jump_to_epilog(dyn, addr, 0, ninst);
+            }
+            break;
         case 0xA0:
             INST_NAME("MOV AL,Ob");
             if (rex.is32bits)
@@ -1075,6 +1119,35 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             LD_BU(x2, x1, 0);
             BSTRINS_D(xRAX, x2, 7, 0);
             break;
+        case 0xA1:
+            INST_NAME("MOV EAX, Od");
+            if (rex.is32bits)
+                u64 = F32;
+            else
+                u64 = F64;
+            MOV64z(x1, u64);
+            LDxw(xRAX, x1, 0);
+            break;
+        case 0xA2:
+            INST_NAME("MOV Ob, AL");
+            if (rex.is32bits)
+                u64 = F32;
+            else
+                u64 = F64;
+            MOV64z(x1, u64);
+            ST_B(xRAX, x1, 0);
+            SMWRITE();
+            break;
+        case 0xA3:
+            INST_NAME("MOV Od, EAX");
+            if (rex.is32bits)
+                u64 = F32;
+            else
+                u64 = F64;
+            MOV64z(x1, u64);
+            SDxw(xRAX, x1, 0);
+            SMWRITE();
+            break;
         case 0xA4:
             if (rep) {
                 INST_NAME("REP MOVSB");
diff --git a/src/dynarec/la64/dynarec_la64_64.c b/src/dynarec/la64/dynarec_la64_64.c
index 677b1633..0753c11c 100644
--- a/src/dynarec/la64/dynarec_la64_64.c
+++ b/src/dynarec/la64/dynarec_la64_64.c
@@ -349,6 +349,20 @@ uintptr_t dynarec64_64(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 }
             }
             break;
+        case 0xA1:
+            INST_NAME("MOV EAX, FS:Od");
+            grab_segdata(dyn, addr, ninst, x4, seg);
+            if (rex.is32bits)
+                u64 = F32;
+            else
+                u64 = F64;
+            MOV64z(x1, u64);
+            if (rex.is32bits) {
+                ADDz(x4, x1, x4);
+                LDxw(xRAX, x4, 0);
+            } else
+                LDXxw(xRAX, x4, x1);
+            break;
         case 0xC6:
             INST_NAME("MOV Seg:Eb, Ib");
             grab_segdata(dyn, addr, ninst, x4, seg);