diff options
| author | Yang Liu <numbksco@gmail.com> | 2023-06-27 21:18:44 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-27 15:18:44 +0200 |
| commit | 3b9772471724e663acc29fa22d466486a7539071 (patch) | |
| tree | 985a459d8b765667baf41c483370b55454d45f53 /src | |
| parent | 144db5f07f8ff2754cc78e99a71262fad1d711e0 (diff) | |
| download | box64-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.c | 10 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_df.c | 41 | ||||
| -rw-r--r-- | src/emu/x64test.c | 6 |
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]) { |