diff options
| author | Yang Liu <liuyang22@iscas.ac.cn> | 2023-12-22 23:51:33 +0800 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-12-22 16:51:33 +0100 |
| commit | 9c7320422458f746326c8123b92173eacc53dae8 (patch) | |
| tree | 79cb6be3ad5ed89ebe23cee0217e8f7594da5d70 /src | |
| parent | 7da59d5a3919383cca0b68a3a9d6e74d23d1f19e (diff) | |
| download | box64-9c7320422458f746326c8123b92173eacc53dae8.tar.gz box64-9c7320422458f746326c8123b92173eacc53dae8.zip | |
[DYNAREC_RV64] Added more opcodes and fixes (#1154)
* [DYNAREC_RV64] Added 66 0F 38 28 PMULDQ opcode * [DYNAREC_RV64] Added DD /6 FSAVE opcode * [DYNAREC_RV64] Added 66 8C MOV opcode * [DYNAREC_RV64] Fixed DF /1 /2 opcodes * [DYNAREC_RV64] Added DB /1 FISTTP opcode
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_66.c | 12 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_660f.c | 13 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_db.c | 19 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_dd.c | 8 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_df.c | 12 |
5 files changed, 60 insertions, 4 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c index fdc2d7e4..d4e196c6 100644 --- a/src/dynarec/rv64/dynarec_rv64_66.c +++ b/src/dynarec/rv64/dynarec_rv64_66.c @@ -570,6 +570,18 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni OR(gd, gd, x1); } break; + case 0x8C: + INST_NAME("MOV Ed, Seg"); + nextop = F8; + if ((nextop & 0xC0) == 0xC0) { // reg <= seg + LHU(xRAX + (nextop & 7) + (rex.b << 3), xEmu, offsetof(x64emu_t, segs[(nextop & 0x38) >> 3])); + } else { // mem <= seg + addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 1, 0); + LHU(x3, xEmu, offsetof(x64emu_t, segs[(nextop & 0x38) >> 3])); + SH(x3, ed, fixedaddress); + SMWRITE2(); + } + break; case 0x90: case 0x91: case 0x92: diff --git a/src/dynarec/rv64/dynarec_rv64_660f.c b/src/dynarec/rv64/dynarec_rv64_660f.c index f7953c56..b3b92a49 100644 --- a/src/dynarec/rv64/dynarec_rv64_660f.c +++ b/src/dynarec/rv64/dynarec_rv64_660f.c @@ -522,7 +522,18 @@ uintptr_t dynarec64_660F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int SW(x4, gback, gdoffset + i * 4); } break; - + case 0x28: + INST_NAME("PMULDQ Gx, Ex"); + nextop = F8; + GETEX(x2, 0); + GETGX(); + for (int i = 1; i >= 0; --i) { + LW(x3, wback, fixedaddress + i * 8); + LW(x4, gback, gdoffset + i * 8); + MUL(x3, x3, x4); + SD(x3, gback, gdoffset + i * 8); + } + break; case 0x2B: INST_NAME("PACKUSDW Gx, Ex"); nextop = F8; diff --git a/src/dynarec/rv64/dynarec_rv64_db.c b/src/dynarec/rv64/dynarec_rv64_db.c index f6c1f704..d60fcfbd 100644 --- a/src/dynarec/rv64/dynarec_rv64_db.c +++ b/src/dynarec/rv64/dynarec_rv64_db.c @@ -220,7 +220,24 @@ uintptr_t dynarec64_DB(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni break; case 1: INST_NAME("FISTTP Ed, ST0"); - DEFAULT; + v1 = x87_get_st(dyn, ninst, x1, x2, 0, EXT_CACHE_ST_D); + addr = geted(dyn, addr, ninst, nextop, &wback, x3, x4, &fixedaddress, rex, NULL, 1, 0); + if (!box64_dynarec_fastround) { + FSFLAGSI(0); // reset all bits + } + FCVTWD(x4, v1, RD_RTZ); + if (!box64_dynarec_fastround) { + FRFLAGS(x5); // get back FPSR to check the IOC bit + ANDI(x5, x5, 1 << FR_NV); + BNEZ_MARK(x5); + SEXT_W(x5, x4); + BEQ_MARK2(x5, x4); + MARK; + MOV32w(x4, 0x80000000); + } + MARK2; + SW(x4, wback, fixedaddress); + X87_POP_OR_FAIL(dyn, ninst, x3); break; case 2: INST_NAME("FIST Ed, ST0"); diff --git a/src/dynarec/rv64/dynarec_rv64_dd.c b/src/dynarec/rv64/dynarec_rv64_dd.c index 47718d64..35273745 100644 --- a/src/dynarec/rv64/dynarec_rv64_dd.c +++ b/src/dynarec/rv64/dynarec_rv64_dd.c @@ -173,6 +173,14 @@ uintptr_t dynarec64_DD(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni FSD(v1, wback, fixedaddress); X87_POP_OR_FAIL(dyn, ninst, x3); break; + case 6: + INST_NAME("FSAVE m108byte"); + MESSAGE(LOG_DUMP, "Need Optimization\n"); + fpu_purgecache(dyn, ninst, 0, x1, x2, x3); + addr = geted(dyn, addr, ninst, nextop, &ed, x4, x6, &fixedaddress, rex, NULL, 0, 0); + if (ed != x1) { MV(x1, ed); } + CALL(native_fsave, -1); + break; case 7: INST_NAME("FNSTSW m2byte"); fpu_purgecache(dyn, ninst, 0, x1, x2, x3); diff --git a/src/dynarec/rv64/dynarec_rv64_df.c b/src/dynarec/rv64/dynarec_rv64_df.c index 704e1302..08e603e5 100644 --- a/src/dynarec/rv64/dynarec_rv64_df.c +++ b/src/dynarec/rv64/dynarec_rv64_df.c @@ -131,7 +131,11 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni if(!box64_dynarec_fastround) { FSFLAGSI(0); // reset all bits } - FCVTWD(x4, v1, RD_RTZ); + if (ST_IS_F(0)) { + FCVTWS(x4, v1, RD_RTZ); + } else { + FCVTWD(x4, v1, RD_RTZ); + } if(!box64_dynarec_fastround) { FRFLAGS(x5); // get back FPSR to check the IOC bit ANDI(x5, x5, 1<<FR_NV); @@ -154,7 +158,11 @@ uintptr_t dynarec64_DF(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni if(!box64_dynarec_fastround) { FSFLAGSI(0); // reset all bits } - FCVTWD(x4, v1, RD_DYN); + if (ST_IS_F(0)) { + FCVTWS(x4, v1, RD_DYN); + } else { + FCVTWD(x4, v1, RD_DYN); + } x87_restoreround(dyn, ninst, u8); if(!box64_dynarec_fastround) { FRFLAGS(x5); // get back FPSR to check the IOC bit |