]> git.proxmox.com Git - qemu.git/commitdiff
Allow use of SPE extension by all PowerPC targets,
authorj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>
Mon, 12 Nov 2007 01:56:18 +0000 (01:56 +0000)
committerj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>
Mon, 12 Nov 2007 01:56:18 +0000 (01:56 +0000)
  adding gprh registers to store GPR MSBs when GPRs are 32 bits.
Remove not-needed-anymore ppcemb-linux-user target.
Keep ppcemb-softmmu target, which provides 1kB pages support
  and 36 bits physical address space.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3628 c046a42c-6fe2-441c-8c8c-71466251a162

configure
darwin-user/main.c
linux-user/main.c
target-ppc/cpu.h
target-ppc/helper.c
target-ppc/op.c
target-ppc/op_helper.c
target-ppc/op_helper.h
target-ppc/op_mem.h
target-ppc/op_template.h
target-ppc/translate.c

index 897df1029bebc1a3d319270cc3093c6eb678adff..535876d6aa8684f2cca75ac7f1baaa5dc50043a9 100755 (executable)
--- a/configure
+++ b/configure
@@ -520,7 +520,7 @@ if test -z "$target_list" ; then
     fi
 # the following are Linux specific
     if [ "$linux_user" = "yes" ] ; then
-        target_list="i386-linux-user arm-linux-user armeb-linux-user sparc-linux-user sparc64-linux-user sparc32plus-linux-user mips-linux-user mipsel-linux-user m68k-linux-user alpha-linux-user sh4-linux-user ppc-linux-user ppcemb-linux-user ppc64-linux-user ppc64abi32-linux-user x86_64-linux-user cris-linux-user $target_list"
+        target_list="i386-linux-user arm-linux-user armeb-linux-user sparc-linux-user sparc64-linux-user sparc32plus-linux-user mips-linux-user mipsel-linux-user m68k-linux-user alpha-linux-user sh4-linux-user ppc-linux-user ppc64-linux-user ppc64abi32-linux-user x86_64-linux-user cris-linux-user $target_list"
     fi
 # the following are Darwin specific
     if [ "$darwin_user" = "yes" ] ; then
index 607d3d65f1218e51e26153e09a4db7898b6f9dc8..0a371dedfeec86a5afed53016229bf79a11b85ce 100644 (file)
@@ -357,7 +357,6 @@ void cpu_loop(CPUPPCState *env)
         case POWERPC_EXCP_DEBUG:    /* Debug interrupt                       */
             gdb_handlesig (env, SIGTRAP);
             break;
-#if defined(TARGET_PPCEMB)
         case POWERPC_EXCP_SPEU:     /* SPE/embedded floating-point unavail.  */
             EXCP_DUMP(env, "No SPE/floating-point instruction allowed\n");
             info.si_signo = SIGILL;
@@ -383,7 +382,6 @@ void cpu_loop(CPUPPCState *env)
             cpu_abort(env, "Doorbell critical interrupt while in user mode. "
                       "Aborting\n");
             break;
-#endif /* defined(TARGET_PPCEMB) */
         case POWERPC_EXCP_RESET:    /* System reset exception                */
             cpu_abort(env, "Reset interrupt while in user mode. "
                       "Aborting\n");
index 5cc2d41370aab8a4cf812df63fc7d5b7f0261987..eb5861ad17a354091710616ecb0115420fecadac 100644 (file)
@@ -976,7 +976,6 @@ void cpu_loop(CPUPPCState *env)
                   }
             }
             break;
-#if defined(TARGET_PPCEMB)
         case POWERPC_EXCP_SPEU:     /* SPE/embedded floating-point unavail.  */
             EXCP_DUMP(env, "No SPE/floating-point instruction allowed\n");
             info.si_signo = TARGET_SIGILL;
@@ -1006,7 +1005,6 @@ void cpu_loop(CPUPPCState *env)
             cpu_abort(env, "Reset interrupt while in user mode. "
                       "Aborting\n");
             break;
-#endif /* defined(TARGET_PPCEMB) */
 #if defined(TARGET_PPC64) && !defined(TARGET_ABI32) /* PowerPC 64 */
         case POWERPC_EXCP_DSEG:     /* Data segment exception                */
             cpu_abort(env, "Data segment exception while in user mode. "
index 198da43f3ea9ff05ed2116be05efc87e51659353..a463b457c745bc079bf474ec89bbda60ffb62b68 100644 (file)
 #include <inttypes.h>
 
 #if defined (TARGET_PPC64)
+/* PowerPC 64 definitions */
 typedef uint64_t ppc_gpr_t;
 #define TARGET_GPR_BITS  64
 #define TARGET_LONG_BITS 64
 #define REGX "%016" PRIx64
 #define TARGET_PAGE_BITS 12
-#elif defined(TARGET_PPCEMB)
-/* BookE have 36 bits physical address space */
-#define TARGET_PHYS_ADDR_BITS 64
-/* GPR are 64 bits: used by vector extension */
-typedef uint64_t ppc_gpr_t;
-#define TARGET_GPR_BITS  64
-#define TARGET_LONG_BITS 32
-#define REGX "%016" PRIx64
-#if defined(CONFIG_USER_ONLY)
-/* It looks like a lot of Linux programs assume page size
- * is 4kB long. This is evil, but we have to deal with it...
- */
-#define TARGET_PAGE_BITS 12
-#else
-/* Pages can be 1 kB small */
-#define TARGET_PAGE_BITS 10
-#endif
-#else
+
+#else /* defined (TARGET_PPC64) */
+/* PowerPC 32 definitions */
 #if (HOST_LONG_BITS >= 64)
 /* When using 64 bits temporary registers,
  * we can use 64 bits GPR with no extra cost
- * It's even an optimization as it will prevent
+ * It's even an optimization as this will prevent
  * the compiler to do unuseful masking in the micro-ops.
  */
 typedef uint64_t ppc_gpr_t;
 #define TARGET_GPR_BITS  64
 #define REGX "%08" PRIx64
-#else
+#else /* (HOST_LONG_BITS >= 64) */
 typedef uint32_t ppc_gpr_t;
 #define TARGET_GPR_BITS  32
 #define REGX "%08" PRIx32
-#endif
+#endif /* (HOST_LONG_BITS >= 64) */
+
 #define TARGET_LONG_BITS 32
+
+#if defined(TARGET_PPCEMB)
+/* Specific definitions for PowerPC embedded */
+/* BookE have 36 bits physical address space */
+#define TARGET_PHYS_ADDR_BITS 64
+#if defined(CONFIG_USER_ONLY)
+/* It looks like a lot of Linux programs assume page size
+ * is 4kB long. This is evil, but we have to deal with it...
+ */
 #define TARGET_PAGE_BITS 12
-#endif
+#else /* defined(CONFIG_USER_ONLY) */
+/* Pages can be 1 kB small */
+#define TARGET_PAGE_BITS 10
+#endif /* defined(CONFIG_USER_ONLY) */
+#else /* defined(TARGET_PPCEMB) */
+/* "standard" PowerPC 32 definitions */
+#define TARGET_PAGE_BITS 12
+#endif /* defined(TARGET_PPCEMB) */
+
+#endif /* defined (TARGET_PPC64) */
 
 #include "cpu-defs.h"
 
@@ -166,14 +171,12 @@ enum {
     POWERPC_EXCP_ITLB     = 14, /* Instruction TLB error                     */
     POWERPC_EXCP_DEBUG    = 15, /* Debug interrupt                           */
     /* Vectors 16 to 31 are reserved                                         */
-#if defined(TARGET_PPCEMB)
     POWERPC_EXCP_SPEU     = 32, /* SPE/embedded floating-point unavailable   */
     POWERPC_EXCP_EFPDI    = 33, /* Embedded floating-point data interrupt    */
     POWERPC_EXCP_EFPRI    = 34, /* Embedded floating-point round interrupt   */
     POWERPC_EXCP_EPERFM   = 35, /* Embedded performance monitor interrupt    */
     POWERPC_EXCP_DOORI    = 36, /* Embedded doorbell interrupt               */
     POWERPC_EXCP_DOORCI   = 37, /* Embedded doorbell critical interrupt      */
-#endif /* defined(TARGET_PPCEMB) */
     /* Vectors 38 to 63 are reserved                                         */
     /* Exceptions defined in the PowerPC server specification                */
     POWERPC_EXCP_RESET    = 64, /* System reset exception                    */
@@ -527,6 +530,10 @@ struct CPUPPCState {
 
     /* general purpose registers */
     ppc_gpr_t gpr[32];
+#if TARGET_GPR_BITS < 64
+    /* Storage for GPR MSB, used by the SPE extension */
+    ppc_gpr_t gprh[32];
+#endif
     /* LR */
     target_ulong lr;
     /* CTR */
@@ -597,12 +604,10 @@ struct CPUPPCState {
     /* Altivec registers */
     ppc_avr_t avr[32];
     uint32_t vscr;
-#if defined(TARGET_PPCEMB)
     /* SPE registers */
     ppc_gpr_t spe_acc;
     float_status spe_status;
     uint32_t spe_fscr;
-#endif
 
     /* Internal devices resources */
     /* Time base and decrementer */
index 4937a75482ba2b53ff5aa69b2a0809f42b8031ef..268703cd4e68cc26a5684765424ed71823567b7c 100644 (file)
@@ -2395,7 +2395,6 @@ static always_inline void powerpc_excp (CPUState *env,
         /* XXX: TODO */
         cpu_abort(env, "Debug exception is not implemented yet !\n");
         goto store_next;
-#if defined(TARGET_PPCEMB)
     case POWERPC_EXCP_SPEU:      /* SPE/embedded floating-point unavailable  */
         new_msr &= ~((target_ulong)1 << MSR_RI); /* XXX: check this */
         goto store_current;
@@ -2433,7 +2432,6 @@ static always_inline void powerpc_excp (CPUState *env,
         cpu_abort(env, "Embedded doorbell critical interrupt "
                   "is not implemented yet !\n");
         goto store_next;
-#endif /* defined(TARGET_PPCEMB) */
     case POWERPC_EXCP_RESET:     /* System reset exception                   */
         new_msr &= ~((target_ulong)1 << MSR_RI);
 #if defined(TARGET_PPC64H)
@@ -2833,26 +2831,11 @@ void ppc_hw_interrupt (CPUPPCState *env)
             powerpc_excp(env, env->excp_model, POWERPC_EXCP_WDT);
             return;
         }
-#if defined(TARGET_PPCEMB)
         if (env->pending_interrupts & (1 << PPC_INTERRUPT_CDOORBELL)) {
             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_CDOORBELL);
             powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORCI);
             return;
         }
-#endif
-#if defined(TARGET_PPCEMB)
-        /* External interrupt */
-        if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
-            /* Taking an external interrupt does not clear the external
-             * interrupt status
-             */
-#if 0
-            env->pending_interrupts &= ~(1 << PPC_INTERRUPT_EXT);
-#endif
-            powerpc_excp(env, env->excp_model, POWERPC_EXCP_EXTERNAL);
-            return;
-        }
-#endif
         /* Fixed interval timer on embedded PowerPC */
         if (env->pending_interrupts & (1 << PPC_INTERRUPT_FIT)) {
             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_FIT);
@@ -2871,7 +2854,6 @@ void ppc_hw_interrupt (CPUPPCState *env)
             powerpc_excp(env, env->excp_model, POWERPC_EXCP_DECR);
             return;
         }
-#if !defined(TARGET_PPCEMB)
         /* External interrupt */
         if (env->pending_interrupts & (1 << PPC_INTERRUPT_EXT)) {
             /* Taking an external interrupt does not clear the external
@@ -2883,14 +2865,11 @@ void ppc_hw_interrupt (CPUPPCState *env)
             powerpc_excp(env, env->excp_model, POWERPC_EXCP_EXTERNAL);
             return;
         }
-#endif
-#if defined(TARGET_PPCEMB)
         if (env->pending_interrupts & (1 << PPC_INTERRUPT_DOORBELL)) {
             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DOORBELL);
             powerpc_excp(env, env->excp_model, POWERPC_EXCP_DOORI);
             return;
         }
-#endif
         if (env->pending_interrupts & (1 << PPC_INTERRUPT_PERFM)) {
             env->pending_interrupts &= ~(1 << PPC_INTERRUPT_PERFM);
             powerpc_excp(env, env->excp_model, POWERPC_EXCP_PERFM);
index 05a6de31d3928c435b148454f5667d6144b95a6b..9bf16f5b31f7b1d4ee190dc8efbd63bcfce18a1a 100644 (file)
@@ -2720,7 +2720,6 @@ void OPPROTO op_store_booke_tsr (void)
 }
 #endif /* !defined(CONFIG_USER_ONLY) */
 
-#if defined(TARGET_PPCEMB)
 /* SPE extension */
 void OPPROTO op_splatw_T1_64 (void)
 {
@@ -3439,4 +3438,3 @@ void OPPROTO op_efdtsteq (void)
     T0 = _do_efdtsteq(T0_64, T1_64);
     RETURN();
 }
-#endif /* defined(TARGET_PPCEMB) */
index 68e90ceb57e239106c2782fa99b9520808c34011..1dde1a18c91a88b1bb6a42ea238938547ebee8cb 100644 (file)
@@ -1853,7 +1853,6 @@ void do_440_dlmzb (void)
     T0 = i;
 }
 
-#if defined(TARGET_PPCEMB)
 /* SPE extension helpers */
 /* Use a table to make this quicker */
 static uint8_t hbrev[16] = {
@@ -1872,16 +1871,16 @@ static always_inline uint32_t word_reverse (uint32_t val)
         (byte_reverse(val >> 8) << 16) | (byte_reverse(val) << 24);
 }
 
-#define MASKBITS 16 // Random value - to be fixed
+#define MASKBITS 16 // Random value - to be fixed (implementation dependant)
 void do_brinc (void)
 {
     uint32_t a, b, d, mask;
 
-    mask = UINT32_MAX >> MASKBITS;
-    b = T1_64 & mask;
-    a = T0_64 & mask;
-    d = word_reverse(1 + word_reverse(a | ~mask));
-    T0_64 = (T0_64 & ~mask) | (d & mask);
+    mask = UINT32_MAX >> (32 - MASKBITS);
+    a = T0 & mask;
+    b = T1 & mask;
+    d = word_reverse(1 + word_reverse(a | ~b));
+    T0 = (T0 & ~mask) | (d & b);
 }
 
 #define DO_SPE_OP2(name)                                                      \
@@ -2713,7 +2712,6 @@ DO_SPE_OP1(fsctuiz);
 DO_SPE_OP1(fsctsf);
 /* evfsctuf */
 DO_SPE_OP1(fsctuf);
-#endif /* defined(TARGET_PPCEMB) */
 
 /*****************************************************************************/
 /* Softmmu support */
index 5b77cb25ae74416ddd3fab239bf95eacbc5b9e20..657825fa28a42c0e351110022439403250b7d015 100644 (file)
@@ -205,7 +205,6 @@ void do_load_403_pb (int num);
 void do_store_403_pb (int num);
 #endif
 
-#if defined(TARGET_PPCEMB)
 /* SPE extension helpers */
 void do_brinc (void);
 /* Fixed-point vector helpers */
@@ -286,9 +285,7 @@ void do_evfsctsi (void);
 void do_evfsctui (void);
 void do_evfsctsiz (void);
 void do_evfsctuiz (void);
-#endif /* defined(TARGET_PPCEMB) */
 
-#if defined(TARGET_PPCEMB)
 /* SPE extension */
 /* Single precision floating-point helpers */
 static always_inline uint32_t _do_efsabs (uint32_t val)
@@ -409,5 +406,4 @@ static always_inline int _do_efdtsteq (uint64_t op1, uint64_t op2)
     u2.u = op2;
     return float64_eq(u1.f, u2.f, &env->spe_status) ? 1 : 0;
 }
-#endif /* defined(TARGET_PPCEMB) */
 #endif
index 560a0edaefbd9cc8be74c11c510491d0c384a6f6..971cc18381cd53d1e70f2efcd24e02e45b572d7b 100644 (file)
@@ -37,7 +37,6 @@ static always_inline uint32_t glue(ld32r, MEMSUFFIX) (target_ulong EA)
         ((tmp & 0x0000FF00) << 8) | ((tmp & 0x000000FF) << 24);
 }
 
-#if defined(TARGET_PPC64) || defined(TARGET_PPCEMB)
 static always_inline uint64_t glue(ld64r, MEMSUFFIX) (target_ulong EA)
 {
     uint64_t tmp = glue(ldq, MEMSUFFIX)(EA);
@@ -50,7 +49,6 @@ static always_inline uint64_t glue(ld64r, MEMSUFFIX) (target_ulong EA)
         ((tmp & 0x000000000000FF00ULL) << 40) |
         ((tmp & 0x00000000000000FFULL) << 54);
 }
-#endif
 
 #if defined(TARGET_PPC64)
 static always_inline int64_t glue(ldsl, MEMSUFFIX) (target_ulong EA)
@@ -81,7 +79,6 @@ static always_inline void glue(st32r, MEMSUFFIX) (target_ulong EA,
     glue(stl, MEMSUFFIX)(EA, tmp);
 }
 
-#if defined(TARGET_PPC64) || defined(TARGET_PPCEMB)
 static always_inline void glue(st64r, MEMSUFFIX) (target_ulong EA,
                                                   uint64_t data)
 {
@@ -95,7 +92,6 @@ static always_inline void glue(st64r, MEMSUFFIX) (target_ulong EA,
         ((data & 0x00000000000000FFULL) << 56);
     glue(stq, MEMSUFFIX)(EA, tmp);
 }
-#endif
 
 /***                             Integer load                              ***/
 #define PPC_LD_OP(name, op)                                                   \
@@ -1123,7 +1119,6 @@ void OPPROTO glue(op_vr_stvx_le_64, MEMSUFFIX) (void)
 #undef VR_DWORD0
 #undef VR_DWORD1
 
-#if defined(TARGET_PPCEMB)
 /* SPE extension */
 #define _PPC_SPE_LD_OP(name, op)                                              \
 void OPPROTO glue(glue(op_spe_l, name), MEMSUFFIX) (void)                     \
@@ -1385,6 +1380,5 @@ uint64_t glue(spe_lwhsplat_le, MEMSUFFIX) (target_ulong EA)
     return ret;
 }
 PPC_SPE_LD_OP(whsplat_le, spe_lwhsplat_le);
-#endif /* defined(TARGET_PPCEMB) */
 
 #undef MEMSUFFIX
index 51f9b3681b1daddb8b1b72832eae41932222ecc9..26a066245bee4ad1568d81c169b6c53c0c384c71 100644 (file)
@@ -58,23 +58,23 @@ void OPPROTO glue(op_store_T2_gpr_gpr, REG) (void)
 #endif
 
 /* General purpose registers containing vector operands moves */
-#if defined(TARGET_PPCEMB)
+#if TARGET_GPR_BITS < 64
 void OPPROTO glue(op_load_gpr64_T0_gpr, REG) (void)
 {
-    T0_64 = env->gpr[REG];
+    T0_64 = (uint64_t)env->gpr[REG] | ((uint64_t)env->gprh[REG] << 32);
     RETURN();
 }
 
 void OPPROTO glue(op_load_gpr64_T1_gpr, REG) (void)
 {
-    T1_64 = env->gpr[REG];
+    T1_64 = (uint64_t)env->gpr[REG] | ((uint64_t)env->gprh[REG] << 32);
     RETURN();
 }
 
 #if 0 // unused
 void OPPROTO glue(op_load_gpr64_T2_gpr, REG) (void)
 {
-    T2_64 = env->gpr[REG];
+    T2_64 = (uint64_t)env->gpr[REG] | ((uint64_t)env->gprh[REG] << 32);
     RETURN();
 }
 #endif
@@ -82,12 +82,14 @@ void OPPROTO glue(op_load_gpr64_T2_gpr, REG) (void)
 void OPPROTO glue(op_store_T0_gpr64_gpr, REG) (void)
 {
     env->gpr[REG] = T0_64;
+    env->gprh[REG] = T0_64 >> 32;
     RETURN();
 }
 
 void OPPROTO glue(op_store_T1_gpr64_gpr, REG) (void)
 {
     env->gpr[REG] = T1_64;
+    env->gprh[REG] = T1_64 >> 32;
     RETURN();
 }
 
@@ -95,10 +97,11 @@ void OPPROTO glue(op_store_T1_gpr64_gpr, REG) (void)
 void OPPROTO glue(op_store_T2_gpr64_gpr, REG) (void)
 {
     env->gpr[REG] = T2_64;
+    env->gprh[REG] = T2_64 >> 32;
     RETURN();
 }
 #endif
-#endif /* defined(TARGET_PPCEMB) */
+#endif /* TARGET_GPR_BITS < 64 */
 
 /* Altivec registers moves */
 void OPPROTO glue(op_load_avr_A0_avr, REG) (void)
index be4ac53909be5f3a83409e9add3498016a89b4b4..d1741b6a3be74437fd88b9e37924752171136194 100644 (file)
@@ -162,9 +162,7 @@ typedef struct DisasContext {
 #endif
     int fpu_enabled;
     int altivec_enabled;
-#if defined(TARGET_PPCEMB)
     int spe_enabled;
-#endif
     ppc_spr_t *spr_cb; /* Needed to check rights for mfspr/mtspr */
     int singlestep_enabled;
     int dcache_line_size;
@@ -5821,10 +5819,11 @@ GEN_VR_STX(vx, 0x07, 0x07);
 #define gen_op_vr_stvxl gen_op_vr_stvx
 GEN_VR_STX(vxl, 0x07, 0x0F);
 
-#if defined(TARGET_PPCEMB)
 /***                           SPE extension                               ***/
 
 /* Register moves */
+#if TARGET_GPR_BITS < 64
+
 GEN32(gen_op_load_gpr64_T0, gen_op_load_gpr64_T0_gpr);
 GEN32(gen_op_load_gpr64_T1, gen_op_load_gpr64_T1_gpr);
 #if 0 // unused
@@ -5837,6 +5836,23 @@ GEN32(gen_op_store_T1_gpr64, gen_op_store_T1_gpr64_gpr);
 GEN32(gen_op_store_T2_gpr64, gen_op_store_T2_gpr64_gpr);
 #endif
 
+#else /* TARGET_GPR_BITS < 64 */
+
+/* No specific load/store functions: GPRs are already 64 bits */
+#define gen_op_load_gpr64_T0 gen_op_load_gpr_T0
+#define gen_op_load_gpr64_T1 gen_op_load_gpr_T1
+#if 0 // unused
+#define gen_op_load_gpr64_T2 gen_op_load_gpr_T2
+#endif
+
+#define gen_op_store_T0_gpr64 gen_op_store_T0_gpr
+#define gen_op_store_T1_gpr64 gen_op_store_T1_gpr
+#if 0 // unused
+#define gen_op_store_T2_gpr64 gen_op_store_T2_gpr
+#endif
+
+#endif /* TARGET_GPR_BITS < 64 */
+
 #define GEN_SPE(name0, name1, opc2, opc3, inval, type)                        \
 GEN_HANDLER(name0##_##name1, 0x04, opc2, opc3, inval, type)                   \
 {                                                                             \
@@ -6105,10 +6121,10 @@ GEN_SPEOP_ARITH1(evcntlsw);
 static always_inline void gen_brinc (DisasContext *ctx)
 {
     /* Note: brinc is usable even if SPE is disabled */
-    gen_op_load_gpr64_T0(rA(ctx->opcode));
-    gen_op_load_gpr64_T1(rB(ctx->opcode));
+    gen_op_load_gpr_T0(rA(ctx->opcode));
+    gen_op_load_gpr_T1(rB(ctx->opcode));
     gen_op_brinc();
-    gen_op_store_T0_gpr64(rD(ctx->opcode));
+    gen_op_store_T0_gpr(rD(ctx->opcode));
 }
 
 #define GEN_SPEOP_ARITH_IMM2(name)                                            \
@@ -6242,6 +6258,12 @@ GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
 #define gen_op_spe_stdd_le_raw gen_op_std_le_raw
 #define gen_op_spe_stdd_le_64_raw gen_op_std_le_64_raw
 #else /* defined(CONFIG_USER_ONLY) */
+#if defined(TARGET_PPC64H)
+#define gen_op_spe_ldd_hypv gen_op_ld_hypv
+#define gen_op_spe_ldd_64_hypv gen_op_ld_64_hypv
+#define gen_op_spe_ldd_le_hypv gen_op_ld_hypv
+#define gen_op_spe_ldd_le_64_hypv gen_op_ld_64_hypv
+#endif
 #define gen_op_spe_ldd_kernel gen_op_ld_kernel
 #define gen_op_spe_ldd_64_kernel gen_op_ld_64_kernel
 #define gen_op_spe_ldd_le_kernel gen_op_ld_kernel
@@ -6250,6 +6272,12 @@ GEN_HANDLER2(evsel3, "evsel", 0x04, 0x1f, 0x09, 0x00000000, PPC_SPE)
 #define gen_op_spe_ldd_64_user gen_op_ld_64_user
 #define gen_op_spe_ldd_le_user gen_op_ld_le_user
 #define gen_op_spe_ldd_le_64_user gen_op_ld_le_64_user
+#if defined(TARGET_PPC64H)
+#define gen_op_spe_stdd_hypv gen_op_std_hypv
+#define gen_op_spe_stdd_64_hypv gen_op_std_64_hypv
+#define gen_op_spe_stdd_le_hypv gen_op_std_hypv
+#define gen_op_spe_stdd_le_64_hypv gen_op_std_64_hypv
+#endif
 #define gen_op_spe_stdd_kernel gen_op_std_kernel
 #define gen_op_spe_stdd_64_kernel gen_op_std_64_kernel
 #define gen_op_spe_stdd_le_kernel gen_op_std_kernel
@@ -6284,6 +6312,12 @@ GEN_SPEOP_ST(who, 2);
 #define gen_op_spe_stwwo_le_kernel gen_op_stw_le_kernel
 #define gen_op_spe_stwwo_64_kernel gen_op_stw_64_kernel
 #define gen_op_spe_stwwo_le_64_kernel gen_op_stw_le_64_kernel
+#if defined(TARGET_PPC64H)
+#define gen_op_spe_stwwo_hypv gen_op_stw_hypv
+#define gen_op_spe_stwwo_le_hypv gen_op_stw_le_hypv
+#define gen_op_spe_stwwo_64_hypv gen_op_stw_64_hypv
+#define gen_op_spe_stwwo_le_64_hypv gen_op_stw_le_64_hypv
+#endif
 #endif
 #endif
 #define _GEN_OP_SPE_STWWE(suffix)                                             \
@@ -6320,6 +6354,9 @@ _GEN_OP_SPE_STWWE_LE(suffix)
 #if defined(CONFIG_USER_ONLY)
 GEN_OP_SPE_STWWE(raw);
 #else /* defined(CONFIG_USER_ONLY) */
+#if defined(TARGET_PPC64H)
+GEN_OP_SPE_STWWE(hypv);
+#endif
 GEN_OP_SPE_STWWE(kernel);
 GEN_OP_SPE_STWWE(user);
 #endif /* defined(CONFIG_USER_ONLY) */
@@ -6371,45 +6408,105 @@ GEN_OP_SPE_LHX(le_64_raw);
 GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_raw);
 #endif
 #else
+#if defined(TARGET_PPC64H)
+GEN_OP_SPE_LHE(hypv);
+#endif
 GEN_OP_SPE_LHE(kernel);
 GEN_OP_SPE_LHE(user);
+#if defined(TARGET_PPC64H)
+GEN_SPE_LDSPLAT(hhesplat, spe_lhe, hypv);
+#endif
 GEN_SPE_LDSPLAT(hhesplat, spe_lhe, kernel);
 GEN_SPE_LDSPLAT(hhesplat, spe_lhe, user);
+#if defined(TARGET_PPC64H)
+GEN_OP_SPE_LHE(le_hypv);
+#endif
 GEN_OP_SPE_LHE(le_kernel);
 GEN_OP_SPE_LHE(le_user);
+#if defined(TARGET_PPC64H)
+GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_hypv);
+#endif
 GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_kernel);
 GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_user);
+#if defined(TARGET_PPC64H)
+GEN_SPE_LDSPLAT(hhousplat, spe_lh, hypv);
+#endif
 GEN_SPE_LDSPLAT(hhousplat, spe_lh, kernel);
 GEN_SPE_LDSPLAT(hhousplat, spe_lh, user);
+#if defined(TARGET_PPC64H)
+GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_hypv);
+#endif
 GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_kernel);
 GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_user);
+#if defined(TARGET_PPC64H)
+GEN_OP_SPE_LHX(hypv);
+#endif
 GEN_OP_SPE_LHX(kernel);
 GEN_OP_SPE_LHX(user);
+#if defined(TARGET_PPC64H)
+GEN_SPE_LDSPLAT(hhossplat, spe_lhx, hypv);
+#endif
 GEN_SPE_LDSPLAT(hhossplat, spe_lhx, kernel);
 GEN_SPE_LDSPLAT(hhossplat, spe_lhx, user);
+#if defined(TARGET_PPC64H)
+GEN_OP_SPE_LHX(le_hypv);
+#endif
 GEN_OP_SPE_LHX(le_kernel);
 GEN_OP_SPE_LHX(le_user);
+#if defined(TARGET_PPC64H)
+GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_hypv);
+#endif
 GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_kernel);
 GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_user);
 #if defined(TARGET_PPC64)
+#if defined(TARGET_PPC64H)
+GEN_OP_SPE_LHE(64_hypv);
+#endif
 GEN_OP_SPE_LHE(64_kernel);
 GEN_OP_SPE_LHE(64_user);
+#if defined(TARGET_PPC64H)
+GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_hypv);
+#endif
 GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_kernel);
 GEN_SPE_LDSPLAT(hhesplat, spe_lhe, 64_user);
+#if defined(TARGET_PPC64H)
+GEN_OP_SPE_LHE(le_64_hypv);
+#endif
 GEN_OP_SPE_LHE(le_64_kernel);
 GEN_OP_SPE_LHE(le_64_user);
+#if defined(TARGET_PPC64H)
+GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_hypv);
+#endif
 GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_kernel);
 GEN_SPE_LDSPLAT(hhesplat, spe_lhe, le_64_user);
+#if defined(TARGET_PPC64H)
+GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_hypv);
+#endif
 GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_kernel);
 GEN_SPE_LDSPLAT(hhousplat, spe_lh, 64_user);
+#if defined(TARGET_PPC64H)
+GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_hypv);
+#endif
 GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_kernel);
 GEN_SPE_LDSPLAT(hhousplat, spe_lh, le_64_user);
+#if defined(TARGET_PPC64H)
+GEN_OP_SPE_LHX(64_hypv);
+#endif
 GEN_OP_SPE_LHX(64_kernel);
 GEN_OP_SPE_LHX(64_user);
+#if defined(TARGET_PPC64H)
+GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_hypv);
+#endif
 GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_kernel);
 GEN_SPE_LDSPLAT(hhossplat, spe_lhx, 64_user);
+#if defined(TARGET_PPC64H)
+GEN_OP_SPE_LHX(le_64_hypv);
+#endif
 GEN_OP_SPE_LHX(le_64_kernel);
 GEN_OP_SPE_LHX(le_64_user);
+#if defined(TARGET_PPC64H)
+GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_hypv);
+#endif
 GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_kernel);
 GEN_SPE_LDSPLAT(hhossplat, spe_lhx, le_64_user);
 #endif
@@ -6663,7 +6760,6 @@ 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); //
-#endif
 
 /* End opcode list */
 GEN_OPCODE_MARK(end);
@@ -6830,12 +6926,10 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
 #endif
     ctx.dcache_line_size = env->dcache_line_size;
     ctx.fpu_enabled = msr_fp;
-#if defined(TARGET_PPCEMB)
     if ((env->flags & POWERPC_FLAG_SPE) && msr_spe)
         ctx.spe_enabled = msr_spe;
     else
         ctx.spe_enabled = 0;
-#endif
     if ((env->flags & POWERPC_FLAG_VRE) && msr_vr)
         ctx.altivec_enabled = msr_vr;
     else