summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>2007-11-12 01:56:18 +0000
committerj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>2007-11-12 01:56:18 +0000
commit3cd7d1ddbba67a79854ea258cdf3a07eb0ad5136 (patch)
tree5dee929d68c3c96baae508887156292d975cbe82
parenta73666f6564e17adcae2908f7b52d42de2ff5211 (diff)
downloadqemu-3cd7d1ddbba67a79854ea258cdf3a07eb0ad5136.tar.gz
Allow use of SPE extension by all PowerPC targets,
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
-rwxr-xr-xconfigure2
-rw-r--r--darwin-user/main.c2
-rw-r--r--linux-user/main.c2
-rw-r--r--target-ppc/cpu.h57
-rw-r--r--target-ppc/helper.c21
-rw-r--r--target-ppc/op.c2
-rw-r--r--target-ppc/op_helper.c14
-rw-r--r--target-ppc/op_helper.h4
-rw-r--r--target-ppc/op_mem.h6
-rw-r--r--target-ppc/op_template.h13
-rw-r--r--target-ppc/translate.c112
11 files changed, 149 insertions, 86 deletions
diff --git a/configure b/configure
index 897df1029b..535876d6aa 100755
--- 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
diff --git a/darwin-user/main.c b/darwin-user/main.c
index 607d3d65f1..0a371dedfe 100644
--- a/darwin-user/main.c
+++ b/darwin-user/main.c
@@ -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");
diff --git a/linux-user/main.c b/linux-user/main.c
index 5cc2d41370..eb5861ad17 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -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. "
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 198da43f3e..a463b457c7 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -24,46 +24,51 @@
#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 */
diff --git a/target-ppc/helper.c b/target-ppc/helper.c
index 4937a75482..268703cd4e 100644
--- a/target-ppc/helper.c
+++ b/target-ppc/helper.c
@@ -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);
diff --git a/target-ppc/op.c b/target-ppc/op.c
index 05a6de31d3..9bf16f5b31 100644
--- a/target-ppc/op.c
+++ b/target-ppc/op.c
@@ -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) */
diff --git a/target-ppc/op_helper.c b/target-ppc/op_helper.c
index 68e90ceb57..1dde1a18c9 100644
--- a/target-ppc/op_helper.c
+++ b/target-ppc/op_helper.c
@@ -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 */
diff --git a/target-ppc/op_helper.h b/target-ppc/op_helper.h
index 5b77cb25ae..657825fa28 100644
--- a/target-ppc/op_helper.h
+++ b/target-ppc/op_helper.h
@@ -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
diff --git a/target-ppc/op_mem.h b/target-ppc/op_mem.h
index 560a0edaef..971cc18381 100644
--- a/target-ppc/op_mem.h
+++ b/target-ppc/op_mem.h
@@ -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
diff --git a/target-ppc/op_template.h b/target-ppc/op_template.h
index 51f9b3681b..26a066245b 100644
--- a/target-ppc/op_template.h
+++ b/target-ppc/op_template.h
@@ -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)
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index be4ac53909..d1741b6a3b 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -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