Refactor and enhance break/watchpoint API (Jan Kiszka)
[qemu] / target-ppc / translate.c
index 7b977a7..085c7a1 100644 (file)
 #include "cpu.h"
 #include "exec-all.h"
 #include "disas.h"
-#include "helper.h"
 #include "tcg-op.h"
 #include "qemu-common.h"
 
+#include "helper.h"
+#define GEN_HELPER 1
+#include "helper.h"
+
 #define CPU_SINGLE_STEP 0x1
 #define CPU_BRANCH_STEP 0x2
 #define GDBSTUB_SINGLE_STEP 0x4
@@ -44,7 +47,7 @@
 /* Code translation helpers                                                  */
 
 /* global register indexes */
-static TCGv cpu_env;
+static TCGv_ptr cpu_env;
 static char cpu_reg_names[10*3 + 22*4 /* GPR */
 #if !defined(TARGET_PPC64)
     + 10*4 + 22*5 /* SPE GPRh */
@@ -56,24 +59,24 @@ static TCGv cpu_gpr[32];
 #if !defined(TARGET_PPC64)
 static TCGv cpu_gprh[32];
 #endif
-static TCGv cpu_fpr[32];
-static TCGv cpu_avrh[32], cpu_avrl[32];
-static TCGv cpu_crf[8];
+static TCGv_i64 cpu_fpr[32];
+static TCGv_i64 cpu_avrh[32], cpu_avrl[32];
+static TCGv_i32 cpu_crf[8];
 static TCGv cpu_nip;
 static TCGv cpu_ctr;
 static TCGv cpu_lr;
 static TCGv cpu_xer;
-static TCGv cpu_fpscr;
+static TCGv_i32 cpu_fpscr;
 
 /* dyngen register indexes */
 static TCGv cpu_T[3];
 #if defined(TARGET_PPC64)
 #define cpu_T64 cpu_T
 #else
-static TCGv cpu_T64[3];
+static TCGv_i64 cpu_T64[3];
 #endif
-static TCGv cpu_FT[3];
-static TCGv cpu_AVRh[3], cpu_AVRl[3];
+static TCGv_i64 cpu_FT[3];
+static TCGv_i64 cpu_AVRh[3], cpu_AVRl[3];
 
 #include "gen-icount.h"
 
@@ -86,115 +89,107 @@ void ppc_translate_init(void)
     if (done_init)
         return;
 
-    cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
+    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
 #if TARGET_LONG_BITS > HOST_LONG_BITS
-    cpu_T[0] = tcg_global_mem_new(TCG_TYPE_TL,
-                                  TCG_AREG0, offsetof(CPUState, t0), "T0");
-    cpu_T[1] = tcg_global_mem_new(TCG_TYPE_TL,
-                                  TCG_AREG0, offsetof(CPUState, t1), "T1");
-    cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL,
-                                  TCG_AREG0, offsetof(CPUState, t2), "T2");
+    cpu_T[0] = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, t0), "T0");
+    cpu_T[1] = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, t1), "T1");
+    cpu_T[2] = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, t2), "T2");
 #else
-    cpu_T[0] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG1, "T0");
-    cpu_T[1] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG2, "T1");
+    cpu_T[0] = tcg_global_reg_new(TCG_AREG1, "T0");
+    cpu_T[1] = tcg_global_reg_new(TCG_AREG2, "T1");
 #ifdef HOST_I386
     /* XXX: This is a temporary workaround for i386.
      *      On i386 qemu_st32 runs out of registers.
      *      The proper fix is to remove cpu_T.
      */
-    cpu_T[2] = tcg_global_mem_new(TCG_TYPE_TL,
-                                  TCG_AREG0, offsetof(CPUState, t2), "T2");
+    cpu_T[2] = tcg_global_mem_new(TCG_AREG0, offsetof(CPUState, t2), "T2");
 #else
-    cpu_T[2] = tcg_global_reg_new(TCG_TYPE_TL, TCG_AREG3, "T2");
+    cpu_T[2] = tcg_global_reg_new(TCG_AREG3, "T2");
 #endif
 #endif
 #if !defined(TARGET_PPC64)
-    cpu_T64[0] = tcg_global_mem_new(TCG_TYPE_I64,
-                                    TCG_AREG0, offsetof(CPUState, t0_64),
-                                    "T0_64");
-    cpu_T64[1] = tcg_global_mem_new(TCG_TYPE_I64,
-                                    TCG_AREG0, offsetof(CPUState, t1_64),
-                                    "T1_64");
-    cpu_T64[2] = tcg_global_mem_new(TCG_TYPE_I64,
-                                    TCG_AREG0, offsetof(CPUState, t2_64),
-                                    "T2_64");
-#endif
-
-    cpu_FT[0] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
-                                   offsetof(CPUState, ft0), "FT0");
-    cpu_FT[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
-                                   offsetof(CPUState, ft1), "FT1");
-    cpu_FT[2] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
-                                   offsetof(CPUState, ft2), "FT2");
-
-    cpu_AVRh[0] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
+    cpu_T64[0] = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, t0_64),
+                                        "T0_64");
+    cpu_T64[1] = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, t1_64),
+                                        "T1_64");
+    cpu_T64[2] = tcg_global_mem_new_i64(TCG_AREG0, offsetof(CPUState, t2_64),
+                                        "T2_64");
+#endif
+
+    cpu_FT[0] = tcg_global_mem_new_i64(TCG_AREG0,
+                                       offsetof(CPUState, ft0), "FT0");
+    cpu_FT[1] = tcg_global_mem_new_i64(TCG_AREG0,
+                                       offsetof(CPUState, ft1), "FT1");
+    cpu_FT[2] = tcg_global_mem_new_i64(TCG_AREG0,
+                                       offsetof(CPUState, ft2), "FT2");
+
+    cpu_AVRh[0] = tcg_global_mem_new_i64(TCG_AREG0,
                                      offsetof(CPUState, avr0.u64[0]), "AVR0H");
-    cpu_AVRl[0] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
+    cpu_AVRl[0] = tcg_global_mem_new_i64(TCG_AREG0,
                                      offsetof(CPUState, avr0.u64[1]), "AVR0L");
-    cpu_AVRh[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
+    cpu_AVRh[1] = tcg_global_mem_new_i64(TCG_AREG0,
                                      offsetof(CPUState, avr1.u64[0]), "AVR1H");
-    cpu_AVRl[1] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
+    cpu_AVRl[1] = tcg_global_mem_new_i64(TCG_AREG0,
                                      offsetof(CPUState, avr1.u64[1]), "AVR1L");
-    cpu_AVRh[2] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
+    cpu_AVRh[2] = tcg_global_mem_new_i64(TCG_AREG0,
                                      offsetof(CPUState, avr2.u64[0]), "AVR2H");
-    cpu_AVRl[2] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
+    cpu_AVRl[2] = tcg_global_mem_new_i64(TCG_AREG0,
                                      offsetof(CPUState, avr2.u64[1]), "AVR2L");
 
     p = cpu_reg_names;
 
     for (i = 0; i < 8; i++) {
         sprintf(p, "crf%d", i);
-        cpu_crf[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
-                                        offsetof(CPUState, crf[i]), p);
+        cpu_crf[i] = tcg_global_mem_new_i32(TCG_AREG0,
+                                            offsetof(CPUState, crf[i]), p);
         p += 5;
     }
 
     for (i = 0; i < 32; i++) {
         sprintf(p, "r%d", i);
-        cpu_gpr[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
+        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
                                         offsetof(CPUState, gpr[i]), p);
         p += (i < 10) ? 3 : 4;
 #if !defined(TARGET_PPC64)
         sprintf(p, "r%dH", i);
-        cpu_gprh[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
-                                         offsetof(CPUState, gprh[i]), p);
+        cpu_gprh[i] = tcg_global_mem_new_i32(TCG_AREG0,
+                                             offsetof(CPUState, gprh[i]), p);
         p += (i < 10) ? 4 : 5;
 #endif
 
         sprintf(p, "fp%d", i);
-        cpu_fpr[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
-                                        offsetof(CPUState, fpr[i]), p);
+        cpu_fpr[i] = tcg_global_mem_new_i64(TCG_AREG0,
+                                            offsetof(CPUState, fpr[i]), p);
         p += (i < 10) ? 4 : 5;
 
         sprintf(p, "avr%dH", i);
-        cpu_avrh[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
+        cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0,
                                          offsetof(CPUState, avr[i].u64[0]), p);
         p += (i < 10) ? 6 : 7;
 
         sprintf(p, "avr%dL", i);
-        cpu_avrl[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
+        cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0,
                                          offsetof(CPUState, avr[i].u64[1]), p);
         p += (i < 10) ? 6 : 7;
     }
 
-    cpu_nip = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
+    cpu_nip = tcg_global_mem_new(TCG_AREG0,
                                  offsetof(CPUState, nip), "nip");
 
-    cpu_ctr = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
+    cpu_ctr = tcg_global_mem_new(TCG_AREG0,
                                  offsetof(CPUState, ctr), "ctr");
 
-    cpu_lr = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
+    cpu_lr = tcg_global_mem_new(TCG_AREG0,
                                 offsetof(CPUState, lr), "lr");
 
-    cpu_xer = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
+    cpu_xer = tcg_global_mem_new(TCG_AREG0,
                                  offsetof(CPUState, xer), "xer");
 
-    cpu_fpscr = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
-                                   offsetof(CPUState, fpscr), "fpscr");
+    cpu_fpscr = tcg_global_mem_new_i32(TCG_AREG0,
+                                       offsetof(CPUState, fpscr), "fpscr");
 
     /* register helpers */
-#undef DEF_HELPER
-#define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
+#define GEN_HELPER 2
 #include "helper.h"
 
     done_init = 1;
@@ -258,13 +253,16 @@ static always_inline void gen_compute_fprf (int set_fprf, int set_rc)
         *gen_fprf_ptr++ = gen_opc_ptr;
 #endif
         gen_op_compute_fprf(1);
-        if (unlikely(set_rc))
-            tcg_gen_andi_i32(cpu_crf[1], cpu_T[0], 0xf);
+        if (unlikely(set_rc)) {
+            tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_T[0]);
+            tcg_gen_andi_i32(cpu_crf[1], cpu_crf[1], 0xf);
+        }
         gen_op_float_check_status();
     } else if (unlikely(set_rc)) {
         /* We always need to compute fpcc */
         gen_op_compute_fprf(0);
-        tcg_gen_andi_i32(cpu_crf[1], cpu_T[0], 0xf);
+        tcg_gen_trunc_tl_i32(cpu_crf[1], cpu_T[0]);
+        tcg_gen_andi_i32(cpu_crf[1], cpu_crf[1], 0xf);
         if (set_fprf)
             gen_op_float_check_status();
     }
@@ -751,8 +749,8 @@ static always_inline void gen_op_cmpi(TCGv arg0, target_ulong arg1, int s, int c
 static always_inline void gen_op_cmp32(TCGv arg0, TCGv arg1, int s, int crf)
 {
     TCGv t0, t1;
-    t0 = tcg_temp_local_new(TCG_TYPE_TL);
-    t1 = tcg_temp_local_new(TCG_TYPE_TL);
+    t0 = tcg_temp_local_new();
+    t1 = tcg_temp_local_new();
     if (s) {
         tcg_gen_ext32s_tl(t0, arg0);
         tcg_gen_ext32s_tl(t1, arg1);
@@ -841,13 +839,13 @@ GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL)
     int l1, l2;
     uint32_t bi = rC(ctx->opcode);
     uint32_t mask;
-    TCGv t0;
+    TCGv_i32 t0;
 
     l1 = gen_new_label();
     l2 = gen_new_label();
 
     mask = 1 << (3 - (bi & 0x03));
-    t0 = tcg_temp_new(TCG_TYPE_I32);
+    t0 = tcg_temp_new_i32();
     tcg_gen_andi_i32(t0, cpu_crf[bi >> 2], mask);
     tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
     if (rA(ctx->opcode) == 0)
@@ -858,6 +856,7 @@ GEN_HANDLER(isel, 0x1F, 0x0F, 0xFF, 0x00000001, PPC_ISEL)
     gen_set_label(l1);
     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
     gen_set_label(l2);
+    tcg_temp_free_i32(t0);
 }
 
 /***                           Integer arithmetic                          ***/
@@ -870,7 +869,7 @@ static always_inline void gen_op_arith_compute_ov(DisasContext *ctx, TCGv arg0,
     l1 = gen_new_label();
     /* Start with XER OV disabled, the most likely case */
     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
-    t0 = tcg_temp_local_new(TCG_TYPE_TL);
+    t0 = tcg_temp_local_new();
     tcg_gen_xor_tl(t0, arg0, arg1);
 #if defined(TARGET_PPC64)
     if (!ctx->sf_mode)
@@ -901,8 +900,8 @@ static always_inline void gen_op_arith_compute_ca(DisasContext *ctx, TCGv arg1,
 #if defined(TARGET_PPC64)
     if (!(ctx->sf_mode)) {
         TCGv t0, t1;
-        t0 = tcg_temp_new(TCG_TYPE_TL);
-        t1 = tcg_temp_new(TCG_TYPE_TL);
+        t0 = tcg_temp_new();
+        t1 = tcg_temp_new();
 
         tcg_gen_ext32u_tl(t0, arg1);
         tcg_gen_ext32u_tl(t1, arg2);
@@ -911,15 +910,21 @@ static always_inline void gen_op_arith_compute_ca(DisasContext *ctx, TCGv arg1,
         } else {
             tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
         }
+        tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
+        gen_set_label(l1);
+        tcg_temp_free(t0);
+        tcg_temp_free(t1);
     } else
 #endif
-    if (sub) {
-        tcg_gen_brcond_tl(TCG_COND_GTU, arg1, arg2, l1);
-    } else {
-        tcg_gen_brcond_tl(TCG_COND_GEU, arg1, arg2, l1);
+    {
+        if (sub) {
+            tcg_gen_brcond_tl(TCG_COND_GTU, arg1, arg2, l1);
+        } else {
+            tcg_gen_brcond_tl(TCG_COND_GEU, arg1, arg2, l1);
+        }
+        tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
+        gen_set_label(l1);
     }
-    tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
-    gen_set_label(l1);
 }
 
 /* Common add function */
@@ -929,14 +934,14 @@ static always_inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg
     TCGv t0, t1;
 
     if ((!compute_ca && !compute_ov) ||
-        (GET_TCGV(ret) != GET_TCGV(arg1) && GET_TCGV(ret) != GET_TCGV(arg2)))  {
+        (!TCGV_EQUAL(ret,arg1) && !TCGV_EQUAL(ret, arg2)))  {
         t0 = ret;
     } else {
-        t0 = tcg_temp_local_new(TCG_TYPE_TL);
+        t0 = tcg_temp_local_new();
     }
 
     if (add_ca) {
-        t1 = tcg_temp_local_new(TCG_TYPE_TL);
+        t1 = tcg_temp_local_new();
         tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA));
         tcg_gen_shri_tl(t1, t1, XER_CA);
     }
@@ -969,7 +974,7 @@ static always_inline void gen_op_arith_add(DisasContext *ctx, TCGv ret, TCGv arg
     if (unlikely(Rc(ctx->opcode) != 0))
         gen_set_Rc0(ctx, t0);
 
-    if (GET_TCGV(t0) != GET_TCGV(ret)) {
+    if (!TCGV_EQUAL(t0, ret)) {
         tcg_gen_mov_tl(ret, t0);
         tcg_temp_free(t0);
     }
@@ -1031,7 +1036,7 @@ static always_inline void gen_op_addic (DisasContext *ctx, TCGv ret, TCGv arg1,
     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
 
     if (likely(simm != 0)) {
-        TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
+        TCGv t0 = tcg_temp_local_new();
         tcg_gen_addi_tl(t0, arg1, simm);
         gen_op_arith_compute_ca(ctx, t0, arg1, 0);
         tcg_gen_mov_tl(ret, t0);
@@ -1069,8 +1074,8 @@ static always_inline void gen_op_arith_divw (DisasContext *ctx, TCGv ret, TCGv a
 {
     int l1 = gen_new_label();
     int l2 = gen_new_label();
-    TCGv t0 = tcg_temp_local_new(TCG_TYPE_I32);
-    TCGv t1 = tcg_temp_local_new(TCG_TYPE_I32);
+    TCGv_i32 t0 = tcg_temp_local_new_i32();
+    TCGv_i32 t1 = tcg_temp_local_new_i32();
 
     tcg_gen_trunc_tl_i32(t0, arg1);
     tcg_gen_trunc_tl_i32(t1, arg2);
@@ -1099,8 +1104,8 @@ static always_inline void gen_op_arith_divw (DisasContext *ctx, TCGv ret, TCGv a
     }
     gen_set_label(l2);
     tcg_gen_extu_i32_tl(ret, t0);
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
+    tcg_temp_free_i32(t0);
+    tcg_temp_free_i32(t1);
     if (unlikely(Rc(ctx->opcode) != 0))
         gen_set_Rc0(ctx, ret);
 }
@@ -1170,10 +1175,10 @@ GEN_INT_ARITH_DIVD(divdo, 0x1F, 1, 1);
 /* mulhw  mulhw. */
 GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER)
 {
-    TCGv t0, t1;
+    TCGv_i64 t0, t1;
 
-    t0 = tcg_temp_new(TCG_TYPE_I64);
-    t1 = tcg_temp_new(TCG_TYPE_I64);
+    t0 = tcg_temp_new_i64();
+    t1 = tcg_temp_new_i64();
 #if defined(TARGET_PPC64)
     tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
     tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
@@ -1186,18 +1191,18 @@ GEN_HANDLER(mulhw, 0x1F, 0x0B, 0x02, 0x00000400, PPC_INTEGER)
     tcg_gen_shri_i64(t0, t0, 32);
     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
 #endif
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
+    tcg_temp_free_i64(t0);
+    tcg_temp_free_i64(t1);
     if (unlikely(Rc(ctx->opcode) != 0))
         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
 }
 /* mulhwu  mulhwu.  */
 GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER)
 {
-    TCGv t0, t1;
+    TCGv_i64 t0, t1;
 
-    t0 = tcg_temp_new(TCG_TYPE_I64);
-    t1 = tcg_temp_new(TCG_TYPE_I64);
+    t0 = tcg_temp_new_i64();
+    t1 = tcg_temp_new_i64();
 #if defined(TARGET_PPC64)
     tcg_gen_ext32u_i64(t0, cpu_gpr[rA(ctx->opcode)]);
     tcg_gen_ext32u_i64(t1, cpu_gpr[rB(ctx->opcode)]);
@@ -1210,8 +1215,8 @@ GEN_HANDLER(mulhwu, 0x1F, 0x0B, 0x00, 0x00000400, PPC_INTEGER)
     tcg_gen_shri_i64(t0, t0, 32);
     tcg_gen_trunc_i64_tl(cpu_gpr[rD(ctx->opcode)], t0);
 #endif
-    tcg_temp_free(t0);
-    tcg_temp_free(t1);
+    tcg_temp_free_i64(t0);
+    tcg_temp_free_i64(t1);
     if (unlikely(Rc(ctx->opcode) != 0))
         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
 }
@@ -1228,10 +1233,10 @@ GEN_HANDLER(mullw, 0x1F, 0x0B, 0x07, 0x00000000, PPC_INTEGER)
 GEN_HANDLER(mullwo, 0x1F, 0x0B, 0x17, 0x00000000, PPC_INTEGER)
 {
     int l1;
-    TCGv t0, t1;
+    TCGv_i64 t0, t1;
 
-    t0 = tcg_temp_local_new(TCG_TYPE_I64);
-    t1 = tcg_temp_local_new(TCG_TYPE_I64);
+    t0 = tcg_temp_new_i64();
+    t1 = tcg_temp_new_i64();
     l1 = gen_new_label();
     /* Start with XER OV disabled, the most likely case */
     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_OV));
@@ -1253,6 +1258,8 @@ GEN_HANDLER(mullwo, 0x1F, 0x0B, 0x17, 0x00000000, PPC_INTEGER)
 #endif
     tcg_gen_ori_tl(cpu_xer, cpu_xer, (1 << XER_OV) | (1 << XER_SO));
     gen_set_label(l1);
+    tcg_temp_free_i64(t0);
+    tcg_temp_free_i64(t1);
     if (unlikely(Rc(ctx->opcode) != 0))
         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
 }
@@ -1266,7 +1273,7 @@ GEN_HANDLER(mulli, 0x07, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
 #define GEN_INT_ARITH_MUL_HELPER(name, opc3)                                  \
 GEN_HANDLER(name, 0x1F, 0x09, opc3, 0x00000000, PPC_64B)                      \
 {                                                                             \
-    tcg_gen_helper_1_2(helper_##name, cpu_gpr[rD(ctx->opcode)],               \
+    gen_helper_##name (cpu_gpr[rD(ctx->opcode)],                              \
                        cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);   \
     if (unlikely(Rc(ctx->opcode) != 0))                                       \
         gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);                           \
@@ -1292,10 +1299,10 @@ static always_inline void gen_op_arith_neg (DisasContext *ctx, TCGv ret, TCGv ar
 {
     int l1 = gen_new_label();
     int l2 = gen_new_label();
-    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
+    TCGv t0 = tcg_temp_local_new();
 #if defined(TARGET_PPC64)
     if (ctx->sf_mode) {
-        tcg_gen_movi_tl(t0, arg1);
+        tcg_gen_mov_tl(t0, arg1);
         tcg_gen_brcondi_tl(TCG_COND_EQ, t0, INT64_MIN, l1);
     } else
 #endif
@@ -1334,14 +1341,14 @@ static always_inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv ar
     TCGv t0, t1;
 
     if ((!compute_ca && !compute_ov) ||
-        (GET_TCGV(ret) != GET_TCGV(arg1) && GET_TCGV(ret) != GET_TCGV(arg2)))  {
+        (!TCGV_EQUAL(ret, arg1) && !TCGV_EQUAL(ret, arg2)))  {
         t0 = ret;
     } else {
-        t0 = tcg_temp_local_new(TCG_TYPE_TL);
+        t0 = tcg_temp_local_new();
     }
 
     if (add_ca) {
-        t1 = tcg_temp_local_new(TCG_TYPE_TL);
+        t1 = tcg_temp_local_new();
         tcg_gen_andi_tl(t1, cpu_xer, (1 << XER_CA));
         tcg_gen_shri_tl(t1, t1, XER_CA);
     }
@@ -1377,7 +1384,7 @@ static always_inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv ar
     if (unlikely(Rc(ctx->opcode) != 0))
         gen_set_Rc0(ctx, t0);
 
-    if (GET_TCGV(t0) != GET_TCGV(ret)) {
+    if (!TCGV_EQUAL(t0, ret)) {
         tcg_gen_mov_tl(ret, t0);
         tcg_temp_free(t0);
     }
@@ -1421,7 +1428,7 @@ GEN_HANDLER(subfic, 0x08, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
 {
     /* Start with XER CA and OV disabled, the most likely case */
     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
-    TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
+    TCGv t0 = tcg_temp_local_new();
     TCGv t1 = tcg_const_local_tl(SIMM(ctx->opcode));
     tcg_gen_sub_tl(t0, t1, cpu_gpr[rA(ctx->opcode)]);
     gen_op_arith_compute_ca(ctx, t0, t1, 1);
@@ -1467,7 +1474,7 @@ GEN_HANDLER2(andis_, "andis.", 0x1D, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
 /* cntlzw */
 GEN_HANDLER(cntlzw, 0x1F, 0x1A, 0x00, 0x00000000, PPC_INTEGER)
 {
-    tcg_gen_helper_1_1(helper_cntlzw, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
+    gen_helper_cntlzw(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
     if (unlikely(Rc(ctx->opcode) != 0))
         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
 }
@@ -1547,7 +1554,7 @@ GEN_HANDLER(or, 0x1F, 0x1C, 0x0D, 0x00000000, PPC_INTEGER)
             break;
         }
         if (prio) {
-            TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
+            TCGv t0 = tcg_temp_new();
             tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, spr[SPR_PPR]));
             tcg_gen_andi_tl(t0, t0, ~0x001C000000000000ULL);
             tcg_gen_ori_tl(t0, t0, ((uint64_t)prio) << 50);
@@ -1620,10 +1627,10 @@ GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB)
 {
 #if defined(TARGET_PPC64)
     if (ctx->sf_mode)
-        tcg_gen_helper_1_1(helper_popcntb_64, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
+        gen_helper_popcntb_64(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
     else
 #endif
-        tcg_gen_helper_1_1(helper_popcntb, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
+        gen_helper_popcntb(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
 }
 
 #if defined(TARGET_PPC64)
@@ -1632,7 +1639,7 @@ GEN_LOGICAL1(extsw, tcg_gen_ext32s_tl, 0x1E, PPC_64B);
 /* cntlzd */
 GEN_HANDLER(cntlzd, 0x1F, 0x1A, 0x01, 0x00000000, PPC_64B)
 {
-    tcg_gen_helper_1_1(helper_cntlzd, cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
+    gen_helper_cntlzd(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
     if (unlikely(Rc(ctx->opcode) != 0))
         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
 }
@@ -1650,16 +1657,15 @@ GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
     if (likely(sh == 0 && mb == 0 && me == 31)) {
         tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
     } else {
-        TCGv t0, t1;
         target_ulong mask;
-
-        t0 = tcg_temp_new(TCG_TYPE_TL);
+        TCGv t1;
+        TCGv t0 = tcg_temp_new();
 #if defined(TARGET_PPC64)
-        t1 = tcg_temp_new(TCG_TYPE_I32);
-        tcg_gen_trunc_i64_i32(t1, cpu_gpr[rS(ctx->opcode)]);
-        tcg_gen_rotli_i32(t1, t1, sh);
-        tcg_gen_extu_i32_i64(t0, t1);
-        tcg_temp_free(t1);
+        TCGv_i32 t2 = tcg_temp_new_i32();
+        tcg_gen_trunc_i64_i32(t2, cpu_gpr[rS(ctx->opcode)]);
+        tcg_gen_rotli_i32(t2, t2, sh);
+        tcg_gen_extu_i32_i64(t0, t2);
+        tcg_temp_free_i32(t2);
 #else
         tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
 #endif
@@ -1668,7 +1674,7 @@ GEN_HANDLER(rlwimi, 0x14, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
         me += 32;
 #endif
         mask = MASK(mb, me);
-        t1 = tcg_temp_new(TCG_TYPE_TL);
+        t1 = tcg_temp_new();
         tcg_gen_andi_tl(t0, t0, mask);
         tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
         tcg_gen_or_tl(cpu_gpr[rA(ctx->opcode)], t0, t1);
@@ -1691,26 +1697,26 @@ GEN_HANDLER(rlwinm, 0x15, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
         if (likely(sh == 0)) {
             tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
         } else {
-            TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
+            TCGv t0 = tcg_temp_new();
             tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
             tcg_gen_shli_tl(t0, t0, sh);
             tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
             tcg_temp_free(t0);
         }
     } else if (likely(sh != 0 && me == 31 && sh == (32 - mb))) {
-        TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
+        TCGv t0 = tcg_temp_new();
         tcg_gen_ext32u_tl(t0, cpu_gpr[rS(ctx->opcode)]);
         tcg_gen_shri_tl(t0, t0, mb);
         tcg_gen_ext32u_tl(cpu_gpr[rA(ctx->opcode)], t0);
         tcg_temp_free(t0);
     } else {
-        TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
+        TCGv t0 = tcg_temp_new();
 #if defined(TARGET_PPC64)
-        TCGv t1 = tcg_temp_new(TCG_TYPE_I32);
+        TCGv_i32 t1 = tcg_temp_new_i32();
         tcg_gen_trunc_i64_i32(t1, cpu_gpr[rS(ctx->opcode)]);
         tcg_gen_rotli_i32(t1, t1, sh);
         tcg_gen_extu_i32_i64(t0, t1);
-        tcg_temp_free(t1);
+        tcg_temp_free_i32(t1);
 #else
         tcg_gen_rotli_i32(t0, cpu_gpr[rS(ctx->opcode)], sh);
 #endif
@@ -1730,22 +1736,22 @@ GEN_HANDLER(rlwnm, 0x17, 0xFF, 0xFF, 0x00000000, PPC_INTEGER)
     uint32_t mb, me;
     TCGv t0;
 #if defined(TARGET_PPC64)
-    TCGv t1, t2;
+    TCGv_i32 t1, t2;
 #endif
 
     mb = MB(ctx->opcode);
     me = ME(ctx->opcode);
-    t0 = tcg_temp_new(TCG_TYPE_TL);
+    t0 = tcg_temp_new();
     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x1f);
 #if defined(TARGET_PPC64)
-    t1 = tcg_temp_new(TCG_TYPE_I32);
-    t2 = tcg_temp_new(TCG_TYPE_I32);
+    t1 = tcg_temp_new_i32();
+    t2 = tcg_temp_new_i32();
     tcg_gen_trunc_i64_i32(t1, cpu_gpr[rS(ctx->opcode)]);
     tcg_gen_trunc_i64_i32(t2, t0);
     tcg_gen_rotl_i32(t1, t1, t2);
     tcg_gen_extu_i32_i64(t0, t1);
-    tcg_temp_free(t1);
-    tcg_temp_free(t2);
+    tcg_temp_free_i32(t1);
+    tcg_temp_free_i32(t2);
 #else
     tcg_gen_rotl_i32(t0, cpu_gpr[rS(ctx->opcode)], t0);
 #endif
@@ -1803,7 +1809,7 @@ static always_inline void gen_rldinm (DisasContext *ctx, uint32_t mb,
     } else if (likely(sh != 0 && me == 63 && sh == (64 - mb))) {
         tcg_gen_shri_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], mb);
     } else {
-        TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
+        TCGv t0 = tcg_temp_new();
         tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
         if (likely(mb == 0 && me == 63)) {
             tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], t0);
@@ -1853,7 +1859,7 @@ static always_inline void gen_rldnm (DisasContext *ctx, uint32_t mb,
 
     mb = MB(ctx->opcode);
     me = ME(ctx->opcode);
-    t0 = tcg_temp_new(TCG_TYPE_TL);
+    t0 = tcg_temp_new();
     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
     tcg_gen_rotl_tl(t0, cpu_gpr[rS(ctx->opcode)], t0);
     if (unlikely(mb != 0 || me != 63)) {
@@ -1898,9 +1904,9 @@ static always_inline void gen_rldimi (DisasContext *ctx, int mbn, int shn)
         TCGv t0, t1;
         target_ulong mask;
 
-        t0 = tcg_temp_new(TCG_TYPE_TL);
+        t0 = tcg_temp_new();
         tcg_gen_rotli_tl(t0, cpu_gpr[rS(ctx->opcode)], sh);
-        t1 = tcg_temp_new(TCG_TYPE_TL);
+        t1 = tcg_temp_new();
         mask = MASK(mb, me);
         tcg_gen_andi_tl(t0, t0, mask);
         tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], ~mask);
@@ -1923,7 +1929,7 @@ GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER)
     l1 = gen_new_label();
     l2 = gen_new_label();
 
-    t0 = tcg_temp_local_new(TCG_TYPE_TL);
+    t0 = tcg_temp_local_new();
     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
     tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0x20, l1);
     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
@@ -1939,8 +1945,8 @@ GEN_HANDLER(slw, 0x1F, 0x18, 0x00, 0x00000000, PPC_INTEGER)
 /* sraw & sraw. */
 GEN_HANDLER(sraw, 0x1F, 0x18, 0x18, 0x00000000, PPC_INTEGER)
 {
-    tcg_gen_helper_1_2(helper_sraw, cpu_gpr[rA(ctx->opcode)],
-                       cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
+    gen_helper_sraw(cpu_gpr[rA(ctx->opcode)],
+                    cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
     if (unlikely(Rc(ctx->opcode) != 0))
         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
 }
@@ -1953,7 +1959,7 @@ GEN_HANDLER(srawi, 0x1F, 0x18, 0x19, 0x00000000, PPC_INTEGER)
         TCGv t0;
         l1 = gen_new_label();
         l2 = gen_new_label();
-        t0 = tcg_temp_local_new(TCG_TYPE_TL);
+        t0 = tcg_temp_local_new();
         tcg_gen_ext32s_tl(t0, cpu_gpr[rS(ctx->opcode)]);
         tcg_gen_brcondi_tl(TCG_COND_GE, t0, 0, l1);
         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
@@ -1981,13 +1987,13 @@ GEN_HANDLER(srw, 0x1F, 0x18, 0x10, 0x00000000, PPC_INTEGER)
     l1 = gen_new_label();
     l2 = gen_new_label();
 
-    t0 = tcg_temp_local_new(TCG_TYPE_TL);
+    t0 = tcg_temp_local_new();
     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x3f);
     tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0x20, l1);
     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
     tcg_gen_br(l2);
     gen_set_label(l1);
-    t1 = tcg_temp_new(TCG_TYPE_TL);
+    t1 = tcg_temp_new();
     tcg_gen_ext32u_tl(t1, cpu_gpr[rS(ctx->opcode)]);
     tcg_gen_shr_tl(cpu_gpr[rA(ctx->opcode)], t1, t0);
     tcg_temp_free(t1);
@@ -2005,7 +2011,7 @@ GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B)
     l1 = gen_new_label();
     l2 = gen_new_label();
 
-    t0 = tcg_temp_local_new(TCG_TYPE_TL);
+    t0 = tcg_temp_local_new();
     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x7f);
     tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0x40, l1);
     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
@@ -2020,8 +2026,8 @@ GEN_HANDLER(sld, 0x1F, 0x1B, 0x00, 0x00000000, PPC_64B)
 /* srad & srad. */
 GEN_HANDLER(srad, 0x1F, 0x1A, 0x18, 0x00000000, PPC_64B)
 {
-    tcg_gen_helper_1_2(helper_srad, cpu_gpr[rA(ctx->opcode)],
-                       cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
+    gen_helper_srad(cpu_gpr[rA(ctx->opcode)],
+                    cpu_gpr[rS(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
     if (unlikely(Rc(ctx->opcode) != 0))
         gen_set_Rc0(ctx, cpu_gpr[rA(ctx->opcode)]);
 }
@@ -2034,8 +2040,8 @@ static always_inline void gen_sradi (DisasContext *ctx, int n)
         TCGv t0;
         l1 = gen_new_label();
         l2 = gen_new_label();
+        t0 = tcg_temp_local_new();
         tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rS(ctx->opcode)], 0, l1);
-        t0 = tcg_temp_new(TCG_TYPE_TL);
         tcg_gen_andi_tl(t0, cpu_gpr[rS(ctx->opcode)], (1ULL << sh) - 1);
         tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
         tcg_gen_ori_tl(cpu_xer, cpu_xer, 1 << XER_CA);
@@ -2043,6 +2049,7 @@ static always_inline void gen_sradi (DisasContext *ctx, int n)
         gen_set_label(l1);
         tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_CA));
         gen_set_label(l2);
+        tcg_temp_free(t0);
         tcg_gen_sari_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)], sh);
     } else {
         tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
@@ -2067,7 +2074,7 @@ GEN_HANDLER(srd, 0x1F, 0x1B, 0x10, 0x00000000, PPC_64B)
     l1 = gen_new_label();
     l2 = gen_new_label();
 
-    t0 = tcg_temp_local_new(TCG_TYPE_TL);
+    t0 = tcg_temp_local_new();
     tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x7f);
     tcg_gen_brcondi_tl(TCG_COND_LT, t0, 0x40, l1);
     tcg_gen_movi_tl(cpu_gpr[rA(ctx->opcode)], 0);
@@ -2278,7 +2285,7 @@ GEN_HANDLER(fcmpo, 0x3F, 0x00, 0x01, 0x00600001, PPC_FLOAT)
     tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);
     tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rB(ctx->opcode)]);
     gen_reset_fpstatus();
-    tcg_gen_helper_1_0(helper_fcmpo, cpu_crf[crfD(ctx->opcode)]);
+    gen_helper_fcmpo(cpu_crf[crfD(ctx->opcode)]);
     gen_op_float_check_status();
 }
 
@@ -2292,7 +2299,7 @@ GEN_HANDLER(fcmpu, 0x3F, 0x00, 0x00, 0x00600001, PPC_FLOAT)
     tcg_gen_mov_i64(cpu_FT[0], cpu_fpr[rA(ctx->opcode)]);
     tcg_gen_mov_i64(cpu_FT[1], cpu_fpr[rB(ctx->opcode)]);
     gen_reset_fpstatus();
-    tcg_gen_helper_1_0(helper_fcmpu, cpu_crf[crfD(ctx->opcode)]);
+    gen_helper_fcmpu(cpu_crf[crfD(ctx->opcode)]);
     gen_op_float_check_status();
 }
 
@@ -2518,7 +2525,7 @@ static always_inline void gen_qemu_ld##width##_ppc64(TCGv t0, TCGv t1, int flags
     if (likely(flags & 2))                                                       \
         tcg_gen_qemu_ld##width(t0, t1, flags >> 2);                              \
     else {                                                                       \
-        TCGv addr = tcg_temp_new(TCG_TYPE_TL);                                   \
+        TCGv addr = tcg_temp_new();                                   \
         tcg_gen_ext32u_tl(addr, t1);                                             \
         tcg_gen_qemu_ld##width(t0, addr, flags >> 2);                            \
         tcg_temp_free(addr);                                                     \
@@ -2538,7 +2545,7 @@ static always_inline void gen_qemu_st##width##_ppc64(TCGv t0, TCGv t1, int flags
     if (likely(flags & 2))                                                       \
         tcg_gen_qemu_st##width(t0, t1, flags >> 2);                              \
     else {                                                                       \
-        TCGv addr = tcg_temp_new(TCG_TYPE_TL);                                   \
+        TCGv addr = tcg_temp_new();                                   \
         tcg_gen_ext32u_tl(addr, t1);                                             \
         tcg_gen_qemu_st##width(t0, addr, flags >> 2);                            \
         tcg_temp_free(addr);                                                     \
@@ -2562,13 +2569,13 @@ static always_inline void gen_qemu_ld8s(TCGv arg0, TCGv arg1, int flags)
 static always_inline void gen_qemu_ld16u(TCGv arg0, TCGv arg1, int flags)
 {
     if (unlikely(flags & 1)) {
-        TCGv t0;
+        TCGv_i32 t0;
         gen_qemu_ld16u_ppc64(arg0, arg1, flags);
-        t0 = tcg_temp_new(TCG_TYPE_I32);
+        t0 = tcg_temp_new_i32();
         tcg_gen_trunc_tl_i32(t0, arg0);
         tcg_gen_bswap16_i32(t0, t0);
         tcg_gen_extu_i32_tl(arg0, t0);
-        tcg_temp_free(t0);
+        tcg_temp_free_i32(t0);
     } else
         gen_qemu_ld16u_ppc64(arg0, arg1, flags);
 }
@@ -2576,14 +2583,14 @@ static always_inline void gen_qemu_ld16u(TCGv arg0, TCGv arg1, int flags)
 static always_inline void gen_qemu_ld16s(TCGv arg0, TCGv arg1, int flags)
 {
     if (unlikely(flags & 1)) {
-        TCGv t0;
+        TCGv_i32 t0;
         gen_qemu_ld16u_ppc64(arg0, arg1, flags);
-        t0 = tcg_temp_new(TCG_TYPE_I32);
+        t0 = tcg_temp_new_i32();
         tcg_gen_trunc_tl_i32(t0, arg0);
         tcg_gen_bswap16_i32(t0, t0);
         tcg_gen_extu_i32_tl(arg0, t0);
         tcg_gen_ext16s_tl(arg0, arg0);
-        tcg_temp_free(t0);
+        tcg_temp_free_i32(t0);
     } else
         gen_qemu_ld16s_ppc64(arg0, arg1, flags);
 }
@@ -2591,13 +2598,13 @@ static always_inline void gen_qemu_ld16s(TCGv arg0, TCGv arg1, int flags)
 static always_inline void gen_qemu_ld32u(TCGv arg0, TCGv arg1, int flags)
 {
     if (unlikely(flags & 1)) {
-        TCGv t0;
+        TCGv_i32 t0;
         gen_qemu_ld32u_ppc64(arg0, arg1, flags);
-        t0 = tcg_temp_new(TCG_TYPE_I32);
+        t0 = tcg_temp_new_i32();
         tcg_gen_trunc_tl_i32(t0, arg0);
         tcg_gen_bswap_i32(t0, t0);
         tcg_gen_extu_i32_tl(arg0, t0);
-        tcg_temp_free(t0);
+        tcg_temp_free_i32(t0);
     } else
         gen_qemu_ld32u_ppc64(arg0, arg1, flags);
 }
@@ -2605,13 +2612,13 @@ static always_inline void gen_qemu_ld32u(TCGv arg0, TCGv arg1, int flags)
 static always_inline void gen_qemu_ld32s(TCGv arg0, TCGv arg1, int flags)
 {
     if (unlikely(flags & 1)) {
-        TCGv t0;
+        TCGv_i32 t0;
         gen_qemu_ld32u_ppc64(arg0, arg1, flags);
-        t0 = tcg_temp_new(TCG_TYPE_I32);
+        t0 = tcg_temp_new_i32();
         tcg_gen_trunc_tl_i32(t0, arg0);
         tcg_gen_bswap_i32(t0, t0);
         tcg_gen_ext_i32_tl(arg0, t0);
-        tcg_temp_free(t0);
+        tcg_temp_free_i32(t0);
     } else
         gen_qemu_ld32s_ppc64(arg0, arg1, flags);
 }
@@ -2631,16 +2638,17 @@ static always_inline void gen_qemu_st8(TCGv arg0, TCGv arg1, int flags)
 static always_inline void gen_qemu_st16(TCGv arg0, TCGv arg1, int flags)
 {
     if (unlikely(flags & 1)) {
-        TCGv t0, t1;
-        t0 = tcg_temp_new(TCG_TYPE_I32);
+        TCGv_i32 t0;
+        TCGv_i64 t1;
+        t0 = tcg_temp_new_i32();
         tcg_gen_trunc_tl_i32(t0, arg0);
         tcg_gen_ext16u_i32(t0, t0);
         tcg_gen_bswap16_i32(t0, t0);
-        t1 = tcg_temp_new(TCG_TYPE_I64);
+        t1 = tcg_temp_new_i64();
         tcg_gen_extu_i32_tl(t1, t0);
-        tcg_temp_free(t0);
+        tcg_temp_free_i32(t0);
         gen_qemu_st16_ppc64(t1, arg1, flags);
-        tcg_temp_free(t1);
+        tcg_temp_free_i64(t1);
     } else
         gen_qemu_st16_ppc64(arg0, arg1, flags);
 }
@@ -2648,15 +2656,16 @@ static always_inline void gen_qemu_st16(TCGv arg0, TCGv arg1, int flags)
 static always_inline void gen_qemu_st32(TCGv arg0, TCGv arg1, int flags)
 {
     if (unlikely(flags & 1)) {
-        TCGv t0, t1;
-        t0 = tcg_temp_new(TCG_TYPE_I32);
+        TCGv_i32 t0;
+        TCGv_i64 t1;
+        t0 = tcg_temp_new_i32();
         tcg_gen_trunc_tl_i32(t0, arg0);
         tcg_gen_bswap_i32(t0, t0);
-        t1 = tcg_temp_new(TCG_TYPE_I64);
+        t1 = tcg_temp_new_i64();
         tcg_gen_extu_i32_tl(t1, t0);
-        tcg_temp_free(t0);
+        tcg_temp_free_i32(t0);
         gen_qemu_st32_ppc64(t1, arg1, flags);
-        tcg_temp_free(t1);
+        tcg_temp_free_i64(t1);
     } else
         gen_qemu_st32_ppc64(arg0, arg1, flags);
 }
@@ -2664,10 +2673,10 @@ static always_inline void gen_qemu_st32(TCGv arg0, TCGv arg1, int flags)
 static always_inline void gen_qemu_st64(TCGv arg0, TCGv arg1, int flags)
 {
     if (unlikely(flags & 1)) {
-        TCGv t0 = tcg_temp_new(TCG_TYPE_I64);
+        TCGv_i64 t0 = tcg_temp_new_i64();
         tcg_gen_bswap_i64(t0, arg0);
         gen_qemu_st64_ppc64(t0, arg1, flags);
-        tcg_temp_free(t0);
+        tcg_temp_free_i64(t0);
     } else
         gen_qemu_st64_ppc64(arg0, arg1, flags);
 }
@@ -2685,7 +2694,6 @@ GEN_QEMU_LD_PPC32(16u)
 GEN_QEMU_LD_PPC32(16s)
 GEN_QEMU_LD_PPC32(32u)
 GEN_QEMU_LD_PPC32(32s)
-GEN_QEMU_LD_PPC32(64)
 
 #define GEN_QEMU_ST_PPC32(width)                                                 \
 static always_inline void gen_qemu_st##width##_ppc32(TCGv arg0, TCGv arg1, int flags)\
@@ -2695,7 +2703,6 @@ static always_inline void gen_qemu_st##width##_ppc32(TCGv arg0, TCGv arg1, int f
 GEN_QEMU_ST_PPC32(8)
 GEN_QEMU_ST_PPC32(16)
 GEN_QEMU_ST_PPC32(32)
-GEN_QEMU_ST_PPC32(64)
 
 static always_inline void gen_qemu_ld8u(TCGv arg0, TCGv arg1, int flags)
 {
@@ -2731,13 +2738,6 @@ static always_inline void gen_qemu_ld32u(TCGv arg0, TCGv arg1, int flags)
         tcg_gen_bswap_i32(arg0, arg0);
 }
 
-static always_inline void gen_qemu_ld64(TCGv arg0, TCGv arg1, int flags)
-{
-    gen_qemu_ld64_ppc32(arg0, arg1, flags);
-    if (unlikely(flags & 1))
-        tcg_gen_bswap_i64(arg0, arg0);
-}
-
 static always_inline void gen_qemu_st8(TCGv arg0, TCGv arg1, int flags)
 {
     gen_qemu_st8_ppc32(arg0, arg1, flags);
@@ -2746,11 +2746,11 @@ static always_inline void gen_qemu_st8(TCGv arg0, TCGv arg1, int flags)
 static always_inline void gen_qemu_st16(TCGv arg0, TCGv arg1, int flags)
 {
     if (unlikely(flags & 1)) {
-        TCGv temp = tcg_temp_new(TCG_TYPE_I32);
+        TCGv_i32 temp = tcg_temp_new_i32();
         tcg_gen_ext16u_i32(temp, arg0);
         tcg_gen_bswap16_i32(temp, temp);
         gen_qemu_st16_ppc32(temp, arg1, flags);
-        tcg_temp_free(temp);
+        tcg_temp_free_i32(temp);
     } else
         gen_qemu_st16_ppc32(arg0, arg1, flags);
 }
@@ -2758,31 +2758,20 @@ static always_inline void gen_qemu_st16(TCGv arg0, TCGv arg1, int flags)
 static always_inline void gen_qemu_st32(TCGv arg0, TCGv arg1, int flags)
 {
     if (unlikely(flags & 1)) {
-        TCGv temp = tcg_temp_new(TCG_TYPE_I32);
+        TCGv_i32 temp = tcg_temp_new_i32();
         tcg_gen_bswap_i32(temp, arg0);
         gen_qemu_st32_ppc32(temp, arg1, flags);
-        tcg_temp_free(temp);
+        tcg_temp_free_i32(temp);
     } else
         gen_qemu_st32_ppc32(arg0, arg1, flags);
 }
 
-static always_inline void gen_qemu_st64(TCGv arg0, TCGv arg1, int flags)
-{
-    if (unlikely(flags & 1)) {
-        TCGv temp = tcg_temp_new(TCG_TYPE_I64);
-        tcg_gen_bswap_i64(temp, arg0);
-        gen_qemu_st64_ppc32(temp, arg1, flags);
-        tcg_temp_free(temp);
-    } else
-        gen_qemu_st64_ppc32(arg0, arg1, flags);
-}
-
 #endif
 
 #define GEN_LD(width, opc, type)                                              \
 GEN_HANDLER(l##width, opc, 0xFF, 0xFF, 0x00000000, type)                      \
 {                                                                             \
-    TCGv EA = tcg_temp_new(TCG_TYPE_TL);                                      \
+    TCGv EA = tcg_temp_new();                                      \
     gen_addr_imm_index(EA, ctx, 0);                                           \
     gen_qemu_ld##width(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx);           \
     tcg_temp_free(EA);                                                        \
@@ -2797,7 +2786,7 @@ GEN_HANDLER(l##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                   \
         GEN_EXCP_INVAL(ctx);                                                  \
         return;                                                               \
     }                                                                         \
-    EA = tcg_temp_new(TCG_TYPE_TL);                                           \
+    EA = tcg_temp_new();                                           \
     if (type == PPC_64B)                                                      \
         gen_addr_imm_index(EA, ctx, 0x03);                                    \
     else                                                                      \
@@ -2816,7 +2805,7 @@ GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                 \
         GEN_EXCP_INVAL(ctx);                                                  \
         return;                                                               \
     }                                                                         \
-    EA = tcg_temp_new(TCG_TYPE_TL);                                           \
+    EA = tcg_temp_new();                                           \
     gen_addr_reg_index(EA, ctx);                                              \
     gen_qemu_ld##width(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx);           \
     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
@@ -2826,7 +2815,7 @@ GEN_HANDLER(l##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                 \
 #define GEN_LDX(width, opc2, opc3, type)                                      \
 GEN_HANDLER(l##width##x, 0x1F, opc2, opc3, 0x00000001, type)                  \
 {                                                                             \
-    TCGv EA = tcg_temp_new(TCG_TYPE_TL);                                      \
+    TCGv EA = tcg_temp_new();                                      \
     gen_addr_reg_index(EA, ctx);                                              \
     gen_qemu_ld##width(cpu_gpr[rD(ctx->opcode)], EA, ctx->mem_idx);           \
     tcg_temp_free(EA);                                                        \
@@ -2865,7 +2854,7 @@ GEN_HANDLER(ld, 0x3A, 0xFF, 0xFF, 0x00000000, PPC_64B)
             return;
         }
     }
-    EA = tcg_temp_new(TCG_TYPE_TL);
+    EA = tcg_temp_new();
     gen_addr_imm_index(EA, ctx, 0x03);
     if (ctx->opcode & 0x02) {
         /* lwa (lwau is undefined) */
@@ -2903,7 +2892,7 @@ GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX)
         GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
         return;
     }
-    EA = tcg_temp_new(TCG_TYPE_TL);
+    EA = tcg_temp_new();
     gen_addr_imm_index(EA, ctx, 0x0F);
     gen_qemu_ld64(cpu_gpr[rd], EA, ctx->mem_idx);
     tcg_gen_addi_tl(EA, EA, 8);
@@ -2917,7 +2906,7 @@ GEN_HANDLER(lq, 0x38, 0xFF, 0xFF, 0x00000000, PPC_64BX)
 #define GEN_ST(width, opc, type)                                              \
 GEN_HANDLER(st##width, opc, 0xFF, 0xFF, 0x00000000, type)                     \
 {                                                                             \
-    TCGv EA = tcg_temp_new(TCG_TYPE_TL);                                      \
+    TCGv EA = tcg_temp_new();                                      \
     gen_addr_imm_index(EA, ctx, 0);                                           \
     gen_qemu_st##width(cpu_gpr[rS(ctx->opcode)], EA, ctx->mem_idx);       \
     tcg_temp_free(EA);                                                        \
@@ -2931,7 +2920,7 @@ GEN_HANDLER(st##width##u, opc, 0xFF, 0xFF, 0x00000000, type)                  \
         GEN_EXCP_INVAL(ctx);                                                  \
         return;                                                               \
     }                                                                         \
-    EA = tcg_temp_new(TCG_TYPE_TL);                                           \
+    EA = tcg_temp_new();                                           \
     if (type == PPC_64B)                                                      \
         gen_addr_imm_index(EA, ctx, 0x03);                                    \
     else                                                                      \
@@ -2949,7 +2938,7 @@ GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                \
         GEN_EXCP_INVAL(ctx);                                                  \
         return;                                                               \
     }                                                                         \
-    EA = tcg_temp_new(TCG_TYPE_TL);                                           \
+    EA = tcg_temp_new();                                           \
     gen_addr_reg_index(EA, ctx);                                              \
     gen_qemu_st##width(cpu_gpr[rS(ctx->opcode)], EA, ctx->mem_idx);           \
     tcg_gen_mov_tl(cpu_gpr[rA(ctx->opcode)], EA);                             \
@@ -2959,7 +2948,7 @@ GEN_HANDLER(st##width##ux, 0x1F, opc2, opc3, 0x00000001, type)                \
 #define GEN_STX(width, opc2, opc3, type)                                      \
 GEN_HANDLER(st##width##x, 0x1F, opc2, opc3, 0x00000001, type)                 \
 {                                                                             \
-    TCGv EA = tcg_temp_new(TCG_TYPE_TL);                                      \
+    TCGv EA = tcg_temp_new();                                      \
     gen_addr_reg_index(EA, ctx);                                              \
     gen_qemu_st##width(cpu_gpr[rS(ctx->opcode)], EA, ctx->mem_idx);           \
     tcg_temp_free(EA);                                                        \
@@ -3004,7 +2993,7 @@ GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B)
             GEN_EXCP(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
             return;
         }
-        EA = tcg_temp_new(TCG_TYPE_TL);
+        EA = tcg_temp_new();
         gen_addr_imm_index(EA, ctx, 0x03);
         gen_qemu_st64(cpu_gpr[rs], EA, ctx->mem_idx);
         tcg_gen_addi_tl(EA, EA, 8);
@@ -3019,7 +3008,7 @@ GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B)
                 return;
             }
         }
-        EA = tcg_temp_new(TCG_TYPE_TL);
+        EA = tcg_temp_new();
         gen_addr_imm_index(EA, ctx, 0x03);
         gen_qemu_st64(cpu_gpr[rs], EA, ctx->mem_idx);
         if (Rc(ctx->opcode))
@@ -3032,45 +3021,53 @@ GEN_HANDLER(std, 0x3E, 0xFF, 0xFF, 0x00000000, PPC_64B)
 /* lhbrx */
 void always_inline gen_qemu_ld16ur(TCGv t0, TCGv t1, int flags)
 {
-    TCGv temp = tcg_temp_new(TCG_TYPE_I32);
-    gen_qemu_ld16u(temp, t1, flags);
+    TCGv_i32 temp = tcg_temp_new_i32();
+    gen_qemu_ld16u(t0, t1, flags);
+    tcg_gen_trunc_tl_i32(temp, t0);
     tcg_gen_bswap16_i32(temp, temp);
     tcg_gen_extu_i32_tl(t0, temp);
-    tcg_temp_free(temp);
+    tcg_temp_free_i32(temp);
 }
 GEN_LDX(16ur, 0x16, 0x18, PPC_INTEGER);
 
 /* lwbrx */
 void always_inline gen_qemu_ld32ur(TCGv t0, TCGv t1, int flags)
 {
-    TCGv temp = tcg_temp_new(TCG_TYPE_I32);
-    gen_qemu_ld32u(temp, t1, flags);
+    TCGv_i32 temp = tcg_temp_new_i32();
+    gen_qemu_ld32u(t0, t1, flags);
+    tcg_gen_trunc_tl_i32(temp, t0);
     tcg_gen_bswap_i32(temp, temp);
     tcg_gen_extu_i32_tl(t0, temp);
-    tcg_temp_free(temp);
+    tcg_temp_free_i32(temp);
 }
 GEN_LDX(32ur, 0x16, 0x10, PPC_INTEGER);
 
 /* sthbrx */
 void always_inline gen_qemu_st16r(TCGv t0, TCGv t1, int flags)
 {
-    TCGv temp = tcg_temp_new(TCG_TYPE_I32);
+    TCGv_i32 temp = tcg_temp_new_i32();
+    TCGv t2 = tcg_temp_new();
     tcg_gen_trunc_tl_i32(temp, t0);
     tcg_gen_ext16u_i32(temp, temp);
     tcg_gen_bswap16_i32(temp, temp);
-    gen_qemu_st16(temp, t1, flags);
-    tcg_temp_free(temp);
+    tcg_gen_extu_i32_tl(t2, temp);
+    tcg_temp_free_i32(temp);
+    gen_qemu_st16(t2, t1, flags);
+    tcg_temp_free(t2);
 }
 GEN_STX(16r, 0x16, 0x1C, PPC_INTEGER);
 
 /* stwbrx */
 void always_inline gen_qemu_st32r(TCGv t0, TCGv t1, int flags)
 {
-    TCGv temp = tcg_temp_new(TCG_TYPE_I32);
+    TCGv_i32 temp = tcg_temp_new_i32();
+    TCGv t2 = tcg_temp_new();
     tcg_gen_trunc_tl_i32(temp, t0);
     tcg_gen_bswap_i32(temp, temp);
-    gen_qemu_st32(temp, t1, flags);
-    tcg_temp_free(temp);
+    tcg_gen_extu_i32_tl(t2, temp);
+    tcg_temp_free_i32(temp);
+    gen_qemu_st32(t2, t1, flags);
+    tcg_temp_free(t2);
 }
 GEN_STX(32r, 0x16, 0x14, PPC_INTEGER);
 
@@ -3520,7 +3517,7 @@ static always_inline void gen_bcond (DisasContext *ctx, int type)
 
     ctx->exception = POWERPC_EXCP_BRANCH;
     if (type == BCOND_LR || type == BCOND_CTR) {
-        target = tcg_temp_local_new(TCG_TYPE_TL);
+        target = tcg_temp_local_new();
         if (type == BCOND_CTR)
             tcg_gen_mov_tl(target, cpu_ctr);
         else
@@ -3531,7 +3528,7 @@ static always_inline void gen_bcond (DisasContext *ctx, int type)
     l1 = gen_new_label();
     if ((bo & 0x4) == 0) {
         /* Decrement and test CTR */
-        TCGv temp = tcg_temp_new(TCG_TYPE_TL);
+        TCGv temp = tcg_temp_new();
         if (unlikely(type == BCOND_CTR)) {
             GEN_EXCP_INVAL(ctx);
             return;
@@ -3548,12 +3545,13 @@ static always_inline void gen_bcond (DisasContext *ctx, int type)
         } else {
             tcg_gen_brcondi_tl(TCG_COND_EQ, temp, 0, l1);
         }
+        tcg_temp_free(temp);
     }
     if ((bo & 0x10) == 0) {
         /* Test CR */
         uint32_t bi = BI(ctx->opcode);
         uint32_t mask = 1 << (3 - (bi & 0x03));
-        TCGv temp = tcg_temp_new(TCG_TYPE_I32);
+        TCGv_i32 temp = tcg_temp_new_i32();
 
         if (bo & 0x8) {
             tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
@@ -3562,6 +3560,7 @@ static always_inline void gen_bcond (DisasContext *ctx, int type)
             tcg_gen_andi_i32(temp, cpu_crf[bi >> 2], mask);
             tcg_gen_brcondi_i32(TCG_COND_NE, temp, 0, l1);
         }
+        tcg_temp_free_i32(temp);
     }
     if (type == BCOND_IM) {
         target_ulong li = (target_long)((int16_t)(BD(ctx->opcode)));
@@ -3612,16 +3611,16 @@ GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                   \
 {                                                                             \
     uint8_t bitmask;                                                          \
     int sh;                                                                   \
-    TCGv t0, t1;                                                              \
+    TCGv_i32 t0, t1;                                                          \
     sh = (crbD(ctx->opcode) & 0x03) - (crbA(ctx->opcode) & 0x03);             \
-    t0 = tcg_temp_new(TCG_TYPE_I32);                                          \
+    t0 = tcg_temp_new_i32();                                                  \
     if (sh > 0)                                                               \
         tcg_gen_shri_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], sh);            \
     else if (sh < 0)                                                          \
         tcg_gen_shli_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2], -sh);           \
     else                                                                      \
         tcg_gen_mov_i32(t0, cpu_crf[crbA(ctx->opcode) >> 2]);                 \
-    t1 = tcg_temp_new(TCG_TYPE_I32);                                          \
+    t1 = tcg_temp_new_i32();                                                  \
     sh = (crbD(ctx->opcode) & 0x03) - (crbB(ctx->opcode) & 0x03);             \
     if (sh > 0)                                                               \
         tcg_gen_shri_i32(t1, cpu_crf[crbB(ctx->opcode) >> 2], sh);            \
@@ -3634,8 +3633,8 @@ GEN_HANDLER(name, 0x13, 0x01, opc, 0x00000001, PPC_INTEGER)                   \
     tcg_gen_andi_i32(t0, t0, bitmask);                                        \
     tcg_gen_andi_i32(t1, cpu_crf[crbD(ctx->opcode) >> 2], ~bitmask);          \
     tcg_gen_or_i32(cpu_crf[crbD(ctx->opcode) >> 2], t0, t1);                  \
-    tcg_temp_free(t0);                                                        \
-    tcg_temp_free(t1);                                                        \
+    tcg_temp_free_i32(t0);                                                    \
+    tcg_temp_free_i32(t1);                                                    \
 }
 
 /* crand */
@@ -3787,7 +3786,7 @@ GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
             tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], cpu_crf[7 - crn]);
         }
     } else {
-        tcg_gen_helper_1_0(helper_load_cr, cpu_gpr[rD(ctx->opcode)]);
+        gen_helper_load_cr(cpu_gpr[rD(ctx->opcode)]);
     }
 }
 
@@ -3882,13 +3881,16 @@ GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
 
     crm = CRM(ctx->opcode);
     if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
+        TCGv_i32 temp = tcg_temp_new_i32();
         crn = ffs(crm);
-        tcg_gen_shri_i32(cpu_crf[7 - crn], cpu_gpr[rS(ctx->opcode)], crn * 4);
+        tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
+        tcg_gen_shri_i32(cpu_crf[7 - crn], temp, crn * 4);
         tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_crf[7 - crn], 0xf);
+        tcg_temp_free_i32(temp);
     } else {
-        TCGv t0 = tcg_const_tl(crm);
-        tcg_gen_helper_0_2(helper_store_cr, cpu_gpr[rS(ctx->opcode)], t0);
-        tcg_temp_free(t0);
+        TCGv_i32 temp = tcg_const_i32(crm);
+        gen_helper_store_cr(cpu_gpr[rS(ctx->opcode)], temp);
+        tcg_temp_free_i32(temp);
     }
 }
 
@@ -4000,7 +4002,7 @@ GEN_HANDLER(mtspr, 0x1F, 0x13, 0x0E, 0x00000001, PPC_MISC)
 GEN_HANDLER(dcbf, 0x1F, 0x16, 0x02, 0x03C00001, PPC_CACHE)
 {
     /* XXX: specification says this is treated as a load by the MMU */
-    TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
+    TCGv t0 = tcg_temp_new();
     gen_addr_reg_index(t0, ctx);
     gen_qemu_ld8u(t0, t0, ctx->mem_idx);
     tcg_temp_free(t0);
@@ -4017,9 +4019,9 @@ GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
         GEN_EXCP_PRIVOPC(ctx);
         return;
     }
-    EA = tcg_temp_new(TCG_TYPE_TL);
+    EA = tcg_temp_new();
     gen_addr_reg_index(EA, ctx);
-    val = tcg_temp_new(TCG_TYPE_TL);
+    val = tcg_temp_new();
     /* XXX: specification says this should be treated as a store by the MMU */
     gen_qemu_ld8u(val, EA, ctx->mem_idx);
     gen_qemu_st8(val, EA, ctx->mem_idx);
@@ -4032,7 +4034,7 @@ GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE)
 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE)
 {
     /* XXX: specification say this is treated as a load by the MMU */
-    TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
+    TCGv t0 = tcg_temp_new();
     gen_addr_reg_index(t0, ctx);
     gen_qemu_ld8u(t0, t0, ctx->mem_idx);
     tcg_temp_free(t0);
@@ -5178,8 +5180,8 @@ static always_inline void gen_405_mulladd_insn (DisasContext *ctx,
 {
     TCGv t0, t1;
 
-    t0 = tcg_temp_local_new(TCG_TYPE_TL);
-    t1 = tcg_temp_local_new(TCG_TYPE_TL);
+    t0 = tcg_temp_local_new();
+    t1 = tcg_temp_local_new();
 
     switch (opc3 & 0x0D) {
     case 0x05:
@@ -5501,9 +5503,9 @@ GEN_HANDLER(dcread, 0x1F, 0x06, 0x0F, 0x00000001, PPC_4xx_COMMON)
         GEN_EXCP_PRIVOPC(ctx);
         return;
     }
-    EA = tcg_temp_new(TCG_TYPE_TL);
+    EA = tcg_temp_new();
     gen_addr_reg_index(EA, ctx);
-    val = tcg_temp_new(TCG_TYPE_TL);
+    val = tcg_temp_new();
     gen_qemu_ld32u(val, EA, ctx->mem_idx);
     tcg_temp_free(val);
     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], EA);
@@ -5806,7 +5808,8 @@ GEN_HANDLER(dlmzb, 0x1F, 0x0E, 0x02, 0x00000000, PPC_440_SPEC)
     tcg_gen_or_tl(cpu_xer, cpu_xer, cpu_T[0]);
     if (Rc(ctx->opcode)) {
         gen_op_440_dlmzb_update_Rc();
-        tcg_gen_andi_i32(cpu_crf[0], cpu_T[0], 0xf);
+        tcg_gen_trunc_tl_i32(cpu_crf[0], cpu_T[0]);
+        tcg_gen_andi_i32(cpu_crf[0], cpu_crf[0], 0xf);
     }
 }
 
@@ -5893,7 +5896,7 @@ GEN_VR_STX(vxl, 0x07, 0x0F);
 /***                           SPE extension                               ***/
 /* Register moves */
 
-static always_inline void gen_load_gpr64(TCGv t, int reg) {
+static always_inline void gen_load_gpr64(TCGv_i64 t, int reg) {
 #if defined(TARGET_PPC64)
     tcg_gen_mov_i64(t, cpu_gpr[reg]);
 #else
@@ -5901,15 +5904,15 @@ static always_inline void gen_load_gpr64(TCGv t, int reg) {
 #endif
 }
 
-static always_inline void gen_store_gpr64(int reg, TCGv t) {
+static always_inline void gen_store_gpr64(int reg, TCGv_i64 t) {
 #if defined(TARGET_PPC64)
     tcg_gen_mov_i64(cpu_gpr[reg], t);
 #else
+    TCGv_i64 tmp = tcg_temp_new_i64();
     tcg_gen_trunc_i64_i32(cpu_gpr[reg], t);
-    TCGv tmp = tcg_temp_new(TCG_TYPE_I64);
     tcg_gen_shri_i64(tmp, t, 32);
     tcg_gen_trunc_i64_i32(cpu_gprh[reg], tmp);
-    tcg_temp_free(tmp);
+    tcg_temp_free_i64(tmp);
 #endif
 }
 
@@ -6013,158 +6016,556 @@ GEN_SPE_STX(name)
 GEN_SPEOP_LD(name, sh);                                                       \
 GEN_SPEOP_ST(name, sh)
 
-/* SPE arithmetic and logic */
-#define GEN_SPEOP_ARITH2(name)                                                \
+/* SPE logic */
+#if defined(TARGET_PPC64)
+#define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
 static always_inline void gen_##name (DisasContext *ctx)                      \
 {                                                                             \
     if (unlikely(!ctx->spe_enabled)) {                                        \
         GEN_EXCP_NO_AP(ctx);                                                  \
         return;                                                               \
     }                                                                         \
-    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
-    gen_load_gpr64(cpu_T64[1], rB(ctx->opcode));                              \
-    gen_op_##name();                                                          \
-    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
+    tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
+           cpu_gpr[rB(ctx->opcode)]);                                         \
 }
-
-#define GEN_SPEOP_TCG_ARITH2(name, tcg_op)                                    \
+#else
+#define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
 static always_inline void gen_##name (DisasContext *ctx)                      \
 {                                                                             \
     if (unlikely(!ctx->spe_enabled)) {                                        \
         GEN_EXCP_NO_AP(ctx);                                                  \
         return;                                                               \
     }                                                                         \
-    TCGv t0 = tcg_temp_new(TCG_TYPE_I64);                                     \
-    TCGv t1 = tcg_temp_new(TCG_TYPE_I64);                                     \
-    gen_load_gpr64(t0, rA(ctx->opcode));                                      \
-    gen_load_gpr64(t1, rB(ctx->opcode));                                      \
-    tcg_op(t0, t0, t1);                                                       \
-    gen_store_gpr64(rD(ctx->opcode), t0);                                     \
-    tcg_temp_free(t0);                                                        \
-    tcg_temp_free(t1);                                                        \
+    tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
+           cpu_gpr[rB(ctx->opcode)]);                                         \
+    tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
+           cpu_gprh[rB(ctx->opcode)]);                                        \
 }
+#endif
 
-#define GEN_SPEOP_ARITH1(name)                                                \
+GEN_SPEOP_LOGIC2(evand, tcg_gen_and_tl);
+GEN_SPEOP_LOGIC2(evandc, tcg_gen_andc_tl);
+GEN_SPEOP_LOGIC2(evxor, tcg_gen_xor_tl);
+GEN_SPEOP_LOGIC2(evor, tcg_gen_or_tl);
+GEN_SPEOP_LOGIC2(evnor, tcg_gen_nor_tl);
+GEN_SPEOP_LOGIC2(eveqv, tcg_gen_eqv_tl);
+GEN_SPEOP_LOGIC2(evorc, tcg_gen_orc_tl);
+GEN_SPEOP_LOGIC2(evnand, tcg_gen_nand_tl);
+
+/* SPE logic immediate */
+#if defined(TARGET_PPC64)
+#define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
 static always_inline void gen_##name (DisasContext *ctx)                      \
 {                                                                             \
     if (unlikely(!ctx->spe_enabled)) {                                        \
         GEN_EXCP_NO_AP(ctx);                                                  \
         return;                                                               \
     }                                                                         \
-    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
-    gen_op_##name();                                                          \
-    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
+    TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
+    TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
+    TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
+    tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
+    tcg_opi(t0, t0, rB(ctx->opcode));                                         \
+    tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
+    tcg_gen_trunc_i64_i32(t1, t2);                                            \
+    tcg_temp_free_i64(t2);                                                    \
+    tcg_opi(t1, t1, rB(ctx->opcode));                                         \
+    tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
+    tcg_temp_free_i32(t0);                                                    \
+    tcg_temp_free_i32(t1);                                                    \
 }
+#else
+#define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
+static always_inline void gen_##name (DisasContext *ctx)                      \
+{                                                                             \
+    if (unlikely(!ctx->spe_enabled)) {                                        \
+        GEN_EXCP_NO_AP(ctx);                                                  \
+        return;                                                               \
+    }                                                                         \
+    tcg_opi(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],               \
+            rB(ctx->opcode));                                                 \
+    tcg_opi(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],             \
+            rB(ctx->opcode));                                                 \
+}
+#endif
+GEN_SPEOP_TCG_LOGIC_IMM2(evslwi, tcg_gen_shli_i32);
+GEN_SPEOP_TCG_LOGIC_IMM2(evsrwiu, tcg_gen_shri_i32);
+GEN_SPEOP_TCG_LOGIC_IMM2(evsrwis, tcg_gen_sari_i32);
+GEN_SPEOP_TCG_LOGIC_IMM2(evrlwi, tcg_gen_rotli_i32);
 
-#define GEN_SPEOP_COMP(name)                                                  \
+/* SPE arithmetic */
+#if defined(TARGET_PPC64)
+#define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
 static always_inline void gen_##name (DisasContext *ctx)                      \
 {                                                                             \
     if (unlikely(!ctx->spe_enabled)) {                                        \
         GEN_EXCP_NO_AP(ctx);                                                  \
         return;                                                               \
     }                                                                         \
-    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
-    gen_load_gpr64(cpu_T64[1], rB(ctx->opcode));                              \
-    gen_op_##name();                                                          \
-    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_T[0], 0xf);              \
-}
-
-/* Logical */
-GEN_SPEOP_TCG_ARITH2(evand, tcg_gen_and_i64);
-GEN_SPEOP_TCG_ARITH2(evandc, tcg_gen_andc_i64);
-GEN_SPEOP_TCG_ARITH2(evxor, tcg_gen_xor_i64);
-GEN_SPEOP_TCG_ARITH2(evor, tcg_gen_or_i64);
-GEN_SPEOP_TCG_ARITH2(evnor, tcg_gen_nor_i64);
-GEN_SPEOP_TCG_ARITH2(eveqv, tcg_gen_eqv_i64);
-GEN_SPEOP_TCG_ARITH2(evorc, tcg_gen_orc_i64);
-GEN_SPEOP_TCG_ARITH2(evnand, tcg_gen_nand_i64);
-GEN_SPEOP_ARITH2(evsrwu);
-GEN_SPEOP_ARITH2(evsrws);
-GEN_SPEOP_ARITH2(evslw);
-GEN_SPEOP_ARITH2(evrlw);
-GEN_SPEOP_ARITH2(evmergehi);
-GEN_SPEOP_ARITH2(evmergelo);
-GEN_SPEOP_ARITH2(evmergehilo);
-GEN_SPEOP_ARITH2(evmergelohi);
+    TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
+    TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
+    TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
+    tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
+    tcg_op(t0, t0);                                                           \
+    tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
+    tcg_gen_trunc_i64_i32(t1, t2);                                            \
+    tcg_temp_free_i64(t2);                                                    \
+    tcg_op(t1, t1);                                                           \
+    tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
+    tcg_temp_free_i32(t0);                                                    \
+    tcg_temp_free_i32(t1);                                                    \
+}
+#else
+#define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
+static always_inline void gen_##name (DisasContext *ctx)                      \
+{                                                                             \
+    if (unlikely(!ctx->spe_enabled)) {                                        \
+        GEN_EXCP_NO_AP(ctx);                                                  \
+        return;                                                               \
+    }                                                                         \
+    tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);               \
+    tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);             \
+}
+#endif
 
-/* Arithmetic */
-GEN_SPEOP_ARITH2(evaddw);
-GEN_SPEOP_ARITH2(evsubfw);
-GEN_SPEOP_ARITH1(evabs);
-GEN_SPEOP_ARITH1(evneg);
-GEN_SPEOP_ARITH1(evextsb);
-GEN_SPEOP_ARITH1(evextsh);
-GEN_SPEOP_ARITH1(evrndw);
-GEN_SPEOP_ARITH1(evcntlzw);
-GEN_SPEOP_ARITH1(evcntlsw);
-static always_inline void gen_brinc (DisasContext *ctx)
+static always_inline void gen_op_evabs (TCGv_i32 ret, TCGv_i32 arg1)
 {
-    /* Note: brinc is usable even if SPE is disabled */
-    tcg_gen_mov_tl(cpu_T[0], cpu_gpr[rA(ctx->opcode)]);
-    tcg_gen_mov_tl(cpu_T[1], cpu_gpr[rB(ctx->opcode)]);
-    gen_op_brinc();
-    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_T[0]);
+    int l1 = gen_new_label();
+    int l2 = gen_new_label();
+
+    tcg_gen_brcondi_i32(TCG_COND_GE, arg1, 0, l1);
+    tcg_gen_neg_i32(ret, arg1);
+    tcg_gen_br(l2);
+    gen_set_label(l1);
+    tcg_gen_mov_i32(ret, arg1);
+    gen_set_label(l2);
 }
+GEN_SPEOP_ARITH1(evabs, gen_op_evabs);
+GEN_SPEOP_ARITH1(evneg, tcg_gen_neg_i32);
+GEN_SPEOP_ARITH1(evextsb, tcg_gen_ext8s_i32);
+GEN_SPEOP_ARITH1(evextsh, tcg_gen_ext16s_i32);
+static always_inline void gen_op_evrndw (TCGv_i32 ret, TCGv_i32 arg1)
+{
+    tcg_gen_addi_i32(ret, arg1, 0x8000);
+    tcg_gen_ext16u_i32(ret, ret);
+}
+GEN_SPEOP_ARITH1(evrndw, gen_op_evrndw);
+GEN_SPEOP_ARITH1(evcntlsw, gen_helper_cntlsw32);
+GEN_SPEOP_ARITH1(evcntlzw, gen_helper_cntlzw32);
 
-#define GEN_SPEOP_ARITH_IMM2(name)                                            \
-static always_inline void gen_##name##i (DisasContext *ctx)                   \
+#if defined(TARGET_PPC64)
+#define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
+static always_inline void gen_##name (DisasContext *ctx)                      \
 {                                                                             \
     if (unlikely(!ctx->spe_enabled)) {                                        \
         GEN_EXCP_NO_AP(ctx);                                                  \
         return;                                                               \
     }                                                                         \
-    gen_load_gpr64(cpu_T64[0], rB(ctx->opcode));                              \
-    gen_op_splatwi_T1_64(rA(ctx->opcode));                                    \
-    gen_op_##name();                                                          \
-    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
+    TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
+    TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
+    TCGv_i32 t2 = tcg_temp_local_new_i32();                                   \
+    TCGv_i64 t3 = tcg_temp_local_new(TCG_TYPE_I64);                           \
+    tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
+    tcg_gen_trunc_i64_i32(t2, cpu_gpr[rB(ctx->opcode)]);                      \
+    tcg_op(t0, t0, t2);                                                       \
+    tcg_gen_shri_i64(t3, cpu_gpr[rA(ctx->opcode)], 32);                       \
+    tcg_gen_trunc_i64_i32(t1, t3);                                            \
+    tcg_gen_shri_i64(t3, cpu_gpr[rB(ctx->opcode)], 32);                       \
+    tcg_gen_trunc_i64_i32(t2, t3);                                            \
+    tcg_temp_free_i64(t3);                                                    \
+    tcg_op(t1, t1, t2);                                                       \
+    tcg_temp_free_i32(t2);                                                    \
+    tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
+    tcg_temp_free_i32(t0);                                                    \
+    tcg_temp_free_i32(t1);                                                    \
 }
-
-#define GEN_SPEOP_LOGIC_IMM2(name)                                            \
-static always_inline void gen_##name##i (DisasContext *ctx)                   \
+#else
+#define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
+static always_inline void gen_##name (DisasContext *ctx)                      \
 {                                                                             \
     if (unlikely(!ctx->spe_enabled)) {                                        \
         GEN_EXCP_NO_AP(ctx);                                                  \
         return;                                                               \
     }                                                                         \
-    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
-    gen_op_splatwi_T1_64(rB(ctx->opcode));                                    \
-    gen_op_##name();                                                          \
-    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
+    tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
+           cpu_gpr[rB(ctx->opcode)]);                                         \
+    tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
+           cpu_gprh[rB(ctx->opcode)]);                                        \
 }
+#endif
 
-GEN_SPEOP_ARITH_IMM2(evaddw);
-#define gen_evaddiw gen_evaddwi
-GEN_SPEOP_ARITH_IMM2(evsubfw);
-#define gen_evsubifw gen_evsubfwi
-GEN_SPEOP_LOGIC_IMM2(evslw);
-GEN_SPEOP_LOGIC_IMM2(evsrwu);
-#define gen_evsrwis gen_evsrwsi
-GEN_SPEOP_LOGIC_IMM2(evsrws);
-#define gen_evsrwiu gen_evsrwui
-GEN_SPEOP_LOGIC_IMM2(evrlw);
+static always_inline void gen_op_evsrwu (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
+{
+    TCGv_i32 t0;
+    int l1, l2;
 
-static always_inline void gen_evsplati (DisasContext *ctx)
+    l1 = gen_new_label();
+    l2 = gen_new_label();
+    t0 = tcg_temp_local_new_i32();
+    /* No error here: 6 bits are used */
+    tcg_gen_andi_i32(t0, arg2, 0x3F);
+    tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
+    tcg_gen_shr_i32(ret, arg1, t0);
+    tcg_gen_br(l2);
+    gen_set_label(l1);
+    tcg_gen_movi_i32(ret, 0);
+    tcg_gen_br(l2);
+    tcg_temp_free_i32(t0);
+}
+GEN_SPEOP_ARITH2(evsrwu, gen_op_evsrwu);
+static always_inline void gen_op_evsrws (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
 {
-    int32_t imm = (int32_t)(rA(ctx->opcode) << 27) >> 27;
+    TCGv_i32 t0;
+    int l1, l2;
+
+    l1 = gen_new_label();
+    l2 = gen_new_label();
+    t0 = tcg_temp_local_new_i32();
+    /* No error here: 6 bits are used */
+    tcg_gen_andi_i32(t0, arg2, 0x3F);
+    tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
+    tcg_gen_sar_i32(ret, arg1, t0);
+    tcg_gen_br(l2);
+    gen_set_label(l1);
+    tcg_gen_movi_i32(ret, 0);
+    tcg_gen_br(l2);
+    tcg_temp_free_i32(t0);
+}
+GEN_SPEOP_ARITH2(evsrws, gen_op_evsrws);
+static always_inline void gen_op_evslw (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
+{
+    TCGv_i32 t0;
+    int l1, l2;
+
+    l1 = gen_new_label();
+    l2 = gen_new_label();
+    t0 = tcg_temp_local_new_i32();
+    /* No error here: 6 bits are used */
+    tcg_gen_andi_i32(t0, arg2, 0x3F);
+    tcg_gen_brcondi_i32(TCG_COND_GE, t0, 32, l1);
+    tcg_gen_shl_i32(ret, arg1, t0);
+    tcg_gen_br(l2);
+    gen_set_label(l1);
+    tcg_gen_movi_i32(ret, 0);
+    tcg_gen_br(l2);
+    tcg_temp_free_i32(t0);
+}
+GEN_SPEOP_ARITH2(evslw, gen_op_evslw);
+static always_inline void gen_op_evrlw (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
+{
+    TCGv_i32 t0 = tcg_temp_new_i32();
+    tcg_gen_andi_i32(t0, arg2, 0x1F);
+    tcg_gen_rotl_i32(ret, arg1, t0);
+    tcg_temp_free_i32(t0);
+}
+GEN_SPEOP_ARITH2(evrlw, gen_op_evrlw);
+static always_inline void gen_evmergehi (DisasContext *ctx)
+{
+    if (unlikely(!ctx->spe_enabled)) {
+        GEN_EXCP_NO_AP(ctx);
+        return;
+    }
+#if defined(TARGET_PPC64)
+    TCGv t0 = tcg_temp_new();
+    TCGv t1 = tcg_temp_new();
+    tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32);
+    tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL);
+    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
+    tcg_temp_free(t0);
+    tcg_temp_free(t1);
+#else
+    tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
+    tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
+#endif
+}
+GEN_SPEOP_ARITH2(evaddw, tcg_gen_add_i32);
+static always_inline void gen_op_evsubf (TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
+{
+    tcg_gen_sub_i32(ret, arg2, arg1);
+}
+GEN_SPEOP_ARITH2(evsubfw, gen_op_evsubf);
+
+/* SPE arithmetic immediate */
+#if defined(TARGET_PPC64)
+#define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
+static always_inline void gen_##name (DisasContext *ctx)                      \
+{                                                                             \
+    if (unlikely(!ctx->spe_enabled)) {                                        \
+        GEN_EXCP_NO_AP(ctx);                                                  \
+        return;                                                               \
+    }                                                                         \
+    TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
+    TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
+    TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
+    tcg_gen_trunc_i64_i32(t0, cpu_gpr[rB(ctx->opcode)]);                      \
+    tcg_op(t0, t0, rA(ctx->opcode));                                          \
+    tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32);                       \
+    tcg_gen_trunc_i64_i32(t1, t2);                                            \
+    tcg_temp_free_i64(t2);                                                        \
+    tcg_op(t1, t1, rA(ctx->opcode));                                          \
+    tcg_gen_concat_i32_i64(cpu_gpr[rD(ctx->opcode)], t0, t1);                 \
+    tcg_temp_free_i32(t0);                                                    \
+    tcg_temp_free_i32(t1);                                                    \
+}
+#else
+#define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
+static always_inline void gen_##name (DisasContext *ctx)                      \
+{                                                                             \
+    if (unlikely(!ctx->spe_enabled)) {                                        \
+        GEN_EXCP_NO_AP(ctx);                                                  \
+        return;                                                               \
+    }                                                                         \
+    tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)],                \
+           rA(ctx->opcode));                                                  \
+    tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)],              \
+           rA(ctx->opcode));                                                  \
+}
+#endif
+GEN_SPEOP_ARITH_IMM2(evaddiw, tcg_gen_addi_i32);
+GEN_SPEOP_ARITH_IMM2(evsubifw, tcg_gen_subi_i32);
 
-    gen_op_splatwi_T0_64(imm);
-    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);
+/* SPE comparison */
+#if defined(TARGET_PPC64)
+#define GEN_SPEOP_COMP(name, tcg_cond)                                        \
+static always_inline void gen_##name (DisasContext *ctx)                      \
+{                                                                             \
+    if (unlikely(!ctx->spe_enabled)) {                                        \
+        GEN_EXCP_NO_AP(ctx);                                                  \
+        return;                                                               \
+    }                                                                         \
+    int l1 = gen_new_label();                                                 \
+    int l2 = gen_new_label();                                                 \
+    int l3 = gen_new_label();                                                 \
+    int l4 = gen_new_label();                                                 \
+    TCGv_i32 t0 = tcg_temp_local_new_i32();                                   \
+    TCGv_i32 t1 = tcg_temp_local_new_i32();                                   \
+    TCGv_i64 t2 = tcg_temp_local_new_i64();                                   \
+    tcg_gen_trunc_i64_i32(t0, cpu_gpr[rA(ctx->opcode)]);                      \
+    tcg_gen_trunc_i64_i32(t1, cpu_gpr[rB(ctx->opcode)]);                      \
+    tcg_gen_brcond_i32(tcg_cond, t0, t1, l1);                                 \
+    tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)], 0);                          \
+    tcg_gen_br(l2);                                                           \
+    gen_set_label(l1);                                                        \
+    tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)],                              \
+                     CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL);                  \
+    gen_set_label(l2);                                                        \
+    tcg_gen_shri_i64(t2, cpu_gpr[rA(ctx->opcode)], 32);                       \
+    tcg_gen_trunc_i64_i32(t0, t2);                                            \
+    tcg_gen_shri_i64(t2, cpu_gpr[rB(ctx->opcode)], 32);                       \
+    tcg_gen_trunc_i64_i32(t1, t2);                                            \
+    tcg_temp_free_i64(t2);                                                    \
+    tcg_gen_brcond_i32(tcg_cond, t0, t1, l3);                                 \
+    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],  \
+                     ~(CRF_CH | CRF_CH_AND_CL));                              \
+    tcg_gen_br(l4);                                                           \
+    gen_set_label(l3);                                                        \
+    tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],   \
+                    CRF_CH | CRF_CH_OR_CL);                                   \
+    gen_set_label(l4);                                                        \
+    tcg_temp_free_i32(t0);                                                    \
+    tcg_temp_free_i32(t1);                                                    \
+}
+#else
+#define GEN_SPEOP_COMP(name, tcg_cond)                                        \
+static always_inline void gen_##name (DisasContext *ctx)                      \
+{                                                                             \
+    if (unlikely(!ctx->spe_enabled)) {                                        \
+        GEN_EXCP_NO_AP(ctx);                                                  \
+        return;                                                               \
+    }                                                                         \
+    int l1 = gen_new_label();                                                 \
+    int l2 = gen_new_label();                                                 \
+    int l3 = gen_new_label();                                                 \
+    int l4 = gen_new_label();                                                 \
+                                                                              \
+    tcg_gen_brcond_i32(tcg_cond, cpu_gpr[rA(ctx->opcode)],                    \
+                       cpu_gpr[rB(ctx->opcode)], l1);                         \
+    tcg_gen_movi_tl(cpu_crf[crfD(ctx->opcode)], 0);                           \
+    tcg_gen_br(l2);                                                           \
+    gen_set_label(l1);                                                        \
+    tcg_gen_movi_i32(cpu_crf[crfD(ctx->opcode)],                              \
+                     CRF_CL | CRF_CH_OR_CL | CRF_CH_AND_CL);                  \
+    gen_set_label(l2);                                                        \
+    tcg_gen_brcond_i32(tcg_cond, cpu_gprh[rA(ctx->opcode)],                   \
+                       cpu_gprh[rB(ctx->opcode)], l3);                        \
+    tcg_gen_andi_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],  \
+                     ~(CRF_CH | CRF_CH_AND_CL));                              \
+    tcg_gen_br(l4);                                                           \
+    gen_set_label(l3);                                                        \
+    tcg_gen_ori_i32(cpu_crf[crfD(ctx->opcode)], cpu_crf[crfD(ctx->opcode)],   \
+                    CRF_CH | CRF_CH_OR_CL);                                   \
+    gen_set_label(l4);                                                        \
+}
+#endif
+GEN_SPEOP_COMP(evcmpgtu, TCG_COND_GTU);
+GEN_SPEOP_COMP(evcmpgts, TCG_COND_GT);
+GEN_SPEOP_COMP(evcmpltu, TCG_COND_LTU);
+GEN_SPEOP_COMP(evcmplts, TCG_COND_LT);
+GEN_SPEOP_COMP(evcmpeq, TCG_COND_EQ);
+
+/* SPE misc */
+static always_inline void gen_brinc (DisasContext *ctx)
+{
+    /* Note: brinc is usable even if SPE is disabled */
+    gen_helper_brinc(cpu_gpr[rD(ctx->opcode)],
+                     cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
+}
+static always_inline void gen_evmergelo (DisasContext *ctx)
+{
+    if (unlikely(!ctx->spe_enabled)) {
+        GEN_EXCP_NO_AP(ctx);
+        return;
+    }
+#if defined(TARGET_PPC64)
+    TCGv t0 = tcg_temp_new();
+    TCGv t1 = tcg_temp_new();
+    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFLL);
+    tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);
+    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
+    tcg_temp_free(t0);
+    tcg_temp_free(t1);
+#else
+    tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
+    tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
+#endif
+}
+static always_inline void gen_evmergehilo (DisasContext *ctx)
+{
+    if (unlikely(!ctx->spe_enabled)) {
+        GEN_EXCP_NO_AP(ctx);
+        return;
+    }
+#if defined(TARGET_PPC64)
+    TCGv t0 = tcg_temp_new();
+    TCGv t1 = tcg_temp_new();
+    tcg_gen_andi_tl(t0, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFLL);
+    tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF0000000ULL);
+    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
+    tcg_temp_free(t0);
+    tcg_temp_free(t1);
+#else
+    tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
+    tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
+#endif
 }
+static always_inline void gen_evmergelohi (DisasContext *ctx)
+{
+    if (unlikely(!ctx->spe_enabled)) {
+        GEN_EXCP_NO_AP(ctx);
+        return;
+    }
+#if defined(TARGET_PPC64)
+    TCGv t0 = tcg_temp_new();
+    TCGv t1 = tcg_temp_new();
+    tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 32);
+    tcg_gen_shli_tl(t1, cpu_gpr[rA(ctx->opcode)], 32);
+    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
+    tcg_temp_free(t0);
+    tcg_temp_free(t1);
+#else
+    tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
+    tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
+#endif
+}
+static always_inline void gen_evsplati (DisasContext *ctx)
+{
+    int32_t imm = (int32_t)(rA(ctx->opcode) << 11) >> 27;
 
+#if defined(TARGET_PPC64)
+    TCGv t0 = tcg_temp_new();
+    TCGv t1 = tcg_temp_new();
+    tcg_gen_movi_tl(t0, imm);
+    tcg_gen_shri_tl(t1, t0, 32);
+    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
+    tcg_temp_free(t0);
+    tcg_temp_free(t1);
+#else
+    tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
+    tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
+#endif
+}
 static always_inline void gen_evsplatfi (DisasContext *ctx)
 {
-    uint32_t imm = rA(ctx->opcode) << 27;
+    uint32_t imm = rA(ctx->opcode) << 11;
 
-    gen_op_splatwi_T0_64(imm);
-    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);
+#if defined(TARGET_PPC64)
+    TCGv t0 = tcg_temp_new();
+    TCGv t1 = tcg_temp_new();
+    tcg_gen_movi_tl(t0, imm);
+    tcg_gen_shri_tl(t1, t0, 32);
+    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t0, t1);
+    tcg_temp_free(t0);
+    tcg_temp_free(t1);
+#else
+    tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
+    tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
+#endif
 }
 
-/* Comparison */
-GEN_SPEOP_COMP(evcmpgtu);
-GEN_SPEOP_COMP(evcmpgts);
-GEN_SPEOP_COMP(evcmpltu);
-GEN_SPEOP_COMP(evcmplts);
-GEN_SPEOP_COMP(evcmpeq);
+static always_inline void gen_evsel (DisasContext *ctx)
+{
+    int l1 = gen_new_label();
+    int l2 = gen_new_label();
+    int l3 = gen_new_label();
+    int l4 = gen_new_label();
+    TCGv_i32 t0 = tcg_temp_local_new_i32();
+#if defined(TARGET_PPC64)
+    TCGv t1 = tcg_temp_local_new();
+    TCGv t2 = tcg_temp_local_new();
+#endif
+    tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 3);
+    tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
+#if defined(TARGET_PPC64)
+    tcg_gen_andi_tl(t1, cpu_gpr[rA(ctx->opcode)], 0xFFFFFFFF00000000ULL);
+#else
+    tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
+#endif
+    tcg_gen_br(l2);
+    gen_set_label(l1);
+#if defined(TARGET_PPC64)
+    tcg_gen_andi_tl(t1, cpu_gpr[rB(ctx->opcode)], 0xFFFFFFFF00000000ULL);
+#else
+    tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
+#endif
+    gen_set_label(l2);
+    tcg_gen_andi_i32(t0, cpu_crf[ctx->opcode & 0x07], 1 << 2);
+    tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l3);
+#if defined(TARGET_PPC64)
+    tcg_gen_andi_tl(t2, cpu_gpr[rA(ctx->opcode)], 0x00000000FFFFFFFFULL);
+#else
+    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
+#endif
+    tcg_gen_br(l4);
+    gen_set_label(l3);
+#if defined(TARGET_PPC64)
+    tcg_gen_andi_tl(t2, cpu_gpr[rB(ctx->opcode)], 0x00000000FFFFFFFFULL);
+#else
+    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
+#endif
+    gen_set_label(l4);
+    tcg_temp_free_i32(t0);
+#if defined(TARGET_PPC64)
+    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], t1, t2);
+    tcg_temp_free(t1);
+    tcg_temp_free(t2);
+#endif
+}
+GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
+{
+    gen_evsel(ctx);
+}
+GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
+{
+    gen_evsel(ctx);
+}
+GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
+{
+    gen_evsel(ctx);
+}
+GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
+{
+    gen_evsel(ctx);
+}
 
 GEN_SPE(evaddw,         speundef,      0x00, 0x08, 0x00000000, PPC_SPE); ////
 GEN_SPE(evaddiw,        speundef,      0x01, 0x08, 0x00000000, PPC_SPE);
@@ -6192,36 +6593,6 @@ GEN_SPE(evcmpgtu,       evcmpgts,      0x18, 0x08, 0x00600000, PPC_SPE); ////
 GEN_SPE(evcmpltu,       evcmplts,      0x19, 0x08, 0x00600000, PPC_SPE); ////
 GEN_SPE(evcmpeq,        speundef,      0x1A, 0x08, 0x00600000, PPC_SPE); ////
 
-static always_inline void gen_evsel (DisasContext *ctx)
-{
-    if (unlikely(!ctx->spe_enabled)) {
-        GEN_EXCP_NO_AP(ctx);
-        return;
-    }
-    tcg_gen_mov_i32(cpu_T[0], cpu_crf[ctx->opcode & 0x7]);
-    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));
-    gen_load_gpr64(cpu_T64[1], rB(ctx->opcode));
-    gen_op_evsel();
-    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);
-}
-
-GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE)
-{
-    gen_evsel(ctx);
-}
-GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE)
-{
-    gen_evsel(ctx);
-}
-GEN_HANDLER2(evsel2, "evsel", 0x04, 0x1e, 0x09, 0x00000000, PPC_SPE)
-{
-    gen_evsel(ctx);
-}
-GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
-{
-    gen_evsel(ctx);
-}
-
 /* Load and stores */
 GEN_SPEOP_LDST(dd, 3);
 GEN_SPEOP_LDST(dw, 3);
@@ -6490,15 +6861,55 @@ static always_inline void gen_##name (DisasContext *ctx)                      \
     gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
 }
 
+#define GEN_SPEFPUOP_ARITH1(name)                                             \
+static always_inline void gen_##name (DisasContext *ctx)                      \
+{                                                                             \
+    if (unlikely(!ctx->spe_enabled)) {                                        \
+        GEN_EXCP_NO_AP(ctx);                                                  \
+        return;                                                               \
+    }                                                                         \
+    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
+    gen_op_##name();                                                          \
+    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
+}
+
+#define GEN_SPEFPUOP_ARITH2(name)                                             \
+static always_inline void gen_##name (DisasContext *ctx)                      \
+{                                                                             \
+    if (unlikely(!ctx->spe_enabled)) {                                        \
+        GEN_EXCP_NO_AP(ctx);                                                  \
+        return;                                                               \
+    }                                                                         \
+    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
+    gen_load_gpr64(cpu_T64[1], rB(ctx->opcode));                              \
+    gen_op_##name();                                                          \
+    gen_store_gpr64(rD(ctx->opcode), cpu_T64[0]);                             \
+}
+
+#define GEN_SPEFPUOP_COMP(name)                                               \
+static always_inline void gen_##name (DisasContext *ctx)                      \
+{                                                                             \
+    TCGv_i32 crf = cpu_crf[crfD(ctx->opcode)];                                \
+    if (unlikely(!ctx->spe_enabled)) {                                        \
+        GEN_EXCP_NO_AP(ctx);                                                  \
+        return;                                                               \
+    }                                                                         \
+    gen_load_gpr64(cpu_T64[0], rA(ctx->opcode));                              \
+    gen_load_gpr64(cpu_T64[1], rB(ctx->opcode));                              \
+    gen_op_##name();                                                          \
+    tcg_gen_trunc_tl_i32(crf, cpu_T[0]);                                      \
+    tcg_gen_andi_i32(crf, crf, 0xf);                                          \
+}
+
 /* Single precision floating-point vectors operations */
 /* Arithmetic */
-GEN_SPEOP_ARITH2(evfsadd);
-GEN_SPEOP_ARITH2(evfssub);
-GEN_SPEOP_ARITH2(evfsmul);
-GEN_SPEOP_ARITH2(evfsdiv);
-GEN_SPEOP_ARITH1(evfsabs);
-GEN_SPEOP_ARITH1(evfsnabs);
-GEN_SPEOP_ARITH1(evfsneg);
+GEN_SPEFPUOP_ARITH2(evfsadd);
+GEN_SPEFPUOP_ARITH2(evfssub);
+GEN_SPEFPUOP_ARITH2(evfsmul);
+GEN_SPEFPUOP_ARITH2(evfsdiv);
+GEN_SPEFPUOP_ARITH1(evfsabs);
+GEN_SPEFPUOP_ARITH1(evfsnabs);
+GEN_SPEFPUOP_ARITH1(evfsneg);
 /* Conversion */
 GEN_SPEFPUOP_CONV(evfscfui);
 GEN_SPEFPUOP_CONV(evfscfsi);
@@ -6511,12 +6922,12 @@ GEN_SPEFPUOP_CONV(evfsctsf);
 GEN_SPEFPUOP_CONV(evfsctuiz);
 GEN_SPEFPUOP_CONV(evfsctsiz);
 /* Comparison */
-GEN_SPEOP_COMP(evfscmpgt);
-GEN_SPEOP_COMP(evfscmplt);
-GEN_SPEOP_COMP(evfscmpeq);
-GEN_SPEOP_COMP(evfststgt);
-GEN_SPEOP_COMP(evfststlt);
-GEN_SPEOP_COMP(evfststeq);
+GEN_SPEFPUOP_COMP(evfscmpgt);
+GEN_SPEFPUOP_COMP(evfscmplt);
+GEN_SPEFPUOP_COMP(evfscmpeq);
+GEN_SPEFPUOP_COMP(evfststgt);
+GEN_SPEFPUOP_COMP(evfststlt);
+GEN_SPEFPUOP_COMP(evfststeq);
 
 /* Opcodes definitions */
 GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
@@ -6536,13 +6947,13 @@ GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPEFPU); //
 
 /* Single precision floating-point operations */
 /* Arithmetic */
-GEN_SPEOP_ARITH2(efsadd);
-GEN_SPEOP_ARITH2(efssub);
-GEN_SPEOP_ARITH2(efsmul);
-GEN_SPEOP_ARITH2(efsdiv);
-GEN_SPEOP_ARITH1(efsabs);
-GEN_SPEOP_ARITH1(efsnabs);
-GEN_SPEOP_ARITH1(efsneg);
+GEN_SPEFPUOP_ARITH2(efsadd);
+GEN_SPEFPUOP_ARITH2(efssub);
+GEN_SPEFPUOP_ARITH2(efsmul);
+GEN_SPEFPUOP_ARITH2(efsdiv);
+GEN_SPEFPUOP_ARITH1(efsabs);
+GEN_SPEFPUOP_ARITH1(efsnabs);
+GEN_SPEFPUOP_ARITH1(efsneg);
 /* Conversion */
 GEN_SPEFPUOP_CONV(efscfui);
 GEN_SPEFPUOP_CONV(efscfsi);
@@ -6556,12 +6967,12 @@ GEN_SPEFPUOP_CONV(efsctuiz);
 GEN_SPEFPUOP_CONV(efsctsiz);
 GEN_SPEFPUOP_CONV(efscfd);
 /* Comparison */
-GEN_SPEOP_COMP(efscmpgt);
-GEN_SPEOP_COMP(efscmplt);
-GEN_SPEOP_COMP(efscmpeq);
-GEN_SPEOP_COMP(efststgt);
-GEN_SPEOP_COMP(efststlt);
-GEN_SPEOP_COMP(efststeq);
+GEN_SPEFPUOP_COMP(efscmpgt);
+GEN_SPEFPUOP_COMP(efscmplt);
+GEN_SPEFPUOP_COMP(efscmpeq);
+GEN_SPEFPUOP_COMP(efststgt);
+GEN_SPEFPUOP_COMP(efststlt);
+GEN_SPEFPUOP_COMP(efststeq);
 
 /* Opcodes definitions */
 GEN_SPE(efsadd,         efssub,        0x00, 0x0B, 0x00000000, PPC_SPEFPU); //
@@ -6581,13 +6992,13 @@ GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPEFPU); //
 
 /* Double precision floating-point operations */
 /* Arithmetic */
-GEN_SPEOP_ARITH2(efdadd);
-GEN_SPEOP_ARITH2(efdsub);
-GEN_SPEOP_ARITH2(efdmul);
-GEN_SPEOP_ARITH2(efddiv);
-GEN_SPEOP_ARITH1(efdabs);
-GEN_SPEOP_ARITH1(efdnabs);
-GEN_SPEOP_ARITH1(efdneg);
+GEN_SPEFPUOP_ARITH2(efdadd);
+GEN_SPEFPUOP_ARITH2(efdsub);
+GEN_SPEFPUOP_ARITH2(efdmul);
+GEN_SPEFPUOP_ARITH2(efddiv);
+GEN_SPEFPUOP_ARITH1(efdabs);
+GEN_SPEFPUOP_ARITH1(efdnabs);
+GEN_SPEFPUOP_ARITH1(efdneg);
 /* Conversion */
 
 GEN_SPEFPUOP_CONV(efdcfui);
@@ -6606,12 +7017,12 @@ GEN_SPEFPUOP_CONV(efdcfsid);
 GEN_SPEFPUOP_CONV(efdctuidz);
 GEN_SPEFPUOP_CONV(efdctsidz);
 /* Comparison */
-GEN_SPEOP_COMP(efdcmpgt);
-GEN_SPEOP_COMP(efdcmplt);
-GEN_SPEOP_COMP(efdcmpeq);
-GEN_SPEOP_COMP(efdtstgt);
-GEN_SPEOP_COMP(efdtstlt);
-GEN_SPEOP_COMP(efdtsteq);
+GEN_SPEFPUOP_COMP(efdcmpgt);
+GEN_SPEFPUOP_COMP(efdcmplt);
+GEN_SPEFPUOP_COMP(efdcmpeq);
+GEN_SPEFPUOP_COMP(efdtstgt);
+GEN_SPEFPUOP_COMP(efdtstlt);
+GEN_SPEFPUOP_COMP(efdtsteq);
 
 /* Opcodes definitions */
 GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
@@ -6759,6 +7170,7 @@ static always_inline void gen_intermediate_code_internal (CPUState *env,
     target_ulong pc_start;
     uint16_t *gen_opc_end;
     int supervisor, little_endian;
+    CPUBreakpoint *bp;
     int j, lj = -1;
     int num_insns;
     int max_insns;
@@ -6813,9 +7225,9 @@ static always_inline void gen_intermediate_code_internal (CPUState *env,
     gen_icount_start();
     /* Set env in case of segfault during code fetch */
     while (ctx.exception == POWERPC_EXCP_NONE && gen_opc_ptr < gen_opc_end) {
-        if (unlikely(env->nb_breakpoints > 0)) {
-            for (j = 0; j < env->nb_breakpoints; j++) {
-                if (env->breakpoints[j] == ctx.nip) {
+        if (unlikely(env->breakpoints)) {
+            for (bp = env->breakpoints; bp != NULL; bp = bp->next) {
+                if (bp->pc == ctx.nip) {
                     gen_update_nip(&ctx, ctx.nip);
                     gen_op_debug();
                     break;