about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <numbksco@gmail.com>2023-06-27 21:18:44 +0800
committerGitHub <noreply@github.com>2023-06-27 15:18:44 +0200
commit3b9772471724e663acc29fa22d466486a7539071 (patch)
tree985a459d8b765667baf41c483370b55454d45f53 /src
parent144db5f07f8ff2754cc78e99a71262fad1d711e0 (diff)
downloadbox64-3b9772471724e663acc29fa22d466486a7539071.tar.gz
box64-3b9772471724e663acc29fa22d466486a7539071.zip
[32BITS][RV64_DYNAREC] Hanlding of STll struct in FILD/FISTP (#868)
* [32BITS][RV64_DYNAREC] Hanlding of STll struct in FILD/FISTP

* Fixed 0F B3 BTR
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f.c10
-rw-r--r--src/dynarec/rv64/dynarec_rv64_df.c41
-rw-r--r--src/emu/x64test.c6
3 files changed, 47 insertions, 10 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c
index 3074dd5b..5c8d7b81 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f.c
@@ -1091,7 +1091,7 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 wback = 0;
             } else {
                 SMREAD();
-                addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0);
+                addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, NULL, 1, 0);
                 SRAI(x1, gd, 5+rex.w);
                 SLLI(x1, x1, 2+rex.w);
                 ADD(x3, wback, x1);
@@ -1108,10 +1108,10 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
             ANDI(x4, x4, 1); // F_CF is 1
             ANDI(xFlags, xFlags, ~1);
             OR(xFlags, xFlags, x4);
-            ADDI(x3, xZR, 1);
-            SLL(x3, x3, x2);
-            NOT(x3, x3);
-            AND(ed, ed, x3);
+            ADDI(x5, xZR, 1);
+            SLL(x5, x5, x2);
+            NOT(x5, x5);
+            AND(ed, ed, x5);
             if(wback) {
                 SDxw(ed, wback, fixedaddress);
                 SMWRITE();
diff --git a/src/dynarec/rv64/dynarec_rv64_df.c b/src/dynarec/rv64/dynarec_rv64_df.c
index 9dcc9500..de99b02a 100644
--- a/src/dynarec/rv64/dynarec_rv64_df.c
+++ b/src/dynarec/rv64/dynarec_rv64_df.c
@@ -175,19 +175,54 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     v1 = x87_do_push(dyn, ninst, x1, EXT_CACHE_ST_D);
                     addr = geted(dyn, addr, ninst, nextop, &wback, x2, x3, &fixedaddress, rex, NULL, 1, 0);
                     LD(x1, wback, fixedaddress);
+                    if (rex.is32bits) {
+                        // need to also feed the STll stuff...
+                        ADDI(x4, xEmu, offsetof(x64emu_t, fpu_ll));
+                        LWU(x5, xEmu, offsetof(x64emu_t, top));
+                        int a = 0 - dyn->e.x87stack;
+                        if(a) {
+                            ADDIW(x5, x5, a);
+                            ANDI(x5, x5, 0x7);
+                        }
+                        SLLI(x5, x5, 4); // fpu_ll is 2 i64
+                        ADD(x5, x5, x4);
+                        SD(x1, x5, 8);   // ll
+                    }
                     FCVTDL(v1, x1, RD_RTZ);
+                    if(rex.is32bits) {
+                        FSD(v1, x5, 0);  // ref
+                    }
                     break;
                 case 7:
                     INST_NAME("FISTP i64, ST0");
                     v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D);
                     u8 = x87_setround(dyn, ninst, x1, x2);
                     addr = geted(dyn, addr, ninst, nextop, &wback, x2, x3, &fixedaddress, rex, NULL, 1, 0);
-                    v2 = fpu_get_scratch(dyn);
+
+                    if(rex.is32bits) {
+                        // need to check STll first...
+                        ADDI(x4, xEmu, offsetof(x64emu_t, fpu_ll));
+                        LWU(x5, xEmu, offsetof(x64emu_t, top));
+                        int a = 0 - dyn->e.x87stack;
+                        if(a) {
+                            ADDIW(x5, x5, a);
+                            ANDI(x5, x5, 0x7);
+                        }
+                        SLLI(x5, x5, 4); // fpu_ll is 2 i64
+                        ADD(x5, x5, x4);
+                        FMVXD(x3, v1);
+                        LD(x6, x5, 0);  // ref
+                        BNE_MARK(x6, x3);
+                        LD(x6, x5, 8);  // ll
+                        SD(x6, wback, fixedaddress);
+                        B_MARK3_nocond;
+                        MARK;
+                    }
+
                     if(!box64_dynarec_fastround) {
                         FSFLAGSI(0); // reset all bits
                     }
                     FCVTLD(x4, v1, RD_DYN);
-                    x87_restoreround(dyn, ninst, u8);
                     if(!box64_dynarec_fastround) {
                         FRFLAGS(x5);   // get back FPSR to check the IOC bit
                         ANDI(x5, x5, 1<<FR_NV);
@@ -196,6 +231,8 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     }
                     MARK2;
                     SD(x4, wback, fixedaddress);
+                    MARK3;
+                    x87_restoreround(dyn, ninst, u8);
                     x87_do_pop(dyn, ninst, x3);
                     break;
                 default:
diff --git a/src/emu/x64test.c b/src/emu/x64test.c
index 402ab235..8e0327a7 100644
--- a/src/emu/x64test.c
+++ b/src/emu/x64test.c
@@ -25,8 +25,8 @@
 void print_banner(x64emu_t* ref)
 {
     printf_log(LOG_NONE, "Warning, difference between Interpreter and Dynarec in %p (%02x %02x %02x %02x %02x %02x %02x %02x)\n"\
-        "=======================================\n", 
-        (void*)ref->old_ip, 
+        "=======================================\n",
+        (void*)ref->old_ip,
         ((uint8_t*)ref->old_ip)[0], ((uint8_t*)ref->old_ip)[1], ((uint8_t*)ref->old_ip)[2], ((uint8_t*)ref->old_ip)[3],
         ((uint8_t*)ref->old_ip)[4], ((uint8_t*)ref->old_ip)[5], ((uint8_t*)ref->old_ip)[6], ((uint8_t*)ref->old_ip)[7]
     );
@@ -55,7 +55,7 @@ void x64test_check(x64emu_t* ref, uintptr_t ip)
     // flags are volatile, so don't test them
 	//memcpy(&ref->eflags, &emu->eflags, sizeof(emu->eflags));
     if(memcmp(ref->segs, emu->segs, sizeof(emu->segs))) {
-        static const char* segname[] = {"CS", "DS", "ES", "SS", "FS", "GS"};
+        static const char* segname[] = {"ES", "CS", "SS", "DS", "FS", "GS"};
         BANNER;
         for(int i=0; i<6; ++i) {
             if(ref->segs[i]!=emu->segs[i]) {