]> Git Repo - qemu.git/blobdiff - target-ppc/translate.c
rdma: bug fixes
[qemu.git] / target-ppc / translate.c
index ec32771b6a271844a3018bbe57ceb380f3957bda..48017219a4ac25594b160ea85bee5fa1cb598067 100644 (file)
 #include "disas/disas.h"
 #include "tcg-op.h"
 #include "qemu/host-utils.h"
+#include "exec/cpu_ldst.h"
 
-#include "helper.h"
-#define GEN_HELPER 1
-#include "helper.h"
+#include "exec/helper-proto.h"
+#include "exec/helper-gen.h"
 
 #define CPU_SINGLE_STEP 0x1
 #define CPU_BRANCH_STEP 0x2
 /* global register indexes */
 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 */
-#endif
     + 10*4 + 22*5 /* FPR */
     + 2*(10*6 + 22*7) /* AVRh, AVRl */
     + 10*5 + 22*6 /* VSR */
     + 8*5 /* CRF */];
 static TCGv cpu_gpr[32];
-#if !defined(TARGET_PPC64)
 static TCGv cpu_gprh[32];
-#endif
 static TCGv_i64 cpu_fpr[32];
 static TCGv_i64 cpu_avrh[32], cpu_avrl[32];
 static TCGv_i64 cpu_vsr[32];
@@ -104,13 +100,11 @@ void ppc_translate_init(void)
                                         offsetof(CPUPPCState, gpr[i]), p);
         p += (i < 10) ? 3 : 4;
         cpu_reg_names_size -= (i < 10) ? 3 : 4;
-#if !defined(TARGET_PPC64)
         snprintf(p, cpu_reg_names_size, "r%dH", i);
-        cpu_gprh[i] = tcg_global_mem_new_i32(TCG_AREG0,
-                                             offsetof(CPUPPCState, gprh[i]), p);
+        cpu_gprh[i] = tcg_global_mem_new(TCG_AREG0,
+                                         offsetof(CPUPPCState, gprh[i]), p);
         p += (i < 10) ? 4 : 5;
         cpu_reg_names_size -= (i < 10) ? 4 : 5;
-#endif
 
         snprintf(p, cpu_reg_names_size, "fp%d", i);
         cpu_fpr[i] = tcg_global_mem_new_i64(TCG_AREG0,
@@ -196,6 +190,7 @@ typedef struct DisasContext {
     int access_type;
     /* Translation flags */
     int le_mode;
+    TCGMemOp default_tcg_memop_mask;
 #if defined(TARGET_PPC64)
     int sf_mode;
     int has_cfar;
@@ -210,6 +205,16 @@ typedef struct DisasContext {
     uint64_t insns_flags2;
 } DisasContext;
 
+/* Return true iff byteswap is needed in a scalar memop */
+static inline bool need_byteswap(const DisasContext *ctx)
+{
+#if defined(TARGET_WORDS_BIGENDIAN)
+     return ctx->le_mode;
+#else
+     return !ctx->le_mode;
+#endif
+}
+
 /* True when active word size < size of target_long.  */
 #ifdef TARGET_PPC64
 # define NARROW_MODE(C)  (!(C)->sf_mode)
@@ -279,6 +284,13 @@ static inline void gen_update_nip(DisasContext *ctx, target_ulong nip)
     tcg_gen_movi_tl(cpu_nip, nip);
 }
 
+void gen_update_current_nip(void *opaque)
+{
+    DisasContext *ctx = opaque;
+
+    tcg_gen_movi_tl(cpu_nip, ctx->nip);
+}
+
 static inline void gen_exception_err(DisasContext *ctx, uint32_t excp, uint32_t error)
 {
     TCGv_i32 t0, t1;
@@ -467,6 +479,12 @@ EXTRACT_HELPER(AA, 1, 1);
 /* Link */
 EXTRACT_HELPER(LK, 0, 1);
 
+/* DFP Z22-form */
+EXTRACT_HELPER(DCM, 10, 6)
+
+/* DFP Z23-form */
+EXTRACT_HELPER(RMC, 9, 2)
+
 /* Create a mask between <start> and <end> bits */
 static inline target_ulong MASK(uint32_t start, uint32_t end)
 {
@@ -503,6 +521,7 @@ EXTRACT_HELPER_SPLIT(xC, 3, 1,  6, 5);
 EXTRACT_HELPER(DM, 8, 2);
 EXTRACT_HELPER(UIM, 16, 2);
 EXTRACT_HELPER(SHW, 8, 2);
+EXTRACT_HELPER(SP, 19, 2);
 /*****************************************************************************/
 /* PowerPC instructions table                                                */
 
@@ -1217,6 +1236,7 @@ static inline void gen_op_arith_subf(DisasContext *ctx, TCGv ret, TCGv arg1,
             }
             tcg_gen_xor_tl(t1, arg2, inv1);         /* add without carry */
             tcg_gen_add_tl(t0, t0, inv1);
+            tcg_temp_free(inv1);
             tcg_gen_xor_tl(cpu_ca, t0, t1);         /* bits changes w/ carry */
             tcg_temp_free(t1);
             tcg_gen_shri_tl(cpu_ca, cpu_ca, 32);    /* extract bit 32 */
@@ -2652,29 +2672,20 @@ static inline void gen_qemu_ld8s(DisasContext *ctx, TCGv arg1, TCGv arg2)
 
 static inline void gen_qemu_ld16u(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
-    if (unlikely(ctx->le_mode)) {
-        tcg_gen_bswap16_tl(arg1, arg1);
-    }
+    TCGMemOp op = MO_UW | ctx->default_tcg_memop_mask;
+    tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op);
 }
 
 static inline void gen_qemu_ld16s(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    if (unlikely(ctx->le_mode)) {
-        tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
-        tcg_gen_bswap16_tl(arg1, arg1);
-        tcg_gen_ext16s_tl(arg1, arg1);
-    } else {
-        tcg_gen_qemu_ld16s(arg1, arg2, ctx->mem_idx);
-    }
+    TCGMemOp op = MO_SW | ctx->default_tcg_memop_mask;
+    tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op);
 }
 
 static inline void gen_qemu_ld32u(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
-    if (unlikely(ctx->le_mode)) {
-        tcg_gen_bswap32_tl(arg1, arg1);
-    }
+    TCGMemOp op = MO_UL | ctx->default_tcg_memop_mask;
+    tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op);
 }
 
 static void gen_qemu_ld32u_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr)
@@ -2687,12 +2698,8 @@ static void gen_qemu_ld32u_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr)
 
 static inline void gen_qemu_ld32s(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    if (unlikely(ctx->le_mode)) {
-        tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
-        tcg_gen_bswap32_tl(arg1, arg1);
-        tcg_gen_ext32s_tl(arg1, arg1);
-    } else
-        tcg_gen_qemu_ld32s(arg1, arg2, ctx->mem_idx);
+    TCGMemOp op = MO_SL | ctx->default_tcg_memop_mask;
+    tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op);
 }
 
 static void gen_qemu_ld32s_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr)
@@ -2705,10 +2712,8 @@ static void gen_qemu_ld32s_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr)
 
 static inline void gen_qemu_ld64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
 {
-    tcg_gen_qemu_ld64(arg1, arg2, ctx->mem_idx);
-    if (unlikely(ctx->le_mode)) {
-        tcg_gen_bswap64_i64(arg1, arg1);
-    }
+    TCGMemOp op = MO_Q | ctx->default_tcg_memop_mask;
+    tcg_gen_qemu_ld_i64(arg1, arg2, ctx->mem_idx, op);
 }
 
 static inline void gen_qemu_st8(DisasContext *ctx, TCGv arg1, TCGv arg2)
@@ -2718,28 +2723,14 @@ static inline void gen_qemu_st8(DisasContext *ctx, TCGv arg1, TCGv arg2)
 
 static inline void gen_qemu_st16(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    if (unlikely(ctx->le_mode)) {
-        TCGv t0 = tcg_temp_new();
-        tcg_gen_ext16u_tl(t0, arg1);
-        tcg_gen_bswap16_tl(t0, t0);
-        tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx);
-        tcg_temp_free(t0);
-    } else {
-        tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx);
-    }
+    TCGMemOp op = MO_UW | ctx->default_tcg_memop_mask;
+    tcg_gen_qemu_st_tl(arg1, arg2, ctx->mem_idx, op);
 }
 
 static inline void gen_qemu_st32(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    if (unlikely(ctx->le_mode)) {
-        TCGv t0 = tcg_temp_new();
-        tcg_gen_ext32u_tl(t0, arg1);
-        tcg_gen_bswap32_tl(t0, t0);
-        tcg_gen_qemu_st32(t0, arg2, ctx->mem_idx);
-        tcg_temp_free(t0);
-    } else {
-        tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx);
-    }
+    TCGMemOp op = MO_UL | ctx->default_tcg_memop_mask;
+    tcg_gen_qemu_st_tl(arg1, arg2, ctx->mem_idx, op);
 }
 
 static void gen_qemu_st32_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr)
@@ -2752,13 +2743,8 @@ static void gen_qemu_st32_i64(DisasContext *ctx, TCGv_i64 val, TCGv addr)
 
 static inline void gen_qemu_st64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
 {
-    if (unlikely(ctx->le_mode)) {
-        TCGv_i64 t0 = tcg_temp_new_i64();
-        tcg_gen_bswap64_i64(t0, arg1);
-        tcg_gen_qemu_st64(t0, arg2, ctx->mem_idx);
-        tcg_temp_free_i64(t0);
-    } else
-        tcg_gen_qemu_st64(arg1, arg2, ctx->mem_idx);
+    TCGMemOp op = MO_Q | ctx->default_tcg_memop_mask;
+    tcg_gen_qemu_st_i64(arg1, arg2, ctx->mem_idx, op);
 }
 
 #define GEN_LD(name, ldop, opc, type)                                         \
@@ -2902,6 +2888,8 @@ static void gen_lq(DisasContext *ctx)
     EA = tcg_temp_new();
     gen_addr_imm_index(ctx, EA, 0x0F);
 
+    /* We only need to swap high and low halves. gen_qemu_ld64 does necessary
+       64-bit byteswap already. */
     if (unlikely(ctx->le_mode)) {
         gen_qemu_ld64(ctx, cpu_gpr[rd+1], EA);
         gen_addr_add(ctx, EA, EA, 8);
@@ -3020,6 +3008,8 @@ static void gen_std(DisasContext *ctx)
         EA = tcg_temp_new();
         gen_addr_imm_index(ctx, EA, 0x03);
 
+        /* We only need to swap high and low halves. gen_qemu_st64 does
+           necessary 64-bit byteswap already. */
         if (unlikely(ctx->le_mode)) {
             gen_qemu_st64(ctx, cpu_gpr[rs+1], EA);
             gen_addr_add(ctx, EA, EA, 8);
@@ -3049,23 +3039,20 @@ static void gen_std(DisasContext *ctx)
 }
 #endif
 /***                Integer load and store with byte reverse               ***/
+
 /* lhbrx */
 static inline void gen_qemu_ld16ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
-    if (likely(!ctx->le_mode)) {
-        tcg_gen_bswap16_tl(arg1, arg1);
-    }
+    TCGMemOp op = MO_UW | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
+    tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op);
 }
 GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER);
 
 /* lwbrx */
 static inline void gen_qemu_ld32ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
-    if (likely(!ctx->le_mode)) {
-        tcg_gen_bswap32_tl(arg1, arg1);
-    }
+    TCGMemOp op = MO_UL | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
+    tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, op);
 }
 GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER);
 
@@ -3073,10 +3060,8 @@ GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER);
 /* ldbrx */
 static inline void gen_qemu_ld64ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    tcg_gen_qemu_ld64(arg1, arg2, ctx->mem_idx);
-    if (likely(!ctx->le_mode)) {
-        tcg_gen_bswap64_tl(arg1, arg1);
-    }
+    TCGMemOp op = MO_Q | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
+    tcg_gen_qemu_ld_i64(arg1, arg2, ctx->mem_idx, op);
 }
 GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX);
 #endif  /* TARGET_PPC64 */
@@ -3084,30 +3069,16 @@ GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX);
 /* sthbrx */
 static inline void gen_qemu_st16r(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    if (likely(!ctx->le_mode)) {
-        TCGv t0 = tcg_temp_new();
-        tcg_gen_ext16u_tl(t0, arg1);
-        tcg_gen_bswap16_tl(t0, t0);
-        tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx);
-        tcg_temp_free(t0);
-    } else {
-        tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx);
-    }
+    TCGMemOp op = MO_UW | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
+    tcg_gen_qemu_st_tl(arg1, arg2, ctx->mem_idx, op);
 }
 GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER);
 
 /* stwbrx */
 static inline void gen_qemu_st32r(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    if (likely(!ctx->le_mode)) {
-        TCGv t0 = tcg_temp_new();
-        tcg_gen_ext32u_tl(t0, arg1);
-        tcg_gen_bswap32_tl(t0, t0);
-        tcg_gen_qemu_st32(t0, arg2, ctx->mem_idx);
-        tcg_temp_free(t0);
-    } else {
-        tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx);
-    }
+    TCGMemOp op = MO_UL | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
+    tcg_gen_qemu_st_tl(arg1, arg2, ctx->mem_idx, op);
 }
 GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
 
@@ -3115,14 +3086,8 @@ GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
 /* stdbrx */
 static inline void gen_qemu_st64r(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    if (likely(!ctx->le_mode)) {
-        TCGv t0 = tcg_temp_new();
-        tcg_gen_bswap64_tl(t0, arg1);
-        tcg_gen_qemu_st64(t0, arg2, ctx->mem_idx);
-        tcg_temp_free(t0);
-    } else {
-        tcg_gen_qemu_st64(arg1, arg2, ctx->mem_idx);
-    }
+    TCGMemOp op = MO_Q | (ctx->default_tcg_memop_mask ^ MO_BSWAP);
+    tcg_gen_qemu_st_i64(arg1, arg2, ctx->mem_idx, op);
 }
 GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX);
 #endif  /* TARGET_PPC64 */
@@ -3333,7 +3298,7 @@ static void gen_conditional_store(DisasContext *ctx, TCGv EA,
         gen_qemu_st16(ctx, cpu_gpr[reg], EA);
 #if defined(TARGET_PPC64)
     } else if (size == 16) {
-        TCGv gpr1, gpr2;
+        TCGv gpr1, gpr2 , EA8;
         if (unlikely(ctx->le_mode)) {
             gpr1 = cpu_gpr[reg+1];
             gpr2 = cpu_gpr[reg];
@@ -3342,8 +3307,10 @@ static void gen_conditional_store(DisasContext *ctx, TCGv EA,
             gpr2 = cpu_gpr[reg+1];
         }
         gen_qemu_st64(ctx, gpr1, EA);
-        gen_addr_add(ctx, EA, EA, 8);
-        gen_qemu_st64(ctx, gpr2, EA);
+        EA8 = tcg_temp_local_new();
+        gen_addr_add(ctx, EA8, EA, 8);
+        gen_qemu_st64(ctx, gpr2, EA8);
+        tcg_temp_free(EA8);
 #endif
     } else {
         gen_qemu_st8(ctx, cpu_gpr[reg], EA);
@@ -3540,7 +3507,9 @@ static void gen_lfdp(DisasContext *ctx)
     }
     gen_set_access_type(ctx, ACCESS_FLOAT);
     EA = tcg_temp_new();
-    gen_addr_imm_index(ctx, EA, 0);                                           \
+    gen_addr_imm_index(ctx, EA, 0);
+    /* We only need to swap high and low halves. gen_qemu_ld64 does necessary
+       64-bit byteswap already. */
     if (unlikely(ctx->le_mode)) {
         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
         tcg_gen_addi_tl(EA, EA, 8);
@@ -3564,6 +3533,8 @@ static void gen_lfdpx(DisasContext *ctx)
     gen_set_access_type(ctx, ACCESS_FLOAT);
     EA = tcg_temp_new();
     gen_addr_reg_index(ctx, EA);
+    /* We only need to swap high and low halves. gen_qemu_ld64 does necessary
+       64-bit byteswap already. */
     if (unlikely(ctx->le_mode)) {
         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
         tcg_gen_addi_tl(EA, EA, 8);
@@ -3712,7 +3683,9 @@ static void gen_stfdp(DisasContext *ctx)
     }
     gen_set_access_type(ctx, ACCESS_FLOAT);
     EA = tcg_temp_new();
-    gen_addr_imm_index(ctx, EA, 0);                                           \
+    gen_addr_imm_index(ctx, EA, 0);
+    /* We only need to swap high and low halves. gen_qemu_st64 does necessary
+       64-bit byteswap already. */
     if (unlikely(ctx->le_mode)) {
         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
         tcg_gen_addi_tl(EA, EA, 8);
@@ -3736,6 +3709,8 @@ static void gen_stfdpx(DisasContext *ctx)
     gen_set_access_type(ctx, ACCESS_FLOAT);
     EA = tcg_temp_new();
     gen_addr_reg_index(ctx, EA);
+    /* We only need to swap high and low halves. gen_qemu_st64 does necessary
+       64-bit byteswap already. */
     if (unlikely(ctx->le_mode)) {
         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
         tcg_gen_addi_tl(EA, EA, 8);
@@ -3911,6 +3886,9 @@ static inline void gen_bcond(DisasContext *ctx, int type)
         gen_update_nip(ctx, ctx->nip);
         tcg_gen_exit_tb(0);
     }
+    if (type == BCOND_LR || type == BCOND_CTR || type == BCOND_TAR) {
+        tcg_temp_free(target);
+    }
 }
 
 static void gen_bc(DisasContext *ctx)
@@ -4358,6 +4336,7 @@ static void gen_mtmsr(DisasContext *ctx)
         tcg_gen_mov_tl(msr, cpu_gpr[rS(ctx->opcode)]);
 #endif
         gen_helper_store_msr(cpu_env, msr);
+        tcg_temp_free(msr);
         /* Must stop the translation as machine state (may have) changed */
         /* Note that mtmsr is not always defined as context-synchronizing */
         gen_stop_exception(ctx);
@@ -4467,6 +4446,17 @@ static void gen_dcbtst(DisasContext *ctx)
      */
 }
 
+/* dcbtls */
+static void gen_dcbtls(DisasContext *ctx)
+{
+    /* Always fails locking the cache */
+    TCGv t0 = tcg_temp_new();
+    gen_load_spr(t0, SPR_Exxx_L1CSR0);
+    tcg_gen_ori_tl(t0, t0, L1CSR0_CUL);
+    gen_store_spr(SPR_Exxx_L1CSR0, t0);
+    tcg_temp_free(t0);
+}
+
 /* dcbz */
 static void gen_dcbz(DisasContext *ctx)
 {
@@ -6492,6 +6482,7 @@ static void gen_tlbsx_booke206(DisasContext *ctx)
 
     tcg_gen_add_tl(t0, t0, cpu_gpr[rB(ctx->opcode)]);
     gen_helper_booke206_tlbsx(cpu_env, t0);
+    tcg_temp_free(t0);
 #endif
 }
 
@@ -6525,6 +6516,7 @@ static void gen_tlbivax_booke206(DisasContext *ctx)
     gen_addr_reg_index(ctx, t0);
 
     gen_helper_booke206_tlbivax(cpu_env, t0);
+    tcg_temp_free(t0);
 #endif
 }
 
@@ -6689,6 +6681,8 @@ static void glue(gen_, name)(DisasContext *ctx)
     EA = tcg_temp_new();                                                      \
     gen_addr_reg_index(ctx, EA);                                              \
     tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
+    /* We only need to swap high and low halves. gen_qemu_ld64 does necessary \
+       64-bit byteswap already. */                                            \
     if (ctx->le_mode) {                                                       \
         gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
         tcg_gen_addi_tl(EA, EA, 8);                                           \
@@ -6713,6 +6707,8 @@ static void gen_st##name(DisasContext *ctx)                                   \
     EA = tcg_temp_new();                                                      \
     gen_addr_reg_index(ctx, EA);                                              \
     tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
+    /* We only need to swap high and low halves. gen_qemu_st64 does necessary \
+       64-bit byteswap already. */                                            \
     if (ctx->le_mode) {                                                       \
         gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
         tcg_gen_addi_tl(EA, EA, 8);                                           \
@@ -7018,12 +7014,15 @@ GEN_VXFORM(vmulesw, 4, 14);
 GEN_VXFORM(vslb, 2, 4);
 GEN_VXFORM(vslh, 2, 5);
 GEN_VXFORM(vslw, 2, 6);
+GEN_VXFORM(vsld, 2, 23);
 GEN_VXFORM(vsrb, 2, 8);
 GEN_VXFORM(vsrh, 2, 9);
 GEN_VXFORM(vsrw, 2, 10);
+GEN_VXFORM(vsrd, 2, 27);
 GEN_VXFORM(vsrab, 2, 12);
 GEN_VXFORM(vsrah, 2, 13);
 GEN_VXFORM(vsraw, 2, 14);
+GEN_VXFORM(vsrad, 2, 15);
 GEN_VXFORM(vslo, 6, 16);
 GEN_VXFORM(vsro, 6, 17);
 GEN_VXFORM(vaddcuw, 0, 6);
@@ -7040,9 +7039,22 @@ GEN_VXFORM_ENV(vsubuws, 0, 26);
 GEN_VXFORM_ENV(vsubsbs, 0, 28);
 GEN_VXFORM_ENV(vsubshs, 0, 29);
 GEN_VXFORM_ENV(vsubsws, 0, 30);
+GEN_VXFORM(vadduqm, 0, 4);
+GEN_VXFORM(vaddcuq, 0, 5);
+GEN_VXFORM3(vaddeuqm, 30, 0);
+GEN_VXFORM3(vaddecuq, 30, 0);
+GEN_VXFORM_DUAL(vaddeuqm, PPC_NONE, PPC2_ALTIVEC_207, \
+            vaddecuq, PPC_NONE, PPC2_ALTIVEC_207)
+GEN_VXFORM(vsubuqm, 0, 20);
+GEN_VXFORM(vsubcuq, 0, 21);
+GEN_VXFORM3(vsubeuqm, 31, 0);
+GEN_VXFORM3(vsubecuq, 31, 0);
+GEN_VXFORM_DUAL(vsubeuqm, PPC_NONE, PPC2_ALTIVEC_207, \
+            vsubecuq, PPC_NONE, PPC2_ALTIVEC_207)
 GEN_VXFORM(vrlb, 2, 0);
 GEN_VXFORM(vrlh, 2, 1);
 GEN_VXFORM(vrlw, 2, 2);
+GEN_VXFORM(vrld, 2, 3);
 GEN_VXFORM(vsl, 2, 7);
 GEN_VXFORM(vsr, 2, 11);
 GEN_VXFORM_ENV(vpkuhum, 7, 0);
@@ -7120,17 +7132,27 @@ static void glue(gen_, name0##_##name1)(DisasContext *ctx)             \
 GEN_VXRFORM(vcmpequb, 3, 0)
 GEN_VXRFORM(vcmpequh, 3, 1)
 GEN_VXRFORM(vcmpequw, 3, 2)
+GEN_VXRFORM(vcmpequd, 3, 3)
 GEN_VXRFORM(vcmpgtsb, 3, 12)
 GEN_VXRFORM(vcmpgtsh, 3, 13)
 GEN_VXRFORM(vcmpgtsw, 3, 14)
+GEN_VXRFORM(vcmpgtsd, 3, 15)
 GEN_VXRFORM(vcmpgtub, 3, 8)
 GEN_VXRFORM(vcmpgtuh, 3, 9)
 GEN_VXRFORM(vcmpgtuw, 3, 10)
+GEN_VXRFORM(vcmpgtud, 3, 11)
 GEN_VXRFORM(vcmpeqfp, 3, 3)
 GEN_VXRFORM(vcmpgefp, 3, 7)
 GEN_VXRFORM(vcmpgtfp, 3, 11)
 GEN_VXRFORM(vcmpbfp, 3, 15)
 
+GEN_VXRFORM_DUAL(vcmpeqfp, PPC_ALTIVEC, PPC_NONE, \
+                 vcmpequd, PPC_NONE, PPC2_ALTIVEC_207)
+GEN_VXRFORM_DUAL(vcmpbfp, PPC_ALTIVEC, PPC_NONE, \
+                 vcmpgtsd, PPC_NONE, PPC2_ALTIVEC_207)
+GEN_VXRFORM_DUAL(vcmpgtfp, PPC_ALTIVEC, PPC_NONE, \
+                 vcmpgtud, PPC_NONE, PPC2_ALTIVEC_207)
+
 #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
 static void glue(gen_, name)(DisasContext *ctx)                         \
     {                                                                   \
@@ -7344,6 +7366,98 @@ GEN_VXFORM_DUAL(vclzw, PPC_NONE, PPC2_ALTIVEC_207, \
                 vpopcntw, PPC_NONE, PPC2_ALTIVEC_207)
 GEN_VXFORM_DUAL(vclzd, PPC_NONE, PPC2_ALTIVEC_207, \
                 vpopcntd, PPC_NONE, PPC2_ALTIVEC_207)
+GEN_VXFORM(vbpermq, 6, 21);
+GEN_VXFORM_NOA(vgbbd, 6, 20);
+GEN_VXFORM(vpmsumb, 4, 16)
+GEN_VXFORM(vpmsumh, 4, 17)
+GEN_VXFORM(vpmsumw, 4, 18)
+GEN_VXFORM(vpmsumd, 4, 19)
+
+#define GEN_BCD(op)                                 \
+static void gen_##op(DisasContext *ctx)             \
+{                                                   \
+    TCGv_ptr ra, rb, rd;                            \
+    TCGv_i32 ps;                                    \
+                                                    \
+    if (unlikely(!ctx->altivec_enabled)) {          \
+        gen_exception(ctx, POWERPC_EXCP_VPU);       \
+        return;                                     \
+    }                                               \
+                                                    \
+    ra = gen_avr_ptr(rA(ctx->opcode));              \
+    rb = gen_avr_ptr(rB(ctx->opcode));              \
+    rd = gen_avr_ptr(rD(ctx->opcode));              \
+                                                    \
+    ps = tcg_const_i32((ctx->opcode & 0x200) != 0); \
+                                                    \
+    gen_helper_##op(cpu_crf[6], rd, ra, rb, ps);    \
+                                                    \
+    tcg_temp_free_ptr(ra);                          \
+    tcg_temp_free_ptr(rb);                          \
+    tcg_temp_free_ptr(rd);                          \
+    tcg_temp_free_i32(ps);                          \
+}
+
+GEN_BCD(bcdadd)
+GEN_BCD(bcdsub)
+
+GEN_VXFORM_DUAL(vsububm, PPC_ALTIVEC, PPC_NONE, \
+                bcdadd, PPC_NONE, PPC2_ALTIVEC_207)
+GEN_VXFORM_DUAL(vsububs, PPC_ALTIVEC, PPC_NONE, \
+                bcdadd, PPC_NONE, PPC2_ALTIVEC_207)
+GEN_VXFORM_DUAL(vsubuhm, PPC_ALTIVEC, PPC_NONE, \
+                bcdsub, PPC_NONE, PPC2_ALTIVEC_207)
+GEN_VXFORM_DUAL(vsubuhs, PPC_ALTIVEC, PPC_NONE, \
+                bcdsub, PPC_NONE, PPC2_ALTIVEC_207)
+
+static void gen_vsbox(DisasContext *ctx)
+{
+    TCGv_ptr ra, rd;
+    if (unlikely(!ctx->altivec_enabled)) {
+        gen_exception(ctx, POWERPC_EXCP_VPU);
+        return;
+    }
+    ra = gen_avr_ptr(rA(ctx->opcode));
+    rd = gen_avr_ptr(rD(ctx->opcode));
+    gen_helper_vsbox(rd, ra);
+    tcg_temp_free_ptr(ra);
+    tcg_temp_free_ptr(rd);
+}
+
+GEN_VXFORM(vcipher, 4, 20)
+GEN_VXFORM(vcipherlast, 4, 20)
+GEN_VXFORM(vncipher, 4, 21)
+GEN_VXFORM(vncipherlast, 4, 21)
+
+GEN_VXFORM_DUAL(vcipher, PPC_NONE, PPC2_ALTIVEC_207,
+                vcipherlast, PPC_NONE, PPC2_ALTIVEC_207)
+GEN_VXFORM_DUAL(vncipher, PPC_NONE, PPC2_ALTIVEC_207,
+                vncipherlast, PPC_NONE, PPC2_ALTIVEC_207)
+
+#define VSHASIGMA(op)                         \
+static void gen_##op(DisasContext *ctx)       \
+{                                             \
+    TCGv_ptr ra, rd;                          \
+    TCGv_i32 st_six;                          \
+    if (unlikely(!ctx->altivec_enabled)) {    \
+        gen_exception(ctx, POWERPC_EXCP_VPU); \
+        return;                               \
+    }                                         \
+    ra = gen_avr_ptr(rA(ctx->opcode));        \
+    rd = gen_avr_ptr(rD(ctx->opcode));        \
+    st_six = tcg_const_i32(rB(ctx->opcode));  \
+    gen_helper_##op(rd, ra, st_six);          \
+    tcg_temp_free_ptr(ra);                    \
+    tcg_temp_free_ptr(rd);                    \
+    tcg_temp_free_i32(st_six);                \
+}
+
+VSHASIGMA(vshasigmaw)
+VSHASIGMA(vshasigmad)
+
+GEN_VXFORM3(vpermxor, 22, 0xFF)
+GEN_VXFORM_DUAL(vsldoi, PPC_ALTIVEC, PPC_NONE,
+                vpermxor, PPC_NONE, PPC2_ALTIVEC_207)
 
 /***                           VSX extension                               ***/
 
@@ -7609,8 +7723,8 @@ static void gen_xxpermdi(DisasContext *ctx)
 #define OP_NABS 2
 #define OP_NEG 3
 #define OP_CPSGN 4
-#define SGN_MASK_DP  0x8000000000000000ul
-#define SGN_MASK_SP 0x8000000080000000ul
+#define SGN_MASK_DP  0x8000000000000000ull
+#define SGN_MASK_SP 0x8000000080000000ull
 
 #define VSX_SCALAR_MOVE(name, op, sgn_mask)                       \
 static void glue(gen_, name)(DisasContext * ctx)                  \
@@ -8060,6 +8174,225 @@ static void gen_xxsldwi(DisasContext *ctx)
     tcg_temp_free_i64(xtl);
 }
 
+/*** Decimal Floating Point ***/
+
+static inline TCGv_ptr gen_fprp_ptr(int reg)
+{
+    TCGv_ptr r = tcg_temp_new_ptr();
+    tcg_gen_addi_ptr(r, cpu_env, offsetof(CPUPPCState, fpr[reg]));
+    return r;
+}
+
+#if defined(TARGET_PPC64)
+static void gen_set_cr6_from_fpscr(DisasContext *ctx)
+{
+    TCGv_i32 tmp = tcg_temp_new_i32();
+    tcg_gen_trunc_tl_i32(tmp, cpu_fpscr);
+    tcg_gen_shri_i32(cpu_crf[1], tmp, 28);
+    tcg_temp_free_i32(tmp);
+}
+#else
+static void gen_set_cr6_from_fpscr(DisasContext *ctx)
+{
+        tcg_gen_shri_tl(cpu_crf[1], cpu_fpscr, 28);
+}
+#endif
+
+#define GEN_DFP_T_A_B_Rc(name)                   \
+static void gen_##name(DisasContext *ctx)        \
+{                                                \
+    TCGv_ptr rd, ra, rb;                         \
+    if (unlikely(!ctx->fpu_enabled)) {           \
+        gen_exception(ctx, POWERPC_EXCP_FPU);    \
+        return;                                  \
+    }                                            \
+    gen_update_nip(ctx, ctx->nip - 4);           \
+    rd = gen_fprp_ptr(rD(ctx->opcode));          \
+    ra = gen_fprp_ptr(rA(ctx->opcode));          \
+    rb = gen_fprp_ptr(rB(ctx->opcode));          \
+    gen_helper_##name(cpu_env, rd, ra, rb);      \
+    if (unlikely(Rc(ctx->opcode) != 0)) {        \
+        gen_set_cr6_from_fpscr(ctx);             \
+    }                                            \
+    tcg_temp_free_ptr(rd);                       \
+    tcg_temp_free_ptr(ra);                       \
+    tcg_temp_free_ptr(rb);                       \
+}
+
+#define GEN_DFP_BF_A_B(name)                      \
+static void gen_##name(DisasContext *ctx)         \
+{                                                 \
+    TCGv_ptr ra, rb;                              \
+    if (unlikely(!ctx->fpu_enabled)) {            \
+        gen_exception(ctx, POWERPC_EXCP_FPU);     \
+        return;                                   \
+    }                                             \
+    gen_update_nip(ctx, ctx->nip - 4);            \
+    ra = gen_fprp_ptr(rA(ctx->opcode));           \
+    rb = gen_fprp_ptr(rB(ctx->opcode));           \
+    gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
+                      cpu_env, ra, rb);           \
+    tcg_temp_free_ptr(ra);                        \
+    tcg_temp_free_ptr(rb);                        \
+}
+
+#define GEN_DFP_BF_A_DCM(name)                    \
+static void gen_##name(DisasContext *ctx)         \
+{                                                 \
+    TCGv_ptr ra;                                  \
+    TCGv_i32 dcm;                                 \
+    if (unlikely(!ctx->fpu_enabled)) {            \
+        gen_exception(ctx, POWERPC_EXCP_FPU);     \
+        return;                                   \
+    }                                             \
+    gen_update_nip(ctx, ctx->nip - 4);            \
+    ra = gen_fprp_ptr(rA(ctx->opcode));           \
+    dcm = tcg_const_i32(DCM(ctx->opcode));        \
+    gen_helper_##name(cpu_crf[crfD(ctx->opcode)], \
+                      cpu_env, ra, dcm);          \
+    tcg_temp_free_ptr(ra);                        \
+    tcg_temp_free_i32(dcm);                       \
+}
+
+#define GEN_DFP_T_B_U32_U32_Rc(name, u32f1, u32f2)    \
+static void gen_##name(DisasContext *ctx)             \
+{                                                     \
+    TCGv_ptr rt, rb;                                  \
+    TCGv_i32 u32_1, u32_2;                            \
+    if (unlikely(!ctx->fpu_enabled)) {                \
+        gen_exception(ctx, POWERPC_EXCP_FPU);         \
+        return;                                       \
+    }                                                 \
+    gen_update_nip(ctx, ctx->nip - 4);                \
+    rt = gen_fprp_ptr(rD(ctx->opcode));               \
+    rb = gen_fprp_ptr(rB(ctx->opcode));               \
+    u32_1 = tcg_const_i32(u32f1(ctx->opcode));        \
+    u32_2 = tcg_const_i32(u32f2(ctx->opcode));        \
+    gen_helper_##name(cpu_env, rt, rb, u32_1, u32_2); \
+    if (unlikely(Rc(ctx->opcode) != 0)) {             \
+        gen_set_cr6_from_fpscr(ctx);                  \
+    }                                                 \
+    tcg_temp_free_ptr(rt);                            \
+    tcg_temp_free_ptr(rb);                            \
+    tcg_temp_free_i32(u32_1);                         \
+    tcg_temp_free_i32(u32_2);                         \
+}
+
+#define GEN_DFP_T_A_B_I32_Rc(name, i32fld)       \
+static void gen_##name(DisasContext *ctx)        \
+{                                                \
+    TCGv_ptr rt, ra, rb;                         \
+    TCGv_i32 i32;                                \
+    if (unlikely(!ctx->fpu_enabled)) {           \
+        gen_exception(ctx, POWERPC_EXCP_FPU);    \
+        return;                                  \
+    }                                            \
+    gen_update_nip(ctx, ctx->nip - 4);           \
+    rt = gen_fprp_ptr(rD(ctx->opcode));          \
+    ra = gen_fprp_ptr(rA(ctx->opcode));          \
+    rb = gen_fprp_ptr(rB(ctx->opcode));          \
+    i32 = tcg_const_i32(i32fld(ctx->opcode));    \
+    gen_helper_##name(cpu_env, rt, ra, rb, i32); \
+    if (unlikely(Rc(ctx->opcode) != 0)) {        \
+        gen_set_cr6_from_fpscr(ctx);             \
+    }                                            \
+    tcg_temp_free_ptr(rt);                       \
+    tcg_temp_free_ptr(rb);                       \
+    tcg_temp_free_ptr(ra);                       \
+    tcg_temp_free_i32(i32);                      \
+    }
+
+#define GEN_DFP_T_B_Rc(name)                     \
+static void gen_##name(DisasContext *ctx)        \
+{                                                \
+    TCGv_ptr rt, rb;                             \
+    if (unlikely(!ctx->fpu_enabled)) {           \
+        gen_exception(ctx, POWERPC_EXCP_FPU);    \
+        return;                                  \
+    }                                            \
+    gen_update_nip(ctx, ctx->nip - 4);           \
+    rt = gen_fprp_ptr(rD(ctx->opcode));          \
+    rb = gen_fprp_ptr(rB(ctx->opcode));          \
+    gen_helper_##name(cpu_env, rt, rb);          \
+    if (unlikely(Rc(ctx->opcode) != 0)) {        \
+        gen_set_cr6_from_fpscr(ctx);             \
+    }                                            \
+    tcg_temp_free_ptr(rt);                       \
+    tcg_temp_free_ptr(rb);                       \
+    }
+
+#define GEN_DFP_T_FPR_I32_Rc(name, fprfld, i32fld) \
+static void gen_##name(DisasContext *ctx)          \
+{                                                  \
+    TCGv_ptr rt, rs;                               \
+    TCGv_i32 i32;                                  \
+    if (unlikely(!ctx->fpu_enabled)) {             \
+        gen_exception(ctx, POWERPC_EXCP_FPU);      \
+        return;                                    \
+    }                                              \
+    gen_update_nip(ctx, ctx->nip - 4);             \
+    rt = gen_fprp_ptr(rD(ctx->opcode));            \
+    rs = gen_fprp_ptr(fprfld(ctx->opcode));        \
+    i32 = tcg_const_i32(i32fld(ctx->opcode));      \
+    gen_helper_##name(cpu_env, rt, rs, i32);       \
+    if (unlikely(Rc(ctx->opcode) != 0)) {          \
+        gen_set_cr6_from_fpscr(ctx);               \
+    }                                              \
+    tcg_temp_free_ptr(rt);                         \
+    tcg_temp_free_ptr(rs);                         \
+    tcg_temp_free_i32(i32);                        \
+}
+
+GEN_DFP_T_A_B_Rc(dadd)
+GEN_DFP_T_A_B_Rc(daddq)
+GEN_DFP_T_A_B_Rc(dsub)
+GEN_DFP_T_A_B_Rc(dsubq)
+GEN_DFP_T_A_B_Rc(dmul)
+GEN_DFP_T_A_B_Rc(dmulq)
+GEN_DFP_T_A_B_Rc(ddiv)
+GEN_DFP_T_A_B_Rc(ddivq)
+GEN_DFP_BF_A_B(dcmpu)
+GEN_DFP_BF_A_B(dcmpuq)
+GEN_DFP_BF_A_B(dcmpo)
+GEN_DFP_BF_A_B(dcmpoq)
+GEN_DFP_BF_A_DCM(dtstdc)
+GEN_DFP_BF_A_DCM(dtstdcq)
+GEN_DFP_BF_A_DCM(dtstdg)
+GEN_DFP_BF_A_DCM(dtstdgq)
+GEN_DFP_BF_A_B(dtstex)
+GEN_DFP_BF_A_B(dtstexq)
+GEN_DFP_BF_A_B(dtstsf)
+GEN_DFP_BF_A_B(dtstsfq)
+GEN_DFP_T_B_U32_U32_Rc(dquai, SIMM5, RMC)
+GEN_DFP_T_B_U32_U32_Rc(dquaiq, SIMM5, RMC)
+GEN_DFP_T_A_B_I32_Rc(dqua, RMC)
+GEN_DFP_T_A_B_I32_Rc(dquaq, RMC)
+GEN_DFP_T_A_B_I32_Rc(drrnd, RMC)
+GEN_DFP_T_A_B_I32_Rc(drrndq, RMC)
+GEN_DFP_T_B_U32_U32_Rc(drintx, FPW, RMC)
+GEN_DFP_T_B_U32_U32_Rc(drintxq, FPW, RMC)
+GEN_DFP_T_B_U32_U32_Rc(drintn, FPW, RMC)
+GEN_DFP_T_B_U32_U32_Rc(drintnq, FPW, RMC)
+GEN_DFP_T_B_Rc(dctdp)
+GEN_DFP_T_B_Rc(dctqpq)
+GEN_DFP_T_B_Rc(drsp)
+GEN_DFP_T_B_Rc(drdpq)
+GEN_DFP_T_B_Rc(dcffix)
+GEN_DFP_T_B_Rc(dcffixq)
+GEN_DFP_T_B_Rc(dctfix)
+GEN_DFP_T_B_Rc(dctfixq)
+GEN_DFP_T_FPR_I32_Rc(ddedpd, rB, SP)
+GEN_DFP_T_FPR_I32_Rc(ddedpdq, rB, SP)
+GEN_DFP_T_FPR_I32_Rc(denbcd, rB, SP)
+GEN_DFP_T_FPR_I32_Rc(denbcdq, rB, SP)
+GEN_DFP_T_B_Rc(dxex)
+GEN_DFP_T_B_Rc(dxexq)
+GEN_DFP_T_A_B_Rc(diex)
+GEN_DFP_T_A_B_Rc(diexq)
+GEN_DFP_T_FPR_I32_Rc(dscli, rA, DCM)
+GEN_DFP_T_FPR_I32_Rc(dscliq, rA, DCM)
+GEN_DFP_T_FPR_I32_Rc(dscri, rA, DCM)
+GEN_DFP_T_FPR_I32_Rc(dscriq, rA, DCM)
 
 /***                           SPE extension                               ***/
 /* Register moves */
@@ -8072,50 +8405,28 @@ static inline void gen_evmra(DisasContext *ctx)
         return;
     }
 
-#if defined(TARGET_PPC64)
-    /* rD := rA */
-    tcg_gen_mov_i64(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
-
-    /* spe_acc := rA */
-    tcg_gen_st_i64(cpu_gpr[rA(ctx->opcode)],
-                   cpu_env,
-                   offsetof(CPUPPCState, spe_acc));
-#else
     TCGv_i64 tmp = tcg_temp_new_i64();
 
     /* tmp := rA_lo + rA_hi << 32 */
-    tcg_gen_concat_i32_i64(tmp, cpu_gpr[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
+    tcg_gen_concat_tl_i64(tmp, cpu_gpr[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
 
     /* spe_acc := tmp */
     tcg_gen_st_i64(tmp, cpu_env, offsetof(CPUPPCState, spe_acc));
     tcg_temp_free_i64(tmp);
 
     /* rD := rA */
-    tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
-    tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
-#endif
+    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
+    tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
 }
 
 static inline void gen_load_gpr64(TCGv_i64 t, int reg)
 {
-#if defined(TARGET_PPC64)
-    tcg_gen_mov_i64(t, cpu_gpr[reg]);
-#else
-    tcg_gen_concat_i32_i64(t, cpu_gpr[reg], cpu_gprh[reg]);
-#endif
+    tcg_gen_concat_tl_i64(t, cpu_gpr[reg], cpu_gprh[reg]);
 }
 
 static 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);
-    tcg_gen_shri_i64(tmp, t, 32);
-    tcg_gen_trunc_i64_i32(cpu_gprh[reg], tmp);
-    tcg_temp_free_i64(tmp);
-#endif
+    tcg_gen_extr_i64_tl(cpu_gpr[reg], cpu_gprh[reg], t);
 }
 
 #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type)         \
@@ -8134,18 +8445,6 @@ static inline void gen_speundef(DisasContext *ctx)
 }
 
 /* SPE logic */
-#if defined(TARGET_PPC64)
-#define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
-static inline void gen_##name(DisasContext *ctx)                              \
-{                                                                             \
-    if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
-        return;                                                               \
-    }                                                                         \
-    tcg_op(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],                \
-           cpu_gpr[rB(ctx->opcode)]);                                         \
-}
-#else
 #define GEN_SPEOP_LOGIC2(name, tcg_op)                                        \
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
@@ -8158,7 +8457,6 @@ static inline void gen_##name(DisasContext *ctx)                              \
     tcg_op(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],              \
            cpu_gprh[rB(ctx->opcode)]);                                        \
 }
-#endif
 
 GEN_SPEOP_LOGIC2(evand, tcg_gen_and_tl);
 GEN_SPEOP_LOGIC2(evandc, tcg_gen_andc_tl);
@@ -8170,80 +8468,52 @@ 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 inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
+    TCGv_i32 t0;                                                              \
     if (unlikely(!ctx->spe_enabled)) {                                        \
         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         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[rA(ctx->opcode)]);                      \
+    t0 = tcg_temp_new_i32();                                                  \
+                                                                              \
+    tcg_gen_trunc_tl_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_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);                        \
+                                                                              \
+    tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]);                      \
+    tcg_opi(t0, t0, rB(ctx->opcode));                                         \
+    tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0);                       \
+                                                                              \
     tcg_temp_free_i32(t0);                                                    \
-    tcg_temp_free_i32(t1);                                                    \
-}
-#else
-#define GEN_SPEOP_TCG_LOGIC_IMM2(name, tcg_opi)                               \
-static inline void gen_##name(DisasContext *ctx)                              \
-{                                                                             \
-    if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
-        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);
 
 /* SPE arithmetic */
-#if defined(TARGET_PPC64)
 #define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
+    TCGv_i32 t0;                                                              \
     if (unlikely(!ctx->spe_enabled)) {                                        \
         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         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[rA(ctx->opcode)]);                      \
+    t0 = tcg_temp_new_i32();                                                  \
+                                                                              \
+    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
+    tcg_op(t0, t0);                                                           \
+    tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);                        \
+                                                                              \
+    tcg_gen_trunc_tl_i32(t0, cpu_gprh[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_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0);                       \
+                                                                              \
     tcg_temp_free_i32(t0);                                                    \
-    tcg_temp_free_i32(t1);                                                    \
-}
-#else
-#define GEN_SPEOP_ARITH1(name, tcg_op)                                        \
-static inline void gen_##name(DisasContext *ctx)                              \
-{                                                                             \
-    if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
-        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
 
 static inline void gen_op_evabs(TCGv_i32 ret, TCGv_i32 arg1)
 {
@@ -8270,46 +8540,30 @@ GEN_SPEOP_ARITH1(evrndw, gen_op_evrndw);
 GEN_SPEOP_ARITH1(evcntlsw, gen_helper_cntlsw32);
 GEN_SPEOP_ARITH1(evcntlzw, gen_helper_cntlzw32);
 
-#if defined(TARGET_PPC64)
 #define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
+    TCGv_i32 t0, t1;                                                          \
     if (unlikely(!ctx->spe_enabled)) {                                        \
         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
-    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_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);                 \
+    t0 = tcg_temp_new_i32();                                                  \
+    t1 = tcg_temp_new_i32();                                                  \
+                                                                              \
+    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
+    tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
+    tcg_op(t0, t0, t1);                                                       \
+    tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);                        \
+                                                                              \
+    tcg_gen_trunc_tl_i32(t0, cpu_gprh[rA(ctx->opcode)]);                      \
+    tcg_gen_trunc_tl_i32(t1, cpu_gprh[rB(ctx->opcode)]);                      \
+    tcg_op(t0, t0, t1);                                                       \
+    tcg_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0);                       \
+                                                                              \
     tcg_temp_free_i32(t0);                                                    \
     tcg_temp_free_i32(t1);                                                    \
 }
-#else
-#define GEN_SPEOP_ARITH2(name, tcg_op)                                        \
-static inline void gen_##name(DisasContext *ctx)                              \
-{                                                                             \
-    if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
-        return;                                                               \
-    }                                                                         \
-    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
 
 static inline void gen_op_evsrwu(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
 {
@@ -8382,18 +8636,8 @@ static inline void gen_evmergehi(DisasContext *ctx)
         gen_exception(ctx, POWERPC_EXCP_SPEU);
         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
+    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
+    tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
 }
 GEN_SPEOP_ARITH2(evaddw, tcg_gen_add_i32);
 static inline void gen_op_evsubf(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
@@ -8403,86 +8647,30 @@ static inline void gen_op_evsubf(TCGv_i32 ret, TCGv_i32 arg1, TCGv_i32 arg2)
 GEN_SPEOP_ARITH2(evsubfw, gen_op_evsubf);
 
 /* SPE arithmetic immediate */
-#if defined(TARGET_PPC64)
 #define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
+    TCGv_i32 t0;                                                              \
     if (unlikely(!ctx->spe_enabled)) {                                        \
         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         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)]);                      \
+    t0 = tcg_temp_new_i32();                                                  \
+                                                                              \
+    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
+    tcg_op(t0, t0, rA(ctx->opcode));                                          \
+    tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);                        \
+                                                                              \
+    tcg_gen_trunc_tl_i32(t0, cpu_gprh[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_gen_extu_i32_tl(cpu_gprh[rD(ctx->opcode)], t0);                       \
+                                                                              \
     tcg_temp_free_i32(t0);                                                    \
-    tcg_temp_free_i32(t1);                                                    \
-}
-#else
-#define GEN_SPEOP_ARITH_IMM2(name, tcg_op)                                    \
-static inline void gen_##name(DisasContext *ctx)                              \
-{                                                                             \
-    if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
-        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);
 
 /* SPE comparison */
-#if defined(TARGET_PPC64)
-#define GEN_SPEOP_COMP(name, tcg_cond)                                        \
-static inline void gen_##name(DisasContext *ctx)                              \
-{                                                                             \
-    if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
-        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 inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
@@ -8495,15 +8683,20 @@ static inline void gen_##name(DisasContext *ctx)                              \
     int l3 = gen_new_label();                                                 \
     int l4 = gen_new_label();                                                 \
                                                                               \
-    tcg_gen_brcond_i32(tcg_cond, cpu_gpr[rA(ctx->opcode)],                    \
+    tcg_gen_ext32s_tl(cpu_gpr[rA(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);    \
+    tcg_gen_ext32s_tl(cpu_gpr[rB(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
+    tcg_gen_ext32s_tl(cpu_gprh[rA(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);  \
+    tcg_gen_ext32s_tl(cpu_gprh[rB(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);  \
+                                                                              \
+    tcg_gen_brcond_tl(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_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_brcond_i32(tcg_cond, cpu_gprh[rA(ctx->opcode)],                   \
+    tcg_gen_brcond_tl(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));                              \
@@ -8513,7 +8706,6 @@ static inline void gen_##name(DisasContext *ctx)                              \
                     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);
@@ -8533,18 +8725,8 @@ static inline void gen_evmergelo(DisasContext *ctx)
         gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
-#if defined(TARGET_PPC64)
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
-    tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
-    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_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
-    tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
-#endif
+    tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
+    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
 }
 static inline void gen_evmergehilo(DisasContext *ctx)
 {
@@ -8552,18 +8734,8 @@ static inline void gen_evmergehilo(DisasContext *ctx)
         gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
-#if defined(TARGET_PPC64)
-    TCGv t0 = tcg_temp_new();
-    TCGv t1 = tcg_temp_new();
-    tcg_gen_ext32u_tl(t0, cpu_gpr[rB(ctx->opcode)]);
-    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
+    tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);
+    tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)]);
 }
 static inline void gen_evmergelohi(DisasContext *ctx)
 {
@@ -8571,48 +8743,30 @@ static inline void gen_evmergelohi(DisasContext *ctx)
         gen_exception(ctx, POWERPC_EXCP_SPEU);
         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
     if (rD(ctx->opcode) == rA(ctx->opcode)) {
-        TCGv_i32 tmp = tcg_temp_new_i32();
-        tcg_gen_mov_i32(tmp, cpu_gpr[rA(ctx->opcode)]);
-        tcg_gen_mov_i32(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
-        tcg_gen_mov_i32(cpu_gprh[rD(ctx->opcode)], tmp);
-        tcg_temp_free_i32(tmp);
+        TCGv tmp = tcg_temp_new();
+        tcg_gen_mov_tl(tmp, cpu_gpr[rA(ctx->opcode)]);
+        tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
+        tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], tmp);
+        tcg_temp_free(tmp);
     } 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)]);
+        tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rB(ctx->opcode)]);
+        tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
     }
-#endif
 }
 static inline void gen_evsplati(DisasContext *ctx)
 {
     uint64_t imm = ((int32_t)(rA(ctx->opcode) << 27)) >> 27;
 
-#if defined(TARGET_PPC64)
-    tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], (imm << 32) | imm);
-#else
-    tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
-    tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
-#endif
+    tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], imm);
+    tcg_gen_movi_tl(cpu_gprh[rD(ctx->opcode)], imm);
 }
 static inline void gen_evsplatfi(DisasContext *ctx)
 {
     uint64_t imm = rA(ctx->opcode) << 27;
 
-#if defined(TARGET_PPC64)
-    tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], (imm << 32) | imm);
-#else
-    tcg_gen_movi_i32(cpu_gpr[rD(ctx->opcode)], imm);
-    tcg_gen_movi_i32(cpu_gprh[rD(ctx->opcode)], imm);
-#endif
+    tcg_gen_movi_tl(cpu_gpr[rD(ctx->opcode)], imm);
+    tcg_gen_movi_tl(cpu_gprh[rD(ctx->opcode)], imm);
 }
 
 static inline void gen_evsel(DisasContext *ctx)
@@ -8622,46 +8776,21 @@ static inline void gen_evsel(DisasContext *ctx)
     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_ext32u_tl(t2, cpu_gpr[rA(ctx->opcode)]);
-#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_ext32u_tl(t2, cpu_gpr[rB(ctx->opcode)]);
-#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
 }
 
 static void gen_evsel0(DisasContext *ctx)
@@ -8699,13 +8828,10 @@ static inline void gen_evmwumi(DisasContext *ctx)
     t1 = tcg_temp_new_i64();
 
     /* t0 := rA; t1 := rB */
-#if defined(TARGET_PPC64)
-    tcg_gen_ext32u_tl(t0, cpu_gpr[rA(ctx->opcode)]);
-    tcg_gen_ext32u_tl(t1, cpu_gpr[rB(ctx->opcode)]);
-#else
     tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
+    tcg_gen_ext32u_i64(t0, t0);
     tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
-#endif
+    tcg_gen_ext32u_i64(t1, t1);
 
     tcg_gen_mul_i64(t0, t0, t1);  /* t0 := rA * rB */
 
@@ -8781,13 +8907,10 @@ static inline void gen_evmwsmi(DisasContext *ctx)
     t1 = tcg_temp_new_i64();
 
     /* t0 := rA; t1 := rB */
-#if defined(TARGET_PPC64)
-    tcg_gen_ext32s_tl(t0, cpu_gpr[rA(ctx->opcode)]);
-    tcg_gen_ext32s_tl(t1, cpu_gpr[rB(ctx->opcode)]);
-#else
-    tcg_gen_ext_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
-    tcg_gen_ext_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
-#endif
+    tcg_gen_extu_tl_i64(t0, cpu_gpr[rA(ctx->opcode)]);
+    tcg_gen_ext32s_i64(t0, t0);
+    tcg_gen_extu_tl_i64(t1, cpu_gpr[rB(ctx->opcode)]);
+    tcg_gen_ext32s_i64(t1, t1);
 
     tcg_gen_mul_i64(t0, t0, t1);  /* t0 := rA * rB */
 
@@ -8888,53 +9011,22 @@ static inline void gen_addr_spe_imm_index(DisasContext *ctx, TCGv EA, int sh)
 
 static inline void gen_op_evldd(DisasContext *ctx, TCGv addr)
 {
-#if defined(TARGET_PPC64)
-    gen_qemu_ld64(ctx, cpu_gpr[rD(ctx->opcode)], addr);
-#else
     TCGv_i64 t0 = tcg_temp_new_i64();
     gen_qemu_ld64(ctx, t0, addr);
-    tcg_gen_trunc_i64_i32(cpu_gpr[rD(ctx->opcode)], t0);
-    tcg_gen_shri_i64(t0, t0, 32);
-    tcg_gen_trunc_i64_i32(cpu_gprh[rD(ctx->opcode)], t0);
+    gen_store_gpr64(rD(ctx->opcode), t0);
     tcg_temp_free_i64(t0);
-#endif
 }
 
 static inline void gen_op_evldw(DisasContext *ctx, TCGv addr)
 {
-#if defined(TARGET_PPC64)
-    TCGv t0 = tcg_temp_new();
-    gen_qemu_ld32u(ctx, t0, addr);
-    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
-    gen_addr_add(ctx, addr, addr, 4);
-    gen_qemu_ld32u(ctx, t0, addr);
-    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
-    tcg_temp_free(t0);
-#else
     gen_qemu_ld32u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
     gen_addr_add(ctx, addr, addr, 4);
     gen_qemu_ld32u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
-#endif
 }
 
 static inline void gen_op_evldh(DisasContext *ctx, TCGv addr)
 {
     TCGv t0 = tcg_temp_new();
-#if defined(TARGET_PPC64)
-    gen_qemu_ld16u(ctx, t0, addr);
-    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
-    gen_addr_add(ctx, addr, addr, 2);
-    gen_qemu_ld16u(ctx, t0, addr);
-    tcg_gen_shli_tl(t0, t0, 32);
-    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
-    gen_addr_add(ctx, addr, addr, 2);
-    gen_qemu_ld16u(ctx, t0, addr);
-    tcg_gen_shli_tl(t0, t0, 16);
-    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
-    gen_addr_add(ctx, addr, addr, 2);
-    gen_qemu_ld16u(ctx, t0, addr);
-    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
-#else
     gen_qemu_ld16u(ctx, t0, addr);
     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
     gen_addr_add(ctx, addr, addr, 2);
@@ -8946,7 +9038,6 @@ static inline void gen_op_evldh(DisasContext *ctx, TCGv addr)
     gen_addr_add(ctx, addr, addr, 2);
     gen_qemu_ld16u(ctx, t0, addr);
     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
-#endif
     tcg_temp_free(t0);
 }
 
@@ -8954,15 +9045,9 @@ static inline void gen_op_evlhhesplat(DisasContext *ctx, TCGv addr)
 {
     TCGv t0 = tcg_temp_new();
     gen_qemu_ld16u(ctx, t0, addr);
-#if defined(TARGET_PPC64)
-    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
-    tcg_gen_shli_tl(t0, t0, 16);
-    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
-#else
     tcg_gen_shli_tl(t0, t0, 16);
     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
-#endif
     tcg_temp_free(t0);
 }
 
@@ -8970,13 +9055,8 @@ static inline void gen_op_evlhhousplat(DisasContext *ctx, TCGv addr)
 {
     TCGv t0 = tcg_temp_new();
     gen_qemu_ld16u(ctx, t0, addr);
-#if defined(TARGET_PPC64)
-    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
-    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
-#else
     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
-#endif
     tcg_temp_free(t0);
 }
 
@@ -8984,100 +9064,48 @@ static inline void gen_op_evlhhossplat(DisasContext *ctx, TCGv addr)
 {
     TCGv t0 = tcg_temp_new();
     gen_qemu_ld16s(ctx, t0, addr);
-#if defined(TARGET_PPC64)
-    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
-    tcg_gen_ext32u_tl(t0, t0);
-    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
-#else
     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
-#endif
     tcg_temp_free(t0);
 }
 
 static inline void gen_op_evlwhe(DisasContext *ctx, TCGv addr)
 {
     TCGv t0 = tcg_temp_new();
-#if defined(TARGET_PPC64)
-    gen_qemu_ld16u(ctx, t0, addr);
-    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
-    gen_addr_add(ctx, addr, addr, 2);
-    gen_qemu_ld16u(ctx, t0, addr);
-    tcg_gen_shli_tl(t0, t0, 16);
-    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
-#else
     gen_qemu_ld16u(ctx, t0, addr);
     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
     gen_addr_add(ctx, addr, addr, 2);
     gen_qemu_ld16u(ctx, t0, addr);
     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
-#endif
     tcg_temp_free(t0);
 }
 
 static inline void gen_op_evlwhou(DisasContext *ctx, TCGv addr)
 {
-#if defined(TARGET_PPC64)
-    TCGv t0 = tcg_temp_new();
-    gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
-    gen_addr_add(ctx, addr, addr, 2);
-    gen_qemu_ld16u(ctx, t0, addr);
-    tcg_gen_shli_tl(t0, t0, 32);
-    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
-    tcg_temp_free(t0);
-#else
     gen_qemu_ld16u(ctx, cpu_gprh[rD(ctx->opcode)], addr);
     gen_addr_add(ctx, addr, addr, 2);
     gen_qemu_ld16u(ctx, cpu_gpr[rD(ctx->opcode)], addr);
-#endif
 }
 
 static inline void gen_op_evlwhos(DisasContext *ctx, TCGv addr)
 {
-#if defined(TARGET_PPC64)
-    TCGv t0 = tcg_temp_new();
-    gen_qemu_ld16s(ctx, t0, addr);
-    tcg_gen_ext32u_tl(cpu_gpr[rD(ctx->opcode)], t0);
-    gen_addr_add(ctx, addr, addr, 2);
-    gen_qemu_ld16s(ctx, t0, addr);
-    tcg_gen_shli_tl(t0, t0, 32);
-    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
-    tcg_temp_free(t0);
-#else
     gen_qemu_ld16s(ctx, cpu_gprh[rD(ctx->opcode)], addr);
     gen_addr_add(ctx, addr, addr, 2);
     gen_qemu_ld16s(ctx, cpu_gpr[rD(ctx->opcode)], addr);
-#endif
 }
 
 static inline void gen_op_evlwwsplat(DisasContext *ctx, TCGv addr)
 {
     TCGv t0 = tcg_temp_new();
     gen_qemu_ld32u(ctx, t0, addr);
-#if defined(TARGET_PPC64)
-    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 32);
-    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
-#else
     tcg_gen_mov_tl(cpu_gprh[rD(ctx->opcode)], t0);
     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], t0);
-#endif
     tcg_temp_free(t0);
 }
 
 static inline void gen_op_evlwhsplat(DisasContext *ctx, TCGv addr)
 {
     TCGv t0 = tcg_temp_new();
-#if defined(TARGET_PPC64)
-    gen_qemu_ld16u(ctx, t0, addr);
-    tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 48);
-    tcg_gen_shli_tl(t0, t0, 32);
-    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
-    gen_addr_add(ctx, addr, addr, 2);
-    gen_qemu_ld16u(ctx, t0, addr);
-    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
-    tcg_gen_shli_tl(t0, t0, 16);
-    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t0);
-#else
     gen_qemu_ld16u(ctx, t0, addr);
     tcg_gen_shli_tl(cpu_gprh[rD(ctx->opcode)], t0, 16);
     tcg_gen_or_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
@@ -9085,32 +9113,20 @@ static inline void gen_op_evlwhsplat(DisasContext *ctx, TCGv addr)
     gen_qemu_ld16u(ctx, t0, addr);
     tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)], t0, 16);
     tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gprh[rD(ctx->opcode)], t0);
-#endif
     tcg_temp_free(t0);
 }
 
 static inline void gen_op_evstdd(DisasContext *ctx, TCGv addr)
 {
-#if defined(TARGET_PPC64)
-    gen_qemu_st64(ctx, cpu_gpr[rS(ctx->opcode)], addr);
-#else
     TCGv_i64 t0 = tcg_temp_new_i64();
-    tcg_gen_concat_i32_i64(t0, cpu_gpr[rS(ctx->opcode)], cpu_gprh[rS(ctx->opcode)]);
+    gen_load_gpr64(t0, rS(ctx->opcode));
     gen_qemu_st64(ctx, t0, addr);
     tcg_temp_free_i64(t0);
-#endif
 }
 
 static inline void gen_op_evstdw(DisasContext *ctx, TCGv addr)
 {
-#if defined(TARGET_PPC64)
-    TCGv t0 = tcg_temp_new();
-    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
-    gen_qemu_st32(ctx, t0, addr);
-    tcg_temp_free(t0);
-#else
     gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
-#endif
     gen_addr_add(ctx, addr, addr, 4);
     gen_qemu_st32(ctx, cpu_gpr[rS(ctx->opcode)], addr);
 }
@@ -9118,19 +9134,10 @@ static inline void gen_op_evstdw(DisasContext *ctx, TCGv addr)
 static inline void gen_op_evstdh(DisasContext *ctx, TCGv addr)
 {
     TCGv t0 = tcg_temp_new();
-#if defined(TARGET_PPC64)
-    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 48);
-#else
     tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
-#endif
     gen_qemu_st16(ctx, t0, addr);
     gen_addr_add(ctx, addr, addr, 2);
-#if defined(TARGET_PPC64)
-    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
-    gen_qemu_st16(ctx, t0, addr);
-#else
     gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
-#endif
     gen_addr_add(ctx, addr, addr, 2);
     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
     gen_qemu_st16(ctx, t0, addr);
@@ -9142,11 +9149,7 @@ static inline void gen_op_evstdh(DisasContext *ctx, TCGv addr)
 static inline void gen_op_evstwhe(DisasContext *ctx, TCGv addr)
 {
     TCGv t0 = tcg_temp_new();
-#if defined(TARGET_PPC64)
-    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 48);
-#else
     tcg_gen_shri_tl(t0, cpu_gprh[rS(ctx->opcode)], 16);
-#endif
     gen_qemu_st16(ctx, t0, addr);
     gen_addr_add(ctx, addr, addr, 2);
     tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 16);
@@ -9156,28 +9159,14 @@ static inline void gen_op_evstwhe(DisasContext *ctx, TCGv addr)
 
 static inline void gen_op_evstwho(DisasContext *ctx, TCGv addr)
 {
-#if defined(TARGET_PPC64)
-    TCGv t0 = tcg_temp_new();
-    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
-    gen_qemu_st16(ctx, t0, addr);
-    tcg_temp_free(t0);
-#else
     gen_qemu_st16(ctx, cpu_gprh[rS(ctx->opcode)], addr);
-#endif
     gen_addr_add(ctx, addr, addr, 2);
     gen_qemu_st16(ctx, cpu_gpr[rS(ctx->opcode)], addr);
 }
 
 static inline void gen_op_evstwwe(DisasContext *ctx, TCGv addr)
 {
-#if defined(TARGET_PPC64)
-    TCGv t0 = tcg_temp_new();
-    tcg_gen_shri_tl(t0, cpu_gpr[rS(ctx->opcode)], 32);
-    gen_qemu_st32(ctx, t0, addr);
-    tcg_temp_free(t0);
-#else
     gen_qemu_st32(ctx, cpu_gprh[rS(ctx->opcode)], addr);
-#endif
 }
 
 static inline void gen_op_evstwwo(DisasContext *ctx, TCGv addr)
@@ -9297,133 +9286,36 @@ GEN_SPE(speundef,       evmwsmfan,     0x0D, 0x17, 0xFFFFFFFF, 0x00000000, PPC_S
 #endif
 
 /***                      SPE floating-point extension                     ***/
-#if defined(TARGET_PPC64)
 #define GEN_SPEFPUOP_CONV_32_32(name)                                         \
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
-    TCGv_i32 t0;                                                              \
-    TCGv t1;                                                                  \
-    t0 = tcg_temp_new_i32();                                                  \
+    TCGv_i32 t0 = tcg_temp_new_i32();                                         \
     tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
     gen_helper_##name(t0, cpu_env, t0);                                       \
-    t1 = tcg_temp_new();                                                      \
-    tcg_gen_extu_i32_tl(t1, t0);                                              \
+    tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);                        \
     tcg_temp_free_i32(t0);                                                    \
-    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
-                    0xFFFFFFFF00000000ULL);                                   \
-    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1);    \
-    tcg_temp_free(t1);                                                        \
-}
-#define GEN_SPEFPUOP_CONV_32_64(name)                                         \
-static inline void gen_##name(DisasContext *ctx)                              \
-{                                                                             \
-    TCGv_i32 t0;                                                              \
-    TCGv t1;                                                                  \
-    t0 = tcg_temp_new_i32();                                                  \
-    gen_helper_##name(t0, cpu_env, cpu_gpr[rB(ctx->opcode)]);                 \
-    t1 = tcg_temp_new();                                                      \
-    tcg_gen_extu_i32_tl(t1, t0);                                              \
-    tcg_temp_free_i32(t0);                                                    \
-    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
-                    0xFFFFFFFF00000000ULL);                                   \
-    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t1);    \
-    tcg_temp_free(t1);                                                        \
-}
-#define GEN_SPEFPUOP_CONV_64_32(name)                                         \
-static inline void gen_##name(DisasContext *ctx)                              \
-{                                                                             \
-    TCGv_i32 t0 = tcg_temp_new_i32();                                         \
-    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rB(ctx->opcode)]);                       \
-    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);                 \
-    tcg_temp_free_i32(t0);                                                    \
-}
-#define GEN_SPEFPUOP_CONV_64_64(name)                                         \
-static inline void gen_##name(DisasContext *ctx)                              \
-{                                                                             \
-    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env,                      \
-                      cpu_gpr[rB(ctx->opcode)]);                              \
-}
-#define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
-static inline void gen_##name(DisasContext *ctx)                              \
-{                                                                             \
-    TCGv_i32 t0, t1;                                                          \
-    TCGv_i64 t2;                                                              \
-    if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
-        return;                                                               \
-    }                                                                         \
-    t0 = tcg_temp_new_i32();                                                  \
-    t1 = tcg_temp_new_i32();                                                  \
-    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
-    tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
-    gen_helper_##name(t0, cpu_env, t0, t1);                                   \
-    tcg_temp_free_i32(t1);                                                    \
-    t2 = tcg_temp_new();                                                      \
-    tcg_gen_extu_i32_tl(t2, t0);                                              \
-    tcg_temp_free_i32(t0);                                                    \
-    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)],       \
-                    0xFFFFFFFF00000000ULL);                                   \
-    tcg_gen_or_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rD(ctx->opcode)], t2);    \
-    tcg_temp_free(t2);                                                        \
-}
-#define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
-static inline void gen_##name(DisasContext *ctx)                              \
-{                                                                             \
-    if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
-        return;                                                               \
-    }                                                                         \
-    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env,                      \
-                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
-}
-#define GEN_SPEFPUOP_COMP_32(name)                                            \
-static inline void gen_##name(DisasContext *ctx)                              \
-{                                                                             \
-    TCGv_i32 t0, t1;                                                          \
-    if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
-        return;                                                               \
-    }                                                                         \
-    t0 = tcg_temp_new_i32();                                                  \
-    t1 = tcg_temp_new_i32();                                                  \
-    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
-    tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
-    gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env, t0, t1);           \
-    tcg_temp_free_i32(t0);                                                    \
-    tcg_temp_free_i32(t1);                                                    \
-}
-#define GEN_SPEFPUOP_COMP_64(name)                                            \
-static inline void gen_##name(DisasContext *ctx)                              \
-{                                                                             \
-    if (unlikely(!ctx->spe_enabled)) {                                        \
-        gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
-        return;                                                               \
-    }                                                                         \
-    gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env,                    \
-                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
-}
-#else
-#define GEN_SPEFPUOP_CONV_32_32(name)                                         \
-static inline void gen_##name(DisasContext *ctx)                              \
-{                                                                             \
-    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env,                      \
-                      cpu_gpr[rB(ctx->opcode)]);                              \
 }
 #define GEN_SPEFPUOP_CONV_32_64(name)                                         \
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
+    TCGv_i32 t1 = tcg_temp_new_i32();                                         \
     gen_load_gpr64(t0, rB(ctx->opcode));                                      \
-    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env, t0);                 \
+    gen_helper_##name(t1, cpu_env, t0);                                       \
+    tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t1);                        \
     tcg_temp_free_i64(t0);                                                    \
+    tcg_temp_free_i32(t1);                                                    \
 }
 #define GEN_SPEFPUOP_CONV_64_32(name)                                         \
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
     TCGv_i64 t0 = tcg_temp_new_i64();                                         \
-    gen_helper_##name(t0, cpu_env, cpu_gpr[rB(ctx->opcode)]);                 \
+    TCGv_i32 t1 = tcg_temp_new_i32();                                         \
+    tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
+    gen_helper_##name(t0, cpu_env, t1);                                       \
     gen_store_gpr64(rD(ctx->opcode), t0);                                     \
     tcg_temp_free_i64(t0);                                                    \
+    tcg_temp_free_i32(t1);                                                    \
 }
 #define GEN_SPEFPUOP_CONV_64_64(name)                                         \
 static inline void gen_##name(DisasContext *ctx)                              \
@@ -9437,12 +9329,20 @@ static inline void gen_##name(DisasContext *ctx)                              \
 #define GEN_SPEFPUOP_ARITH2_32_32(name)                                       \
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
+    TCGv_i32 t0, t1;                                                          \
     if (unlikely(!ctx->spe_enabled)) {                                        \
         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
-    gen_helper_##name(cpu_gpr[rD(ctx->opcode)], cpu_env,                      \
-                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
+    t0 = tcg_temp_new_i32();                                                  \
+    t1 = tcg_temp_new_i32();                                                  \
+    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
+    tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
+    gen_helper_##name(t0, cpu_env, t0, t1);                                   \
+    tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);                        \
+                                                                              \
+    tcg_temp_free_i32(t0);                                                    \
+    tcg_temp_free_i32(t1);                                                    \
 }
 #define GEN_SPEFPUOP_ARITH2_64_64(name)                                       \
 static inline void gen_##name(DisasContext *ctx)                              \
@@ -9464,12 +9364,20 @@ static inline void gen_##name(DisasContext *ctx)                              \
 #define GEN_SPEFPUOP_COMP_32(name)                                            \
 static inline void gen_##name(DisasContext *ctx)                              \
 {                                                                             \
+    TCGv_i32 t0, t1;                                                          \
     if (unlikely(!ctx->spe_enabled)) {                                        \
         gen_exception(ctx, POWERPC_EXCP_SPEU);                                \
         return;                                                               \
     }                                                                         \
-    gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env,                    \
-                      cpu_gpr[rA(ctx->opcode)], cpu_gpr[rB(ctx->opcode)]);    \
+    t0 = tcg_temp_new_i32();                                                  \
+    t1 = tcg_temp_new_i32();                                                  \
+                                                                              \
+    tcg_gen_trunc_tl_i32(t0, cpu_gpr[rA(ctx->opcode)]);                       \
+    tcg_gen_trunc_tl_i32(t1, cpu_gpr[rB(ctx->opcode)]);                       \
+    gen_helper_##name(cpu_crf[crfD(ctx->opcode)], cpu_env, t0, t1);           \
+                                                                              \
+    tcg_temp_free_i32(t0);                                                    \
+    tcg_temp_free_i32(t1);                                                    \
 }
 #define GEN_SPEFPUOP_COMP_64(name)                                            \
 static inline void gen_##name(DisasContext *ctx)                              \
@@ -9487,7 +9395,6 @@ static inline void gen_##name(DisasContext *ctx)                              \
     tcg_temp_free_i64(t0);                                                    \
     tcg_temp_free_i64(t1);                                                    \
 }
-#endif
 
 /* Single precision floating-point vectors operations */
 /* Arithmetic */
@@ -9501,12 +9408,10 @@ static inline void gen_evfsabs(DisasContext *ctx)
         gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
-#if defined(TARGET_PPC64)
-    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000080000000LL);
-#else
-    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x80000000);
-    tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000);
-#endif
+    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
+                    ~0x80000000);
+    tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
+                    ~0x80000000);
 }
 static inline void gen_evfsnabs(DisasContext *ctx)
 {
@@ -9514,12 +9419,10 @@ static inline void gen_evfsnabs(DisasContext *ctx)
         gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
-#if defined(TARGET_PPC64)
-    tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL);
-#else
-    tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
-    tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
-#endif
+    tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
+                   0x80000000);
+    tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
+                   0x80000000);
 }
 static inline void gen_evfsneg(DisasContext *ctx)
 {
@@ -9527,12 +9430,10 @@ static inline void gen_evfsneg(DisasContext *ctx)
         gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
-#if defined(TARGET_PPC64)
-    tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000080000000LL);
-#else
-    tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x80000000);
-    tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
-#endif
+    tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)],
+                    0x80000000);
+    tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
+                    0x80000000);
 }
 
 /* Conversion */
@@ -9651,12 +9552,9 @@ static inline void gen_efdabs(DisasContext *ctx)
         gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
-#if defined(TARGET_PPC64)
-    tcg_gen_andi_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], ~0x8000000000000000LL);
-#else
     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
-    tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], ~0x80000000);
-#endif
+    tcg_gen_andi_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
+                    ~0x80000000);
 }
 static inline void gen_efdnabs(DisasContext *ctx)
 {
@@ -9664,12 +9562,9 @@ static inline void gen_efdnabs(DisasContext *ctx)
         gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
-#if defined(TARGET_PPC64)
-    tcg_gen_ori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL);
-#else
     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
-    tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
-#endif
+    tcg_gen_ori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
+                   0x80000000);
 }
 static inline void gen_efdneg(DisasContext *ctx)
 {
@@ -9677,12 +9572,9 @@ static inline void gen_efdneg(DisasContext *ctx)
         gen_exception(ctx, POWERPC_EXCP_SPEU);
         return;
     }
-#if defined(TARGET_PPC64)
-    tcg_gen_xori_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)], 0x8000000000000000LL);
-#else
     tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
-    tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)], 0x80000000);
-#endif
+    tcg_gen_xori_tl(cpu_gprh[rD(ctx->opcode)], cpu_gprh[rA(ctx->opcode)],
+                    0x80000000);
 }
 
 /* Conversion */
@@ -9760,7 +9652,7 @@ GEN_HANDLER(ori, 0x18, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
 GEN_HANDLER(oris, 0x19, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
 GEN_HANDLER(xori, 0x1A, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
 GEN_HANDLER(xoris, 0x1B, 0xFF, 0xFF, 0x00000000, PPC_INTEGER),
-GEN_HANDLER(popcntb, 0x1F, 0x03, 0x03, 0x0000F801, PPC_POPCNTB),
+GEN_HANDLER(popcntb, 0x1F, 0x1A, 0x03, 0x0000F801, PPC_POPCNTB),
 GEN_HANDLER(popcntw, 0x1F, 0x1A, 0x0b, 0x0000F801, PPC_POPCNTWD),
 GEN_HANDLER_E(prtyw, 0x1F, 0x1A, 0x04, 0x0000F801, PPC_NONE, PPC2_ISA205),
 #if defined(TARGET_PPC64)
@@ -9862,6 +9754,7 @@ GEN_HANDLER(dcbi, 0x1F, 0x16, 0x0E, 0x03E00001, PPC_CACHE),
 GEN_HANDLER(dcbst, 0x1F, 0x16, 0x01, 0x03E00001, PPC_CACHE),
 GEN_HANDLER(dcbt, 0x1F, 0x16, 0x08, 0x00000001, PPC_CACHE),
 GEN_HANDLER(dcbtst, 0x1F, 0x16, 0x07, 0x00000001, PPC_CACHE),
+GEN_HANDLER_E(dcbtls, 0x1F, 0x06, 0x05, 0x02000001, PPC_BOOKE, PPC2_BOOKE206),
 GEN_HANDLER(dcbz, 0x1F, 0x16, 0x1F, 0x03C00001, PPC_CACHE_DCBZ),
 GEN_HANDLER(dst, 0x1F, 0x16, 0x0A, 0x01800001, PPC_ALTIVEC),
 GEN_HANDLER(dstst, 0x1F, 0x16, 0x0B, 0x02000001, PPC_ALTIVEC),
@@ -9997,7 +9890,6 @@ GEN_HANDLER(lvsl, 0x1f, 0x06, 0x00, 0x00000001, PPC_ALTIVEC),
 GEN_HANDLER(lvsr, 0x1f, 0x06, 0x01, 0x00000001, PPC_ALTIVEC),
 GEN_HANDLER(mfvscr, 0x04, 0x2, 0x18, 0x001ff800, PPC_ALTIVEC),
 GEN_HANDLER(mtvscr, 0x04, 0x2, 0x19, 0x03ff0000, PPC_ALTIVEC),
-GEN_HANDLER(vsldoi, 0x04, 0x16, 0xFF, 0x00000400, PPC_ALTIVEC),
 GEN_HANDLER(vmladduhm, 0x04, 0x11, 0xFF, 0x00000000, PPC_ALTIVEC),
 GEN_HANDLER2(evsel0, "evsel", 0x04, 0x1c, 0x09, 0x00000000, PPC_SPE),
 GEN_HANDLER2(evsel1, "evsel", 0x04, 0x1d, 0x09, 0x00000000, PPC_SPE),
@@ -10410,8 +10302,8 @@ GEN_VXFORM(vaddubm, 0, 0),
 GEN_VXFORM(vadduhm, 0, 1),
 GEN_VXFORM(vadduwm, 0, 2),
 GEN_VXFORM_207(vaddudm, 0, 3),
-GEN_VXFORM(vsububm, 0, 16),
-GEN_VXFORM(vsubuhm, 0, 17),
+GEN_VXFORM_DUAL(vsububm, bcdadd, 0, 16, PPC_ALTIVEC, PPC_NONE),
+GEN_VXFORM_DUAL(vsubuhm, bcdsub, 0, 17, PPC_ALTIVEC, PPC_NONE),
 GEN_VXFORM(vsubuwm, 0, 18),
 GEN_VXFORM_207(vsubudm, 0, 19),
 GEN_VXFORM(vmaxub, 1, 0),
@@ -10459,12 +10351,15 @@ GEN_VXFORM_207(vmulesw, 4, 14),
 GEN_VXFORM(vslb, 2, 4),
 GEN_VXFORM(vslh, 2, 5),
 GEN_VXFORM(vslw, 2, 6),
+GEN_VXFORM_207(vsld, 2, 23),
 GEN_VXFORM(vsrb, 2, 8),
 GEN_VXFORM(vsrh, 2, 9),
 GEN_VXFORM(vsrw, 2, 10),
+GEN_VXFORM_207(vsrd, 2, 27),
 GEN_VXFORM(vsrab, 2, 12),
 GEN_VXFORM(vsrah, 2, 13),
 GEN_VXFORM(vsraw, 2, 14),
+GEN_VXFORM_207(vsrad, 2, 15),
 GEN_VXFORM(vslo, 6, 16),
 GEN_VXFORM(vsro, 6, 17),
 GEN_VXFORM(vaddcuw, 0, 6),
@@ -10475,15 +10370,22 @@ GEN_VXFORM(vadduws, 0, 10),
 GEN_VXFORM(vaddsbs, 0, 12),
 GEN_VXFORM(vaddshs, 0, 13),
 GEN_VXFORM(vaddsws, 0, 14),
-GEN_VXFORM(vsububs, 0, 24),
-GEN_VXFORM(vsubuhs, 0, 25),
+GEN_VXFORM_DUAL(vsububs, bcdadd, 0, 24, PPC_ALTIVEC, PPC_NONE),
+GEN_VXFORM_DUAL(vsubuhs, bcdsub, 0, 25, PPC_ALTIVEC, PPC_NONE),
 GEN_VXFORM(vsubuws, 0, 26),
 GEN_VXFORM(vsubsbs, 0, 28),
 GEN_VXFORM(vsubshs, 0, 29),
 GEN_VXFORM(vsubsws, 0, 30),
+GEN_VXFORM_207(vadduqm, 0, 4),
+GEN_VXFORM_207(vaddcuq, 0, 5),
+GEN_VXFORM_DUAL(vaddeuqm, vaddecuq, 30, 0xFF, PPC_NONE, PPC2_ALTIVEC_207),
+GEN_VXFORM_207(vsubuqm, 0, 20),
+GEN_VXFORM_207(vsubcuq, 0, 21),
+GEN_VXFORM_DUAL(vsubeuqm, vsubecuq, 31, 0xFF, PPC_NONE, PPC2_ALTIVEC_207),
 GEN_VXFORM(vrlb, 2, 0),
 GEN_VXFORM(vrlh, 2, 1),
 GEN_VXFORM(vrlw, 2, 2),
+GEN_VXFORM_207(vrld, 2, 3),
 GEN_VXFORM(vsl, 2, 7),
 GEN_VXFORM(vsr, 2, 11),
 GEN_VXFORM(vpkuhum, 7, 0),
@@ -10525,10 +10427,10 @@ GEN_VXRFORM(vcmpgtsw, 3, 14)
 GEN_VXRFORM(vcmpgtub, 3, 8)
 GEN_VXRFORM(vcmpgtuh, 3, 9)
 GEN_VXRFORM(vcmpgtuw, 3, 10)
-GEN_VXRFORM(vcmpeqfp, 3, 3)
+GEN_VXRFORM_DUAL(vcmpeqfp, vcmpequd, 3, 3, PPC_ALTIVEC, PPC_NONE)
 GEN_VXRFORM(vcmpgefp, 3, 7)
-GEN_VXRFORM(vcmpgtfp, 3, 11)
-GEN_VXRFORM(vcmpbfp, 3, 15)
+GEN_VXRFORM_DUAL(vcmpgtfp, vcmpgtud, 3, 11, PPC_ALTIVEC, PPC_NONE)
+GEN_VXRFORM_DUAL(vcmpbfp, vcmpgtsd, 3, 15, PPC_ALTIVEC, PPC_NONE)
 
 #undef GEN_VXFORM_SIMM
 #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
@@ -10583,6 +10485,22 @@ GEN_VXFORM_DUAL(vclzh, vpopcnth, 1, 29, PPC_NONE, PPC2_ALTIVEC_207),
 GEN_VXFORM_DUAL(vclzw, vpopcntw, 1, 30, PPC_NONE, PPC2_ALTIVEC_207),
 GEN_VXFORM_DUAL(vclzd, vpopcntd, 1, 31, PPC_NONE, PPC2_ALTIVEC_207),
 
+GEN_VXFORM_207(vbpermq, 6, 21),
+GEN_VXFORM_207(vgbbd, 6, 20),
+GEN_VXFORM_207(vpmsumb, 4, 16),
+GEN_VXFORM_207(vpmsumh, 4, 17),
+GEN_VXFORM_207(vpmsumw, 4, 18),
+GEN_VXFORM_207(vpmsumd, 4, 19),
+
+GEN_VXFORM_207(vsbox, 4, 23),
+
+GEN_VXFORM_DUAL(vcipher, vcipherlast, 4, 20, PPC_NONE, PPC2_ALTIVEC_207),
+GEN_VXFORM_DUAL(vncipher, vncipherlast, 4, 21, PPC_NONE, PPC2_ALTIVEC_207),
+
+GEN_VXFORM_207(vshasigmaw, 1, 26),
+GEN_VXFORM_207(vshasigmad, 1, 27),
+
+GEN_VXFORM_DUAL(vsldoi, vpermxor, 22, 0xFF, PPC_ALTIVEC, PPC_NONE),
 
 GEN_HANDLER_E(lxsdx, 0x1F, 0x0C, 0x12, 0, PPC_NONE, PPC2_VSX),
 GEN_HANDLER_E(lxsiwax, 0x1F, 0x0C, 0x02, 0, PPC_NONE, PPC2_VSX207),
@@ -10854,6 +10772,166 @@ GEN_XXSEL_ROW(0x1F)
 
 GEN_XX3FORM_DM(xxpermdi, 0x08, 0x01),
 
+#undef GEN_DFP_T_A_B_Rc
+#undef GEN_DFP_BF_A_B
+#undef GEN_DFP_BF_A_DCM
+#undef GEN_DFP_T_B_U32_U32_Rc
+#undef GEN_DFP_T_A_B_I32_Rc
+#undef GEN_DFP_T_B_Rc
+#undef GEN_DFP_T_FPR_I32_Rc
+
+#define _GEN_DFP_LONG(name, op1, op2, mask) \
+GEN_HANDLER_E(name, 0x3B, op1, op2, mask, PPC_NONE, PPC2_DFP)
+
+#define _GEN_DFP_LONGx2(name, op1, op2, mask) \
+GEN_HANDLER_E(name, 0x3B, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \
+GEN_HANDLER_E(name, 0x3B, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP)
+
+#define _GEN_DFP_LONGx4(name, op1, op2, mask) \
+GEN_HANDLER_E(name, 0x3B, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \
+GEN_HANDLER_E(name, 0x3B, op1, 0x08 | op2, mask, PPC_NONE, PPC2_DFP), \
+GEN_HANDLER_E(name, 0x3B, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP), \
+GEN_HANDLER_E(name, 0x3B, op1, 0x18 | op2, mask, PPC_NONE, PPC2_DFP)
+
+#define _GEN_DFP_QUAD(name, op1, op2, mask) \
+GEN_HANDLER_E(name, 0x3F, op1, op2, mask, PPC_NONE, PPC2_DFP)
+
+#define _GEN_DFP_QUADx2(name, op1, op2, mask) \
+GEN_HANDLER_E(name, 0x3F, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \
+GEN_HANDLER_E(name, 0x3F, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP)
+
+#define _GEN_DFP_QUADx4(name, op1, op2, mask)                         \
+GEN_HANDLER_E(name, 0x3F, op1, 0x00 | op2, mask, PPC_NONE, PPC2_DFP), \
+GEN_HANDLER_E(name, 0x3F, op1, 0x08 | op2, mask, PPC_NONE, PPC2_DFP), \
+GEN_HANDLER_E(name, 0x3F, op1, 0x10 | op2, mask, PPC_NONE, PPC2_DFP), \
+GEN_HANDLER_E(name, 0x3F, op1, 0x18 | op2, mask, PPC_NONE, PPC2_DFP)
+
+#define GEN_DFP_T_A_B_Rc(name, op1, op2) \
+_GEN_DFP_LONG(name, op1, op2, 0x00000000)
+
+#define GEN_DFP_Tp_Ap_Bp_Rc(name, op1, op2) \
+_GEN_DFP_QUAD(name, op1, op2, 0x00210800)
+
+#define GEN_DFP_Tp_A_Bp_Rc(name, op1, op2) \
+_GEN_DFP_QUAD(name, op1, op2, 0x00200800)
+
+#define GEN_DFP_T_B_Rc(name, op1, op2) \
+_GEN_DFP_LONG(name, op1, op2, 0x001F0000)
+
+#define GEN_DFP_Tp_Bp_Rc(name, op1, op2) \
+_GEN_DFP_QUAD(name, op1, op2, 0x003F0800)
+
+#define GEN_DFP_Tp_B_Rc(name, op1, op2) \
+_GEN_DFP_QUAD(name, op1, op2, 0x003F0000)
+
+#define GEN_DFP_T_Bp_Rc(name, op1, op2) \
+_GEN_DFP_QUAD(name, op1, op2, 0x001F0800)
+
+#define GEN_DFP_BF_A_B(name, op1, op2) \
+_GEN_DFP_LONG(name, op1, op2, 0x00000001)
+
+#define GEN_DFP_BF_Ap_Bp(name, op1, op2) \
+_GEN_DFP_QUAD(name, op1, op2, 0x00610801)
+
+#define GEN_DFP_BF_A_Bp(name, op1, op2) \
+_GEN_DFP_QUAD(name, op1, op2, 0x00600801)
+
+#define GEN_DFP_BF_A_DCM(name, op1, op2) \
+_GEN_DFP_LONGx2(name, op1, op2, 0x00600001)
+
+#define GEN_DFP_BF_Ap_DCM(name, op1, op2) \
+_GEN_DFP_QUADx2(name, op1, op2, 0x00610001)
+
+#define GEN_DFP_T_A_B_RMC_Rc(name, op1, op2) \
+_GEN_DFP_LONGx4(name, op1, op2, 0x00000000)
+
+#define GEN_DFP_Tp_Ap_Bp_RMC_Rc(name, op1, op2) \
+_GEN_DFP_QUADx4(name, op1, op2, 0x02010800)
+
+#define GEN_DFP_Tp_A_Bp_RMC_Rc(name, op1, op2) \
+_GEN_DFP_QUADx4(name, op1, op2, 0x02000800)
+
+#define GEN_DFP_TE_T_B_RMC_Rc(name, op1, op2) \
+_GEN_DFP_LONGx4(name, op1, op2, 0x00000000)
+
+#define GEN_DFP_TE_Tp_Bp_RMC_Rc(name, op1, op2) \
+_GEN_DFP_QUADx4(name, op1, op2, 0x00200800)
+
+#define GEN_DFP_R_T_B_RMC_Rc(name, op1, op2) \
+_GEN_DFP_LONGx4(name, op1, op2, 0x001E0000)
+
+#define GEN_DFP_R_Tp_Bp_RMC_Rc(name, op1, op2) \
+_GEN_DFP_QUADx4(name, op1, op2, 0x003E0800)
+
+#define GEN_DFP_SP_T_B_Rc(name, op1, op2) \
+_GEN_DFP_LONG(name, op1, op2, 0x00070000)
+
+#define GEN_DFP_SP_Tp_Bp_Rc(name, op1, op2) \
+_GEN_DFP_QUAD(name, op1, op2, 0x00270800)
+
+#define GEN_DFP_S_T_B_Rc(name, op1, op2) \
+_GEN_DFP_LONG(name, op1, op2, 0x000F0000)
+
+#define GEN_DFP_S_Tp_Bp_Rc(name, op1, op2) \
+_GEN_DFP_QUAD(name, op1, op2, 0x002F0800)
+
+#define GEN_DFP_T_A_SH_Rc(name, op1, op2) \
+_GEN_DFP_LONGx2(name, op1, op2, 0x00000000)
+
+#define GEN_DFP_Tp_Ap_SH_Rc(name, op1, op2) \
+_GEN_DFP_QUADx2(name, op1, op2, 0x00210000)
+
+GEN_DFP_T_A_B_Rc(dadd, 0x02, 0x00),
+GEN_DFP_Tp_Ap_Bp_Rc(daddq, 0x02, 0x00),
+GEN_DFP_T_A_B_Rc(dsub, 0x02, 0x10),
+GEN_DFP_Tp_Ap_Bp_Rc(dsubq, 0x02, 0x10),
+GEN_DFP_T_A_B_Rc(dmul, 0x02, 0x01),
+GEN_DFP_Tp_Ap_Bp_Rc(dmulq, 0x02, 0x01),
+GEN_DFP_T_A_B_Rc(ddiv, 0x02, 0x11),
+GEN_DFP_Tp_Ap_Bp_Rc(ddivq, 0x02, 0x11),
+GEN_DFP_BF_A_B(dcmpu, 0x02, 0x14),
+GEN_DFP_BF_Ap_Bp(dcmpuq, 0x02, 0x14),
+GEN_DFP_BF_A_B(dcmpo, 0x02, 0x04),
+GEN_DFP_BF_Ap_Bp(dcmpoq, 0x02, 0x04),
+GEN_DFP_BF_A_DCM(dtstdc, 0x02, 0x06),
+GEN_DFP_BF_Ap_DCM(dtstdcq, 0x02, 0x06),
+GEN_DFP_BF_A_DCM(dtstdg, 0x02, 0x07),
+GEN_DFP_BF_Ap_DCM(dtstdgq, 0x02, 0x07),
+GEN_DFP_BF_A_B(dtstex, 0x02, 0x05),
+GEN_DFP_BF_Ap_Bp(dtstexq, 0x02, 0x05),
+GEN_DFP_BF_A_B(dtstsf, 0x02, 0x15),
+GEN_DFP_BF_A_Bp(dtstsfq, 0x02, 0x15),
+GEN_DFP_TE_T_B_RMC_Rc(dquai, 0x03, 0x02),
+GEN_DFP_TE_Tp_Bp_RMC_Rc(dquaiq, 0x03, 0x02),
+GEN_DFP_T_A_B_RMC_Rc(dqua, 0x03, 0x00),
+GEN_DFP_Tp_Ap_Bp_RMC_Rc(dquaq, 0x03, 0x00),
+GEN_DFP_T_A_B_RMC_Rc(drrnd, 0x03, 0x01),
+GEN_DFP_Tp_A_Bp_RMC_Rc(drrndq, 0x03, 0x01),
+GEN_DFP_R_T_B_RMC_Rc(drintx, 0x03, 0x03),
+GEN_DFP_R_Tp_Bp_RMC_Rc(drintxq, 0x03, 0x03),
+GEN_DFP_R_T_B_RMC_Rc(drintn, 0x03, 0x07),
+GEN_DFP_R_Tp_Bp_RMC_Rc(drintnq, 0x03, 0x07),
+GEN_DFP_T_B_Rc(dctdp, 0x02, 0x08),
+GEN_DFP_Tp_B_Rc(dctqpq, 0x02, 0x08),
+GEN_DFP_T_B_Rc(drsp, 0x02, 0x18),
+GEN_DFP_Tp_Bp_Rc(drdpq, 0x02, 0x18),
+GEN_DFP_T_B_Rc(dcffix, 0x02, 0x19),
+GEN_DFP_Tp_B_Rc(dcffixq, 0x02, 0x19),
+GEN_DFP_T_B_Rc(dctfix, 0x02, 0x09),
+GEN_DFP_T_Bp_Rc(dctfixq, 0x02, 0x09),
+GEN_DFP_SP_T_B_Rc(ddedpd, 0x02, 0x0a),
+GEN_DFP_SP_Tp_Bp_Rc(ddedpdq, 0x02, 0x0a),
+GEN_DFP_S_T_B_Rc(denbcd, 0x02, 0x1a),
+GEN_DFP_S_Tp_Bp_Rc(denbcdq, 0x02, 0x1a),
+GEN_DFP_T_B_Rc(dxex, 0x02, 0x0b),
+GEN_DFP_T_Bp_Rc(dxexq, 0x02, 0x0b),
+GEN_DFP_T_A_B_Rc(diex, 0x02, 0x1b),
+GEN_DFP_Tp_A_Bp_Rc(diexq, 0x02, 0x1b),
+GEN_DFP_T_A_SH_Rc(dscli, 0x02, 0x02),
+GEN_DFP_Tp_Ap_SH_Rc(dscliq, 0x02, 0x02),
+GEN_DFP_T_A_SH_Rc(dscri, 0x02, 0x03),
+GEN_DFP_Tp_Ap_SH_Rc(dscriq, 0x02, 0x03),
+
 #undef GEN_SPE
 #define GEN_SPE(name0, name1, opc2, opc3, inval0, inval1, type) \
     GEN_OPCODE_DUAL(name0##_##name1, 0x04, opc2, opc3, inval0, inval1, type, PPC_NONE)
@@ -11192,6 +11270,7 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
     ctx.insns_flags2 = env->insns_flags2;
     ctx.access_type = -1;
     ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
+    ctx.default_tcg_memop_mask = ctx.le_mode ? MO_LE : MO_BE;
 #if defined(TARGET_PPC64)
     ctx.sf_mode = msr_is_64bit(env, env->msr);
     ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR);
@@ -11229,11 +11308,12 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
         max_insns = CF_COUNT_MASK;
 
     gen_tb_start();
+    tcg_clear_temp_count();
     /* Set env in case of segfault during code fetch */
     while (ctx.exception == POWERPC_EXCP_NONE
             && tcg_ctx.gen_opc_ptr < gen_opc_end) {
-        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
-            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
+        if (unlikely(!QTAILQ_EMPTY(&cs->breakpoints))) {
+            QTAILQ_FOREACH(bp, &cs->breakpoints, entry) {
                 if (bp->pc == ctx.nip) {
                     gen_debug_exception(ctxp);
                     break;
@@ -11256,7 +11336,7 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
                   ctx.nip, ctx.mem_idx, (int)msr_ir);
         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
             gen_io_start();
-        if (unlikely(ctx.le_mode)) {
+        if (unlikely(need_byteswap(&ctx))) {
             ctx.opcode = bswap32(cpu_ldl_code(env, ctx.nip));
         } else {
             ctx.opcode = cpu_ldl_code(env, ctx.nip);
@@ -11328,6 +11408,12 @@ static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
              */
             break;
         }
+        if (tcg_check_temp_count()) {
+            fprintf(stderr, "Opcode %02x %02x %02x (%08x) leaked temporaries\n",
+                    opc1(ctx.opcode), opc2(ctx.opcode), opc3(ctx.opcode),
+                    ctx.opcode);
+            exit(1);
+        }
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();
This page took 0.09416 seconds and 4 git commands to generate.