about summary refs log tree commit diff stats
path: root/src/dynarec
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-02-28 03:44:34 +0800
committerGitHub <noreply@github.com>2024-02-27 20:44:34 +0100
commitd658c47cd02823bee50adebf8580537031ef7026 (patch)
tree13dde73cbf719499a32c874112b4b66fae587059 /src/dynarec
parent21b06ace43adb3bc8b88eea8d0e1db79110d4e9c (diff)
downloadbox64-d658c47cd02823bee50adebf8580537031ef7026.tar.gz
box64-d658c47cd02823bee50adebf8580537031ef7026.zip
[RV64_DYNAREC] Fixed RDTSC handling (#1291)
* [LIBWRAP] Fixed a typo in the clocksource wrapping

* [RV64_DYNAREC] Added hardware timer support for RDTSC

* [INTERP] Optmize RV64 ReadTSC using rdtime

* [RV64_DYNAREC] Added 0F 01 F9 RDTSCP opcode

* Fixed typo

* Fixed another typo
Diffstat (limited to 'src/dynarec')
-rw-r--r--src/dynarec/rv64/dynarec_rv64_0f.c60
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