about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-03-19 14:12:20 +0000
committerptitSeb <sebastien.chev@gmail.com>2023-03-19 14:12:20 +0000
commitae81bbb4419d5e4d82b9961c379f32b4b28439ad (patch)
tree9d72b1d66e8149374fa188e46f060169efbdf378 /src
parent7db570af13eed1e90dd9a166e57e37f58db7d5c7 (diff)
downloadbox64-ae81bbb4419d5e4d82b9961c379f32b4b28439ad.tar.gz
box64-ae81bbb4419d5e4d82b9961c379f32b4b28439ad.zip
[RV64_DYNAREC] Various fixes and improvements, getting dynarec more stable now
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_00.c28
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f.c4
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.c17
-rw-r--r--src/dynarec/rv64/dynarec_rv64_helper.h7
4 files changed, 45 insertions, 11 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00.c b/src/dynarec/rv64/dynarec_rv64_00.c
index 6f6be07a..a0a0c9a5 100644
--- a/src/dynarec/rv64/dynarec_rv64_00.c
+++ b/src/dynarec/rv64/dynarec_rv64_00.c
@@ -703,7 +703,9 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     MESSAGE(LOG_DUMP, "Native Call to %s\n", GetNativeName(GetNativeFnc(ip)));
                     //x87_forget(dyn, ninst, x3, x4, 0);
                     //sse_purge07cache(dyn, ninst, x3);
-                    tmp = isSimpleWrapper(*(wrapper_t*)(addr));
+                    // disabling isSimpleWrapper because all signed value less than 64bits needs to be sign extended
+                    // and return value needs to be cleanned up
+                    tmp = 0;//isSimpleWrapper(*(wrapper_t*)(addr));
                     if(tmp<0 || tmp>1)
                         tmp=0;  //TODO: removed when FP is in place
                     if((box64_log<2 && !cycle_log) && tmp) {
@@ -722,8 +724,7 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         LW(w1, xEmu, offsetof(x64emu_t, quit));
                         CBZ_NEXT(w1);
                         MARK;
-                        LOAD_XEMU_REM();
-                        jump_to_epilog(dyn, 0, xRIP, ninst);
+                        jump_to_epilog_fast(dyn, 0, xRIP, ninst);
                     }
                 }
             } else {
@@ -828,7 +829,9 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                     // calling a native function
                     //sse_purge07cache(dyn, ninst, x3);     // TODO: chack the fpxx to purge/save when implemented
                     if((box64_log<2 && !cycle_log) && dyn->insts[ninst].natcall) {
-                        tmp=isSimpleWrapper(*(wrapper_t*)(dyn->insts[ninst].natcall+2));
+                        // disabling isSimpleWrapper because all signed value less than 64bits needs to be sign extended
+                        // and return value needs to be cleanned up
+                        tmp=0;//isSimpleWrapper(*(wrapper_t*)(dyn->insts[ninst].natcall+2));
                         if(tmp>1 || tmp<0)
                             tmp=0;  // float paramters not ready!
                     } else
@@ -861,8 +864,7 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         LW(w1, xEmu, offsetof(x64emu_t, quit));
                         CBZ_NEXT(w1);
                         MARK;
-                        LOAD_XEMU_REM();    // load remaining register, has they have changed
-                        jump_to_epilog(dyn, 0, xRIP, ninst);
+                        jump_to_epilog_fast(dyn, 0, xRIP, ninst);
                         dyn->last_ip = addr;
                     }
                     break;
@@ -881,7 +883,11 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         *need_epilog = 0;
                         *ok = 0;
                     }
-                    TABLE64(x2, addr);
+                    if(addr<0x100000000LL) {
+                        MOV64x(x2, addr);
+                    } else {
+                        TABLE64(x2, addr);
+                    }
                     PUSH1(x2);
                     // TODO: Add support for CALLRET optim
                     /*if(box64_dynarec_callret) {
@@ -903,7 +909,11 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                         *need_epilog = 0;
                     }
                     if(addr+i32==0) {   // self modifying code maybe? so use indirect address fetching
-                        TABLE64(x4, addr-4);
+                        if(addr-4<0x100000000LL) {
+                            MOV64x(x4, addr-4);
+                        } else {
+                            TABLE64(x4, addr-4);
+                        }
                         LD(x4, x4, 0);
                         jump_to_next(dyn, 0, x4, ninst);
                     } else
@@ -1072,7 +1082,7 @@ uintptr_t dynarec64_00(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                             //Need to see if RDX==0 and RAX not signed
                             // or RDX==-1 and RAX signed
                             BNE_MARK2(xRDX, xZR);
-                            BLT_MARK(xRAX, xZR);
+                            BGE_MARK(xRAX, xZR);
                             MARK2;
                             NOT(x2, xRDX);
                             BNE_MARK3(x2, xZR);
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c
index 335c1a45..a2449465 100644
--- a/src/dynarec/rv64/dynarec_rv64_0f.c
+++ b/src/dynarec/rv64/dynarec_rv64_0f.c
@@ -163,8 +163,8 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni
                 addr = geted(dyn, addr, ninst, nextop, &ed, x2, x4, &fixedaddress, rex, NULL, 1, 0); \
                 B##NO(x1, 8);                       \
                 LDxw(gd, ed, fixedaddress);         \
-                if(!rex.w) {ZEROUP(gd);}            \
-            }
+            }                                       \
+            if(!rex.w) ZEROUP(gd);
 
         GOCOND(0x40, "CMOV", "Gd, Ed");
         #undef GO
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c
index 7d493ea8..5b57d4dc 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.c
+++ b/src/dynarec/rv64/dynarec_rv64_helper.c
@@ -199,6 +199,23 @@ void jump_to_epilog(dynarec_rv64_t* dyn, uintptr_t ip, int reg, int ninst)
     BR(x2);
 }
 
+void jump_to_epilog_fast(dynarec_rv64_t* dyn, uintptr_t ip, int reg, int ninst)
+{
+    MAYUSE(dyn); MAYUSE(ip); MAYUSE(ninst);
+    MESSAGE(LOG_DUMP, "Jump to epilog_fast\n");
+
+    if(reg) {
+        if(reg!=xRIP) {
+            MV(xRIP, reg);
+        }
+    } else {
+        GETIP_(ip);
+    }
+    TABLE64(x2, (uintptr_t)rv64_epilog_fast);
+    SMEND();
+    BR(x2);
+}
+
 void jump_to_next(dynarec_rv64_t* dyn, uintptr_t ip, int reg, int ninst)
 {
     MAYUSE(dyn); MAYUSE(ninst);
diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h
index 82a0fbab..f4a7a9a2 100644
--- a/src/dynarec/rv64/dynarec_rv64_helper.h
+++ b/src/dynarec/rv64/dynarec_rv64_helper.h
@@ -223,6 +223,8 @@
 #define BNE_MARK(reg1, reg2) Bxx_gen(NE, MARK, reg1, reg2)
 // Branch to MARK if reg1<reg2 (use j64)
 #define BLT_MARK(reg1, reg2) Bxx_gen(LT, MARK, reg1, reg2)
+// Branch to MARK if reg1>=reg2 (use j64)
+#define BGE_MARK(reg1, reg2) Bxx_gen(GE, MARK, reg1, reg2)
 // Branch to MARK2 if reg1==reg2 (use j64)
 #define BEQ_MARK2(reg1, reg2) Bxx_gen(EQ, MARK2, reg1,reg2)
 // Branch to MARK2 if reg1!=reg2 (use j64)
@@ -457,6 +459,7 @@
 #define MODREG  ((nextop&0xC0)==0xC0)
 
 void rv64_epilog();
+void rv64_epilog_fast();
 void* rv64_next(x64emu_t* emu, uintptr_t addr);
 
 #ifndef STEPNAME
@@ -492,6 +495,7 @@ void* rv64_next(x64emu_t* emu, uintptr_t addr);
 #define geted32         STEPNAME(geted32)
 #define geted16         STEPNAME(geted16)
 #define jump_to_epilog  STEPNAME(jump_to_epilog)
+#define jump_to_epilog_fast  STEPNAME(jump_to_epilog_fast)
 #define jump_to_next    STEPNAME(jump_to_next)
 #define ret_to_epilog   STEPNAME(ret_to_epilog)
 #define retn_to_epilog  STEPNAME(retn_to_epilog)
@@ -622,6 +626,7 @@ uintptr_t geted(dynarec_rv64_t* dyn, uintptr_t addr, int ninst, uint8_t nextop,
 
 // generic x64 helper
 void jump_to_epilog(dynarec_rv64_t* dyn, uintptr_t ip, int reg, int ninst);
+void jump_to_epilog_fast(dynarec_rv64_t* dyn, uintptr_t ip, int reg, int ninst);
 void jump_to_next(dynarec_rv64_t* dyn, uintptr_t ip, int reg, int ninst);
 void ret_to_epilog(dynarec_rv64_t* dyn, int ninst);
 void retn_to_epilog(dynarec_rv64_t* dyn, int ninst, int n);
@@ -885,6 +890,7 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
         INST_NAME(T1 "LE " T2);                             \
         GO( SRLI(x1, xFlags, F_SF-F_OF2);                   \
             XOR(x1, x1, xFlags);                            \
+            ANDI(x1, x1, 1<<F_OF2);                         \
             ANDI(x3, xFlags, 1<<F_ZF);                      \
             OR(x1, x1, x3);                                 \
             ANDI(x1, x1, (1<<F_OF2) | (1<<F_ZF))            \
@@ -894,6 +900,7 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int
         INST_NAME(T1 "G " T2);                              \
         GO( SRLI(x1, xFlags, F_SF-F_OF2);                   \
             XOR(x1, x1, xFlags);                            \
+            ANDI(x1, x1, 1<<F_OF2);                         \
             ANDI(x3, xFlags, 1<<F_ZF);                      \
             OR(x1, x1, x3);                                 \
             ANDI(x1, x1, (1<<F_OF2) | (1<<F_ZF))            \