Add detection of pthread library name
[qemu] / target-ppc / translate.c
index af83b19..2cb90f0 100644 (file)
@@ -28,6 +28,7 @@
 #include "disas.h"
 #include "tcg-op.h"
 #include "qemu-common.h"
+#include "host-utils.h"
 
 #include "helper.h"
 #define GEN_HELPER 1
@@ -38,7 +39,6 @@
 #define GDBSTUB_SINGLE_STEP 0x4
 
 /* Include definitions for instructions classes and implementations flags */
-//#define DO_SINGLE_STEP
 //#define PPC_DEBUG_DISAS
 //#define DO_PPC_STATISTICS
 
@@ -81,6 +81,7 @@ void ppc_translate_init(void)
 {
     int i;
     char* p;
+    size_t cpu_reg_names_size;
     static int done_init = 0;
 
     if (done_init)
@@ -89,32 +90,37 @@ void ppc_translate_init(void)
     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
 
     p = cpu_reg_names;
+    cpu_reg_names_size = sizeof(cpu_reg_names);
 
     for (i = 0; i < 8; i++) {
-        sprintf(p, "crf%d", i);
+        snprintf(p, cpu_reg_names_size, "crf%d", i);
         cpu_crf[i] = tcg_global_mem_new_i32(TCG_AREG0,
                                             offsetof(CPUState, crf[i]), p);
         p += 5;
+        cpu_reg_names_size -= 5;
     }
 
     for (i = 0; i < 32; i++) {
-        sprintf(p, "r%d", i);
+        snprintf(p, cpu_reg_names_size, "r%d", i);
         cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
                                         offsetof(CPUState, gpr[i]), p);
         p += (i < 10) ? 3 : 4;
+        cpu_reg_names_size -= (i < 10) ? 3 : 4;
 #if !defined(TARGET_PPC64)
-        sprintf(p, "r%dH", i);
+        snprintf(p, cpu_reg_names_size, "r%dH", i);
         cpu_gprh[i] = tcg_global_mem_new_i32(TCG_AREG0,
                                              offsetof(CPUState, gprh[i]), p);
         p += (i < 10) ? 4 : 5;
+        cpu_reg_names_size -= (i < 10) ? 4 : 5;
 #endif
 
-        sprintf(p, "fp%d", i);
+        snprintf(p, cpu_reg_names_size, "fp%d", i);
         cpu_fpr[i] = tcg_global_mem_new_i64(TCG_AREG0,
                                             offsetof(CPUState, fpr[i]), p);
         p += (i < 10) ? 4 : 5;
+        cpu_reg_names_size -= (i < 10) ? 4 : 5;
 
-        sprintf(p, "avr%dH", i);
+        snprintf(p, cpu_reg_names_size, "avr%dH", i);
 #ifdef WORDS_BIGENDIAN
         cpu_avrh[i] = tcg_global_mem_new_i64(TCG_AREG0,
                                              offsetof(CPUState, avr[i].u64[0]), p);
@@ -123,8 +129,9 @@ void ppc_translate_init(void)
                                              offsetof(CPUState, avr[i].u64[1]), p);
 #endif
         p += (i < 10) ? 6 : 7;
+        cpu_reg_names_size -= (i < 10) ? 6 : 7;
 
-        sprintf(p, "avr%dL", i);
+        snprintf(p, cpu_reg_names_size, "avr%dL", i);
 #ifdef WORDS_BIGENDIAN
         cpu_avrl[i] = tcg_global_mem_new_i64(TCG_AREG0,
                                              offsetof(CPUState, avr[i].u64[1]), p);
@@ -133,6 +140,7 @@ void ppc_translate_init(void)
                                              offsetof(CPUState, avr[i].u64[0]), p);
 #endif
         p += (i < 10) ? 6 : 7;
+        cpu_reg_names_size -= (i < 10) ? 6 : 7;
     }
 
     cpu_nip = tcg_global_mem_new(TCG_AREG0,
@@ -278,7 +286,9 @@ static always_inline void gen_exception (DisasContext *ctx, uint32_t excp)
 static always_inline void gen_debug_exception (DisasContext *ctx)
 {
     TCGv_i32 t0;
-    gen_update_nip(ctx, ctx->nip);
+
+    if (ctx->exception != POWERPC_EXCP_BRANCH)
+        gen_update_nip(ctx, ctx->nip);
     t0 = tcg_const_i32(EXCP_DEBUG);
     gen_helper_raise_exception(t0);
     tcg_temp_free_i32(t0);
@@ -447,142 +457,6 @@ static always_inline target_ulong MASK (uint32_t start, uint32_t end)
 }
 
 /*****************************************************************************/
-/* PowerPC Instructions types definitions                                    */
-enum {
-    PPC_NONE           = 0x0000000000000000ULL,
-    /* PowerPC base instructions set                                         */
-    PPC_INSNS_BASE     = 0x0000000000000001ULL,
-    /*   integer operations instructions                                     */
-#define PPC_INTEGER PPC_INSNS_BASE
-    /*   flow control instructions                                           */
-#define PPC_FLOW    PPC_INSNS_BASE
-    /*   virtual memory instructions                                         */
-#define PPC_MEM     PPC_INSNS_BASE
-    /*   ld/st with reservation instructions                                 */
-#define PPC_RES     PPC_INSNS_BASE
-    /*   spr/msr access instructions                                         */
-#define PPC_MISC    PPC_INSNS_BASE
-    /* Deprecated instruction sets                                           */
-    /*   Original POWER instruction set                                      */
-    PPC_POWER          = 0x0000000000000002ULL,
-    /*   POWER2 instruction set extension                                    */
-    PPC_POWER2         = 0x0000000000000004ULL,
-    /*   Power RTC support                                                   */
-    PPC_POWER_RTC      = 0x0000000000000008ULL,
-    /*   Power-to-PowerPC bridge (601)                                       */
-    PPC_POWER_BR       = 0x0000000000000010ULL,
-    /* 64 bits PowerPC instruction set                                       */
-    PPC_64B            = 0x0000000000000020ULL,
-    /*   New 64 bits extensions (PowerPC 2.0x)                               */
-    PPC_64BX           = 0x0000000000000040ULL,
-    /*   64 bits hypervisor extensions                                       */
-    PPC_64H            = 0x0000000000000080ULL,
-    /*   New wait instruction (PowerPC 2.0x)                                 */
-    PPC_WAIT           = 0x0000000000000100ULL,
-    /*   Time base mftb instruction                                          */
-    PPC_MFTB           = 0x0000000000000200ULL,
-
-    /* Fixed-point unit extensions                                           */
-    /*   PowerPC 602 specific                                                */
-    PPC_602_SPEC       = 0x0000000000000400ULL,
-    /*   isel instruction                                                    */
-    PPC_ISEL           = 0x0000000000000800ULL,
-    /*   popcntb instruction                                                 */
-    PPC_POPCNTB        = 0x0000000000001000ULL,
-    /*   string load / store                                                 */
-    PPC_STRING         = 0x0000000000002000ULL,
-
-    /* Floating-point unit extensions                                        */
-    /*   Optional floating point instructions                                */
-    PPC_FLOAT          = 0x0000000000010000ULL,
-    /* New floating-point extensions (PowerPC 2.0x)                          */
-    PPC_FLOAT_EXT      = 0x0000000000020000ULL,
-    PPC_FLOAT_FSQRT    = 0x0000000000040000ULL,
-    PPC_FLOAT_FRES     = 0x0000000000080000ULL,
-    PPC_FLOAT_FRSQRTE  = 0x0000000000100000ULL,
-    PPC_FLOAT_FRSQRTES = 0x0000000000200000ULL,
-    PPC_FLOAT_FSEL     = 0x0000000000400000ULL,
-    PPC_FLOAT_STFIWX   = 0x0000000000800000ULL,
-
-    /* Vector/SIMD extensions                                                */
-    /*   Altivec support                                                     */
-    PPC_ALTIVEC        = 0x0000000001000000ULL,
-    /*   PowerPC 2.03 SPE extension                                          */
-    PPC_SPE            = 0x0000000002000000ULL,
-    /*   PowerPC 2.03 SPE floating-point extension                           */
-    PPC_SPEFPU         = 0x0000000004000000ULL,
-
-    /* Optional memory control instructions                                  */
-    PPC_MEM_TLBIA      = 0x0000000010000000ULL,
-    PPC_MEM_TLBIE      = 0x0000000020000000ULL,
-    PPC_MEM_TLBSYNC    = 0x0000000040000000ULL,
-    /*   sync instruction                                                    */
-    PPC_MEM_SYNC       = 0x0000000080000000ULL,
-    /*   eieio instruction                                                   */
-    PPC_MEM_EIEIO      = 0x0000000100000000ULL,
-
-    /* Cache control instructions                                            */
-    PPC_CACHE          = 0x0000000200000000ULL,
-    /*   icbi instruction                                                    */
-    PPC_CACHE_ICBI     = 0x0000000400000000ULL,
-    /*   dcbz instruction with fixed cache line size                         */
-    PPC_CACHE_DCBZ     = 0x0000000800000000ULL,
-    /*   dcbz instruction with tunable cache line size                       */
-    PPC_CACHE_DCBZT    = 0x0000001000000000ULL,
-    /*   dcba instruction                                                    */
-    PPC_CACHE_DCBA     = 0x0000002000000000ULL,
-    /*   Freescale cache locking instructions                                */
-    PPC_CACHE_LOCK     = 0x0000004000000000ULL,
-
-    /* MMU related extensions                                                */
-    /*   external control instructions                                       */
-    PPC_EXTERN         = 0x0000010000000000ULL,
-    /*   segment register access instructions                                */
-    PPC_SEGMENT        = 0x0000020000000000ULL,
-    /*   PowerPC 6xx TLB management instructions                             */
-    PPC_6xx_TLB        = 0x0000040000000000ULL,
-    /* PowerPC 74xx TLB management instructions                              */
-    PPC_74xx_TLB       = 0x0000080000000000ULL,
-    /*   PowerPC 40x TLB management instructions                             */
-    PPC_40x_TLB        = 0x0000100000000000ULL,
-    /*   segment register access instructions for PowerPC 64 "bridge"        */
-    PPC_SEGMENT_64B    = 0x0000200000000000ULL,
-    /*   SLB management                                                      */
-    PPC_SLBI           = 0x0000400000000000ULL,
-
-    /* Embedded PowerPC dedicated instructions                               */
-    PPC_WRTEE          = 0x0001000000000000ULL,
-    /* PowerPC 40x exception model                                           */
-    PPC_40x_EXCP       = 0x0002000000000000ULL,
-    /* PowerPC 405 Mac instructions                                          */
-    PPC_405_MAC        = 0x0004000000000000ULL,
-    /* PowerPC 440 specific instructions                                     */
-    PPC_440_SPEC       = 0x0008000000000000ULL,
-    /* BookE (embedded) PowerPC specification                                */
-    PPC_BOOKE          = 0x0010000000000000ULL,
-    /* mfapidi instruction                                                   */
-    PPC_MFAPIDI        = 0x0020000000000000ULL,
-    /* tlbiva instruction                                                    */
-    PPC_TLBIVA         = 0x0040000000000000ULL,
-    /* tlbivax instruction                                                   */
-    PPC_TLBIVAX        = 0x0080000000000000ULL,
-    /* PowerPC 4xx dedicated instructions                                    */
-    PPC_4xx_COMMON     = 0x0100000000000000ULL,
-    /* PowerPC 40x ibct instructions                                         */
-    PPC_40x_ICBT       = 0x0200000000000000ULL,
-    /* rfmci is not implemented in all BookE PowerPC                         */
-    PPC_RFMCI          = 0x0400000000000000ULL,
-    /* rfdi instruction                                                      */
-    PPC_RFDI           = 0x0800000000000000ULL,
-    /* DCR accesses                                                          */
-    PPC_DCR            = 0x1000000000000000ULL,
-    /* DCR extended accesse                                                  */
-    PPC_DCRX           = 0x2000000000000000ULL,
-    /* user-mode DCR access, implemented in PowerPC 460                      */
-    PPC_DCRUX          = 0x4000000000000000ULL,
-};
-
-/*****************************************************************************/
 /* PowerPC instructions table                                                */
 #if HOST_LONG_BITS == 64
 #define OPC_ALIGN 8
@@ -599,6 +473,7 @@ enum {
 
 #if defined(DO_PPC_STATISTICS)
 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
+extern opcode_t opc_##name;                                                   \
 OPCODES_SECTION opcode_t opc_##name = {                                       \
     .opc1 = op1,                                                              \
     .opc2 = op2,                                                              \
@@ -628,6 +503,7 @@ OPCODES_SECTION opcode_t opc_##name = {                                       \
 }
 #else
 #define GEN_OPCODE(name, op1, op2, op3, invl, _typ)                           \
+extern opcode_t opc_##name;                                                   \
 OPCODES_SECTION opcode_t opc_##name = {                                       \
     .opc1 = op1,                                                              \
     .opc2 = op2,                                                              \
@@ -641,6 +517,7 @@ OPCODES_SECTION opcode_t opc_##name = {                                       \
     .oname = stringify(name),                                                 \
 }
 #define GEN_OPCODE2(name, onam, op1, op2, op3, invl, _typ)                    \
+extern opcode_t opc_##name;                                                   \
 OPCODES_SECTION opcode_t opc_##name = {                                       \
     .opc1 = op1,                                                              \
     .opc2 = op2,                                                              \
@@ -656,6 +533,7 @@ OPCODES_SECTION opcode_t opc_##name = {                                       \
 #endif
 
 #define GEN_OPCODE_MARK(name)                                                 \
+extern opcode_t opc_##name;                                                   \
 OPCODES_SECTION opcode_t opc_##name = {                                       \
     .opc1 = 0xFF,                                                             \
     .opc2 = 0xFF,                                                             \
@@ -2411,9 +2289,10 @@ GEN_HANDLER(mtfsb1, 0x3F, 0x06, 0x01, 0x001FF800, PPC_FLOAT)
 }
 
 /* mtfsf */
-GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
+GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x00010000, PPC_FLOAT)
 {
     TCGv_i32 t0;
+    int L = ctx->opcode & 0x02000000;
 
     if (unlikely(!ctx->fpu_enabled)) {
         gen_exception(ctx, POWERPC_EXCP_FPU);
@@ -2422,7 +2301,10 @@ GEN_HANDLER(mtfsf, 0x3F, 0x07, 0x16, 0x02010000, PPC_FLOAT)
     /* NIP cannot be restored if the memory exception comes from an helper */
     gen_update_nip(ctx, ctx->nip - 4);
     gen_reset_fpstatus();
-    t0 = tcg_const_i32(FM(ctx->opcode));
+    if (L)
+        t0 = tcg_const_i32(0xff);
+    else
+        t0 = tcg_const_i32(FM(ctx->opcode));
     gen_helper_store_fpscr(cpu_fpr[rB(ctx->opcode)], t0);
     tcg_temp_free_i32(t0);
     if (unlikely(Rc(ctx->opcode) != 0)) {
@@ -2567,35 +2449,16 @@ static always_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)) {
-#if defined(TARGET_PPC64)
-        TCGv_i32 t0 = tcg_temp_new_i32();
-        tcg_gen_trunc_tl_i32(t0, arg1);
-        tcg_gen_bswap16_i32(t0, t0);
-        tcg_gen_extu_i32_tl(arg1, t0);
-        tcg_temp_free_i32(t0);
-#else
-        tcg_gen_bswap16_i32(arg1, arg1);
-#endif
+        tcg_gen_bswap16_tl(arg1, arg1);
     }
 }
 
 static always_inline void gen_qemu_ld16s(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
     if (unlikely(ctx->le_mode)) {
-#if defined(TARGET_PPC64)
-        TCGv_i32 t0;
         tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
-        t0 = tcg_temp_new_i32();
-        tcg_gen_trunc_tl_i32(t0, arg1);
-        tcg_gen_bswap16_i32(t0, t0);
-        tcg_gen_extu_i32_tl(arg1, t0);
+        tcg_gen_bswap16_tl(arg1, arg1);
         tcg_gen_ext16s_tl(arg1, arg1);
-        tcg_temp_free_i32(t0);
-#else
-        tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
-        tcg_gen_bswap16_i32(arg1, arg1);
-        tcg_gen_ext16s_i32(arg1, arg1);
-#endif
     } else {
         tcg_gen_qemu_ld16s(arg1, arg2, ctx->mem_idx);
     }
@@ -2605,29 +2468,17 @@ static always_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)) {
-#if defined(TARGET_PPC64)
-        TCGv_i32 t0 = tcg_temp_new_i32();
-        tcg_gen_trunc_tl_i32(t0, arg1);
-        tcg_gen_bswap_i32(t0, t0);
-        tcg_gen_extu_i32_tl(arg1, t0);
-        tcg_temp_free_i32(t0);
-#else
-        tcg_gen_bswap_i32(arg1, arg1);
-#endif
+        tcg_gen_bswap32_tl(arg1, arg1);
     }
 }
 
 #if defined(TARGET_PPC64)
 static always_inline void gen_qemu_ld32s(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    if (unlikely(ctx->mem_idx)) {
-        TCGv_i32 t0;
+    if (unlikely(ctx->le_mode)) {
         tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
-        t0 = tcg_temp_new_i32();
-        tcg_gen_trunc_tl_i32(t0, arg1);
-        tcg_gen_bswap_i32(t0, t0);
-        tcg_gen_ext_i32_tl(arg1, t0);
-        tcg_temp_free_i32(t0);
+        tcg_gen_bswap32_tl(arg1, arg1);
+        tcg_gen_ext32s_tl(arg1, arg1);
     } else
         tcg_gen_qemu_ld32s(arg1, arg2, ctx->mem_idx);
 }
@@ -2637,7 +2488,7 @@ static always_inline void gen_qemu_ld64(DisasContext *ctx, TCGv_i64 arg1, TCGv a
 {
     tcg_gen_qemu_ld64(arg1, arg2, ctx->mem_idx);
     if (unlikely(ctx->le_mode)) {
-        tcg_gen_bswap_i64(arg1, arg1);
+        tcg_gen_bswap64_i64(arg1, arg1);
     }
 }
 
@@ -2649,25 +2500,11 @@ static always_inline void gen_qemu_st8(DisasContext *ctx, TCGv arg1, TCGv arg2)
 static always_inline void gen_qemu_st16(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
     if (unlikely(ctx->le_mode)) {
-#if defined(TARGET_PPC64)
-        TCGv_i32 t0;
-        TCGv t1;
-        t0 = tcg_temp_new_i32();
-        tcg_gen_trunc_tl_i32(t0, arg1);
-        tcg_gen_ext16u_i32(t0, t0);
-        tcg_gen_bswap16_i32(t0, t0);
-        t1 = tcg_temp_new();
-        tcg_gen_extu_i32_tl(t1, t0);
-        tcg_temp_free_i32(t0);
-        tcg_gen_qemu_st16(t1, arg2, ctx->mem_idx);
-        tcg_temp_free(t1);
-#else
         TCGv t0 = tcg_temp_new();
         tcg_gen_ext16u_tl(t0, arg1);
-        tcg_gen_bswap16_i32(t0, t0);
+        tcg_gen_bswap16_tl(t0, t0);
         tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx);
         tcg_temp_free(t0);
-#endif
     } else {
         tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx);
     }
@@ -2676,23 +2513,11 @@ static always_inline void gen_qemu_st16(DisasContext *ctx, TCGv arg1, TCGv arg2)
 static always_inline void gen_qemu_st32(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
     if (unlikely(ctx->le_mode)) {
-#if defined(TARGET_PPC64)
-        TCGv_i32 t0;
-        TCGv t1;
-        t0 = tcg_temp_new_i32();
-        tcg_gen_trunc_tl_i32(t0, arg1);
-        tcg_gen_bswap_i32(t0, t0);
-        t1 = tcg_temp_new();
-        tcg_gen_extu_i32_tl(t1, t0);
-        tcg_temp_free_i32(t0);
-        tcg_gen_qemu_st32(t1, arg2, ctx->mem_idx);
-        tcg_temp_free(t1);
-#else
-        TCGv t0 = tcg_temp_new_i32();
-        tcg_gen_bswap_i32(t0, arg1);
+        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);
-#endif
     } else {
         tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx);
     }
@@ -2702,7 +2527,7 @@ static always_inline void gen_qemu_st64(DisasContext *ctx, TCGv_i64 arg1, TCGv a
 {
     if (unlikely(ctx->le_mode)) {
         TCGv_i64 t0 = tcg_temp_new_i64();
-        tcg_gen_bswap_i64(t0, arg1);
+        tcg_gen_bswap64_i64(t0, arg1);
         tcg_gen_qemu_st64(t0, arg2, ctx->mem_idx);
         tcg_temp_free_i64(t0);
     } else
@@ -2980,15 +2805,7 @@ static void always_inline gen_qemu_ld16ur(DisasContext *ctx, TCGv arg1, TCGv arg
 {
     tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
     if (likely(!ctx->le_mode)) {
-#if defined(TARGET_PPC64)
-        TCGv_i32 t0 = tcg_temp_new_i32();
-        tcg_gen_trunc_tl_i32(t0, arg1);
-        tcg_gen_bswap16_i32(t0, t0);
-        tcg_gen_extu_i32_tl(arg1, t0);
-        tcg_temp_free_i32(t0);
-#else
-        tcg_gen_bswap16_i32(arg1, arg1);
-#endif
+        tcg_gen_bswap16_tl(arg1, arg1);
     }
 }
 GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER);
@@ -2998,15 +2815,7 @@ static void always_inline gen_qemu_ld32ur(DisasContext *ctx, TCGv arg1, TCGv arg
 {
     tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
     if (likely(!ctx->le_mode)) {
-#if defined(TARGET_PPC64)
-        TCGv_i32 t0 = tcg_temp_new_i32();
-        tcg_gen_trunc_tl_i32(t0, arg1);
-        tcg_gen_bswap_i32(t0, t0);
-        tcg_gen_extu_i32_tl(arg1, t0);
-        tcg_temp_free_i32(t0);
-#else
-        tcg_gen_bswap_i32(arg1, arg1);
-#endif
+        tcg_gen_bswap32_tl(arg1, arg1);
     }
 }
 GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER);
@@ -3015,25 +2824,11 @@ GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER);
 static void always_inline gen_qemu_st16r(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
     if (likely(!ctx->le_mode)) {
-#if defined(TARGET_PPC64)
-        TCGv_i32 t0;
-        TCGv t1;
-        t0 = tcg_temp_new_i32();
-        tcg_gen_trunc_tl_i32(t0, arg1);
-        tcg_gen_ext16u_i32(t0, t0);
-        tcg_gen_bswap16_i32(t0, t0);
-        t1 = tcg_temp_new();
-        tcg_gen_extu_i32_tl(t1, t0);
-        tcg_temp_free_i32(t0);
-        tcg_gen_qemu_st16(t1, arg2, ctx->mem_idx);
-        tcg_temp_free(t1);
-#else
         TCGv t0 = tcg_temp_new();
         tcg_gen_ext16u_tl(t0, arg1);
-        tcg_gen_bswap16_i32(t0, t0);
+        tcg_gen_bswap16_tl(t0, t0);
         tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx);
         tcg_temp_free(t0);
-#endif
     } else {
         tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx);
     }
@@ -3044,23 +2839,11 @@ GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER);
 static void always_inline gen_qemu_st32r(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
     if (likely(!ctx->le_mode)) {
-#if defined(TARGET_PPC64)
-        TCGv_i32 t0;
-        TCGv t1;
-        t0 = tcg_temp_new_i32();
-        tcg_gen_trunc_tl_i32(t0, arg1);
-        tcg_gen_bswap_i32(t0, t0);
-        t1 = tcg_temp_new();
-        tcg_gen_extu_i32_tl(t1, t0);
-        tcg_temp_free_i32(t0);
-        tcg_gen_qemu_st32(t1, arg2, ctx->mem_idx);
-        tcg_temp_free(t1);
-#else
-        TCGv t0 = tcg_temp_new_i32();
-        tcg_gen_bswap_i32(t0, arg1);
+        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);
-#endif
     } else {
         tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx);
     }
@@ -3832,19 +3615,38 @@ GEN_HANDLER(mcrxr, 0x1F, 0x00, 0x10, 0x007FF801, PPC_MISC)
     tcg_gen_andi_tl(cpu_xer, cpu_xer, ~(1 << XER_SO | 1 << XER_OV | 1 << XER_CA));
 }
 
-/* mfcr */
+/* mfcr mfocrf */
 GEN_HANDLER(mfcr, 0x1F, 0x13, 0x00, 0x00000801, PPC_MISC)
 {
     uint32_t crm, crn;
 
     if (likely(ctx->opcode & 0x00100000)) {
         crm = CRM(ctx->opcode);
-        if (likely((crm ^ (crm - 1)) == 0)) {
-            crn = ffs(crm);
+        if (likely(crm && ((crm & (crm - 1)) == 0))) {
+            crn = ctz32 (crm);
             tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], cpu_crf[7 - crn]);
+            tcg_gen_shli_tl(cpu_gpr[rD(ctx->opcode)],
+                            cpu_gpr[rD(ctx->opcode)], crn * 4);
         }
     } else {
-        gen_helper_load_cr(cpu_gpr[rD(ctx->opcode)]);
+        TCGv_i32 t0 = tcg_temp_new_i32();
+        tcg_gen_mov_i32(t0, cpu_crf[0]);
+        tcg_gen_shli_i32(t0, t0, 4);
+        tcg_gen_or_i32(t0, t0, cpu_crf[1]);
+        tcg_gen_shli_i32(t0, t0, 4);
+        tcg_gen_or_i32(t0, t0, cpu_crf[2]);
+        tcg_gen_shli_i32(t0, t0, 4);
+        tcg_gen_or_i32(t0, t0, cpu_crf[3]);
+        tcg_gen_shli_i32(t0, t0, 4);
+        tcg_gen_or_i32(t0, t0, cpu_crf[4]);
+        tcg_gen_shli_i32(t0, t0, 4);
+        tcg_gen_or_i32(t0, t0, cpu_crf[5]);
+        tcg_gen_shli_i32(t0, t0, 4);
+        tcg_gen_or_i32(t0, t0, cpu_crf[6]);
+        tcg_gen_shli_i32(t0, t0, 4);
+        tcg_gen_or_i32(t0, t0, cpu_crf[7]);
+        tcg_gen_extu_i32_tl(cpu_gpr[rD(ctx->opcode)], t0);
+        tcg_temp_free_i32(t0);
     }
 }
 
@@ -3925,22 +3727,30 @@ GEN_HANDLER(mftb, 0x1F, 0x13, 0x0B, 0x00000001, PPC_MFTB)
     gen_op_mfspr(ctx);
 }
 
-/* mtcrf */
+/* mtcrf mtocrf*/
 GEN_HANDLER(mtcrf, 0x1F, 0x10, 0x04, 0x00000801, PPC_MISC)
 {
     uint32_t crm, crn;
 
     crm = CRM(ctx->opcode);
-    if (likely((ctx->opcode & 0x00100000) || (crm ^ (crm - 1)) == 0)) {
+    if (likely((ctx->opcode & 0x00100000))) {
+        if (crm && ((crm & (crm - 1)) == 0)) {
+            TCGv_i32 temp = tcg_temp_new_i32();
+            crn = ctz32 (crm);
+            tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
+            tcg_gen_shri_i32(temp, temp, crn * 4);
+            tcg_gen_andi_i32(cpu_crf[7 - crn], temp, 0xf);
+            tcg_temp_free_i32(temp);
+        }
+    } else {
         TCGv_i32 temp = tcg_temp_new_i32();
-        crn = ffs(crm);
         tcg_gen_trunc_tl_i32(temp, cpu_gpr[rS(ctx->opcode)]);
-        tcg_gen_shri_i32(cpu_crf[7 - crn], temp, crn * 4);
-        tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_crf[7 - crn], 0xf);
-        tcg_temp_free_i32(temp);
-    } else {
-        TCGv_i32 temp = tcg_const_i32(crm);
-        gen_helper_store_cr(cpu_gpr[rS(ctx->opcode)], temp);
+        for (crn = 0 ; crn < 8 ; crn++) {
+            if (crm & (1 << crn)) {
+                    tcg_gen_shri_i32(cpu_crf[7 - crn], temp, crn * 4);
+                    tcg_gen_andi_i32(cpu_crf[7 - crn], cpu_crf[7 - crn], 0xf);
+            }
+        }
         tcg_temp_free_i32(temp);
     }
 }
@@ -4287,7 +4097,7 @@ GEN_HANDLER2(mfsr_64b, "mfsr", 0x1F, 0x13, 0x12, 0x0010F801, PPC_SEGMENT_64B)
         return;
     }
     t0 = tcg_const_tl(SR(ctx->opcode));
-    gen_helper_load_slb(cpu_gpr[rD(ctx->opcode)], t0);
+    gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
     tcg_temp_free(t0);
 #endif
 }
@@ -4307,7 +4117,7 @@ GEN_HANDLER2(mfsrin_64b, "mfsrin", 0x1F, 0x13, 0x14, 0x001F0001,
     t0 = tcg_temp_new();
     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
     tcg_gen_andi_tl(t0, t0, 0xF);
-    gen_helper_load_slb(cpu_gpr[rD(ctx->opcode)], t0);
+    gen_helper_load_sr(cpu_gpr[rD(ctx->opcode)], t0);
     tcg_temp_free(t0);
 #endif
 }
@@ -4324,7 +4134,7 @@ GEN_HANDLER2(mtsr_64b, "mtsr", 0x1F, 0x12, 0x06, 0x0010F801, PPC_SEGMENT_64B)
         return;
     }
     t0 = tcg_const_tl(SR(ctx->opcode));
-    gen_helper_store_slb(t0, cpu_gpr[rS(ctx->opcode)]);
+    gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
     tcg_temp_free(t0);
 #endif
 }
@@ -4344,10 +4154,25 @@ GEN_HANDLER2(mtsrin_64b, "mtsrin", 0x1F, 0x12, 0x07, 0x001F0001,
     t0 = tcg_temp_new();
     tcg_gen_shri_tl(t0, cpu_gpr[rB(ctx->opcode)], 28);
     tcg_gen_andi_tl(t0, t0, 0xF);
-    gen_helper_store_slb(t0, cpu_gpr[rS(ctx->opcode)]);
+    gen_helper_store_sr(t0, cpu_gpr[rS(ctx->opcode)]);
     tcg_temp_free(t0);
 #endif
 }
+
+/* slbmte */
+GEN_HANDLER2(slbmte, "slbmte", 0x1F, 0x12, 0x0C, 0x00000000, PPC_SEGMENT_64B)
+{
+#if defined(CONFIG_USER_ONLY)
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+#else
+    if (unlikely(!ctx->mem_idx)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG);
+        return;
+    }
+    gen_helper_store_slb(cpu_gpr[rB(ctx->opcode)], cpu_gpr[rS(ctx->opcode)]);
+#endif
+}
+
 #endif /* defined(TARGET_PPC64) */
 
 /***                      Lookaside buffer management                      ***/
@@ -4366,6 +4191,20 @@ GEN_HANDLER(tlbia, 0x1F, 0x12, 0x0B, 0x03FFFC01, PPC_MEM_TLBIA)
 #endif
 }
 
+/* tlbiel */
+GEN_HANDLER(tlbiel, 0x1F, 0x12, 0x08, 0x03FF0001, PPC_MEM_TLBIE)
+{
+#if defined(CONFIG_USER_ONLY)
+    gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+#else
+    if (unlikely(!ctx->mem_idx)) {
+        gen_inval_exception(ctx, POWERPC_EXCP_PRIV_OPC);
+        return;
+    }
+    gen_helper_tlbie(cpu_gpr[rB(ctx->opcode)]);
+#endif
+}
+
 /* tlbie */
 GEN_HANDLER(tlbie, 0x1F, 0x12, 0x09, 0x03FF0001, PPC_MEM_TLBIE)
 {
@@ -6430,6 +6269,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(vcmpgefp, 3, 7)
+GEN_VXRFORM(vcmpgtfp, 3, 11)
+GEN_VXRFORM(vcmpbfp, 3, 15)
 
 #define GEN_VXFORM_SIMM(name, opc2, opc3)                               \
     GEN_HANDLER(name, 0x04, opc2, opc3, 0x00000000, PPC_ALTIVEC)        \
@@ -6472,6 +6315,8 @@ GEN_VXFORM_NOA(vupklsb, 7, 10);
 GEN_VXFORM_NOA(vupklsh, 7, 11);
 GEN_VXFORM_NOA(vupkhpx, 7, 13);
 GEN_VXFORM_NOA(vupklpx, 7, 15);
+GEN_VXFORM_NOA(vrefp, 5, 4);
+GEN_VXFORM_NOA(vrsqrtefp, 5, 5);
 GEN_VXFORM_NOA(vlogefp, 5, 7);
 GEN_VXFORM_NOA(vrfim, 5, 8);
 GEN_VXFORM_NOA(vrfin, 5, 9);
@@ -6517,6 +6362,8 @@ GEN_VXFORM_UIMM(vsplth, 6, 9);
 GEN_VXFORM_UIMM(vspltw, 6, 10);
 GEN_VXFORM_UIMM(vcfux, 5, 12);
 GEN_VXFORM_UIMM(vcfsx, 5, 13);
+GEN_VXFORM_UIMM(vctuxs, 5, 14);
+GEN_VXFORM_UIMM(vctsxs, 5, 15);
 
 GEN_HANDLER(vsldoi, 0x04, 0x16, 0xFF, 0x00000400, PPC_ALTIVEC)
 {
@@ -6584,6 +6431,7 @@ GEN_VAFORM_PAIRED(vmsumubm, vmsummbm, 18)
 GEN_VAFORM_PAIRED(vmsumuhm, vmsumuhs, 19)
 GEN_VAFORM_PAIRED(vmsumshm, vmsumshs, 20)
 GEN_VAFORM_PAIRED(vsel, vperm, 21)
+GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23)
 
 /***                           SPE extension                               ***/
 /* Register moves */
@@ -7877,20 +7725,20 @@ GEN_SPEFPUOP_COMP_64(evfststlt);
 GEN_SPEFPUOP_COMP_64(evfststeq);
 
 /* Opcodes definitions */
-GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPEFPU); //
-GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPEFPU); //
-GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPEFPU); //
-GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPEFPU); //
-GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPEFPU); //
-GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPEFPU); //
-GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPEFPU); //
-GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPEFPU); //
-GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPEFPU); //
-GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPEFPU); //
-GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPEFPU); //
-GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPEFPU); //
-GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPEFPU); //
-GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPEFPU); //
+GEN_SPE(evfsadd,        evfssub,       0x00, 0x0A, 0x00000000, PPC_SPE_SINGLE); //
+GEN_SPE(evfsabs,        evfsnabs,      0x02, 0x0A, 0x0000F800, PPC_SPE_SINGLE); //
+GEN_SPE(evfsneg,        speundef,      0x03, 0x0A, 0x0000F800, PPC_SPE_SINGLE); //
+GEN_SPE(evfsmul,        evfsdiv,       0x04, 0x0A, 0x00000000, PPC_SPE_SINGLE); //
+GEN_SPE(evfscmpgt,      evfscmplt,     0x06, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
+GEN_SPE(evfscmpeq,      speundef,      0x07, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
+GEN_SPE(evfscfui,       evfscfsi,      0x08, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
+GEN_SPE(evfscfuf,       evfscfsf,      0x09, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
+GEN_SPE(evfsctui,       evfsctsi,      0x0A, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
+GEN_SPE(evfsctuf,       evfsctsf,      0x0B, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
+GEN_SPE(evfsctuiz,      speundef,      0x0C, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
+GEN_SPE(evfsctsiz,      speundef,      0x0D, 0x0A, 0x00180000, PPC_SPE_SINGLE); //
+GEN_SPE(evfststgt,      evfststlt,     0x0E, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
+GEN_SPE(evfststeq,      speundef,      0x0F, 0x0A, 0x00600000, PPC_SPE_SINGLE); //
 
 /* Single precision floating-point operations */
 /* Arithmetic */
@@ -7945,20 +7793,20 @@ GEN_SPEFPUOP_COMP_32(efststlt);
 GEN_SPEFPUOP_COMP_32(efststeq);
 
 /* Opcodes definitions */
-GEN_SPE(efsadd,         efssub,        0x00, 0x0B, 0x00000000, PPC_SPEFPU); //
-GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPEFPU); //
-GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPEFPU); //
-GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPEFPU); //
-GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPEFPU); //
-GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPEFPU); //
-GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPEFPU); //
-GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPEFPU); //
-GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPEFPU); //
-GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPEFPU); //
-GEN_SPE(efsctuiz,       speundef,      0x0C, 0x0B, 0x00180000, PPC_SPEFPU); //
-GEN_SPE(efsctsiz,       speundef,      0x0D, 0x0B, 0x00180000, PPC_SPEFPU); //
-GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPEFPU); //
-GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPEFPU); //
+GEN_SPE(efsadd,         efssub,        0x00, 0x0B, 0x00000000, PPC_SPE_SINGLE); //
+GEN_SPE(efsabs,         efsnabs,       0x02, 0x0B, 0x0000F800, PPC_SPE_SINGLE); //
+GEN_SPE(efsneg,         speundef,      0x03, 0x0B, 0x0000F800, PPC_SPE_SINGLE); //
+GEN_SPE(efsmul,         efsdiv,        0x04, 0x0B, 0x00000000, PPC_SPE_SINGLE); //
+GEN_SPE(efscmpgt,       efscmplt,      0x06, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
+GEN_SPE(efscmpeq,       efscfd,        0x07, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
+GEN_SPE(efscfui,        efscfsi,       0x08, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
+GEN_SPE(efscfuf,        efscfsf,       0x09, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
+GEN_SPE(efsctui,        efsctsi,       0x0A, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
+GEN_SPE(efsctuf,        efsctsf,       0x0B, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
+GEN_SPE(efsctuiz,       speundef,      0x0C, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
+GEN_SPE(efsctsiz,       speundef,      0x0D, 0x0B, 0x00180000, PPC_SPE_SINGLE); //
+GEN_SPE(efststgt,       efststlt,      0x0E, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
+GEN_SPE(efststeq,       speundef,      0x0F, 0x0B, 0x00600000, PPC_SPE_SINGLE); //
 
 /* Double precision floating-point operations */
 /* Arithmetic */
@@ -8029,22 +7877,22 @@ GEN_SPEFPUOP_COMP_64(efdtstlt);
 GEN_SPEFPUOP_COMP_64(efdtsteq);
 
 /* Opcodes definitions */
-GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPEFPU); //
-GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPEFPU); //
-GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPEFPU); //
-GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPEFPU); //
-GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPEFPU); //
-GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPEFPU); //
-GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPEFPU); //
-GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPEFPU); //
-GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPEFPU); //
-GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPEFPU); //
-GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPEFPU); //
-GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPEFPU); //
-GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPEFPU); //
-GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPEFPU); //
-GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPEFPU); //
-GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPEFPU); //
+GEN_SPE(efdadd,         efdsub,        0x10, 0x0B, 0x00000000, PPC_SPE_DOUBLE); //
+GEN_SPE(efdcfuid,       efdcfsid,      0x11, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
+GEN_SPE(efdabs,         efdnabs,       0x12, 0x0B, 0x0000F800, PPC_SPE_DOUBLE); //
+GEN_SPE(efdneg,         speundef,      0x13, 0x0B, 0x0000F800, PPC_SPE_DOUBLE); //
+GEN_SPE(efdmul,         efddiv,        0x14, 0x0B, 0x00000000, PPC_SPE_DOUBLE); //
+GEN_SPE(efdctuidz,      efdctsidz,     0x15, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
+GEN_SPE(efdcmpgt,       efdcmplt,      0x16, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
+GEN_SPE(efdcmpeq,       efdcfs,        0x17, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
+GEN_SPE(efdcfui,        efdcfsi,       0x18, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
+GEN_SPE(efdcfuf,        efdcfsf,       0x19, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
+GEN_SPE(efdctui,        efdctsi,       0x1A, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
+GEN_SPE(efdctuf,        efdctsf,       0x1B, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
+GEN_SPE(efdctuiz,       speundef,      0x1C, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
+GEN_SPE(efdctsiz,       speundef,      0x1D, 0x0B, 0x00180000, PPC_SPE_DOUBLE); //
+GEN_SPE(efdtstgt,       efdtstlt,      0x1E, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
+GEN_SPE(efdtsteq,       speundef,      0x1F, 0x0B, 0x00600000, PPC_SPE_DOUBLE); //
 
 /* End opcode list */
 GEN_OPCODE_MARK(end);
@@ -8234,10 +8082,10 @@ static always_inline void gen_intermediate_code_internal (CPUState *env,
                 lj++;
                 while (lj < j)
                     gen_opc_instr_start[lj++] = 0;
-                gen_opc_pc[lj] = ctx.nip;
-                gen_opc_instr_start[lj] = 1;
-                gen_opc_icount[lj] = num_insns;
             }
+            gen_opc_pc[lj] = ctx.nip;
+            gen_opc_instr_start[lj] = 1;
+            gen_opc_icount[lj] = num_insns;
         }
         LOG_DISAS("----------------\n");
         LOG_DISAS("nip=" ADDRX " super=%d ir=%d\n",
@@ -8309,15 +8157,13 @@ static always_inline void gen_intermediate_code_internal (CPUState *env,
             gen_exception(ctxp, POWERPC_EXCP_TRACE);
         } else if (unlikely(((ctx.nip & (TARGET_PAGE_SIZE - 1)) == 0) ||
                             (env->singlestep_enabled) ||
+                            singlestep ||
                             num_insns >= max_insns)) {
             /* if we reach a page boundary or are single stepping, stop
              * generation
              */
             break;
         }
-#if defined (DO_SINGLE_STEP)
-        break;
-#endif
     }
     if (tb->cflags & CF_LAST_IO)
         gen_io_end();