diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-04-19 20:37:08 +0000 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-04-19 20:37:20 +0000 |
| commit | d0ae6a9a7da7d77f17b97b41c14951a4af0f9c70 (patch) | |
| tree | d1f7c8c30287cad9a49a0a2ea6b1a13a400070b6 /src | |
| parent | 9aca360fe5bb1496324cfcbf2a41fafcf5f2fc63 (diff) | |
| download | box64-d0ae6a9a7da7d77f17b97b41c14951a4af0f9c70.tar.gz box64-d0ae6a9a7da7d77f17b97b41c14951a4af0f9c70.zip | |
[RV64_DYNAREC] Various fixes on many opcodes
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_2.c | 11 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_3.c | 10 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f.c | 2 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_660f.c | 3 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_emit_tests.c | 8 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_f0.c | 7 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_f30f.c | 20 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.c | 4 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_helper.h | 15 |
9 files changed, 47 insertions, 33 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_00_2.c b/src/dynarec/rv64/dynarec_rv64_00_2.c index f7572790..c02b1796 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_2.c +++ b/src/dynarec/rv64/dynarec_rv64_00_2.c @@ -193,8 +193,13 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int if(i64) { MOV64xw(x2, i64); emit_cmp32(dyn, ninst, rex, ed, x2, x3, x4, x5, x6); - } else + } else { + if(!rex.w && MODREG) { + AND(x1, ed, xMASK); + ed = x1; + } emit_cmp32_0(dyn, ninst, rex, ed, x3, x4); + } break; } break; @@ -429,8 +434,8 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int case 0x9C: INST_NAME("PUSHF"); READFLAGS(X_ALL); - FLAGS_ADJUST_TO11(xFlags, x2); - PUSH1(xFlags); + FLAGS_ADJUST_TO11(x3, xFlags, x2); + PUSH1(x3); break; case 0x9D: INST_NAME("POPF"); diff --git a/src/dynarec/rv64/dynarec_rv64_00_3.c b/src/dynarec/rv64/dynarec_rv64_00_3.c index 11b0ac5e..f6c2a4ed 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_3.c +++ b/src/dynarec/rv64/dynarec_rv64_00_3.c @@ -775,7 +775,12 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int MUL(xRAX, xRAX, ed); if(gd!=xRDX) {MV(xRDX, gd);} } else { - MUL(xRDX, xRAX, ed); //64 <- 32x32 + AND(x3, xRAX, xMASK); + if(MODREG) { + AND(x4, ed, xMASK); + ed = x4; + } + MUL(xRDX, x3, ed); //64 <- 32x32 AND(xRAX, xRDX, xMASK); SRLI(xRDX, xRDX, 32); } @@ -793,7 +798,8 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int MUL(xRAX, xRAX, ed); if(gd!=xRDX) {MV(xRDX, gd);} } else { - MUL(xRDX, xRAX, ed); //64 <- 32x32 + ADDIW(x3, xRAX, 0); // sign extend 32bits-> 64bits + MUL(xRDX, x3, ed); //64 <- 32x32 AND(xRAX, xRDX, xMASK); SRLI(xRDX, xRDX, 32); } diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c index adcfc5fe..40e52e63 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_0f.c @@ -635,6 +635,7 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0: INST_NAME("FXSAVE Ed"); MESSAGE(LOG_DUMP, "Need Optimization\n"); + SKIPTEST(x1); fpu_purgecache(dyn, ninst, 0, x1, x2, x3); if(MODREG) { DEFAULT; @@ -647,6 +648,7 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 1: INST_NAME("FXRSTOR Ed"); MESSAGE(LOG_DUMP, "Need Optimization\n"); + SKIPTEST(x1); fpu_purgecache(dyn, ninst, 0, x1, x2, x3); if(MODREG) { DEFAULT; diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c index fa391f82..20a5b441 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f.c +++ b/src/dynarec/rv64/dynarec_rv64_660f.c @@ -173,7 +173,8 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int GETGX(x1); GETEX(x2, 0); sse_forget_reg(dyn, ninst, x5); - ADDI(x5, xEmu, offsetof(x64emu_t, xmm[x5])); + + ADDI(x5, xEmu, offsetof(x64emu_t, scratch)); // perserve gd LD(x3, gback, 0); diff --git a/src/dynarec/rv64/dynarec_rv64_emit_tests.c b/src/dynarec/rv64/dynarec_rv64_emit_tests.c index 5d346059..79ebe6cb 100644 --- a/src/dynarec/rv64/dynarec_rv64_emit_tests.c +++ b/src/dynarec/rv64/dynarec_rv64_emit_tests.c @@ -324,9 +324,12 @@ void emit_test32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, SET_DFNONE(); } - if(c>=-2048 && c<=2047) + if(c>=-2048 && c<=2047) { ANDI(s3, s1, c); - else { + IFX(X_SF|X_ZF) { + if (!rex.w && c<0) ZEROUP(s3); + } + } else { MOV64xw(s3, c); AND(s3, s1, s3); // res = s1 & s2 } @@ -335,7 +338,6 @@ void emit_test32c(dynarec_rv64_t* dyn, int ninst, rex_t rex, int s1, int64_t c, SDxw(s3, xEmu, offsetof(x64emu_t, res)); } IFX(X_SF) { - if (!rex.w) ZEROUP(s3); SRLI(s4, s3, rex.w?63:31); BEQZ(s4, 8); ORI(xFlags, xFlags, 1 << F_SF); diff --git a/src/dynarec/rv64/dynarec_rv64_f0.c b/src/dynarec/rv64/dynarec_rv64_f0.c index 781990ac..ff15db2b 100644 --- a/src/dynarec/rv64/dynarec_rv64_f0.c +++ b/src/dynarec/rv64/dynarec_rv64_f0.c @@ -89,7 +89,6 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SETFLAGS(X_ALL, SF_SET_PENDING); nextop = F8; GETGD; - SMDMB(); if (MODREG) { ed = xRAX+(nextop&7)+(rex.b<<3); wback = 0; @@ -100,12 +99,12 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni MV(ed, gd); MARK2; MVxw(xRAX, x1); - B_NEXT_nocond; } else { + SMDMB(); addr = geted(dyn, addr, ninst, nextop, &wback, x2, x1, &fixedaddress, rex, LOCK_LOCK, 0, 0); MARKLOCK; LRxw(x1, wback, 1, 1); - SUB(x3, x1, xRAX); + SUBxw(x3, x1, xRAX); BNE_MARK(x3, xZR); // EAX == Ed SCxw(x4, gd, wback, 1, 1); @@ -113,8 +112,8 @@ uintptr_t dynarec64_F0(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni MARK; UFLAG_IF {emit_cmp32(dyn, ninst, rex, xRAX, x1, x3, x4, x5, x6);} MVxw(xRAX, x1); + SMDMB(); } - SMDMB(); break; default: DEFAULT; diff --git a/src/dynarec/rv64/dynarec_rv64_f30f.c b/src/dynarec/rv64/dynarec_rv64_f30f.c index bce8879f..e942e9b5 100644 --- a/src/dynarec/rv64/dynarec_rv64_f30f.c +++ b/src/dynarec/rv64/dynarec_rv64_f30f.c @@ -289,47 +289,45 @@ uintptr_t dynarec64_F30F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int } BNE_MARK(ed, xZR); MOV32w(gd, rex.w?64:32); - B_MARK2_nocond; - MARK; ANDI(xFlags, xFlags, ~(1<<F_ZF)); + ORI(xFlags, xFlags, 1<<F_CF); + B_NEXT_nocond; + MARK; if(ed!=gd) u8 = gd; else u8 = x1; - ADDI(u8, xZR, 0); + ADDI(u8, xZR, rex.w?63:31); if(rex.w) { MV(x2, ed); SRLI(x3, x2, 32); BEQZ(x3, 4+2*4); - ADDI(u8, u8, 32); + SUBI(u8, u8, 32); MV(x2, x3); } else { AND(x2, ed, xMASK); } SRLI(x3, x2, 16); BEQZ(x3, 4+2*4); - ADDI(u8, u8, 16); + SUBI(u8, u8, 16); MV(x2, x3); SRLI(x3, x2, 8); BEQZ(x3, 4+2*4); - ADDI(u8, u8, 8); + SUBI(u8, u8, 8); MV(x2, x3); SRLI(x3, x2, 4); BEQZ(x3, 4+2*4); - ADDI(u8, u8, 4); + SUBI(u8, u8, 4); MV(x2, x3); ANDI(x2, x2, 0b1111); TABLE64(x3, (uintptr_t)&lead0tab); ADD(x3, x3, x2); LBU(x2, x3, 0); - ADD(gd, u8, x2); + SUB(gd, u8, x2); MARK2; ANDI(xFlags, xFlags, ~((1<<F_ZF) | (1<<F_CF))); BNE(gd, xZR, 4+4); ORI(xFlags, xFlags, 1<<F_ZF); - MOV32w(x2, rex.w?64:32); - BNE(gd, x2, 4+4); - ORI(xFlags, xFlags, 1<<F_CF); break; case 0xC2: diff --git a/src/dynarec/rv64/dynarec_rv64_helper.c b/src/dynarec/rv64/dynarec_rv64_helper.c index 6d7e5e91..a395871d 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.c +++ b/src/dynarec/rv64/dynarec_rv64_helper.c @@ -389,7 +389,7 @@ void call_c(dynarec_rv64_t* dyn, int ninst, void* fnc, int reg, int ret, int sav if(savereg==0) savereg = x6; if(saveflags) { - FLAGS_ADJUST_TO11(xFlags, reg); + FLAGS_ADJUST_TO11(xFlags, xFlags, reg); SD(xFlags, xEmu, offsetof(x64emu_t, eflags)); } fpu_pushcache(dyn, ninst, reg, 0); @@ -442,7 +442,7 @@ void call_c(dynarec_rv64_t* dyn, int ninst, void* fnc, int reg, int ret, int sav void call_n(dynarec_rv64_t* dyn, int ninst, void* fnc, int w) { MAYUSE(fnc); - FLAGS_ADJUST_TO11(xFlags, x3); + FLAGS_ADJUST_TO11(xFlags, xFlags, x3); SD(xFlags, xEmu, offsetof(x64emu_t, eflags)); fpu_pushcache(dyn, ninst, x3, 1); // x5..x8, x10..x17, x28..x31 those needs to be saved by caller diff --git a/src/dynarec/rv64/dynarec_rv64_helper.h b/src/dynarec/rv64/dynarec_rv64_helper.h index 867190e1..95fc3f87 100644 --- a/src/dynarec/rv64/dynarec_rv64_helper.h +++ b/src/dynarec/rv64/dynarec_rv64_helper.h @@ -604,13 +604,14 @@ ANDI(s1, s1, 1<<5); \ OR(reg, reg, s1) -// Adjust the xFlags bit 5 -> bit 11, source in reg (can be xFlags, but not s1) -#define FLAGS_ADJUST_TO11(reg, s1) \ - MOV64x(s1, ~(1<<11)); \ - AND(xFlags, reg, s1); \ - ANDI(s1, xFlags, 1<<5); \ - SLLI(s1, s1, 11-5); \ - OR(xFlags, xFlags, s1) +// Adjust the xFlags bit 5 -> bit 11, src and dst can be the same (and can be xFlags, but not s1) +#define FLAGS_ADJUST_TO11(dst, src, s1) \ + MOV64x(s1, ~(1<<11)); \ + AND(dst, src, s1); \ + ANDI(s1, dst, 1<<5); \ + SLLI(s1, s1, 11-5); \ + ANDI(dst, dst, ~(1<<5)); \ + OR(dst, dst, s1) #ifndef MAYSETFLAGS #define MAYSETFLAGS() |