about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <numbksco@gmail.com>2024-04-06 14:49:37 +0800
committerGitHub <noreply@github.com>2024-04-06 08:49:37 +0200
commit2a75d283867fc7a09b53a3a446989cf1b1b9998d (patch)
treeb7ec427141179ddbceacf7a2c03db03b9be33b20 /src
parent3e412891674af3d4eb77675853c1f10715dfabce (diff)
downloadbox64-2a75d283867fc7a09b53a3a446989cf1b1b9998d.tar.gz
box64-2a75d283867fc7a09b53a3a446989cf1b1b9998d.zip
[LA64_DYNAREC] Fixed missing LBT path and more (#1419)
* [LA64_DYNAREC] Fixed missing LBT path and more

* Fixed D3 /4/6 SHL opcode

* LA64 qemu is not stable too
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/la64/dynarec_la64_00.c22
-rw-r--r--src/dynarec/la64/dynarec_la64_0f.c18
-rw-r--r--src/dynarec/la64/dynarec_la64_emit_shift.c1
3 files changed, 25 insertions, 16 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c
index 6940839d..69394021 100644
--- a/src/dynarec/la64/dynarec_la64_00.c
+++ b/src/dynarec/la64/dynarec_la64_00.c
@@ -332,25 +332,25 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             break;
             break;
         case 0x63:
-            if(rex.is32bits) {
+            if (rex.is32bits) {
                 // this is ARPL opcode
                 DEFAULT;
             } else {
                 INST_NAME("MOVSXD Gd, Ed");
                 nextop = F8;
                 GETGD;
-                if(rex.w) {
-                    if(MODREG) {   // reg <= reg
-                        ADDI_W(gd, TO_LA64((nextop&7)+(rex.b<<3)), 0);
-                    } else {                    // mem <= reg
+                if (rex.w) {
+                    if (MODREG) { // reg <= reg
+                        ADDI_W(gd, TO_LA64((nextop & 7) + (rex.b << 3)), 0);
+                    } else { // mem <= reg
                         SMREAD();
                         addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
                         LD_W(gd, ed, fixedaddress);
                     }
                 } else {
-                    if(MODREG) {   // reg <= reg
-                        AND(gd, xRAX+(nextop&7)+(rex.b<<3), xMASK);
-                    } else {                    // mem <= reg
+                    if (MODREG) { // reg <= reg
+                        AND(gd, TO_LA64((nextop & 7) + (rex.b << 3)), xMASK);
+                    } else { // mem <= reg
                         SMREAD();
                         addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
                         LD_WU(gd, ed, fixedaddress);
@@ -1038,10 +1038,10 @@ uintptr_t dynarec64_00(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 case 4:
                 case 6:
                     INST_NAME("SHL Ed, CL");
-                    SETFLAGS(X_ALL, SF_SET_PENDING);    // some flags are left undefined
-                    ANDI(x3, xRCX, rex.w?0x3f:0x1f);
+                    SETFLAGS(X_ALL, SF_SET_PENDING); // some flags are left undefined
+                    ANDI(x3, xRCX, rex.w ? 0x3f : 0x1f);
                     GETED(0);
-                    if(!rex.w && MODREG) { ZEROUP(ed); }
+                    if (!rex.w && MODREG) { ZEROUP(ed); }
                     CBZ_NEXT(x3);
                     emit_shl32(dyn, ninst, rex, ed, x3, x5, x4, x6);
                     WBACK;
diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c
index ef466ea8..c6879562 100644
--- a/src/dynarec/la64/dynarec_la64_0f.c
+++ b/src/dynarec/la64/dynarec_la64_0f.c
@@ -279,7 +279,10 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             }
             ANDI(x2, gd, rex.w ? 0x3f : 0x1f);
             SRLIxw(x4, ed, x2);
-            BSTRINS_D(xFlags, x4, F_CF, F_CF);
+            if (la64_lbt)
+                X64_SET_EFLAGS(x4, X_CF);
+            else
+                BSTRINS_D(xFlags, x4, F_CF, F_CF);
             break;
         case 0xAF:
             INST_NAME("IMUL Gd, Ed");
@@ -294,6 +297,9 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             if (rex.w) {
                 // 64bits imul
                 UFLAG_IF {
+                    if (la64_lbt) {
+                        X64_MUL_D(gd, ed);
+                    }
                     MULH_D(x3, gd, ed);
                     MUL_D(gd, gd, ed);
                     IFX (X_PEND) {
@@ -303,7 +309,7 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     } else {
                         SET_DFNONE();
                     }
-                    IFX (X_CF | X_OF) {
+                    IFXA (X_CF | X_OF, !la64_lbt) {
                         SRAI_D(x4, gd, 63);
                         XOR(x3, x3, x4);
                         SNEZ(x3, x3);
@@ -320,6 +326,9 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             } else {
                 // 32bits imul
                 UFLAG_IF {
+                    if (la64_lbt) {
+                        X64_MUL_W(gd, ed);
+                    }
                     MUL_D(gd, gd, ed);
                     SRLI_D(x3, gd, 32);
                     SLLI_W(gd, gd, 0);
@@ -330,7 +339,7 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     } else IFX (X_CF | X_OF) {
                         SET_DFNONE();
                     }
-                    IFX (X_CF | X_OF) {
+                    IFXA (X_CF | X_OF, !la64_lbt) {
                         SRAI_W(x4, gd, 31);
                         SUB_D(x3, x3, x4);
                         SNEZ(x3, x3);
@@ -344,8 +353,7 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 } else {
                     MULxw(gd, gd, ed);
                 }
-                SLLI_D(gd, gd, 32);
-                SRLI_D(gd, gd, 32);
+                ZEROUP(gd);
             }
             break;
         case 0xB6:
diff --git a/src/dynarec/la64/dynarec_la64_emit_shift.c b/src/dynarec/la64/dynarec_la64_emit_shift.c
index dff76a5a..377250d5 100644
--- a/src/dynarec/la64/dynarec_la64_emit_shift.c
+++ b/src/dynarec/la64/dynarec_la64_emit_shift.c
@@ -41,6 +41,7 @@ void emit_shl32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
                 X64_SLL_W(s1, s2);
         }
         SLL_D(s1, s1, s2);
+        if (!rex.w) { ZEROUP(s1); }
         IFX(X_PEND) {
             SDxw(s1, xEmu, offsetof(x64emu_t, res));
         }