about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <numbksco@gmail.com>2024-04-12 19:55:46 +0800
committerGitHub <noreply@github.com>2024-04-12 13:55:46 +0200
commit139197230d19e99122abc141fabb0fcafcd01767 (patch)
treedb992a8a8e5100477dfac6e642b3fb83b9777f72 /src
parent1d0e0307c4f2279803a1aa57533c45c6edeea12a (diff)
downloadbox64-139197230d19e99122abc141fabb0fcafcd01767.tar.gz
box64-139197230d19e99122abc141fabb0fcafcd01767.zip
[LA64_DYNAREC] Added more opcodes and fixed more issues (#1439)
* Added F3 0F 10 MOVSS opcodes

* Added F3 0F 2A CVTSI2SS opcode

* Added F3 0F 5E opcode

* Added F3 0F 11 MOVSS opcode

* Added 0C OR opcode

* Added F3 0F 59 MULSS opcode

* Added 81,83 /3 SBB opcode

* Fixed 2 typos
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/la64/dynarec_la64_00.c37
-rw-r--r--src/dynarec/la64/dynarec_la64_emit_math.c8
-rw-r--r--src/dynarec/la64/dynarec_la64_f30f.c63
-rw-r--r--src/dynarec/la64/dynarec_la64_helper.h11
4 files changed, 113 insertions, 6 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c
index bf9722f6..f4987cc6 100644
--- a/src/dynarec/la64/dynarec_la64_00.c
+++ b/src/dynarec/la64/dynarec_la64_00.c
@@ -128,6 +128,14 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             GETED(0);
             emit_or32(dyn, ninst, rex, gd, ed, x3, x4);
             break;
+        case 0x0C:
+            INST_NAME("OR AL, Ib");
+            SETFLAGS(X_ALL, SF_SET_PENDING);
+            u8 = F8;
+            ANDI(x1, xRAX, 0xff);
+            emit_or8c(dyn, ninst, x1, u8, x3, x4, x5);
+            BSTRINS_D(xRAX, x1, 7, 0);
+            break;
         case 0x0D:
             INST_NAME("OR EAX, Id");
             SETFLAGS(X_ALL, SF_SET_PENDING);
@@ -593,7 +601,11 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     WBACK;
                     break;
                 case 1: // OR
-                    if (opcode == 0x81) { INST_NAME("OR Ed, Id"); } else { INST_NAME("OR Ed, Ib"); }
+                    if (opcode == 0x81) {
+                        INST_NAME("OR Ed, Id");
+                    } else {
+                        INST_NAME("OR Ed, Ib");
+                    }
                     SETFLAGS(X_ALL, SF_SET_PENDING);
                     GETED((opcode == 0x81) ? 4 : 1);
                     if (opcode == 0x81) i64 = F32S; else i64 = F8S;
@@ -601,13 +613,34 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     WBACK;
                     break;
                 case 4: // AND
-                    if (opcode == 0x81) { INST_NAME("AND Ed, Id"); } else { INST_NAME("AND Ed, Ib"); }
+                    if (opcode == 0x81) {
+                        INST_NAME("AND Ed, Id");
+                    } else {
+                        INST_NAME("AND Ed, Ib");
+                    }
                     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);
                     WBACK;
                     break;
+                case 3: // SBB
+                    if (opcode == 0x81) {
+                        INST_NAME("SBB Ed, Id");
+                    } else {
+                        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;
+                    MOV64xw(x5, i64);
+                    emit_sbb32(dyn, ninst, rex, ed, x5, x3, x4, x6);
+                    WBACK;
+                    break;
                 case 5: // SUB
                     if (opcode == 0x81) {
                         INST_NAME("SUB Ed, Id");
diff --git a/src/dynarec/la64/dynarec_la64_emit_math.c b/src/dynarec/la64/dynarec_la64_emit_math.c
index 2e670bf4..ca26ecc8 100644
--- a/src/dynarec/la64/dynarec_la64_emit_math.c
+++ b/src/dynarec/la64/dynarec_la64_emit_math.c
@@ -536,9 +536,9 @@ void emit_sub32c(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, i
         IFX(X_PEND) {} else {MOV64xw(s2, c);}
         IFX(X_ALL) {
             if (rex.w) {
-                X64_SUB_WU(s1, s2);
-            } else {
                 X64_SUB_DU(s1, s2);
+            } else {
+                X64_SUB_WU(s1, s2);
             }
         }
         SUBxw(s1, s1, s2);
@@ -664,9 +664,9 @@ void emit_sbb32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
 
     if (la64_lbt) {
         if (rex.w) {
-            SBC_W(s3, s1, s2);
-        } else {
             SBC_D(s3, s1, s2);
+        } else {
+            SBC_W(s3, s1, s2);
         }
         IFX (X_ALL) {
             if (rex.w)
diff --git a/src/dynarec/la64/dynarec_la64_f30f.c b/src/dynarec/la64/dynarec_la64_f30f.c
index f406dead..47670a31 100644
--- a/src/dynarec/la64/dynarec_la64_f30f.c
+++ b/src/dynarec/la64/dynarec_la64_f30f.c
@@ -48,11 +48,74 @@ uintptr_t dynarec64_F30F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int
     MAYUSE(j64);
 
     switch (opcode) {
+        case 0x10:
+            INST_NAME("MOVSS Gx, Ex");
+            nextop = F8;
+            GETG;
+            if(MODREG) {
+                v0 = sse_get_reg(dyn, ninst, x1, gd, 1);
+                v1 = sse_get_reg(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 0);
+            } else {
+                v0 = sse_get_reg_empty(dyn, ninst, x1, gd);
+                v1 = fpu_get_scratch(dyn);
+                SMREAD();
+                addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0);
+                VXOR_V(v0, v0, v0);
+                FLD_S(v1, ed, fixedaddress);
+            }
+            VEXTRINS_W(v0, v1, 0);
+            break;
+        case 0x11:
+            INST_NAME("MOVSS Ex, Gx");
+            nextop = F8;
+            GETG;
+            v0 = sse_get_reg(dyn, ninst, x1, gd, 0);
+            if (MODREG) {
+                q0 = sse_get_reg(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), 1);
+                VEXTRINS_W(q0, v0, 0);
+            } else {
+                addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, 0);
+                FST_S(v0, ed, fixedaddress);
+                SMWRITE2();
+            }
+            break;
         case 0x1E:
             INST_NAME("NOP / ENDBR32 / ENDBR64");
             nextop = F8;
             FAKEED;
             break;
+        case 0x2A:
+            INST_NAME("CVTSI2SS Gx, Ed");
+            nextop = F8;
+            GETGX(v0, 1);
+            GETED(0);
+            d1 = fpu_get_scratch(dyn);
+            MOVGR2FR_D(d1, ed);
+            if(rex.w) {
+                FFINT_S_L(d1, d1);
+            } else {
+                FFINT_S_W(d1, d1);
+            }
+            VEXTRINS_W(v0, d1, 0);
+            break;
+        case 0x59:
+            INST_NAME("MULSS Gx, Ex");
+            nextop = F8;
+            GETGX(v0, 1);
+            d1 = fpu_get_scratch(dyn);
+            GETEXSS(d0, 0, 0);
+            FMUL_S(d1, v0, d0);
+            VEXTRINS_W(v0, d1, 0);
+            break;
+        case 0x5E:
+            INST_NAME("DIVSS Gx, Ex");
+            nextop = F8;
+            GETGX(v0, 1);
+            d1 = fpu_get_scratch(dyn);
+            GETEXSS(d0, 0, 0);
+            FDIV_S(d1, v0, d0);
+            VEXTRINS_W(v0, d1, 0);
+            break;
         case 0x6F:
             INST_NAME("MOVDQU Gx, Ex");
             nextop = F8;
diff --git a/src/dynarec/la64/dynarec_la64_helper.h b/src/dynarec/la64/dynarec_la64_helper.h
index bf5e5abb..d5089d40 100644
--- a/src/dynarec/la64/dynarec_la64_helper.h
+++ b/src/dynarec/la64/dynarec_la64_helper.h
@@ -271,6 +271,17 @@
         FLD_D(a, ed, fixedaddress);                                                            \
     }
 
+// Get Ex as a single, not a quad (warning, x1 get used)
+#define GETEXSS(a, w, D)                                                                     \
+    if (MODREG) {                                                                            \
+        a = sse_get_reg(dyn, ninst, x1, (nextop & 7) + (rex.b << 3), w);                     \
+    } else {                                                                                 \
+        SMREAD();                                                                            \
+        a = fpu_get_scratch(dyn);                                                            \
+        addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 1, D); \
+        FLD_S(a, ed, fixedaddress);                                                          \
+    }
+
 // Write gb (gd) back to original register / memory, using s1 as scratch
 #define GBBACK() BSTRINS_D(gb1, gd, gb2 + 7, gb2);