about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorYang Liu <numbksco@gmail.com>2024-06-02 02:08:33 +0800
committerGitHub <noreply@github.com>2024-06-01 20:08:33 +0200
commitcf37e8ea833355e1e2099696d1dde2588db6e069 (patch)
tree540528236dda4e592c128ff8532162e75662cdb4
parent5384489702d31ad9b74fc852ed953294e892d992 (diff)
downloadbox64-cf37e8ea833355e1e2099696d1dde2588db6e069.tar.gz
box64-cf37e8ea833355e1e2099696d1dde2588db6e069.zip
[LA64_DYNAREC] Added more opcodes and fixed ADC opcode (#1548)
-rw-r--r--src/dynarec/la64/dynarec_la64_00.c31
-rw-r--r--src/dynarec/la64/dynarec_la64_0f.c46
-rw-r--r--src/dynarec/la64/dynarec_la64_emit_math.c9
3 files changed, 67 insertions, 19 deletions
diff --git a/src/dynarec/la64/dynarec_la64_00.c b/src/dynarec/la64/dynarec_la64_00.c
index 586d2392..51818d83 100644
--- a/src/dynarec/la64/dynarec_la64_00.c
+++ b/src/dynarec/la64/dynarec_la64_00.c
@@ -1022,6 +1022,37 @@ 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 0xA4:
+            if (rep) {
+                INST_NAME("REP MOVSB");
+                CBZ_NEXT(xRCX);
+                ANDI(x1, xFlags, 1 << F_DF);
+                BNEZ_MARK2(x1);
+                MARK; // Part with DF==0
+                LD_BU(x1, xRSI, 0);
+                ST_B(x1, xRDI, 0);
+                ADDI_D(xRSI, xRSI, 1);
+                ADDI_D(xRDI, xRDI, 1);
+                ADDI_D(xRCX, xRCX, -1);
+                BNEZ_MARK(xRCX);
+                B_NEXT_nocond;
+                MARK2; // Part with DF==1
+                LD_BU(x1, xRSI, 0);
+                ST_B(x1, xRDI, 0);
+                ADDI_D(xRSI, xRSI, -1);
+                ADDI_D(xRDI, xRDI, -1);
+                ADDI_D(xRCX, xRCX, -1);
+                BNEZ_MARK2(xRCX);
+                // done
+            } else {
+                INST_NAME("MOVSB");
+                GETDIR(x3, x1, 1);
+                LD_BU(x1, xRSI, 0);
+                ST_B(x1, xRDI, 0);
+                ADD_D(xRSI, xRSI, x3);
+                ADD_D(xRDI, xRDI, x3);
+            }
+            break;
         case 0xA5:
             if (rep) {
                 INST_NAME("REP MOVSD");
diff --git a/src/dynarec/la64/dynarec_la64_0f.c b/src/dynarec/la64/dynarec_la64_0f.c
index cf5db94b..7255c32e 100644
--- a/src/dynarec/la64/dynarec_la64_0f.c
+++ b/src/dynarec/la64/dynarec_la64_0f.c
@@ -66,21 +66,12 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             if(MODREG) {
                 switch(nextop) {
                     case 0xD0:
-                        //TODO
-                        DEFAULT;
-                        /*
-                        INST_NAME("FAKE xgetbv");
-                        nextop = F8;
-                        addr = fakeed(dyn, addr, ninst, nextop);
-                        SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state
-                        GETIP(ip);
-                        STORE_XEMU_CALL();
-                        CALL(native_ud, -1);
-                        LOAD_XEMU_CALL();
-                        jump_to_epilog(dyn, 0, xRIP, ninst);
-                        *need_epilog = 0;
-                        *ok = 0;
-                        */
+                        INST_NAME("XGETBV");
+                        BEQZ_MARK(xRCX);
+                        EMIT(0); // Is there any assigned illegal instruction?
+                        MARK;
+                        MOV32w(xRAX, 0b111);
+                        MOV32w(xRDX, 0);
                         break;
                     default:
                         DEFAULT;
@@ -544,6 +535,31 @@ uintptr_t dynarec64_0F(dynarec_la64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             else
                 BSTRINS_D(xFlags, x4, F_CF, F_CF);
             break;
+        case 0xAE:
+            nextop = F8;
+            if (MODREG)
+                switch (nextop) {
+                    case 0xE8:
+                        INST_NAME("LFENCE");
+                        SMDMB();
+                        break;
+                    case 0xF0:
+                        INST_NAME("MFENCE");
+                        SMDMB();
+                        break;
+                    case 0xF8:
+                        INST_NAME("SFENCE");
+                        SMDMB();
+                        break;
+                    default:
+                        DEFAULT;
+                }
+            else
+                switch ((nextop >> 3) & 7) {
+                    default:
+                        DEFAULT;
+                }
+            break;
         case 0xAF:
             INST_NAME("IMUL Gd, Ed");
             SETFLAGS(X_ALL, SF_PENDING);
diff --git a/src/dynarec/la64/dynarec_la64_emit_math.c b/src/dynarec/la64/dynarec_la64_emit_math.c
index ad205467..b2caede0 100644
--- a/src/dynarec/la64/dynarec_la64_emit_math.c
+++ b/src/dynarec/la64/dynarec_la64_emit_math.c
@@ -1037,16 +1037,17 @@ void emit_adc32(dynarec_la64_t* dyn, int ninst, rex_t rex, int s1, int s2, int s
     }
 
     if (la64_lbt) {
+        if (rex.w)
+            ADC_D(s1, s1, s2);
+        else
+            ADC_W(s1, s1, s2);
+
         IFX (X_ALL) {
             if (rex.w)
                 X64_ADC_D(s1, s2);
             else
                 X64_ADC_W(s1, s2);
         }
-        if (rex.w)
-            ADC_D(s1, s1, s2);
-        else
-            ADC_W(s1, s1, s2);
 
         IFX (X_PEND) {
             SDxw(s1, xEmu, offsetof(x64emu_t, res));