diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2025-03-17 15:12:31 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-03-17 08:12:31 +0100 |
| commit | 394513971cf97619f34de6f84a5792d8ecd8f9c7 (patch) | |
| tree | e5b9ef73e6e16fd775ad5ff470b26f59f2562313 /src | |
| parent | 8b750200360cede1b6442462ed47f25c27f376d5 (diff) | |
| download | box64-394513971cf97619f34de6f84a5792d8ecd8f9c7.tar.gz box64-394513971cf97619f34de6f84a5792d8ecd8f9c7.zip | |
[RV64_DYNAREC] Minor x87 changes to enable test31 (#2441)
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_d9.c | 26 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_db.c | 8 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.c | 10 |
3 files changed, 21 insertions, 23 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_d9.c b/src/dynarec/rv64/dynarec_rv64_d9.c index 51321ab9..52c8ec10 100644 --- a/src/dynarec/rv64/dynarec_rv64_d9.c +++ b/src/dynarec/rv64/dynarec_rv64_d9.c @@ -152,17 +152,6 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni ADDI(x5, x5, i2); ANDI(x5, x5, 7); // (emu->top + i)&7 } - // load tag - LHU(x3, xEmu, offsetof(x64emu_t, fpu_tags)); - if (i2 < 0) { - SLLI(x3, x3, -i2 * 2); - } else if (i2 > 0) { - LUI(x2, 0xffff0); - OR(x3, x3, x2); - SRLI(x3, x3, i2 * 2); - } - ANDI(x2, x3, 0b11); - BNEZ_MARK3(x2); // empty: C3,C2,C0 = 101 // load x2 with ST0 anyway, for sign extraction if (rv64_zba) SH3ADD(x1, x5, xEmu); @@ -171,6 +160,17 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni ADD(x1, xEmu, x5); } LD(x2, x1, offsetof(x64emu_t, x87)); + // load tag + if (i2 >= 0) { + LHU(x3, xEmu, offsetof(x64emu_t, fpu_tags)); + if (i2 > 0) { + LUI(x5, 0xffff0); + OR(x3, x3, x5); + SRLI(x3, x3, i2 * 2); + } + ANDI(x3, x3, 0b11); + BNEZ_MARK3(x3); // empty: C3,C2,C0 = 101 + } } } else { // simply move from cache reg to x2 @@ -312,7 +312,7 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0xF4: INST_NAME("FXTRACT"); MESSAGE(LOG_DUMP, "Need Optimization\n"); - X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, 0); + X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, x3); x87_forget(dyn, ninst, x1, x2, 1); s0 = x87_stackcount(dyn, ninst, x3); CALL(native_fxtract, -1, 0, 0); @@ -376,7 +376,7 @@ uintptr_t dynarec64_D9(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0xFB: INST_NAME("FSINCOS"); MESSAGE(LOG_DUMP, "Need Optimization\n"); - X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, 0); + X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, x3); x87_forget(dyn, ninst, x1, x2, 1); s0 = x87_stackcount(dyn, ninst, x3); if (!BOX64ENV(dynarec_fastround)) u8 = x87_setround(dyn, ninst, x1, x2); diff --git a/src/dynarec/rv64/dynarec_rv64_db.c b/src/dynarec/rv64/dynarec_rv64_db.c index cd5f8ee0..37aafc65 100644 --- a/src/dynarec/rv64/dynarec_rv64_db.c +++ b/src/dynarec/rv64/dynarec_rv64_db.c @@ -243,14 +243,14 @@ uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 5: INST_NAME("FLD tbyte"); addr = geted(dyn, addr, ninst, nextop, &ed, x1, x2, &fixedaddress, rex, NULL, 8, 0); - if ((PK(0) == 0xDB && ((PK(1) >> 3) & 7) == 7) || (PK(0) >= 0x40 && PK(0) <= 0x4f && PK(1) == 0xDB && ((PK(2) >> 3) & 7) == 7)) { + if ((PK(0) == 0xDB && ((PK(1) >> 3) & 7) == 7) || (!rex.is32bits && PK(0) >= 0x40 && PK(0) <= 0x4f && PK(1) == 0xDB && ((PK(2) >> 3) & 7) == 7)) { // the FLD is immediatly followed by an FSTP LD(x5, ed, fixedaddress + 0); LH(x6, ed, fixedaddress + 8); // no persistant scratch register, so unrool both instruction here... MESSAGE(LOG_DUMP, "\tHack: FSTP tbyte\n"); nextop = F8; // 0xDB or rex - if (nextop >= 0x40 && nextop <= 0x4f) { + if (!rex.is32bits && nextop >= 0x40 && nextop <= 0x4f) { rex.rex = nextop; nextop = F8; // 0xDB } else @@ -266,7 +266,11 @@ uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else { ADDI(x1, ed, fixedaddress); X87_PUSH_EMPTY_OR_FAIL(dyn, ninst, x3); + // sync top + s0 = x87_stackcount(dyn, ninst, x3); CALL(native_fld, -1, x1, 0); + // go back with the top & stack counter + x87_unstackcount(dyn, ninst, x3, s0); } } break; diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c index 8dc8f9a4..4f3286fa 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.c +++ b/src/dynarec/rv64/dynarec_rv64_helper.c @@ -1023,8 +1023,6 @@ void x87_do_push_empty(dynarec_rv64_t* dyn, int ninst, int s1) MESSAGE(LOG_DUMP, "Incoherent x87 stack cache, aborting\n"); dyn->abort = 1; } - if (s1) - x87_stackcount(dyn, ninst, s1); } static void internal_x87_dopop(dynarec_rv64_t* dyn) { @@ -1083,11 +1081,7 @@ void x87_purgecache(dynarec_rv64_t* dyn, int ninst, int next, int s1, int s2, in // Sub x87stack to top, with and 7 LW(s2, xEmu, offsetof(x64emu_t, top)); // update tags (and top at the same time) - if (a > 0) { - SUBI(s2, s2, a); - } else { - ADDI(s2, s2, -a); - } + SUBI(s2, s2, a); ANDI(s2, s2, 7); SW(s2, xEmu, offsetof(x64emu_t, top)); // update tags (and top at the same time) @@ -1095,7 +1089,7 @@ void x87_purgecache(dynarec_rv64_t* dyn, int ninst, int next, int s1, int s2, in if (a > 0) { SLLI(s1, s1, a * 2); } else { - MOV32w(s3, 0xffff0000); + LUI(s3, 0xffff0); OR(s1, s1, s3); SRLI(s1, s1, -a * 2); } |