]> git.proxmox.com Git - mirror_qemu.git/blobdiff - target/sparc/translate.c
target/sparc: Use tcg_gen_lookup_and_goto_ptr in gen_goto_tb
[mirror_qemu.git] / target / sparc / translate.c
index a20426202e505ad7f1af13f998d10b83223be73d..28d4cdb8b41691a339798eda8f626317e87dcc80 100644 (file)
@@ -33,8 +33,9 @@
 #include "exec/log.h"
 #include "asi.h"
 
-
-#define DEBUG_DISAS
+#define HELPER_H "helper.h"
+#include "exec/helper-info.c.inc"
+#undef  HELPER_H
 
 #define DYNAMIC_PC  1 /* dynamic pc value */
 #define JUMP_PC     2 /* dynamic pc value which takes only two values
@@ -65,8 +66,6 @@ static TCGv cpu_wim;
 /* Floating point registers */
 static TCGv_i64 cpu_fpr[TARGET_DPREGS];
 
-#include "exec/gen-icount.h"
-
 typedef struct DisasContext {
     DisasContextBase base;
     target_ulong pc;    /* current Program Counter: integer or DYNAMIC_PC */
@@ -93,7 +92,6 @@ typedef struct DisasContext {
 typedef struct {
     TCGCond cond;
     bool is_bool;
-    bool g1, g2;
     TCGv c1, c2;
 } DisasCompare;
 
@@ -159,7 +157,6 @@ static void gen_store_fpr_F(DisasContext *dc, unsigned int dst, TCGv_i32 v)
     tcg_gen_extu_i32_i64(t, v);
     tcg_gen_deposit_i64(cpu_fpr[dst / 2], cpu_fpr[dst / 2], t,
                         (dst & 1 ? 0 : 32), 32);
-    tcg_temp_free_i64(t);
     gen_update_fprs_dirty(dc, dst);
 }
 
@@ -321,10 +318,10 @@ static void gen_goto_tb(DisasContext *s, int tb_num,
         tcg_gen_movi_tl(cpu_npc, npc);
         tcg_gen_exit_tb(s->base.tb, tb_num);
     } else {
-        /* jump to another page: currently not optimized */
+        /* jump to another page: we can use an indirect jump */
         tcg_gen_movi_tl(cpu_pc, pc);
         tcg_gen_movi_tl(cpu_npc, npc);
-        tcg_gen_exit_tb(NULL, 0);
+        tcg_gen_lookup_and_goto_ptr();
     }
 }
 
@@ -379,11 +376,6 @@ static TCGv_i32 gen_add32_carry32(void)
     carry_32 = tcg_temp_new_i32();
     tcg_gen_setcond_i32(TCG_COND_LTU, carry_32, cc_src1_32, cc_src2_32);
 
-#if TARGET_LONG_BITS == 64
-    tcg_temp_free_i32(cc_src1_32);
-    tcg_temp_free_i32(cc_src2_32);
-#endif
-
     return carry_32;
 }
 
@@ -405,11 +397,6 @@ static TCGv_i32 gen_sub32_carry32(void)
     carry_32 = tcg_temp_new_i32();
     tcg_gen_setcond_i32(TCG_COND_LTU, carry_32, cc_src1_32, cc_src2_32);
 
-#if TARGET_LONG_BITS == 64
-    tcg_temp_free_i32(cc_src1_32);
-    tcg_temp_free_i32(cc_src2_32);
-#endif
-
     return carry_32;
 }
 
@@ -440,7 +427,6 @@ static void gen_op_addx_int(DisasContext *dc, TCGv dst, TCGv src1,
                generated the carry in the first place.  */
             carry = tcg_temp_new();
             tcg_gen_add2_tl(carry, dst, cpu_cc_src, src1, cpu_cc_src2, src2);
-            tcg_temp_free(carry);
             goto add_done;
         }
         carry_32 = gen_add32_carry32();
@@ -469,11 +455,6 @@ static void gen_op_addx_int(DisasContext *dc, TCGv dst, TCGv src1,
     tcg_gen_add_tl(dst, src1, src2);
     tcg_gen_add_tl(dst, dst, carry);
 
-    tcg_temp_free_i32(carry_32);
-#if TARGET_LONG_BITS == 64
-    tcg_temp_free(carry);
-#endif
-
  add_done:
     if (update_cc) {
         tcg_gen_mov_tl(cpu_cc_src, src1);
@@ -525,7 +506,6 @@ static void gen_op_subx_int(DisasContext *dc, TCGv dst, TCGv src1,
                generated the carry in the first place.  */
             carry = tcg_temp_new();
             tcg_gen_sub2_tl(carry, dst, cpu_cc_src, src1, cpu_cc_src2, src2);
-            tcg_temp_free(carry);
             goto sub_done;
         }
         carry_32 = gen_sub32_carry32();
@@ -548,11 +528,6 @@ static void gen_op_subx_int(DisasContext *dc, TCGv dst, TCGv src1,
     tcg_gen_sub_tl(dst, src1, src2);
     tcg_gen_sub_tl(dst, dst, carry);
 
-    tcg_temp_free_i32(carry_32);
-#if TARGET_LONG_BITS == 64
-    tcg_temp_free(carry);
-#endif
-
  sub_done:
     if (update_cc) {
         tcg_gen_mov_tl(cpu_cc_src, src1);
@@ -574,13 +549,12 @@ static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
     if (!(env->y & 1))
         T1 = 0;
     */
-    zero = tcg_const_tl(0);
+    zero = tcg_constant_tl(0);
     tcg_gen_andi_tl(cpu_cc_src, src1, 0xffffffff);
     tcg_gen_andi_tl(r_temp, cpu_y, 0x1);
     tcg_gen_andi_tl(cpu_cc_src2, src2, 0xffffffff);
     tcg_gen_movcond_tl(TCG_COND_EQ, cpu_cc_src2, r_temp, zero,
                        zero, cpu_cc_src2);
-    tcg_temp_free(zero);
 
     // b2 = T0 & 1;
     // env->y = (b2 << 31) | (env->y >> 1);
@@ -591,14 +565,12 @@ static inline void gen_op_mulscc(TCGv dst, TCGv src1, TCGv src2)
     gen_mov_reg_N(t0, cpu_psr);
     gen_mov_reg_V(r_temp, cpu_psr);
     tcg_gen_xor_tl(t0, t0, r_temp);
-    tcg_temp_free(r_temp);
 
     // T0 = (b1 << 31) | (T0 >> 1);
     // src1 = T0;
     tcg_gen_shli_tl(t0, t0, 31);
     tcg_gen_shri_tl(cpu_cc_src, cpu_cc_src, 1);
     tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, t0);
-    tcg_temp_free(t0);
 
     tcg_gen_add_tl(cpu_cc_dst, cpu_cc_src, cpu_cc_src2);
 
@@ -626,9 +598,6 @@ static inline void gen_op_multiply(TCGv dst, TCGv src1, TCGv src2, int sign_ext)
     }
 
     tcg_gen_mul_i64(dst, t0, t1);
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
-
     tcg_gen_shri_i64(cpu_y, dst, 32);
 #endif
 }
@@ -666,7 +635,6 @@ static inline void gen_op_eval_ble(TCGv dst, TCGv_i32 src)
     tcg_gen_xor_tl(dst, dst, t0);
     gen_mov_reg_Z(t0, src);
     tcg_gen_or_tl(dst, dst, t0);
-    tcg_temp_free(t0);
 }
 
 // N ^ V
@@ -676,7 +644,6 @@ static inline void gen_op_eval_bl(TCGv dst, TCGv_i32 src)
     gen_mov_reg_V(t0, src);
     gen_mov_reg_N(dst, src);
     tcg_gen_xor_tl(dst, dst, t0);
-    tcg_temp_free(t0);
 }
 
 // C | Z
@@ -686,7 +653,6 @@ static inline void gen_op_eval_bleu(TCGv dst, TCGv_i32 src)
     gen_mov_reg_Z(t0, src);
     gen_mov_reg_C(dst, src);
     tcg_gen_or_tl(dst, dst, t0);
-    tcg_temp_free(t0);
 }
 
 // C
@@ -791,7 +757,6 @@ static inline void gen_op_eval_fbne(TCGv dst, TCGv src,
     gen_mov_reg_FCC0(dst, src, fcc_offset);
     gen_mov_reg_FCC1(t0, src, fcc_offset);
     tcg_gen_or_tl(dst, dst, t0);
-    tcg_temp_free(t0);
 }
 
 // 1 or 2: FCC0 ^ FCC1
@@ -802,7 +767,6 @@ static inline void gen_op_eval_fblg(TCGv dst, TCGv src,
     gen_mov_reg_FCC0(dst, src, fcc_offset);
     gen_mov_reg_FCC1(t0, src, fcc_offset);
     tcg_gen_xor_tl(dst, dst, t0);
-    tcg_temp_free(t0);
 }
 
 // 1 or 3: FCC0
@@ -820,7 +784,6 @@ static inline void gen_op_eval_fbl(TCGv dst, TCGv src,
     gen_mov_reg_FCC0(dst, src, fcc_offset);
     gen_mov_reg_FCC1(t0, src, fcc_offset);
     tcg_gen_andc_tl(dst, dst, t0);
-    tcg_temp_free(t0);
 }
 
 // 2 or 3: FCC1
@@ -838,7 +801,6 @@ static inline void gen_op_eval_fbg(TCGv dst, TCGv src,
     gen_mov_reg_FCC0(dst, src, fcc_offset);
     gen_mov_reg_FCC1(t0, src, fcc_offset);
     tcg_gen_andc_tl(dst, t0, dst);
-    tcg_temp_free(t0);
 }
 
 // 3: FCC0 & FCC1
@@ -849,7 +811,6 @@ static inline void gen_op_eval_fbu(TCGv dst, TCGv src,
     gen_mov_reg_FCC0(dst, src, fcc_offset);
     gen_mov_reg_FCC1(t0, src, fcc_offset);
     tcg_gen_and_tl(dst, dst, t0);
-    tcg_temp_free(t0);
 }
 
 // 0: !(FCC0 | FCC1)
@@ -861,7 +822,6 @@ static inline void gen_op_eval_fbe(TCGv dst, TCGv src,
     gen_mov_reg_FCC1(t0, src, fcc_offset);
     tcg_gen_or_tl(dst, dst, t0);
     tcg_gen_xori_tl(dst, dst, 0x1);
-    tcg_temp_free(t0);
 }
 
 // 0 or 3: !(FCC0 ^ FCC1)
@@ -873,7 +833,6 @@ static inline void gen_op_eval_fbue(TCGv dst, TCGv src,
     gen_mov_reg_FCC1(t0, src, fcc_offset);
     tcg_gen_xor_tl(dst, dst, t0);
     tcg_gen_xori_tl(dst, dst, 0x1);
-    tcg_temp_free(t0);
 }
 
 // 0 or 2: !FCC0
@@ -893,7 +852,6 @@ static inline void gen_op_eval_fbuge(TCGv dst, TCGv src,
     gen_mov_reg_FCC1(t0, src, fcc_offset);
     tcg_gen_andc_tl(dst, dst, t0);
     tcg_gen_xori_tl(dst, dst, 0x1);
-    tcg_temp_free(t0);
 }
 
 // 0 or 1: !FCC1
@@ -913,7 +871,6 @@ static inline void gen_op_eval_fbule(TCGv dst, TCGv src,
     gen_mov_reg_FCC1(t0, src, fcc_offset);
     tcg_gen_andc_tl(dst, t0, dst);
     tcg_gen_xori_tl(dst, dst, 0x1);
-    tcg_temp_free(t0);
 }
 
 // !3: !(FCC0 & FCC1)
@@ -925,7 +882,6 @@ static inline void gen_op_eval_fbo(TCGv dst, TCGv src,
     gen_mov_reg_FCC1(t0, src, fcc_offset);
     tcg_gen_and_tl(dst, dst, t0);
     tcg_gen_xori_tl(dst, dst, 0x1);
-    tcg_temp_free(t0);
 }
 
 static inline void gen_branch2(DisasContext *dc, target_ulong pc1,
@@ -971,11 +927,9 @@ static void gen_branch_n(DisasContext *dc, target_ulong pc1)
         tcg_gen_mov_tl(cpu_pc, cpu_npc);
 
         tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
-        t = tcg_const_tl(pc1);
-        z = tcg_const_tl(0);
+        t = tcg_constant_tl(pc1);
+        z = tcg_constant_tl(0);
         tcg_gen_movcond_tl(TCG_COND_NE, cpu_npc, cpu_cond, z, t, cpu_npc);
-        tcg_temp_free(t);
-        tcg_temp_free(z);
 
         dc->pc = DYNAMIC_PC;
     }
@@ -983,15 +937,11 @@ static void gen_branch_n(DisasContext *dc, target_ulong pc1)
 
 static inline void gen_generic_branch(DisasContext *dc)
 {
-    TCGv npc0 = tcg_const_tl(dc->jump_pc[0]);
-    TCGv npc1 = tcg_const_tl(dc->jump_pc[1]);
-    TCGv zero = tcg_const_tl(0);
+    TCGv npc0 = tcg_constant_tl(dc->jump_pc[0]);
+    TCGv npc1 = tcg_constant_tl(dc->jump_pc[1]);
+    TCGv zero = tcg_constant_tl(0);
 
     tcg_gen_movcond_tl(TCG_COND_NE, cpu_npc, cpu_cond, zero, npc0, npc1);
-
-    tcg_temp_free(npc0);
-    tcg_temp_free(npc1);
-    tcg_temp_free(zero);
 }
 
 /* call this function before using the condition register as it may
@@ -1030,20 +980,14 @@ static inline void save_state(DisasContext *dc)
 
 static void gen_exception(DisasContext *dc, int which)
 {
-    TCGv_i32 t;
-
     save_state(dc);
-    t = tcg_const_i32(which);
-    gen_helper_raise_exception(cpu_env, t);
-    tcg_temp_free_i32(t);
+    gen_helper_raise_exception(cpu_env, tcg_constant_i32(which));
     dc->base.is_jmp = DISAS_NORETURN;
 }
 
 static void gen_check_align(TCGv addr, int mask)
 {
-    TCGv_i32 r_mask = tcg_const_i32(mask);
-    gen_helper_check_align(cpu_env, addr, r_mask);
-    tcg_temp_free_i32(r_mask);
+    gen_helper_check_align(cpu_env, addr, tcg_constant_i32(mask));
 }
 
 static inline void gen_mov_pc_npc(DisasContext *dc)
@@ -1066,16 +1010,6 @@ static inline void gen_op_next_insn(void)
     tcg_gen_addi_tl(cpu_npc, cpu_npc, 4);
 }
 
-static void free_compare(DisasCompare *cmp)
-{
-    if (!cmp->g1) {
-        tcg_temp_free(cmp->c1);
-    }
-    if (!cmp->g2) {
-        tcg_temp_free(cmp->c2);
-    }
-}
-
 static void gen_compare(DisasCompare *cmp, bool xcc, unsigned int cond,
                         DisasContext *dc)
 {
@@ -1135,17 +1069,14 @@ static void gen_compare(DisasCompare *cmp, bool xcc, unsigned int cond,
         cmp->cond = logic_cond[cond];
     do_compare_dst_0:
         cmp->is_bool = false;
-        cmp->g2 = false;
-        cmp->c2 = tcg_const_tl(0);
+        cmp->c2 = tcg_constant_tl(0);
 #ifdef TARGET_SPARC64
         if (!xcc) {
-            cmp->g1 = false;
             cmp->c1 = tcg_temp_new();
             tcg_gen_ext32s_tl(cmp->c1, cpu_cc_dst);
             break;
         }
 #endif
-        cmp->g1 = true;
         cmp->c1 = cpu_cc_dst;
         break;
 
@@ -1167,7 +1098,6 @@ static void gen_compare(DisasCompare *cmp, bool xcc, unsigned int cond,
             if (!xcc) {
                 /* Note that sign-extension works for unsigned compares as
                    long as both operands are sign-extended.  */
-                cmp->g1 = cmp->g2 = false;
                 cmp->c1 = tcg_temp_new();
                 cmp->c2 = tcg_temp_new();
                 tcg_gen_ext32s_tl(cmp->c1, cpu_cc_src);
@@ -1175,7 +1105,6 @@ static void gen_compare(DisasCompare *cmp, bool xcc, unsigned int cond,
                 break;
             }
 #endif
-            cmp->g1 = cmp->g2 = true;
             cmp->c1 = cpu_cc_src;
             cmp->c2 = cpu_cc_src2;
             break;
@@ -1192,9 +1121,8 @@ static void gen_compare(DisasCompare *cmp, bool xcc, unsigned int cond,
         /* We're going to generate a boolean result.  */
         cmp->cond = TCG_COND_NE;
         cmp->is_bool = true;
-        cmp->g1 = cmp->g2 = false;
         cmp->c1 = r_dst = tcg_temp_new();
-        cmp->c2 = tcg_const_tl(0);
+        cmp->c2 = tcg_constant_tl(0);
 
         switch (cond) {
         case 0x0:
@@ -1258,9 +1186,8 @@ static void gen_fcompare(DisasCompare *cmp, unsigned int cc, unsigned int cond)
     /* For now we still generate a straight boolean result.  */
     cmp->cond = TCG_COND_NE;
     cmp->is_bool = true;
-    cmp->g1 = cmp->g2 = false;
     cmp->c1 = r_dst = tcg_temp_new();
-    cmp->c2 = tcg_const_tl(0);
+    cmp->c2 = tcg_constant_tl(0);
 
     switch (cc) {
     default:
@@ -1342,8 +1269,6 @@ static void gen_cond(TCGv r_dst, unsigned int cc, unsigned int cond,
     } else {
         tcg_gen_setcond_tl(cmp.cond, r_dst, cmp.c1, cmp.c2);
     }
-
-    free_compare(&cmp);
 }
 
 static void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
@@ -1357,8 +1282,6 @@ static void gen_fcond(TCGv r_dst, unsigned int cc, unsigned int cond)
     } else {
         tcg_gen_setcond_tl(cmp.cond, r_dst, cmp.c1, cmp.c2);
     }
-
-    free_compare(&cmp);
 }
 
 #ifdef TARGET_SPARC64
@@ -1378,10 +1301,8 @@ static void gen_compare_reg(DisasCompare *cmp, int cond, TCGv r_src)
 {
     cmp->cond = tcg_invert_cond(gen_tcg_cond_reg[cond]);
     cmp->is_bool = false;
-    cmp->g1 = true;
-    cmp->g2 = false;
     cmp->c1 = r_src;
-    cmp->c2 = tcg_const_tl(0);
+    cmp->c2 = tcg_constant_tl(0);
 }
 
 static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
@@ -1391,8 +1312,6 @@ static inline void gen_cond_reg(TCGv r_dst, int cond, TCGv r_src)
 
     /* The interface is to return a boolean in r_dst.  */
     tcg_gen_setcond_tl(cmp.cond, r_dst, cmp.c1, cmp.c2);
-
-    free_compare(&cmp);
 }
 #endif
 
@@ -1979,15 +1898,14 @@ static void gen_swap(DisasContext *dc, TCGv dst, TCGv src,
                      TCGv addr, int mmu_idx, MemOp memop)
 {
     gen_address_mask(dc, addr);
-    tcg_gen_atomic_xchg_tl(dst, addr, src, mmu_idx, memop);
+    tcg_gen_atomic_xchg_tl(dst, addr, src, mmu_idx, memop | MO_ALIGN);
 }
 
 static void gen_ldstub(DisasContext *dc, TCGv dst, TCGv addr, int mmu_idx)
 {
-    TCGv m1 = tcg_const_tl(0xff);
+    TCGv m1 = tcg_constant_tl(0xff);
     gen_address_mask(dc, addr);
     tcg_gen_atomic_xchg_tl(dst, addr, m1, mmu_idx, MO_UB);
-    tcg_temp_free(m1);
 }
 
 /* asi moves */
@@ -2236,12 +2154,12 @@ static void gen_ld_asi(DisasContext *dc, TCGv dst, TCGv addr,
         break;
     case GET_ASI_DIRECT:
         gen_address_mask(dc, addr);
-        tcg_gen_qemu_ld_tl(dst, addr, da.mem_idx, da.memop);
+        tcg_gen_qemu_ld_tl(dst, addr, da.mem_idx, da.memop | MO_ALIGN);
         break;
     default:
         {
-            TCGv_i32 r_asi = tcg_const_i32(da.asi);
-            TCGv_i32 r_mop = tcg_const_i32(memop);
+            TCGv_i32 r_asi = tcg_constant_i32(da.asi);
+            TCGv_i32 r_mop = tcg_constant_i32(memop | MO_ALIGN);
 
             save_state(dc);
 #ifdef TARGET_SPARC64
@@ -2251,11 +2169,8 @@ static void gen_ld_asi(DisasContext *dc, TCGv dst, TCGv addr,
                 TCGv_i64 t64 = tcg_temp_new_i64();
                 gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_mop);
                 tcg_gen_trunc_i64_tl(dst, t64);
-                tcg_temp_free_i64(t64);
             }
 #endif
-            tcg_temp_free_i32(r_mop);
-            tcg_temp_free_i32(r_asi);
         }
         break;
     }
@@ -2285,7 +2200,7 @@ static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr,
         /* fall through */
     case GET_ASI_DIRECT:
         gen_address_mask(dc, addr);
-        tcg_gen_qemu_st_tl(src, addr, da.mem_idx, da.memop);
+        tcg_gen_qemu_st_tl(src, addr, da.mem_idx, da.memop | MO_ALIGN);
         break;
 #if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
     case GET_ASI_BCOPY:
@@ -2297,7 +2212,7 @@ static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr,
         {
             TCGv saddr = tcg_temp_new();
             TCGv daddr = tcg_temp_new();
-            TCGv four = tcg_const_tl(4);
+            TCGv four = tcg_constant_tl(4);
             TCGv_i32 tmp = tcg_temp_new_i32();
             int i;
 
@@ -2311,18 +2226,13 @@ static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr,
                 tcg_gen_add_tl(saddr, saddr, four);
                 tcg_gen_add_tl(daddr, daddr, four);
             }
-
-            tcg_temp_free(saddr);
-            tcg_temp_free(daddr);
-            tcg_temp_free(four);
-            tcg_temp_free_i32(tmp);
         }
         break;
 #endif
     default:
         {
-            TCGv_i32 r_asi = tcg_const_i32(da.asi);
-            TCGv_i32 r_mop = tcg_const_i32(memop & MO_SIZE);
+            TCGv_i32 r_asi = tcg_constant_i32(da.asi);
+            TCGv_i32 r_mop = tcg_constant_i32(memop | MO_ALIGN);
 
             save_state(dc);
 #ifdef TARGET_SPARC64
@@ -2332,11 +2242,8 @@ static void gen_st_asi(DisasContext *dc, TCGv src, TCGv addr,
                 TCGv_i64 t64 = tcg_temp_new_i64();
                 tcg_gen_extu_tl_i64(t64, src);
                 gen_helper_st_asi(cpu_env, addr, t64, r_asi, r_mop);
-                tcg_temp_free_i64(t64);
             }
 #endif
-            tcg_temp_free_i32(r_mop);
-            tcg_temp_free_i32(r_asi);
 
             /* A write to a TLB register may alter page maps.  End the TB. */
             dc->npc = DYNAMIC_PC;
@@ -2375,9 +2282,8 @@ static void gen_cas_asi(DisasContext *dc, TCGv addr, TCGv cmpv,
     case GET_ASI_DIRECT:
         oldv = tcg_temp_new();
         tcg_gen_atomic_cmpxchg_tl(oldv, addr, cmpv, gen_load_gpr(dc, rd),
-                                  da.mem_idx, da.memop);
+                                  da.mem_idx, da.memop | MO_ALIGN);
         gen_store_gpr(dc, rd, oldv);
-        tcg_temp_free(oldv);
         break;
     default:
         /* ??? Should be DAE_invalid_asi.  */
@@ -2402,22 +2308,18 @@ static void gen_ldstub_asi(DisasContext *dc, TCGv dst, TCGv addr, int insn)
         if (tb_cflags(dc->base.tb) & CF_PARALLEL) {
             gen_helper_exit_atomic(cpu_env);
         } else {
-            TCGv_i32 r_asi = tcg_const_i32(da.asi);
-            TCGv_i32 r_mop = tcg_const_i32(MO_UB);
+            TCGv_i32 r_asi = tcg_constant_i32(da.asi);
+            TCGv_i32 r_mop = tcg_constant_i32(MO_UB);
             TCGv_i64 s64, t64;
 
             save_state(dc);
             t64 = tcg_temp_new_i64();
             gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_mop);
 
-            s64 = tcg_const_i64(0xff);
+            s64 = tcg_constant_i64(0xff);
             gen_helper_st_asi(cpu_env, addr, s64, r_asi, r_mop);
-            tcg_temp_free_i64(s64);
-            tcg_temp_free_i32(r_mop);
-            tcg_temp_free_i32(r_asi);
 
             tcg_gen_trunc_i64_tl(dst, t64);
-            tcg_temp_free_i64(t64);
 
             /* End the TB.  */
             dc->npc = DYNAMIC_PC;
@@ -2444,7 +2346,7 @@ static void gen_ldf_asi(DisasContext *dc, TCGv addr,
         switch (size) {
         case 4:
             d32 = gen_dest_fpr_F(dc);
-            tcg_gen_qemu_ld_i32(d32, addr, da.mem_idx, da.memop);
+            tcg_gen_qemu_ld_i32(d32, addr, da.mem_idx, da.memop | MO_ALIGN);
             gen_store_fpr_F(dc, rd, d32);
             break;
         case 8:
@@ -2458,7 +2360,6 @@ static void gen_ldf_asi(DisasContext *dc, TCGv addr,
             tcg_gen_qemu_ld_i64(cpu_fpr[rd/2+1], addr, da.mem_idx,
                                 da.memop | MO_ALIGN_4);
             tcg_gen_mov_i64(cpu_fpr[rd / 2], d64);
-            tcg_temp_free_i64(d64);
             break;
         default:
             g_assert_not_reached();
@@ -2476,7 +2377,7 @@ static void gen_ldf_asi(DisasContext *dc, TCGv addr,
 
             /* The first operation checks required alignment.  */
             memop = da.memop | MO_ALIGN_64;
-            eight = tcg_const_tl(8);
+            eight = tcg_constant_tl(8);
             for (i = 0; ; ++i) {
                 tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2 + i], addr,
                                     da.mem_idx, memop);
@@ -2486,7 +2387,6 @@ static void gen_ldf_asi(DisasContext *dc, TCGv addr,
                 tcg_gen_add_tl(addr, addr, eight);
                 memop = da.memop;
             }
-            tcg_temp_free(eight);
         } else {
             gen_exception(dc, TT_ILL_INSN);
         }
@@ -2496,7 +2396,8 @@ static void gen_ldf_asi(DisasContext *dc, TCGv addr,
         /* Valid for lddfa only.  */
         if (size == 8) {
             gen_address_mask(dc, addr);
-            tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
+            tcg_gen_qemu_ld_i64(cpu_fpr[rd / 2], addr, da.mem_idx,
+                                da.memop | MO_ALIGN);
         } else {
             gen_exception(dc, TT_ILL_INSN);
         }
@@ -2504,8 +2405,8 @@ static void gen_ldf_asi(DisasContext *dc, TCGv addr,
 
     default:
         {
-            TCGv_i32 r_asi = tcg_const_i32(da.asi);
-            TCGv_i32 r_mop = tcg_const_i32(da.memop);
+            TCGv_i32 r_asi = tcg_constant_i32(da.asi);
+            TCGv_i32 r_mop = tcg_constant_i32(da.memop | MO_ALIGN);
 
             save_state(dc);
             /* According to the table in the UA2011 manual, the only
@@ -2518,7 +2419,6 @@ static void gen_ldf_asi(DisasContext *dc, TCGv addr,
                 gen_helper_ld_asi(d64, cpu_env, addr, r_asi, r_mop);
                 d32 = gen_dest_fpr_F(dc);
                 tcg_gen_extrl_i64_i32(d32, d64);
-                tcg_temp_free_i64(d64);
                 gen_store_fpr_F(dc, rd, d32);
                 break;
             case 8:
@@ -2530,13 +2430,10 @@ static void gen_ldf_asi(DisasContext *dc, TCGv addr,
                 tcg_gen_addi_tl(addr, addr, 8);
                 gen_helper_ld_asi(cpu_fpr[rd/2+1], cpu_env, addr, r_asi, r_mop);
                 tcg_gen_mov_i64(cpu_fpr[rd / 2], d64);
-                tcg_temp_free_i64(d64);
                 break;
             default:
                 g_assert_not_reached();
             }
-            tcg_temp_free_i32(r_mop);
-            tcg_temp_free_i32(r_asi);
         }
         break;
     }
@@ -2557,7 +2454,7 @@ static void gen_stf_asi(DisasContext *dc, TCGv addr,
         switch (size) {
         case 4:
             d32 = gen_load_fpr_F(dc, rd);
-            tcg_gen_qemu_st_i32(d32, addr, da.mem_idx, da.memop);
+            tcg_gen_qemu_st_i32(d32, addr, da.mem_idx, da.memop | MO_ALIGN);
             break;
         case 8:
             tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx,
@@ -2590,7 +2487,7 @@ static void gen_stf_asi(DisasContext *dc, TCGv addr,
 
             /* The first operation checks required alignment.  */
             memop = da.memop | MO_ALIGN_64;
-            eight = tcg_const_tl(8);
+            eight = tcg_constant_tl(8);
             for (i = 0; ; ++i) {
                 tcg_gen_qemu_st_i64(cpu_fpr[rd / 2 + i], addr,
                                     da.mem_idx, memop);
@@ -2600,7 +2497,6 @@ static void gen_stf_asi(DisasContext *dc, TCGv addr,
                 tcg_gen_add_tl(addr, addr, eight);
                 memop = da.memop;
             }
-            tcg_temp_free(eight);
         } else {
             gen_exception(dc, TT_ILL_INSN);
         }
@@ -2610,7 +2506,8 @@ static void gen_stf_asi(DisasContext *dc, TCGv addr,
         /* Valid for stdfa only.  */
         if (size == 8) {
             gen_address_mask(dc, addr);
-            tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx, da.memop);
+            tcg_gen_qemu_st_i64(cpu_fpr[rd / 2], addr, da.mem_idx,
+                                da.memop | MO_ALIGN);
         } else {
             gen_exception(dc, TT_ILL_INSN);
         }
@@ -2647,7 +2544,7 @@ static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
             TCGv_i64 tmp = tcg_temp_new_i64();
 
             gen_address_mask(dc, addr);
-            tcg_gen_qemu_ld_i64(tmp, addr, da.mem_idx, da.memop);
+            tcg_gen_qemu_ld_i64(tmp, addr, da.mem_idx, da.memop | MO_ALIGN);
 
             /* Note that LE ldda acts as if each 32-bit register
                result is byte swapped.  Having just performed one
@@ -2657,7 +2554,6 @@ static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
             } else {
                 tcg_gen_extr32_i64(hi, lo, tmp);
             }
-            tcg_temp_free_i64(tmp);
         }
         break;
 
@@ -2667,14 +2563,12 @@ static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
            real hardware allows others.  This can be seen with e.g.
            FreeBSD 10.3 wrt ASI_IC_TAG.  */
         {
-            TCGv_i32 r_asi = tcg_const_i32(da.asi);
-            TCGv_i32 r_mop = tcg_const_i32(da.memop);
+            TCGv_i32 r_asi = tcg_constant_i32(da.asi);
+            TCGv_i32 r_mop = tcg_constant_i32(da.memop);
             TCGv_i64 tmp = tcg_temp_new_i64();
 
             save_state(dc);
             gen_helper_ld_asi(tmp, cpu_env, addr, r_asi, r_mop);
-            tcg_temp_free_i32(r_asi);
-            tcg_temp_free_i32(r_mop);
 
             /* See above.  */
             if ((da.memop & MO_BSWAP) == MO_TE) {
@@ -2682,7 +2576,6 @@ static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
             } else {
                 tcg_gen_extr32_i64(hi, lo, tmp);
             }
-            tcg_temp_free_i64(tmp);
         }
         break;
     }
@@ -2721,8 +2614,7 @@ static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
                 tcg_gen_concat32_i64(t64, hi, lo);
             }
             gen_address_mask(dc, addr);
-            tcg_gen_qemu_st_i64(t64, addr, da.mem_idx, da.memop);
-            tcg_temp_free_i64(t64);
+            tcg_gen_qemu_st_i64(t64, addr, da.mem_idx, da.memop | MO_ALIGN);
         }
         break;
 
@@ -2730,8 +2622,8 @@ static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
         /* ??? In theory we've handled all of the ASIs that are valid
            for stda, and this should raise DAE_invalid_asi.  */
         {
-            TCGv_i32 r_asi = tcg_const_i32(da.asi);
-            TCGv_i32 r_mop = tcg_const_i32(da.memop);
+            TCGv_i32 r_asi = tcg_constant_i32(da.asi);
+            TCGv_i32 r_mop = tcg_constant_i32(da.memop);
             TCGv_i64 t64 = tcg_temp_new_i64();
 
             /* See above.  */
@@ -2743,9 +2635,6 @@ static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
 
             save_state(dc);
             gen_helper_st_asi(cpu_env, addr, t64, r_asi, r_mop);
-            tcg_temp_free_i32(r_mop);
-            tcg_temp_free_i32(r_asi);
-            tcg_temp_free_i64(t64);
         }
         break;
     }
@@ -2763,9 +2652,8 @@ static void gen_casx_asi(DisasContext *dc, TCGv addr, TCGv cmpv,
     case GET_ASI_DIRECT:
         oldv = tcg_temp_new();
         tcg_gen_atomic_cmpxchg_tl(oldv, addr, cmpv, gen_load_gpr(dc, rd),
-                                  da.mem_idx, da.memop);
+                                  da.mem_idx, da.memop | MO_ALIGN);
         gen_store_gpr(dc, rd, oldv);
-        tcg_temp_free(oldv);
         break;
     default:
         /* ??? Should be DAE_invalid_asi.  */
@@ -2788,27 +2676,23 @@ static void gen_ldda_asi(DisasContext *dc, TCGv addr, int insn, int rd)
 
     switch (da.type) {
     case GET_ASI_EXCP:
-        tcg_temp_free_i64(t64);
         return;
     case GET_ASI_DIRECT:
         gen_address_mask(dc, addr);
-        tcg_gen_qemu_ld_i64(t64, addr, da.mem_idx, da.memop);
+        tcg_gen_qemu_ld_i64(t64, addr, da.mem_idx, da.memop | MO_ALIGN);
         break;
     default:
         {
-            TCGv_i32 r_asi = tcg_const_i32(da.asi);
-            TCGv_i32 r_mop = tcg_const_i32(MO_UQ);
+            TCGv_i32 r_asi = tcg_constant_i32(da.asi);
+            TCGv_i32 r_mop = tcg_constant_i32(MO_UQ);
 
             save_state(dc);
             gen_helper_ld_asi(t64, cpu_env, addr, r_asi, r_mop);
-            tcg_temp_free_i32(r_mop);
-            tcg_temp_free_i32(r_asi);
         }
         break;
     }
 
     tcg_gen_extr_i64_i32(lo, hi, t64);
-    tcg_temp_free_i64(t64);
     gen_store_gpr(dc, rd | 1, lo);
     gen_store_gpr(dc, rd, hi);
 }
@@ -2827,7 +2711,7 @@ static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
         break;
     case GET_ASI_DIRECT:
         gen_address_mask(dc, addr);
-        tcg_gen_qemu_st_i64(t64, addr, da.mem_idx, da.memop);
+        tcg_gen_qemu_st_i64(t64, addr, da.mem_idx, da.memop | MO_ALIGN);
         break;
     case GET_ASI_BFILL:
         /* Store 32 bytes of T64 to ADDR.  */
@@ -2837,7 +2721,7 @@ static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
            as a cacheline-style operation.  */
         {
             TCGv d_addr = tcg_temp_new();
-            TCGv eight = tcg_const_tl(8);
+            TCGv eight = tcg_constant_tl(8);
             int i;
 
             tcg_gen_andi_tl(d_addr, addr, -8);
@@ -2845,25 +2729,18 @@ static void gen_stda_asi(DisasContext *dc, TCGv hi, TCGv addr,
                 tcg_gen_qemu_st_i64(t64, d_addr, da.mem_idx, da.memop);
                 tcg_gen_add_tl(d_addr, d_addr, eight);
             }
-
-            tcg_temp_free(d_addr);
-            tcg_temp_free(eight);
         }
         break;
     default:
         {
-            TCGv_i32 r_asi = tcg_const_i32(da.asi);
-            TCGv_i32 r_mop = tcg_const_i32(MO_UQ);
+            TCGv_i32 r_asi = tcg_constant_i32(da.asi);
+            TCGv_i32 r_mop = tcg_constant_i32(MO_UQ);
 
             save_state(dc);
             gen_helper_st_asi(cpu_env, addr, t64, r_asi, r_mop);
-            tcg_temp_free_i32(r_mop);
-            tcg_temp_free_i32(r_asi);
         }
         break;
     }
-
-    tcg_temp_free_i64(t64);
 }
 #endif
 
@@ -2901,18 +2778,15 @@ static void gen_fmovs(DisasContext *dc, DisasCompare *cmp, int rd, int rs)
         TCGv_i64 c64 = tcg_temp_new_i64();
         tcg_gen_setcond_i64(cmp->cond, c64, cmp->c1, cmp->c2);
         tcg_gen_extrl_i64_i32(c32, c64);
-        tcg_temp_free_i64(c64);
     }
 
     s1 = gen_load_fpr_F(dc, rs);
     s2 = gen_load_fpr_F(dc, rd);
     dst = gen_dest_fpr_F(dc);
-    zero = tcg_const_i32(0);
+    zero = tcg_constant_i32(0);
 
     tcg_gen_movcond_i32(TCG_COND_NE, dst, c32, zero, s1, s2);
 
-    tcg_temp_free_i32(c32);
-    tcg_temp_free_i32(zero);
     gen_store_fpr_F(dc, rd, dst);
 }
 
@@ -2958,17 +2832,14 @@ static inline void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_env cpu_env)
         TCGv_ptr r_tl_tmp = tcg_temp_new_ptr();
         tcg_gen_ext_i32_ptr(r_tl_tmp, r_tl);
         tcg_gen_add_ptr(r_tsptr, r_tsptr, r_tl_tmp);
-        tcg_temp_free_ptr(r_tl_tmp);
     }
-
-    tcg_temp_free_i32(r_tl);
 }
 #endif
 
 static void gen_edge(DisasContext *dc, TCGv dst, TCGv s1, TCGv s2,
                      int width, bool cc, bool left)
 {
-    TCGv lo1, lo2, t1, t2;
+    TCGv lo1, lo2;
     uint64_t amask, tabl, tabr;
     int shift, imask, omask;
 
@@ -3035,10 +2906,8 @@ static void gen_edge(DisasContext *dc, TCGv dst, TCGv s1, TCGv s2,
     tcg_gen_shli_tl(lo1, lo1, shift);
     tcg_gen_shli_tl(lo2, lo2, shift);
 
-    t1 = tcg_const_tl(tabl);
-    t2 = tcg_const_tl(tabr);
-    tcg_gen_shr_tl(lo1, t1, lo1);
-    tcg_gen_shr_tl(lo2, t2, lo2);
+    tcg_gen_shr_tl(lo1, tcg_constant_tl(tabl), lo1);
+    tcg_gen_shr_tl(lo2, tcg_constant_tl(tabr), lo2);
     tcg_gen_andi_tl(dst, lo1, omask);
     tcg_gen_andi_tl(lo2, lo2, omask);
 
@@ -3057,15 +2926,10 @@ static void gen_edge(DisasContext *dc, TCGv dst, TCGv s1, TCGv s2,
         lo2 |= -(s1 == s2)
         dst &= lo2
     */
-    tcg_gen_setcond_tl(TCG_COND_EQ, t1, s1, s2);
-    tcg_gen_neg_tl(t1, t1);
-    tcg_gen_or_tl(lo2, lo2, t1);
+    tcg_gen_setcond_tl(TCG_COND_EQ, lo1, s1, s2);
+    tcg_gen_neg_tl(lo1, lo1);
+    tcg_gen_or_tl(lo2, lo2, lo1);
     tcg_gen_and_tl(dst, dst, lo2);
-
-    tcg_temp_free(lo1);
-    tcg_temp_free(lo2);
-    tcg_temp_free(t1);
-    tcg_temp_free(t2);
 }
 
 static void gen_alignaddr(TCGv dst, TCGv s1, TCGv s2, bool left)
@@ -3078,8 +2942,6 @@ static void gen_alignaddr(TCGv dst, TCGv s1, TCGv s2, bool left)
         tcg_gen_neg_tl(tmp, tmp);
     }
     tcg_gen_deposit_tl(cpu_gsr, cpu_gsr, tmp, 0, 3);
-
-    tcg_temp_free(tmp);
 }
 
 static void gen_faligndata(TCGv dst, TCGv gsr, TCGv s1, TCGv s2)
@@ -3101,10 +2963,6 @@ static void gen_faligndata(TCGv dst, TCGv gsr, TCGv s1, TCGv s2)
     tcg_gen_shri_tl(t2, t2, 1);
 
     tcg_gen_or_tl(dst, t1, t2);
-
-    tcg_temp_free(t1);
-    tcg_temp_free(t2);
-    tcg_temp_free(shift);
 }
 #endif
 
@@ -3268,7 +3126,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     l1 = gen_new_label();
                     tcg_gen_brcond_tl(tcg_invert_cond(cmp.cond),
                                       cmp.c1, cmp.c2, l1);
-                    free_compare(&cmp);
                 }
 
                 mask = ((dc->def->features & CPU_FEATURE_HYPV) && supervisor(dc)
@@ -3305,7 +3162,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                 }
 
                 gen_helper_raise_exception(cpu_env, trap);
-                tcg_temp_free_i32(trap);
 
                 if (cond == 8) {
                     /* An unconditional trap ends the TB.  */
@@ -3356,21 +3212,15 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                         TCGv_i32 r_const;
 
                         r_tickptr = tcg_temp_new_ptr();
-                        r_const = tcg_const_i32(dc->mem_idx);
+                        r_const = tcg_constant_i32(dc->mem_idx);
                         tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                        offsetof(CPUSPARCState, tick));
-                        if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
-                            gen_io_start();
+                        if (translator_io_start(&dc->base)) {
+                            dc->base.is_jmp = DISAS_EXIT;
                         }
                         gen_helper_tick_get_count(cpu_dst, cpu_env, r_tickptr,
                                                   r_const);
-                        tcg_temp_free_ptr(r_tickptr);
-                        tcg_temp_free_i32(r_const);
                         gen_store_gpr(dc, rd, cpu_dst);
-                        if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
-                            /* I/O operations in icount mode must end the TB */
-                            dc->base.is_jmp = DISAS_EXIT;
-                        }
                     }
                     break;
                 case 0x5: /* V9 rdpc */
@@ -3410,21 +3260,15 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                         TCGv_i32 r_const;
 
                         r_tickptr = tcg_temp_new_ptr();
-                        r_const = tcg_const_i32(dc->mem_idx);
+                        r_const = tcg_constant_i32(dc->mem_idx);
                         tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                        offsetof(CPUSPARCState, stick));
-                        if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
-                            gen_io_start();
+                        if (translator_io_start(&dc->base)) {
+                            dc->base.is_jmp = DISAS_EXIT;
                         }
                         gen_helper_tick_get_count(cpu_dst, cpu_env, r_tickptr,
                                                   r_const);
-                        tcg_temp_free_ptr(r_tickptr);
-                        tcg_temp_free_i32(r_const);
                         gen_store_gpr(dc, rd, cpu_dst);
-                        if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
-                            /* I/O operations in icount mode must end the TB */
-                            dc->base.is_jmp = DISAS_EXIT;
-                        }
                     }
                     break;
                 case 0x19: /* System tick compare */
@@ -3505,7 +3349,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                         gen_load_trap_state_at_tl(r_tsptr, cpu_env);
                         tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
                                       offsetof(trap_state, tpc));
-                        tcg_temp_free_ptr(r_tsptr);
                     }
                     break;
                 case 1: // tnpc
@@ -3516,7 +3359,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                         gen_load_trap_state_at_tl(r_tsptr, cpu_env);
                         tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
                                       offsetof(trap_state, tnpc));
-                        tcg_temp_free_ptr(r_tsptr);
                     }
                     break;
                 case 2: // tstate
@@ -3527,7 +3369,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                         gen_load_trap_state_at_tl(r_tsptr, cpu_env);
                         tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
                                       offsetof(trap_state, tstate));
-                        tcg_temp_free_ptr(r_tsptr);
                     }
                     break;
                 case 3: // tt
@@ -3537,7 +3378,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                         gen_load_trap_state_at_tl(r_tsptr, cpu_env);
                         tcg_gen_ld32s_tl(cpu_tmp0, r_tsptr,
                                          offsetof(trap_state, tt));
-                        tcg_temp_free_ptr(r_tsptr);
                     }
                     break;
                 case 4: // tick
@@ -3546,20 +3386,14 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                         TCGv_i32 r_const;
 
                         r_tickptr = tcg_temp_new_ptr();
-                        r_const = tcg_const_i32(dc->mem_idx);
+                        r_const = tcg_constant_i32(dc->mem_idx);
                         tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                        offsetof(CPUSPARCState, tick));
-                        if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
-                            gen_io_start();
+                        if (translator_io_start(&dc->base)) {
+                            dc->base.is_jmp = DISAS_EXIT;
                         }
                         gen_helper_tick_get_count(cpu_tmp0, cpu_env,
                                                   r_tickptr, r_const);
-                        tcg_temp_free_ptr(r_tickptr);
-                        tcg_temp_free_i32(r_const);
-                        if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
-                            /* I/O operations in icount mode must end the TB */
-                            dc->base.is_jmp = DISAS_EXIT;
-                        }
                     }
                     break;
                 case 5: // tba
@@ -3827,7 +3661,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     cpu_src1 = get_src1(dc, insn);                 \
                     gen_compare_reg(&cmp, cond, cpu_src1);         \
                     gen_fmov##sz(dc, &cmp, rd, rs2);               \
-                    free_compare(&cmp);                            \
                 } while (0)
 
                 if ((xop & 0x11f) == 0x005) { /* V9 fmovsr */
@@ -3851,7 +3684,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                         cond = GET_FIELD_SP(insn, 14, 17);              \
                         gen_fcompare(&cmp, fcc, cond);                  \
                         gen_fmov##sz(dc, &cmp, rd, rs2);                \
-                        free_compare(&cmp);                             \
                     } while (0)
 
                     case 0x001: /* V9 fmovscc %fcc0 */
@@ -3901,7 +3733,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                         cond = GET_FIELD_SP(insn, 14, 17);              \
                         gen_compare(&cmp, xcc, cond, dc);               \
                         gen_fmov##sz(dc, &cmp, rd, rs2);                \
-                        free_compare(&cmp);                             \
                     } while (0)
 
                     case 0x101: /* V9 fmovscc %icc */
@@ -4367,13 +4198,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                                     r_tickptr = tcg_temp_new_ptr();
                                     tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                    offsetof(CPUSPARCState, tick));
-                                    if (tb_cflags(dc->base.tb) &
-                                           CF_USE_ICOUNT) {
-                                        gen_io_start();
-                                    }
+                                    translator_io_start(&dc->base);
                                     gen_helper_tick_set_limit(r_tickptr,
                                                               cpu_tick_cmpr);
-                                    tcg_temp_free_ptr(r_tickptr);
                                     /* End TB to handle timer interrupt */
                                     dc->base.is_jmp = DISAS_EXIT;
                                 }
@@ -4391,13 +4218,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                                     r_tickptr = tcg_temp_new_ptr();
                                     tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                    offsetof(CPUSPARCState, stick));
-                                    if (tb_cflags(dc->base.tb) &
-                                           CF_USE_ICOUNT) {
-                                        gen_io_start();
-                                    }
+                                    translator_io_start(&dc->base);
                                     gen_helper_tick_set_count(r_tickptr,
                                                               cpu_tmp0);
-                                    tcg_temp_free_ptr(r_tickptr);
                                     /* End TB to handle timer interrupt */
                                     dc->base.is_jmp = DISAS_EXIT;
                                 }
@@ -4415,13 +4238,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                                     r_tickptr = tcg_temp_new_ptr();
                                     tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                    offsetof(CPUSPARCState, stick));
-                                    if (tb_cflags(dc->base.tb) &
-                                           CF_USE_ICOUNT) {
-                                        gen_io_start();
-                                    }
+                                    translator_io_start(&dc->base);
                                     gen_helper_tick_set_limit(r_tickptr,
                                                               cpu_stick_cmpr);
-                                    tcg_temp_free_ptr(r_tickptr);
                                     /* End TB to handle timer interrupt */
                                     dc->base.is_jmp = DISAS_EXIT;
                                 }
@@ -4487,7 +4306,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                                     gen_load_trap_state_at_tl(r_tsptr, cpu_env);
                                     tcg_gen_st_tl(cpu_tmp0, r_tsptr,
                                                   offsetof(trap_state, tpc));
-                                    tcg_temp_free_ptr(r_tsptr);
                                 }
                                 break;
                             case 1: // tnpc
@@ -4498,7 +4316,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                                     gen_load_trap_state_at_tl(r_tsptr, cpu_env);
                                     tcg_gen_st_tl(cpu_tmp0, r_tsptr,
                                                   offsetof(trap_state, tnpc));
-                                    tcg_temp_free_ptr(r_tsptr);
                                 }
                                 break;
                             case 2: // tstate
@@ -4510,7 +4327,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                                     tcg_gen_st_tl(cpu_tmp0, r_tsptr,
                                                   offsetof(trap_state,
                                                            tstate));
-                                    tcg_temp_free_ptr(r_tsptr);
                                 }
                                 break;
                             case 3: // tt
@@ -4521,7 +4337,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                                     gen_load_trap_state_at_tl(r_tsptr, cpu_env);
                                     tcg_gen_st32_tl(cpu_tmp0, r_tsptr,
                                                     offsetof(trap_state, tt));
-                                    tcg_temp_free_ptr(r_tsptr);
                                 }
                                 break;
                             case 4: // tick
@@ -4531,13 +4346,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                                     r_tickptr = tcg_temp_new_ptr();
                                     tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                    offsetof(CPUSPARCState, tick));
-                                    if (tb_cflags(dc->base.tb) &
-                                           CF_USE_ICOUNT) {
-                                        gen_io_start();
-                                    }
+                                    translator_io_start(&dc->base);
                                     gen_helper_tick_set_count(r_tickptr,
                                                               cpu_tmp0);
-                                    tcg_temp_free_ptr(r_tickptr);
                                     /* End TB to handle timer interrupt */
                                     dc->base.is_jmp = DISAS_EXIT;
                                 }
@@ -4547,14 +4358,10 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                                 break;
                             case 6: // pstate
                                 save_state(dc);
-                                if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
-                                    gen_io_start();
-                                }
-                                gen_helper_wrpstate(cpu_env, cpu_tmp0);
-                                if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
-                                    /* I/O ops in icount mode must end the TB */
+                                if (translator_io_start(&dc->base)) {
                                     dc->base.is_jmp = DISAS_EXIT;
                                 }
+                                gen_helper_wrpstate(cpu_env, cpu_tmp0);
                                 dc->npc = DYNAMIC_PC;
                                 break;
                             case 7: // tl
@@ -4564,14 +4371,10 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                                 dc->npc = DYNAMIC_PC;
                                 break;
                             case 8: // pil
-                                if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
-                                    gen_io_start();
-                                }
-                                gen_helper_wrpil(cpu_env, cpu_tmp0);
-                                if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
-                                    /* I/O ops in icount mode must end the TB */
+                                if (translator_io_start(&dc->base)) {
                                     dc->base.is_jmp = DISAS_EXIT;
                                 }
+                                gen_helper_wrpil(cpu_env, cpu_tmp0);
                                 break;
                             case 9: // cwp
                                 gen_helper_wrcwp(cpu_env, cpu_tmp0);
@@ -4662,13 +4465,9 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                                     r_tickptr = tcg_temp_new_ptr();
                                     tcg_gen_ld_ptr(r_tickptr, cpu_env,
                                                    offsetof(CPUSPARCState, hstick));
-                                    if (tb_cflags(dc->base.tb) &
-                                           CF_USE_ICOUNT) {
-                                        gen_io_start();
-                                    }
+                                    translator_io_start(&dc->base);
                                     gen_helper_tick_set_limit(r_tickptr,
                                                               cpu_hstick_cmpr);
-                                    tcg_temp_free_ptr(r_tickptr);
                                     /* End TB to handle timer interrupt */
                                     dc->base.is_jmp = DISAS_EXIT;
                                 }
@@ -4713,7 +4512,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                             tcg_gen_movcond_tl(cmp.cond, dst,
                                                cmp.c1, cmp.c2,
                                                cpu_src2, dst);
-                            free_compare(&cmp);
                             gen_store_gpr(dc, rd, dst);
                             break;
                         }
@@ -4745,7 +4543,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                             tcg_gen_movcond_tl(cmp.cond, dst,
                                                cmp.c1, cmp.c2,
                                                cpu_src2, dst);
-                            free_compare(&cmp);
                             gen_store_gpr(dc, rd, dst);
                             break;
                         }
@@ -5291,9 +5088,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                                 goto priv_insn;
                             dc->npc = DYNAMIC_PC;
                             dc->pc = DYNAMIC_PC;
-                            if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
-                                gen_io_start();
-                            }
+                            translator_io_start(&dc->base);
                             gen_helper_done(cpu_env);
                             goto jmp_insn;
                         case 1:
@@ -5301,9 +5096,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                                 goto priv_insn;
                             dc->npc = DYNAMIC_PC;
                             dc->pc = DYNAMIC_PC;
-                            if (tb_cflags(dc->base.tb) & CF_USE_ICOUNT) {
-                                gen_io_start();
-                            }
+                            translator_io_start(&dc->base);
                             gen_helper_retry(cpu_env);
                             goto jmp_insn;
                         default:
@@ -5348,15 +5141,18 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                 switch (xop) {
                 case 0x0:       /* ld, V9 lduw, load unsigned word */
                     gen_address_mask(dc, cpu_addr);
-                    tcg_gen_qemu_ld32u(cpu_val, cpu_addr, dc->mem_idx);
+                    tcg_gen_qemu_ld_tl(cpu_val, cpu_addr,
+                                       dc->mem_idx, MO_TEUL | MO_ALIGN);
                     break;
                 case 0x1:       /* ldub, load unsigned byte */
                     gen_address_mask(dc, cpu_addr);
-                    tcg_gen_qemu_ld8u(cpu_val, cpu_addr, dc->mem_idx);
+                    tcg_gen_qemu_ld_tl(cpu_val, cpu_addr,
+                                       dc->mem_idx, MO_UB);
                     break;
                 case 0x2:       /* lduh, load unsigned halfword */
                     gen_address_mask(dc, cpu_addr);
-                    tcg_gen_qemu_ld16u(cpu_val, cpu_addr, dc->mem_idx);
+                    tcg_gen_qemu_ld_tl(cpu_val, cpu_addr,
+                                       dc->mem_idx, MO_TEUW | MO_ALIGN);
                     break;
                 case 0x3:       /* ldd, load double word */
                     if (rd & 1)
@@ -5366,23 +5162,24 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
 
                         gen_address_mask(dc, cpu_addr);
                         t64 = tcg_temp_new_i64();
-                        tcg_gen_qemu_ld64(t64, cpu_addr, dc->mem_idx);
+                        tcg_gen_qemu_ld_i64(t64, cpu_addr,
+                                            dc->mem_idx, MO_TEUQ | MO_ALIGN);
                         tcg_gen_trunc_i64_tl(cpu_val, t64);
                         tcg_gen_ext32u_tl(cpu_val, cpu_val);
                         gen_store_gpr(dc, rd + 1, cpu_val);
                         tcg_gen_shri_i64(t64, t64, 32);
                         tcg_gen_trunc_i64_tl(cpu_val, t64);
-                        tcg_temp_free_i64(t64);
                         tcg_gen_ext32u_tl(cpu_val, cpu_val);
                     }
                     break;
                 case 0x9:       /* ldsb, load signed byte */
                     gen_address_mask(dc, cpu_addr);
-                    tcg_gen_qemu_ld8s(cpu_val, cpu_addr, dc->mem_idx);
+                    tcg_gen_qemu_ld_tl(cpu_val, cpu_addr, dc->mem_idx, MO_SB);
                     break;
                 case 0xa:       /* ldsh, load signed halfword */
                     gen_address_mask(dc, cpu_addr);
-                    tcg_gen_qemu_ld16s(cpu_val, cpu_addr, dc->mem_idx);
+                    tcg_gen_qemu_ld_tl(cpu_val, cpu_addr,
+                                       dc->mem_idx, MO_TESW | MO_ALIGN);
                     break;
                 case 0xd:       /* ldstub */
                     gen_ldstub(dc, cpu_val, cpu_addr, dc->mem_idx);
@@ -5436,11 +5233,13 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
 #ifdef TARGET_SPARC64
                 case 0x08: /* V9 ldsw */
                     gen_address_mask(dc, cpu_addr);
-                    tcg_gen_qemu_ld32s(cpu_val, cpu_addr, dc->mem_idx);
+                    tcg_gen_qemu_ld_tl(cpu_val, cpu_addr,
+                                       dc->mem_idx, MO_TESL | MO_ALIGN);
                     break;
                 case 0x0b: /* V9 ldx */
                     gen_address_mask(dc, cpu_addr);
-                    tcg_gen_qemu_ld64(cpu_val, cpu_addr, dc->mem_idx);
+                    tcg_gen_qemu_ld_tl(cpu_val, cpu_addr,
+                                       dc->mem_idx, MO_TEUQ | MO_ALIGN);
                     break;
                 case 0x18: /* V9 ldswa */
                     gen_ld_asi(dc, cpu_val, cpu_addr, insn, MO_TESL);
@@ -5491,7 +5290,7 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     gen_address_mask(dc, cpu_addr);
                     cpu_dst_32 = gen_dest_fpr_F(dc);
                     tcg_gen_qemu_ld_i32(cpu_dst_32, cpu_addr,
-                                        dc->mem_idx, MO_TEUL);
+                                        dc->mem_idx, MO_TEUL | MO_ALIGN);
                     gen_store_fpr_F(dc, rd, cpu_dst_32);
                     break;
                 case 0x21:      /* ldfsr, V9 ldxfsr */
@@ -5500,15 +5299,14 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     if (rd == 1) {
                         TCGv_i64 t64 = tcg_temp_new_i64();
                         tcg_gen_qemu_ld_i64(t64, cpu_addr,
-                                            dc->mem_idx, MO_TEUQ);
+                                            dc->mem_idx, MO_TEUQ | MO_ALIGN);
                         gen_helper_ldxfsr(cpu_fsr, cpu_env, cpu_fsr, t64);
-                        tcg_temp_free_i64(t64);
                         break;
                     }
 #endif
                     cpu_dst_32 = tcg_temp_new_i32();
                     tcg_gen_qemu_ld_i32(cpu_dst_32, cpu_addr,
-                                        dc->mem_idx, MO_TEUL);
+                                        dc->mem_idx, MO_TEUL | MO_ALIGN);
                     gen_helper_ldfsr(cpu_fsr, cpu_env, cpu_fsr, cpu_dst_32);
                     break;
                 case 0x22:      /* ldqf, load quad fpreg */
@@ -5522,8 +5320,6 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     tcg_gen_qemu_ld_i64(cpu_src2_64, cpu_addr, dc->mem_idx,
                                         MO_TEUQ | MO_ALIGN_4);
                     gen_store_fpr_Q(dc, rd, cpu_src1_64, cpu_src2_64);
-                    tcg_temp_free_i64(cpu_src1_64);
-                    tcg_temp_free_i64(cpu_src2_64);
                     break;
                 case 0x23:      /* lddf, load double fpreg */
                     gen_address_mask(dc, cpu_addr);
@@ -5542,15 +5338,17 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                 switch (xop) {
                 case 0x4: /* st, store word */
                     gen_address_mask(dc, cpu_addr);
-                    tcg_gen_qemu_st32(cpu_val, cpu_addr, dc->mem_idx);
+                    tcg_gen_qemu_st_tl(cpu_val, cpu_addr,
+                                       dc->mem_idx, MO_TEUL | MO_ALIGN);
                     break;
                 case 0x5: /* stb, store byte */
                     gen_address_mask(dc, cpu_addr);
-                    tcg_gen_qemu_st8(cpu_val, cpu_addr, dc->mem_idx);
+                    tcg_gen_qemu_st_tl(cpu_val, cpu_addr, dc->mem_idx, MO_UB);
                     break;
                 case 0x6: /* sth, store halfword */
                     gen_address_mask(dc, cpu_addr);
-                    tcg_gen_qemu_st16(cpu_val, cpu_addr, dc->mem_idx);
+                    tcg_gen_qemu_st_tl(cpu_val, cpu_addr,
+                                       dc->mem_idx, MO_TEUW | MO_ALIGN);
                     break;
                 case 0x7: /* std, store double word */
                     if (rd & 1)
@@ -5563,8 +5361,8 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                         lo = gen_load_gpr(dc, rd + 1);
                         t64 = tcg_temp_new_i64();
                         tcg_gen_concat_tl_i64(t64, lo, cpu_val);
-                        tcg_gen_qemu_st64(t64, cpu_addr, dc->mem_idx);
-                        tcg_temp_free_i64(t64);
+                        tcg_gen_qemu_st_i64(t64, cpu_addr,
+                                            dc->mem_idx, MO_TEUQ | MO_ALIGN);
                     }
                     break;
 #if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
@@ -5587,7 +5385,8 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
 #ifdef TARGET_SPARC64
                 case 0x0e: /* V9 stx */
                     gen_address_mask(dc, cpu_addr);
-                    tcg_gen_qemu_st64(cpu_val, cpu_addr, dc->mem_idx);
+                    tcg_gen_qemu_st_tl(cpu_val, cpu_addr,
+                                       dc->mem_idx, MO_TEUQ | MO_ALIGN);
                     break;
                 case 0x1e: /* V9 stxa */
                     gen_st_asi(dc, cpu_val, cpu_addr, insn, MO_TEUQ);
@@ -5605,18 +5404,20 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
                     gen_address_mask(dc, cpu_addr);
                     cpu_src1_32 = gen_load_fpr_F(dc, rd);
                     tcg_gen_qemu_st_i32(cpu_src1_32, cpu_addr,
-                                        dc->mem_idx, MO_TEUL);
+                                        dc->mem_idx, MO_TEUL | MO_ALIGN);
                     break;
                 case 0x25: /* stfsr, V9 stxfsr */
                     {
 #ifdef TARGET_SPARC64
                         gen_address_mask(dc, cpu_addr);
                         if (rd == 1) {
-                            tcg_gen_qemu_st64(cpu_fsr, cpu_addr, dc->mem_idx);
+                            tcg_gen_qemu_st_tl(cpu_fsr, cpu_addr,
+                                               dc->mem_idx, MO_TEUQ | MO_ALIGN);
                             break;
                         }
 #endif
-                        tcg_gen_qemu_st32(cpu_fsr, cpu_addr, dc->mem_idx);
+                        tcg_gen_qemu_st_tl(cpu_fsr, cpu_addr,
+                                           dc->mem_idx, MO_TEUL | MO_ALIGN);
                     }
                     break;
                 case 0x26:
@@ -5727,32 +5528,31 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn)
         dc->npc = dc->npc + 4;
     }
  jmp_insn:
-    goto egress;
+    return;
  illegal_insn:
     gen_exception(dc, TT_ILL_INSN);
-    goto egress;
+    return;
  unimp_flush:
     gen_exception(dc, TT_UNIMP_FLUSH);
-    goto egress;
+    return;
 #if !defined(CONFIG_USER_ONLY)
  priv_insn:
     gen_exception(dc, TT_PRIV_INSN);
-    goto egress;
+    return;
 #endif
  nfpu_insn:
     gen_op_fpexception_im(dc, FSR_FTT_UNIMPFPOP);
-    goto egress;
+    return;
 #if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
  nfq_insn:
     gen_op_fpexception_im(dc, FSR_FTT_SEQ_ERROR);
-    goto egress;
+    return;
 #endif
 #ifndef TARGET_SPARC64
  ncp_insn:
     gen_exception(dc, TT_NCP_INSN);
-    goto egress;
+    return;
 #endif
- egress:
 }
 
 static void sparc_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)