diff options
Diffstat (limited to 'src/dynarec')
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_0f.c | 60 |
1 files changed, 45 insertions, 15 deletions
diff --git a/src/dynarec/rv64/dynarec_rv64_0f.c b/src/dynarec/rv64/dynarec_rv64_0f.c index 83ee96c9..8b9eb63c 100644 --- a/src/dynarec/rv64/dynarec_rv64_0f.c +++ b/src/dynarec/rv64/dynarec_rv64_0f.c @@ -61,19 +61,46 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni switch (opcode) { case 0x01: - INST_NAME("FAKE xgetbv"); - nextop = F8; - addr = fakeed(dyn, addr, ninst, nextop); - SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state - GETIP(ip); - STORE_XEMU_CALL(x3); - CALL(native_ud, -1); - LOAD_XEMU_CALL(); - jump_to_epilog(dyn, 0, xRIP, ninst); - *need_epilog = 0; - *ok = 0; - break; + // TODO:, /0 is SGDT. While 0F 01 D0 is XGETBV, etc... + nextop = F8; + if(MODREG) { + switch(nextop) { + case 0xD0: + INST_NAME("FAKE xgetbv"); + nextop = F8; + addr = fakeed(dyn, addr, ninst, nextop); + SETFLAGS(X_ALL, SF_SET); // Hack to set flags in "don't care" state + GETIP(ip); + STORE_XEMU_CALL(x3); + CALL(native_ud, -1); + LOAD_XEMU_CALL(); + jump_to_epilog(dyn, 0, xRIP, ninst); + *need_epilog = 0; + *ok = 0; + break; + case 0xF9: + INST_NAME("RDTSCP"); + NOTEST(x1); + if (box64_rdtsc) { + CALL(ReadTSC, x3); // will return the u64 in x3 + } else { + CSRRS(x3, xZR, 0xC01); // RDTIME + } + SRLI(xRDX, x3, 32); + AND(xRAX, x3, xMASK); // wipe upper part + MV(xRCX, xZR); // IA32_TSC, 0 for now + break; + default: + DEFAULT; + } + } else { + switch((nextop>>3)&7) { + default: + DEFAULT; + } + } + break; case 0x05: INST_NAME("SYSCALL"); NOTEST(x1); @@ -380,10 +407,13 @@ uintptr_t dynarec64_0F(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int ni case 0x31: INST_NAME("RDTSC"); NOTEST(x1); - MESSAGE(LOG_DUMP, "Need Optimization\n"); - CALL(ReadTSC, x3); // will return the u64 in x3 + if (box64_rdtsc) { + CALL(ReadTSC, x3); // will return the u64 in x3 + } else { + CSRRS(x3, xZR, 0xC01); // RDTIME + } SRLI(xRDX, x3, 32); - AND(xRAX, x3, 32); // wipe upper part + AND(xRAX, x3, xMASK); // wipe upper part break; case 0x38: // SSE3 |