From 4295268e947104a17d64fb5b3e53380f269d7bdd Mon Sep 17 00:00:00 2001
From: wargio <wargio@libero.it>
Date: Mon, 26 Jun 2023 22:40:09 +0800
Subject: [PATCH 1/3] Initial working sh4 frame support

---
 linux-user/sh4/trace_info.h |   6 ++
 qobject/block-qdict.c       |   2 +-
 target/sh4/helper.h         |   5 ++
 target/sh4/meson.build      |   4 ++
 target/sh4/trace_helper.c   | 120 ++++++++++++++++++++++++++++++++++++
 target/sh4/translate.c      |  27 ++++++++
 6 files changed, 163 insertions(+), 1 deletion(-)
 create mode 100644 linux-user/sh4/trace_info.h
 create mode 100644 target/sh4/trace_helper.c

diff --git a/linux-user/sh4/trace_info.h b/linux-user/sh4/trace_info.h
new file mode 100644
index 0000000000000..e32f8a07f63d1
--- /dev/null
+++ b/linux-user/sh4/trace_info.h
@@ -0,0 +1,6 @@
+#pragma once
+
+#include "frame_arch.h"
+
+const uint64_t frame_arch = frame_arch_sh;
+const uint64_t frame_mach = frame_mach_sh4;
diff --git a/qobject/block-qdict.c b/qobject/block-qdict.c
index b26524429c0dd..699ddd4fe596d 100644
--- a/qobject/block-qdict.c
+++ b/qobject/block-qdict.c
@@ -222,7 +222,7 @@ void qdict_array_split(QDict *src, QList **dst)
     *dst = qlist_new();
 
     for (i = 0; i < UINT_MAX; i++) {
-        QObject *subqobj;
+        QObject *subqobj = NULL;
         bool is_subqdict;
         QDict *subqdict = NULL;
         char indexstr[32], prefix[32];
diff --git a/target/sh4/helper.h b/target/sh4/helper.h
index 8d792f6b5538d..d2d517cf68f7d 100644
--- a/target/sh4/helper.h
+++ b/target/sh4/helper.h
@@ -41,3 +41,8 @@ DEF_HELPER_FLAGS_2(ftrc_FT, TCG_CALL_NO_WG, i32, env, f32)
 DEF_HELPER_FLAGS_2(ftrc_DT, TCG_CALL_NO_WG, i32, env, f64)
 DEF_HELPER_3(fipr, void, env, i32, i32)
 DEF_HELPER_2(ftrv, void, env, i32)
+
+#ifdef HAS_TRACEWRAP
+DEF_HELPER_1(trace_newframe, void, i32)
+DEF_HELPER_2(trace_endframe, void, env, i32)
+#endif /* HAS_TRACEWRAP */
diff --git a/target/sh4/meson.build b/target/sh4/meson.build
index 56a57576da76b..1f02c289a01d8 100644
--- a/target/sh4/meson.build
+++ b/target/sh4/meson.build
@@ -7,6 +7,10 @@ sh4_ss.add(files(
   'translate.c',
 ))
 
+if get_option('tracewrap')
+  sh4_ss.add(files('trace_helper.c'))
+endif
+
 sh4_softmmu_ss = ss.source_set()
 sh4_softmmu_ss.add(files('monitor.c'))
 
diff --git a/target/sh4/trace_helper.c b/target/sh4/trace_helper.c
new file mode 100644
index 0000000000000..71dad011acd8d
--- /dev/null
+++ b/target/sh4/trace_helper.c
@@ -0,0 +1,120 @@
+#include "tracewrap.h"
+#include "cpu.h"
+#include "qemu/log.h"
+#include "exec/helper-proto.h"
+#include "exec/memop.h"
+
+const char *regs[] = {
+    "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
+    "r0b", "r1b", "r2b", "r3b", "r4b", "r5b", "r6b", "r7b",
+    "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "sr",
+    "gbr", "ssr", "spc", "sgr", "dbr", "vbr", "mach", "macl", "pr"
+};
+static const int reg_max = sizeof(regs) / sizeof(regs[0]);
+
+void HELPER(trace_newframe)(target_ulong pc)
+{
+	qemu_trace_newframe(pc, 0);
+}
+
+void HELPER(trace_endframe)(CPUSH4State *env, target_ulong old_pc)
+{
+	qemu_trace_endframe(env, old_pc, 32);
+}
+
+/*
+OperandInfo * load_store_reg(uint32_t reg, uint32_t val, int ls)
+{
+    RegOperand * ro = g_new(RegOperand,1);
+    reg_operand__init(ro);
+    ro->name = g_strdup(reg < reg_max ? regs[reg] : "UNKNOWN");
+
+    OperandInfoSpecific *ois = g_new(OperandInfoSpecific,1);
+    operand_info_specific__init(ois);
+    ois->reg_operand = ro;
+    OperandUsage *ou = g_new(OperandUsage,1);
+    operand_usage__init(ou);
+    if (ls == 0)
+    {
+        ou->read = 1;
+    } else {
+        ou->written = 1;
+    }
+    OperandInfo *oi = g_new(OperandInfo,1);
+    operand_info__init(oi);
+    oi->bit_length = 0;
+    oi->operand_info_specific = ois;
+    oi->operand_usage = ou;
+    oi->value.len = 4;
+    oi->value.data = g_malloc(oi->value.len);
+    memcpy(oi->value.data, &val, 4);
+    return oi;
+}
+
+void HELPER(trace_load_reg)(uint32_t reg, uint32_t val)
+{
+    qemu_log("This register (r%d) was read. Value 0x%x\n", reg, val);
+
+    //r0 always reads 0
+    OperandInfo *oi = load_store_reg(reg, (reg != 0) ? val : 0, 0);
+
+    qemu_trace_add_operand(oi, 0x1);
+}
+
+void HELPER(trace_store_reg)(uint32_t reg, uint32_t val)
+{
+    qemu_log("This register (r%d) was written. Value: 0x%x\n", reg, val);
+
+    OperandInfo *oi = load_store_reg(reg, val, 1);
+
+    qemu_trace_add_operand(oi, 0x2);
+}
+
+// TODO: signature has changed, see arm
+OperandInfo * load_store_mem(uint32_t addr, uint32_t val, int ls, int len) {
+    MemOperand * mo = g_new(MemOperand,1);
+    mem_operand__init(mo);
+
+    mo->address = addr;
+
+    OperandInfoSpecific *ois = g_new(OperandInfoSpecific,1);
+    operand_info_specific__init(ois);
+    ois->mem_operand = mo;
+
+    OperandUsage *ou = g_new(OperandUsage,1);
+    operand_usage__init(ou);
+    if (ls == 0) {
+        ou->read = 1;
+    } else {
+        ou->written = 1;
+    }
+    OperandInfo *oi = g_new(OperandInfo,1);
+    operand_info__init(oi);
+    oi->bit_length = len*8;
+    oi->operand_info_specific = ois;
+    oi->operand_usage = ou;
+    oi->value.len = len;
+    oi->value.data = g_malloc(oi->value.len);
+    memcpy(oi->value.data, &val, len);
+
+    return oi;
+}
+
+void HELPER(trace_ld)(CPUMIPSState *env, uint32_t val, uint32_t addr)
+{
+    qemu_log("This was a read 0x%x addr:0x%x value:0x%x\n", env->active_tc.PC, addr, val);
+
+    OperandInfo *oi = load_store_mem(addr, val, 0, 4);
+
+    qemu_trace_add_operand(oi, 0x1);
+}
+
+void HELPER(trace_st)(CPUMIPSState *env, uint32_t val, uint32_t addr)
+{
+    qemu_log("This was a store 0x%x addr:0x%x value:0x%x\n", env->active_tc.PC, addr, val);
+
+    OperandInfo *oi = load_store_mem(addr, val, 1, 4);
+
+    qemu_trace_add_operand(oi, 0x2);
+}
+*/
\ No newline at end of file
diff --git a/target/sh4/translate.c b/target/sh4/translate.c
index ce5d674a520e7..36942a7a68c2d 100644
--- a/target/sh4/translate.c
+++ b/target/sh4/translate.c
@@ -2285,6 +2285,24 @@ static void sh4_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
     tcg_gen_insn_start(ctx->base.pc_next, ctx->envflags);
 }
 
+#ifdef HAS_TRACEWRAP
+static inline void gen_trace_newframe(uint32_t pc)
+{
+    TCGv_i32 tmp0 = tcg_temp_new_i32();
+    tcg_gen_movi_i32(tmp0, pc);
+    gen_helper_trace_newframe(tmp0);
+    tcg_temp_free_i32(tmp0);
+}
+
+static inline void gen_trace_endframe(uint32_t pc)
+{
+    TCGv_i32 tmp0 = tcg_temp_new_i32();
+    tcg_gen_movi_i32(tmp0, pc);
+    gen_helper_trace_endframe(cpu_env, tmp0);
+    tcg_temp_free_i32(tmp0);
+}
+#endif /* HAS_TRACEWRAP */
+
 static void sh4_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
 {
     CPUSH4State *env = cs->env_ptr;
@@ -2303,9 +2321,18 @@ static void sh4_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
     }
 #endif
 
+#ifdef HAS_TRACEWRAP
+    gen_trace_newframe(ctx->base.pc_next);
+#endif
+
     ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
     decode_opc(ctx);
     ctx->base.pc_next += 2;
+
+#ifdef HAS_TRACEWRAP
+    gen_trace_endframe(ctx->base.pc_next);
+#endif
+
 }
 
 static void sh4_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)

From 9018d02d7cb0e6142d8b91b3156f1f3792831315 Mon Sep 17 00:00:00 2001
From: wargio <wargio@libero.it>
Date: Mon, 26 Jun 2023 22:48:30 +0800
Subject: [PATCH 2/3] Fixed trace

---
 target/sh4/helper.h       |  4 ++++
 target/sh4/trace_helper.c | 40 +++++++++++++++++++--------------------
 2 files changed, 24 insertions(+), 20 deletions(-)

diff --git a/target/sh4/helper.h b/target/sh4/helper.h
index d2d517cf68f7d..2ed3a5bcfcc69 100644
--- a/target/sh4/helper.h
+++ b/target/sh4/helper.h
@@ -45,4 +45,8 @@ DEF_HELPER_2(ftrv, void, env, i32)
 #ifdef HAS_TRACEWRAP
 DEF_HELPER_1(trace_newframe, void, i32)
 DEF_HELPER_2(trace_endframe, void, env, i32)
+DEF_HELPER_2(trace_load_reg, void, i32, i32)
+DEF_HELPER_2(trace_store_reg, void, i32, i32)
+DEF_HELPER_3(trace_ld, void, env, i32, i32)
+DEF_HELPER_3(trace_st, void, env, i32, i32)
 #endif /* HAS_TRACEWRAP */
diff --git a/target/sh4/trace_helper.c b/target/sh4/trace_helper.c
index 71dad011acd8d..0e6f3c872dcc5 100644
--- a/target/sh4/trace_helper.c
+++ b/target/sh4/trace_helper.c
@@ -22,7 +22,6 @@ void HELPER(trace_endframe)(CPUSH4State *env, target_ulong old_pc)
 	qemu_trace_endframe(env, old_pc, 32);
 }
 
-/*
 OperandInfo * load_store_reg(uint32_t reg, uint32_t val, int ls)
 {
     RegOperand * ro = g_new(RegOperand,1);
@@ -53,7 +52,7 @@ OperandInfo * load_store_reg(uint32_t reg, uint32_t val, int ls)
 
 void HELPER(trace_load_reg)(uint32_t reg, uint32_t val)
 {
-    qemu_log("This register (r%d) was read. Value 0x%x\n", reg, val);
+    // qemu_log("This register (r%d) was read. Value 0x%x\n", reg, val);
 
     //r0 always reads 0
     OperandInfo *oi = load_store_reg(reg, (reg != 0) ? val : 0, 0);
@@ -63,58 +62,59 @@ void HELPER(trace_load_reg)(uint32_t reg, uint32_t val)
 
 void HELPER(trace_store_reg)(uint32_t reg, uint32_t val)
 {
-    qemu_log("This register (r%d) was written. Value: 0x%x\n", reg, val);
+    // qemu_log("This register (r%d) was written. Value: 0x%x\n", reg, val);
 
     OperandInfo *oi = load_store_reg(reg, val, 1);
 
     qemu_trace_add_operand(oi, 0x2);
 }
 
-// TODO: signature has changed, see arm
-OperandInfo * load_store_mem(uint32_t addr, uint32_t val, int ls, int len) {
-    MemOperand * mo = g_new(MemOperand,1);
+OperandInfo *load_store_mem(uint64_t addr, int ls, const void *data, size_t data_size) {
+    MemOperand * mo = g_new(MemOperand, 1);
     mem_operand__init(mo);
 
     mo->address = addr;
 
-    OperandInfoSpecific *ois = g_new(OperandInfoSpecific,1);
+    OperandInfoSpecific *ois = g_new(OperandInfoSpecific, 1);
     operand_info_specific__init(ois);
     ois->mem_operand = mo;
 
-    OperandUsage *ou = g_new(OperandUsage,1);
+    OperandUsage *ou = g_new(OperandUsage, 1);
     operand_usage__init(ou);
     if (ls == 0) {
         ou->read = 1;
     } else {
         ou->written = 1;
     }
-    OperandInfo *oi = g_new(OperandInfo,1);
+    OperandInfo *oi = g_new(OperandInfo, 1);
     operand_info__init(oi);
-    oi->bit_length = len*8;
+    oi->bit_length = data_size * 8;
     oi->operand_info_specific = ois;
     oi->operand_usage = ou;
-    oi->value.len = len;
+    oi->value.len = data_size;
     oi->value.data = g_malloc(oi->value.len);
-    memcpy(oi->value.data, &val, len);
-
+    #ifdef BSWAP_NEEDED
+    memcpy_rev(oi->value.data, data, data_size);
+    #else
+    memcpy(oi->value.data, data, data_size);
+    #endif
     return oi;
 }
 
-void HELPER(trace_ld)(CPUMIPSState *env, uint32_t val, uint32_t addr)
+void HELPER(trace_ld)(CPUSH4State *env, uint32_t val, uint32_t addr)
 {
-    qemu_log("This was a read 0x%x addr:0x%x value:0x%x\n", env->active_tc.PC, addr, val);
+    // qemu_log("This was a read 0x%x addr:0x%x value:0x%x\n", env->active_tc.PC, addr, val);
 
-    OperandInfo *oi = load_store_mem(addr, val, 0, 4);
+    OperandInfo *oi = load_store_mem(addr, 0, val, 4);
 
     qemu_trace_add_operand(oi, 0x1);
 }
 
-void HELPER(trace_st)(CPUMIPSState *env, uint32_t val, uint32_t addr)
+void HELPER(trace_st)(CPUSH4State *env, uint32_t val, uint32_t addr)
 {
-    qemu_log("This was a store 0x%x addr:0x%x value:0x%x\n", env->active_tc.PC, addr, val);
+    // qemu_log("This was a store 0x%x addr:0x%x value:0x%x\n", env->active_tc.PC, addr, val);
 
-    OperandInfo *oi = load_store_mem(addr, val, 1, 4);
+    OperandInfo *oi = load_store_mem(addr, 1, val, 4);
 
     qemu_trace_add_operand(oi, 0x2);
 }
-*/
\ No newline at end of file

From 55cca7a8d322f025475f12b82cf0df26d57c9a94 Mon Sep 17 00:00:00 2001
From: wargio <wargio@libero.it>
Date: Thu, 29 Jun 2023 11:19:14 +0800
Subject: [PATCH 3/3] Trying to make things work

---
 target/sh4/helper.h       |  4 +-
 target/sh4/trace_helper.c | 21 ++++-----
 target/sh4/translate.c    | 95 +++++++++++++++++++++++++++++----------
 3 files changed, 83 insertions(+), 37 deletions(-)

diff --git a/target/sh4/helper.h b/target/sh4/helper.h
index 2ed3a5bcfcc69..cb274a0c38e3c 100644
--- a/target/sh4/helper.h
+++ b/target/sh4/helper.h
@@ -47,6 +47,6 @@ DEF_HELPER_1(trace_newframe, void, i32)
 DEF_HELPER_2(trace_endframe, void, env, i32)
 DEF_HELPER_2(trace_load_reg, void, i32, i32)
 DEF_HELPER_2(trace_store_reg, void, i32, i32)
-DEF_HELPER_3(trace_ld, void, env, i32, i32)
-DEF_HELPER_3(trace_st, void, env, i32, i32)
+DEF_HELPER_3(trace_load_mem, void, i32, i32, i32)
+DEF_HELPER_3(trace_store_mem, void, i32, i32, i32)
 #endif /* HAS_TRACEWRAP */
diff --git a/target/sh4/trace_helper.c b/target/sh4/trace_helper.c
index 0e6f3c872dcc5..a619bc926ddc0 100644
--- a/target/sh4/trace_helper.c
+++ b/target/sh4/trace_helper.c
@@ -3,6 +3,7 @@
 #include "qemu/log.h"
 #include "exec/helper-proto.h"
 #include "exec/memop.h"
+#include "qemu/log.h"
 
 const char *regs[] = {
     "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
@@ -52,7 +53,7 @@ OperandInfo * load_store_reg(uint32_t reg, uint32_t val, int ls)
 
 void HELPER(trace_load_reg)(uint32_t reg, uint32_t val)
 {
-    // qemu_log("This register (r%d) was read. Value 0x%x\n", reg, val);
+    qemu_log("This register (r%d) was read. Value 0x%x\n", reg, val);
 
     //r0 always reads 0
     OperandInfo *oi = load_store_reg(reg, (reg != 0) ? val : 0, 0);
@@ -62,7 +63,7 @@ void HELPER(trace_load_reg)(uint32_t reg, uint32_t val)
 
 void HELPER(trace_store_reg)(uint32_t reg, uint32_t val)
 {
-    // qemu_log("This register (r%d) was written. Value: 0x%x\n", reg, val);
+    qemu_log("This register (r%d) was written. Value: 0x%x\n", reg, val);
 
     OperandInfo *oi = load_store_reg(reg, val, 1);
 
@@ -101,20 +102,16 @@ OperandInfo *load_store_mem(uint64_t addr, int ls, const void *data, size_t data
     return oi;
 }
 
-void HELPER(trace_ld)(CPUSH4State *env, uint32_t val, uint32_t addr)
+void HELPER(trace_load_mem)(uint32_t addr, uint32_t val, uint32_t op)
 {
-    // qemu_log("This was a read 0x%x addr:0x%x value:0x%x\n", env->active_tc.PC, addr, val);
-
-    OperandInfo *oi = load_store_mem(addr, 0, val, 4);
-
+    qemu_log("LOAD at 0x%lx size: %d data: 0x%lx\n", (unsigned long) addr, memop_size(op), (unsigned long) val);
+    OperandInfo *oi = load_store_mem(addr, 0, &val, memop_size(op));
     qemu_trace_add_operand(oi, 0x1);
 }
 
-void HELPER(trace_st)(CPUSH4State *env, uint32_t val, uint32_t addr)
+void HELPER(trace_store_mem)(uint32_t addr, uint32_t val, uint32_t op)
 {
-    // qemu_log("This was a store 0x%x addr:0x%x value:0x%x\n", env->active_tc.PC, addr, val);
-
-    OperandInfo *oi = load_store_mem(addr, 1, val, 4);
-
+    qemu_log("STORE at 0x%lx size: %d data: 0x%lx\n", (unsigned long) addr, memop_size(op), (unsigned long) val);
+    OperandInfo *oi = load_store_mem(addr, 1, &val, memop_size(op));
     qemu_trace_add_operand(oi, 0x2);
 }
diff --git a/target/sh4/translate.c b/target/sh4/translate.c
index 36942a7a68c2d..0aff9da2172e6 100644
--- a/target/sh4/translate.c
+++ b/target/sh4/translate.c
@@ -185,6 +185,66 @@ void superh_cpu_dump_state(CPUState *cs, FILE *f, int flags)
     }
 }
 
+#ifdef HAS_TRACEWRAP
+static void gen_trace_load_reg(uint32_t reg, TCGv var)
+{
+    TCGv_i32 t = tcg_const_i32(reg);
+    gen_helper_trace_load_reg(t, var);
+    tcg_temp_free_i32(t);
+}
+
+static void gen_trace_store_reg(uint32_t reg, TCGv var)
+{
+    TCGv_i32 t = tcg_const_i32(reg);
+    gen_helper_trace_store_reg(t, var);
+    tcg_temp_free_i32(t);
+}
+
+static inline void gen_trace_newframe(uint32_t pc)
+{
+    TCGv_i32 tmp0 = tcg_temp_new_i32();
+    tcg_gen_movi_i32(tmp0, pc);
+    gen_helper_trace_newframe(tmp0);
+    tcg_temp_free_i32(tmp0);
+}
+
+static inline void gen_trace_endframe(uint32_t pc)
+{
+    TCGv_i32 tmp0 = tcg_temp_new_i32();
+    tcg_gen_movi_i32(tmp0, pc);
+    gen_helper_trace_endframe(cpu_env, tmp0);
+    tcg_temp_free_i32(tmp0);
+}
+#endif /* HAS_TRACEWRAP */
+
+static inline void log_load_gpr(uint32_t rx, TCGv var) {
+    #ifdef HAS_TRACEWRAP
+    gen_trace_load_reg(rx, var);
+    #endif
+}
+
+static inline void log_store_gpr(uint32_t rx, TCGv var) {
+    #ifdef HAS_TRACEWRAP
+    gen_trace_store_reg(rx, var);
+    #endif
+}
+
+static inline void log_load_mem(TCGv addr, TCGv val, MemOp op) {
+    #ifdef HAS_TRACEWRAP
+    TCGv_i32 o = tcg_const_i32(op);
+    gen_helper_trace_load_mem(addr, val, o);
+    tcg_temp_free_i32(o);
+    #endif
+}
+
+static inline void log_store_mem(TCGv addr, TCGv val, MemOp op) {
+    #ifdef HAS_TRACEWRAP
+    TCGv_i32 o = tcg_const_i32(op);
+    gen_helper_trace_store_mem(addr, val, o);
+    tcg_temp_free_i32(o);
+    #endif
+}
+
 static void gen_read_sr(TCGv dst)
 {
     TCGv t0 = tcg_temp_new();
@@ -238,6 +298,9 @@ static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
         tcg_gen_goto_tb(n);
         tcg_gen_movi_i32(cpu_pc, dest);
         tcg_gen_exit_tb(ctx->base.tb, n);
+        #ifdef HAS_TRACEWRAP
+        gen_trace_endframe(dest);
+        #endif
     } else {
         tcg_gen_movi_i32(cpu_pc, dest);
         if (use_exit_tb(ctx)) {
@@ -529,8 +592,9 @@ static void _decode_opc(DisasContext * ctx)
 	return;
     case 0xd000:		/* mov.l @(disp,PC),Rn */
 	{
-            TCGv addr = tcg_const_i32((ctx->base.pc_next + 4 + B7_0 * 4) & ~3);
-            tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESL);
+        TCGv addr = tcg_const_i32((ctx->base.pc_next + 4 + B7_0 * 4) & ~3);
+        tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESL);
+        log_load_mem(addr, REG(B11_8), MO_TESL);
 	    tcg_temp_free(addr);
 	}
 	return;
@@ -552,7 +616,7 @@ static void _decode_opc(DisasContext * ctx)
 
     switch (ctx->opcode & 0xf00f) {
     case 0x6003:		/* mov Rm,Rn */
-	tcg_gen_mov_i32(REG(B11_8), REG(B7_4));
+    	tcg_gen_mov_i32(REG(B11_8), REG(B7_4));
 	return;
     case 0x2000:		/* mov.b Rm,@Rn */
         tcg_gen_qemu_st_i32(REG(B7_4), REG(B11_8), ctx->memidx, MO_UB);
@@ -659,8 +723,8 @@ static void _decode_opc(DisasContext * ctx)
 	{
 	    TCGv addr = tcg_temp_new();
 	    tcg_gen_add_i32(addr, REG(B7_4), REG(0));
-            tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESL);
-	    tcg_temp_free(addr);
+        tcg_gen_qemu_ld_i32(REG(B11_8), addr, ctx->memidx, MO_TESL);
+ 	    tcg_temp_free(addr);
 	}
 	return;
     case 0x6008:		/* swap.b Rm,Rn */
@@ -2285,24 +2349,6 @@ static void sh4_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
     tcg_gen_insn_start(ctx->base.pc_next, ctx->envflags);
 }
 
-#ifdef HAS_TRACEWRAP
-static inline void gen_trace_newframe(uint32_t pc)
-{
-    TCGv_i32 tmp0 = tcg_temp_new_i32();
-    tcg_gen_movi_i32(tmp0, pc);
-    gen_helper_trace_newframe(tmp0);
-    tcg_temp_free_i32(tmp0);
-}
-
-static inline void gen_trace_endframe(uint32_t pc)
-{
-    TCGv_i32 tmp0 = tcg_temp_new_i32();
-    tcg_gen_movi_i32(tmp0, pc);
-    gen_helper_trace_endframe(cpu_env, tmp0);
-    tcg_temp_free_i32(tmp0);
-}
-#endif /* HAS_TRACEWRAP */
-
 static void sh4_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
 {
     CPUSH4State *env = cs->env_ptr;
@@ -2353,6 +2399,9 @@ static void sh4_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
     case DISAS_TOO_MANY:
         gen_save_cpu_state(ctx, false);
         gen_goto_tb(ctx, 0, ctx->base.pc_next);
+    #ifdef HAS_TRACEWRAP
+        gen_trace_endframe(ctx->base.pc_next);
+    #endif
         break;
     case DISAS_NORETURN:
         break;