From bb54f234bd5066dd38f73bb802a1f4c8dcf90207 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Mon, 20 Nov 2023 18:07:58 +0800 Subject: [RV64_DYNAREC] Added 64 8F POP & 67 66 89 MOV opcodes (for minipad2.exe) (#1076) * [RV64_DYNAREC] Added 64 8F POP opcode * [RV64_DYNAREC] Added 67 66 89 MOV opcode --- src/dynarec/rv64/dynarec_rv64_64.c | 21 +++++++++++++++++++++ src/dynarec/rv64/dynarec_rv64_66.c | 2 +- src/dynarec/rv64/dynarec_rv64_67.c | 27 +++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 1 deletion(-) diff --git a/src/dynarec/rv64/dynarec_rv64_64.c b/src/dynarec/rv64/dynarec_rv64_64.c index 3e1366fb..ad022f5a 100644 --- a/src/dynarec/rv64/dynarec_rv64_64.c +++ b/src/dynarec/rv64/dynarec_rv64_64.c @@ -410,6 +410,27 @@ uintptr_t dynarec64_64(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni SH(ed, xEmu, offsetof(x64emu_t, segs[u8])); SW(xZR, xEmu, offsetof(x64emu_t, segs_serial[u8])); break; + case 0x8F: + INST_NAME("POP FS:Ed"); + grab_segdata(dyn, addr, ninst, x4, seg); + nextop = F8; + if (MODREG) { + POP1z(xRAX + (nextop & 7) + (rex.b << 3)); + } else { + POP1z(x3); // so this can handle POP [ESP] and maybe some variant too + addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, NULL, 0, 0); + if (ed == xRSP) { + ADD(x4, ed, x4); + SDz(x3, x4, 0); + } else { + // complicated to just allow a segfault that can be recovered correctly + ADDIz(xRSP, xRSP, rex.is32bits ? -4 : -8); + ADD(x4, ed, x4); + SDz(x3, x4, 0); + ADDIz(xRSP, xRSP, rex.is32bits ? 4 : 8); + } + } + break; case 0xA1: INST_NAME("MOV EAX,FS:Od"); grab_segdata(dyn, addr, ninst, x4, seg); diff --git a/src/dynarec/rv64/dynarec_rv64_66.c b/src/dynarec/rv64/dynarec_rv64_66.c index 8b717923..b4e7ad3e 100644 --- a/src/dynarec/rv64/dynarec_rv64_66.c +++ b/src/dynarec/rv64/dynarec_rv64_66.c @@ -544,7 +544,7 @@ uintptr_t dynarec64_66(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni OR(ed, ed, x2); } } else { - addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, &lock, 0, 0); + addr = geted(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, &lock, 1, 0); SH(gd, ed, fixedaddress); SMWRITELOCK(lock); } diff --git a/src/dynarec/rv64/dynarec_rv64_67.c b/src/dynarec/rv64/dynarec_rv64_67.c index e14ebfd1..9fc634f1 100644 --- a/src/dynarec/rv64/dynarec_rv64_67.c +++ b/src/dynarec/rv64/dynarec_rv64_67.c @@ -448,6 +448,33 @@ uintptr_t dynarec64_67(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni } else emit_cmp32_0(dyn, ninst, rex, xRAX, x3, x4); break; + + case 0x66: + opcode = F8; + switch (opcode) { + case 0x89: + INST_NAME("MOV Ew, Gw"); + nextop = F8; + GETGD; // don't need GETGW here + if (MODREG) { + ed = xRAX + (nextop & 7) + (rex.b << 3); + if (ed != gd) { + LUI(x1, 0xffff0); + AND(ed, ed, x1); + ZEXTH(x2, gd); + OR(ed, ed, x2); + } + } else { + addr = geted32(dyn, addr, ninst, nextop, &ed, x2, x1, &fixedaddress, rex, &lock, 1, 0); + SH(gd, ed, fixedaddress); + SMWRITELOCK(lock); + } + break; + + default: + DEFAULT; + } + break; case 0x81: case 0x83: -- cgit 1.4.1