about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorYang Liu <liuyang22@iscas.ac.cn>2024-12-20 19:59:03 +0800
committerGitHub <noreply@github.com>2024-12-20 12:59:03 +0100
commit6ac7d7a1dbb2092b4a7d7b3b678a6cf403f455ca (patch)
tree2cd75b20125c599d953ca36439748832c92c676a /src
parent291db1530cb122e7235ceb707125caf44ac4560c (diff)
downloadbox64-6ac7d7a1dbb2092b4a7d7b3b678a6cf403f455ca.tar.gz
box64-6ac7d7a1dbb2092b4a7d7b3b678a6cf403f455ca.zip
[GDBJIT] Display DynaRec info in source file (#2179)
* [GDBJIT] Display DynaRec info in source file

* fix
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/arm64/dynarec_arm64_functions.c187
-rw-r--r--src/dynarec/dynarec_native.c2
-rw-r--r--src/dynarec/la64/dynarec_la64_functions.c2
-rw-r--r--src/dynarec/rv64/dynarec_rv64_functions.c2
-rw-r--r--src/emu/x64emu.c4
-rw-r--r--src/emu/x64run_private.c2
-rw-r--r--src/emu/x64trace.c10
-rw-r--r--src/include/x64trace.h2
8 files changed, 114 insertions, 97 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_functions.c b/src/dynarec/arm64/dynarec_arm64_functions.c
index c0a2c087..75eef71e 100644
--- a/src/dynarec/arm64/dynarec_arm64_functions.c
+++ b/src/dynarec/arm64/dynarec_arm64_functions.c
@@ -661,97 +661,112 @@ const char* getCacheName(int t, int n)
 
 void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t rex)
 {
-    if(box64_dynarec_dump) {
-        printf_x64_instruction(rex.is32bits?my_context->dec32:my_context->dec, &dyn->insts[ninst].x64, name);
-        dynarec_log(LOG_NONE, "%s%p: %d emitted opcodes, inst=%d, barrier=%d state=%d/%d/%d(%d:%d->%d:%d), %s=%X/%X, use=%X, need=%X/%X, sm=%d(%d/%d)",
-            (box64_dynarec_dump>1)?"\e[32m":"",
-            (void*)(dyn->native_start+dyn->insts[ninst].address),
-            dyn->insts[ninst].size/4,
-            ninst,
-            dyn->insts[ninst].x64.barrier,
-            dyn->insts[ninst].x64.state_flags,
-            dyn->f.pending,
-            dyn->f.dfnone,
-            dyn->insts[ninst].f_entry.pending,
-            dyn->insts[ninst].f_entry.dfnone,
-            dyn->insts[ninst].f_exit.pending,
-            dyn->insts[ninst].f_exit.dfnone,
-            dyn->insts[ninst].x64.may_set?"may":"set",
-            dyn->insts[ninst].x64.set_flags,
-            dyn->insts[ninst].x64.gen_flags,
-            dyn->insts[ninst].x64.use_flags,
-            dyn->insts[ninst].x64.need_before,
-            dyn->insts[ninst].x64.need_after,
-            dyn->smwrite, dyn->insts[ninst].will_write, dyn->insts[ninst].last_write);
-        if(dyn->insts[ninst].nat_flags_op) {
-            if(dyn->insts[ninst].nat_flags_op==NAT_FLAG_OP_TOUCH && dyn->insts[ninst].before_nat_flags)
-                printf_log(LOG_NONE, " NF:%d/read:%x", dyn->insts[ninst].nat_flags_op, dyn->insts[ninst].before_nat_flags);
-            else
-                printf_log(LOG_NONE, " NF:%d", dyn->insts[ninst].nat_flags_op);
-        }
-        if(dyn->insts[ninst].use_nat_flags || dyn->insts[ninst].set_nat_flags || dyn->insts[ninst].need_nat_flags)
-            printf_log(LOG_NONE, " nf:%hhx/%hhx/%hhx", dyn->insts[ninst].set_nat_flags, dyn->insts[ninst].use_nat_flags, dyn->insts[ninst].need_nat_flags);
-        if(dyn->insts[ninst].invert_carry)
-            printf_log(LOG_NONE, " CI");
-        if(dyn->insts[ninst].gen_inverted_carry)
-            printf_log(LOG_NONE, " gic");
-        if(dyn->insts[ninst].before_nat_flags&NF_CF)
-            printf_log(LOG_NONE, " %ccb", dyn->insts[ninst].normal_carry_before?'n':'i');
-        if(dyn->insts[ninst].need_nat_flags&NF_CF)
-            printf_log(LOG_NONE, " %cc", dyn->insts[ninst].normal_carry?'n':'i');
-        if(dyn->insts[ninst].pred_sz) {
-            dynarec_log(LOG_NONE, ", pred=");
-            for(int ii=0; ii<dyn->insts[ninst].pred_sz; ++ii)
-                dynarec_log(LOG_NONE, "%s%d", ii?"/":"", dyn->insts[ninst].pred[ii]);
-        }
-        if(!dyn->insts[ninst].x64.alive)
-            dynarec_log(LOG_NONE, " not executed");
-        if(dyn->insts[ninst].x64.jmp && dyn->insts[ninst].x64.jmp_insts>=0)
-            dynarec_log(LOG_NONE, ", jmp=%d", dyn->insts[ninst].x64.jmp_insts);
-        if(dyn->insts[ninst].x64.jmp && dyn->insts[ninst].x64.jmp_insts==-1)
-            dynarec_log(LOG_NONE, ", jmp=out");
-        if(dyn->insts[ninst].x64.has_callret)
-            dynarec_log(LOG_NONE, ", callret");
-        if(dyn->last_ip)
-            dynarec_log(LOG_NONE, ", last_ip=%p", (void*)dyn->last_ip);
-        for(int ii=0; ii<32; ++ii) {
-            switch(dyn->insts[ninst].n.neoncache[ii].t) {
-                case NEON_CACHE_ST_D: dynarec_log(LOG_NONE, " D%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
-                case NEON_CACHE_ST_F: dynarec_log(LOG_NONE, " S%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
-                case NEON_CACHE_ST_I64: dynarec_log(LOG_NONE, " D%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
-                case NEON_CACHE_MM: dynarec_log(LOG_NONE, " D%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
-                case NEON_CACHE_XMMW: dynarec_log(LOG_NONE, " Q%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
-                case NEON_CACHE_XMMR: dynarec_log(LOG_NONE, " Q%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
-                case NEON_CACHE_YMMW: dynarec_log(LOG_NONE, " Q%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
-                case NEON_CACHE_YMMR: dynarec_log(LOG_NONE, " Q%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
-                //case NEON_CACHE_SCR: dynarec_log(LOG_NONE, " D%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
-                case NEON_CACHE_NONE:
-                default:    break;
-            }
+    if (!box64_dynarec_dump && !box64_dynarec_gdbjit) return;
+
+    static char buf[512];
+    int length = sprintf(buf, "barrier=%d state=%d/%d/%d(%d:%d->%d:%d), %s=%X/%X, use=%X, need=%X/%X, sm=%d(%d/%d)",
+        dyn->insts[ninst].x64.barrier,
+        dyn->insts[ninst].x64.state_flags,
+        dyn->f.pending,
+        dyn->f.dfnone,
+        dyn->insts[ninst].f_entry.pending,
+        dyn->insts[ninst].f_entry.dfnone,
+        dyn->insts[ninst].f_exit.pending,
+        dyn->insts[ninst].f_exit.dfnone,
+        dyn->insts[ninst].x64.may_set ? "may" : "set",
+        dyn->insts[ninst].x64.set_flags,
+        dyn->insts[ninst].x64.gen_flags,
+        dyn->insts[ninst].x64.use_flags,
+        dyn->insts[ninst].x64.need_before,
+        dyn->insts[ninst].x64.need_after,
+        dyn->smwrite, dyn->insts[ninst].will_write, dyn->insts[ninst].last_write);
+    if (dyn->insts[ninst].nat_flags_op) {
+        if (dyn->insts[ninst].nat_flags_op == NAT_FLAG_OP_TOUCH && dyn->insts[ninst].before_nat_flags)
+            length += sprintf(buf + length, " NF:%d/read:%x", dyn->insts[ninst].nat_flags_op, dyn->insts[ninst].before_nat_flags);
+        else
+            length += sprintf(buf + length, " NF:%d", dyn->insts[ninst].nat_flags_op);
+    }
+    if (dyn->insts[ninst].use_nat_flags || dyn->insts[ninst].set_nat_flags || dyn->insts[ninst].need_nat_flags) {
+        length += sprintf(buf + length, " nf:%hhx/%hhx/%hhx", dyn->insts[ninst].set_nat_flags, dyn->insts[ninst].use_nat_flags, dyn->insts[ninst].need_nat_flags);
+    }
+    if (dyn->insts[ninst].invert_carry)
+        length += sprintf(buf + length, " CI");
+    if (dyn->insts[ninst].gen_inverted_carry)
+        length += sprintf(buf + length, " gic");
+    if (dyn->insts[ninst].before_nat_flags & NF_CF) {
+        length += sprintf(buf + length, " %ccb", dyn->insts[ninst].normal_carry_before ? 'n' : 'i');
+    }
+    if (dyn->insts[ninst].need_nat_flags & NF_CF) {
+        length += sprintf(buf + length, " %cc", dyn->insts[ninst].normal_carry ? 'n' : 'i');
+    }
+    if (dyn->insts[ninst].pred_sz) {
+        length += sprintf(buf + length, ", pred=");
+        for (int ii = 0; ii < dyn->insts[ninst].pred_sz; ++ii)
+            length += sprintf(buf + length, "%s%d", ii ? "/" : "", dyn->insts[ninst].pred[ii]);
+    }
+    if (!dyn->insts[ninst].x64.alive)
+        length += sprintf(buf + length, "not executed");
+    if (dyn->insts[ninst].x64.jmp && dyn->insts[ninst].x64.jmp_insts >= 0) {
+        length += sprintf(buf + length, ", jmp=%d", dyn->insts[ninst].x64.jmp_insts);
+    }
+    if (dyn->insts[ninst].x64.jmp && dyn->insts[ninst].x64.jmp_insts == -1)
+        length += sprintf(buf + length, ", jmp=out");
+    if (dyn->insts[ninst].x64.has_callret)
+        length += sprintf(buf + length, ", callret");
+    if (dyn->last_ip) {
+        length += sprintf(buf + length, ", last_ip=%p", (void*)dyn->last_ip);
+    }
+    for (int ii = 0; ii < 32; ++ii) {
+        switch (dyn->insts[ninst].n.neoncache[ii].t) {
+            case NEON_CACHE_ST_D: length += sprintf(buf + length, " D%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
+            case NEON_CACHE_ST_F: length += sprintf(buf + length, " S%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
+            case NEON_CACHE_ST_I64: length += sprintf(buf + length, " D%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
+            case NEON_CACHE_MM: length += sprintf(buf + length, " D%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
+            case NEON_CACHE_XMMW: length += sprintf(buf + length, " Q%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
+            case NEON_CACHE_XMMR: length += sprintf(buf + length, " Q%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
+            case NEON_CACHE_YMMW: length += sprintf(buf + length, " Q%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
+            case NEON_CACHE_YMMR: length += sprintf(buf + length, " Q%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
+            // case NEON_CACHE_SCR: length += sprintf(buf + length, " D%d:%s", ii, getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n)); break;
+            case NEON_CACHE_NONE:
+            default: break;
         }
-        if(memcmp(dyn->insts[ninst].n.neoncache, dyn->n.neoncache, sizeof(dyn->n.neoncache))) {
-            dynarec_log(LOG_NONE, " %s(Change:", (box64_dynarec_dump>1)?"\e[1;91m":"");
-            for(int ii=0; ii<32; ++ii) if(dyn->insts[ninst].n.neoncache[ii].v!=dyn->n.neoncache[ii].v) {
-                dynarec_log(LOG_NONE, " V%d:%s", ii, getCacheName(dyn->n.neoncache[ii].t, dyn->n.neoncache[ii].n));
-                dynarec_log(LOG_NONE, "->%s", getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n));
+    }
+    if (memcmp(dyn->insts[ninst].n.neoncache, dyn->n.neoncache, sizeof(dyn->n.neoncache))) {
+        length += sprintf(buf + length, " %s(Change:", (box64_dynarec_dump > 1) ? "\e[1;91m" : "");
+        for (int ii = 0; ii < 32; ++ii)
+            if (dyn->insts[ninst].n.neoncache[ii].v != dyn->n.neoncache[ii].v) {
+                length += sprintf(buf + length, " V%d:%s", ii, getCacheName(dyn->n.neoncache[ii].t, dyn->n.neoncache[ii].n));
+                length += sprintf(buf + length, "->%s", getCacheName(dyn->insts[ninst].n.neoncache[ii].t, dyn->insts[ninst].n.neoncache[ii].n));
             }
-            dynarec_log(LOG_NONE, ")%s", (box64_dynarec_dump>1)?"\e[0;32m":"");
-        }
-        if(dyn->insts[ninst].n.ymm_used)
-            dynarec_log(LOG_NONE, " ymmUsed=%04x", dyn->insts[ninst].n.ymm_used);
-        if(dyn->ymm_zero || dyn->insts[ninst].ymm0_add || dyn->insts[ninst].ymm0_sub || dyn->insts[ninst].ymm0_out)
-            dynarec_log(LOG_NONE, " ymm0=(%04x/%04x+%04x-%04x=%04x)", dyn->ymm_zero, dyn->insts[ninst].ymm0_in, dyn->insts[ninst].ymm0_add ,dyn->insts[ninst].ymm0_sub, dyn->insts[ninst].ymm0_out);
-        if(dyn->insts[ninst].purge_ymm)
-            dynarec_log(LOG_NONE, " purgeYmm=%04x", dyn->insts[ninst].purge_ymm);
-        if(dyn->n.stack || dyn->insts[ninst].n.stack_next || dyn->insts[ninst].n.x87stack)
-            dynarec_log(LOG_NONE, " X87:%d/%d(+%d/-%d)%d", dyn->n.stack, dyn->insts[ninst].n.stack_next, dyn->insts[ninst].n.stack_push, dyn->insts[ninst].n.stack_pop, dyn->insts[ninst].n.x87stack);
-        if(dyn->insts[ninst].n.combined1 || dyn->insts[ninst].n.combined2)
-            dynarec_log(LOG_NONE, " %s:%d/%d", dyn->insts[ninst].n.swapped?"SWP":"CMB", dyn->insts[ninst].n.combined1, dyn->insts[ninst].n.combined2);
-        dynarec_log(LOG_NONE, "%s\n", (box64_dynarec_dump>1)?"\e[m":"");
+        length += sprintf(buf + length, ")%s", (box64_dynarec_dump > 1) ? "\e[0;32m" : "");
+    }
+    if (dyn->insts[ninst].n.ymm_used) {
+        length += sprintf(buf + length, " ymmUsed=%04x", dyn->insts[ninst].n.ymm_used);
+    }
+    if (dyn->ymm_zero || dyn->insts[ninst].ymm0_add || dyn->insts[ninst].ymm0_sub || dyn->insts[ninst].ymm0_out) {
+        length += sprintf(buf + length, " ymm0=(%04x/%04x+%04x-%04x=%04x)", dyn->ymm_zero, dyn->insts[ninst].ymm0_in, dyn->insts[ninst].ymm0_add, dyn->insts[ninst].ymm0_sub, dyn->insts[ninst].ymm0_out);
+    }
+    if (dyn->insts[ninst].purge_ymm) {
+        length += sprintf(buf + length, " purgeYmm=%04x", dyn->insts[ninst].purge_ymm);
+    }
+    if (dyn->n.stack || dyn->insts[ninst].n.stack_next || dyn->insts[ninst].n.x87stack) {
+        length += sprintf(buf + length, " X87:%d/%d(+%d/-%d)%d", dyn->n.stack, dyn->insts[ninst].n.stack_next, dyn->insts[ninst].n.stack_push, dyn->insts[ninst].n.stack_pop, dyn->insts[ninst].n.x87stack);
+    }
+    if (dyn->insts[ninst].n.combined1 || dyn->insts[ninst].n.combined2) {
+        length += sprintf(buf + length, " %s:%d/%d", dyn->insts[ninst].n.swapped ? "SWP" : "CMB", dyn->insts[ninst].n.combined1, dyn->insts[ninst].n.combined2);
+    }
+    if (box64_dynarec_dump) {
+        printf_x64_instruction(rex.is32bits ? my_context->dec32 : my_context->dec, &dyn->insts[ninst].x64, name);
+        dynarec_log(LOG_NONE, "%s%p: %d emitted opcodes, inst=%d, %s%s\n",
+            (box64_dynarec_dump > 1) ? "\e[32m" : "",
+            (void*)(dyn->native_start + dyn->insts[ninst].address), dyn->insts[ninst].size / 4, ninst, buf, (box64_dynarec_dump > 1) ? "\e[m" : "");
     }
     if (box64_dynarec_gdbjit) {
         zydis_dec_t* dec = rex.is32bits ? my_context->dec32 : my_context->dec;
-        const char* inst_name = dec ? DecodeX64Trace(dec, dyn->insts[ninst].x64.addr) : name;
+        const char* inst_name = dec ? DecodeX64Trace(dec, dyn->insts[ninst].x64.addr, 0) : name;
+        static char buf2[512];
+        sprintf(buf2, "; %d: %d opcodes, %s", ninst, dyn->insts[ninst].size / 4, buf);
+        dyn->gdbjit_block = GdbJITBlockAddLine(dyn->gdbjit_block, (dyn->native_start + dyn->insts[ninst].address), buf2);
         dyn->gdbjit_block = GdbJITBlockAddLine(dyn->gdbjit_block, (dyn->native_start + dyn->insts[ninst].address), inst_name);
     }
 }
diff --git a/src/dynarec/dynarec_native.c b/src/dynarec/dynarec_native.c
index 3b761a19..5abbb9ef 100644
--- a/src/dynarec/dynarec_native.c
+++ b/src/dynarec/dynarec_native.c
@@ -36,7 +36,7 @@ void printf_x64_instruction(zydis_dec_t* dec, instruction_x64_t* inst, const cha
         }
     } else {
         if(dec) {
-            dynarec_log(LOG_NONE, "%s%p: %s", (box64_dynarec_dump>1)?"\e[01;33m":"", ip, DecodeX64Trace(dec, inst->addr));
+            dynarec_log(LOG_NONE, "%s%p: %s", (box64_dynarec_dump > 1) ? "\e[01;33m" : "", ip, DecodeX64Trace(dec, inst->addr, 1));
         } else {
             dynarec_log(LOG_NONE, "%s%p: ", (box64_dynarec_dump>1)?"\e[01;33m":"", ip);
             for(int i=0; i<inst->size; ++i) {
diff --git a/src/dynarec/la64/dynarec_la64_functions.c b/src/dynarec/la64/dynarec_la64_functions.c
index 753410f2..99410b12 100644
--- a/src/dynarec/la64/dynarec_la64_functions.c
+++ b/src/dynarec/la64/dynarec_la64_functions.c
@@ -309,7 +309,7 @@ void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t r
     }
     if (box64_dynarec_gdbjit) {
         zydis_dec_t* dec = rex.is32bits ? my_context->dec32 : my_context->dec;
-        const char* inst_name = dec ? DecodeX64Trace(dec, dyn->insts[ninst].x64.addr) : name;
+        const char* inst_name = dec ? DecodeX64Trace(dec, dyn->insts[ninst].x64.addr, 0) : name;
         dyn->gdbjit_block = GdbJITBlockAddLine(dyn->gdbjit_block, (dyn->native_start + dyn->insts[ninst].address), inst_name);
     }
 }
diff --git a/src/dynarec/rv64/dynarec_rv64_functions.c b/src/dynarec/rv64/dynarec_rv64_functions.c
index 341305bf..da7732e6 100644
--- a/src/dynarec/rv64/dynarec_rv64_functions.c
+++ b/src/dynarec/rv64/dynarec_rv64_functions.c
@@ -725,7 +725,7 @@ void inst_name_pass3(dynarec_native_t* dyn, int ninst, const char* name, rex_t r
     }
     if (box64_dynarec_gdbjit) {
         zydis_dec_t* dec = rex.is32bits ? my_context->dec32 : my_context->dec;
-        const char* inst_name = dec ? DecodeX64Trace(dec, dyn->insts[ninst].x64.addr) : name;
+        const char* inst_name = dec ? DecodeX64Trace(dec, dyn->insts[ninst].x64.addr, 0) : name;
         dyn->gdbjit_block = GdbJITBlockAddLine(dyn->gdbjit_block, (dyn->native_start + dyn->insts[ninst].address), inst_name);
     }
 }
diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c
index 02ef89d5..7619483b 100644
--- a/src/emu/x64emu.c
+++ b/src/emu/x64emu.c
@@ -570,10 +570,10 @@ void StopEmu(x64emu_t* emu, const char* reason, int is32bits)
 #ifdef HAVE_TRACE
     if(box64_is32bits) {
         if(my_context->dec32)
-            printf_log(LOG_NONE, "%s\n", DecodeX64Trace(my_context->dec32, emu->old_ip));
+            printf_log(LOG_NONE, "%s\n", DecodeX64Trace(my_context->dec32, emu->old_ip, 1));
     } else {
         if(my_context->dec)
-            printf_log(LOG_NONE, "%s\n", DecodeX64Trace(my_context->dec, emu->old_ip));
+            printf_log(LOG_NONE, "%s\n", DecodeX64Trace(my_context->dec, emu->old_ip, 1));
     }
 #endif
 }
diff --git a/src/emu/x64run_private.c b/src/emu/x64run_private.c
index 1d80e76a..8bc99819 100644
--- a/src/emu/x64run_private.c
+++ b/src/emu/x64run_private.c
@@ -1232,7 +1232,7 @@ void PrintTrace(x64emu_t* emu, uintptr_t ip, int dynarec)
                 printf_log(LOG_NONE, "%p: Native call to %p => %s\n", (void*)ip, (void*)a, GetNativeName(*(void**)(ip+11)));
             }
         } else {
-            printf_log(LOG_NONE, "%s", DecodeX64Trace(is32bits?my_context->dec32:my_context->dec, ip));
+            printf_log(LOG_NONE, "%s", DecodeX64Trace(is32bits ? my_context->dec32 : my_context->dec, ip, 1));
             uint8_t peek = PK(0);
             rex_t rex = {0};
             if(!is32bits && peek>=0x40 && peek<=0x4f) {
diff --git a/src/emu/x64trace.c b/src/emu/x64trace.c
index 415a268c..e14f22df 100644
--- a/src/emu/x64trace.c
+++ b/src/emu/x64trace.c
@@ -128,7 +128,7 @@ void DeleteX64TraceDecoder(zydis_dec_t **dec)
     #endif
 }
 
-const char* DecodeX64Trace(zydis_dec_t *dec, uintptr_t p)
+const char* DecodeX64Trace(zydis_dec_t* dec, uintptr_t p, int withhex)
 {
     #ifndef HAVE_TRACE
     return "???";
@@ -138,9 +138,11 @@ const char* DecodeX64Trace(zydis_dec_t *dec, uintptr_t p)
         &dec->instruction))) {
         char tmp[511];
         buff[0]='\0';
-        for (int i=0; i<dec->instruction.length; ++i) {
-            sprintf(tmp, "%02X ", *((unsigned char*)p+i));
-            strcat(buff, tmp);
+        if (withhex) {
+            for (int i = 0; i < dec->instruction.length; ++i) {
+                sprintf(tmp, "%02X ", *((unsigned char*)p + i));
+                strcat(buff, tmp);
+            }
         }
         #if 0
         const /*ZydisFormatterToken*/void* token;
diff --git a/src/include/x64trace.h b/src/include/x64trace.h
index e7c3efd7..9a1f20a2 100644
--- a/src/include/x64trace.h
+++ b/src/include/x64trace.h
@@ -13,6 +13,6 @@ void DeleteX86TraceDecoder(zydis_dec_t **dec);
 zydis_dec_t* InitX64TraceDecoder(box64context_t *context);
 void DeleteX64TraceDecoder(zydis_dec_t **dec);
 
-const char* DecodeX64Trace(zydis_dec_t *dec, uintptr_t p);
+const char* DecodeX64Trace(zydis_dec_t* dec, uintptr_t p, int withhex);
 
 #endif //__X64TRACE_H_
\ No newline at end of file