diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-03-19 14:12:20 +0000 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-03-19 14:12:20 +0000 |
| commit | ae81bbb4419d5e4d82b9961c379f32b4b28439ad (patch) | |
| tree | 9d72b1d66e8149374fa188e46f060169efbdf378 /src | |
| parent | 7db570af13eed1e90dd9a166e57e37f58db7d5c7 (diff) | |
| download | box64-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.c | 28 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f.c | 4 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.c | 17 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 7 |
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)) \ |