mirror of
https://github.com/xemu-project/xemu.git
synced 2024-11-23 19:49:43 +00:00
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
This commit is contained in:
parent
a73666f656
commit
3cd7d1ddbb
2
configure
vendored
2
configure
vendored
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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. "
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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) */
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user