mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
PowerPC 2.03 SPE extension - first pass.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2519 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
+47
-35
@@ -26,15 +26,20 @@
|
||||
#if defined (TARGET_PPC64)
|
||||
typedef uint64_t ppc_gpr_t;
|
||||
#define TARGET_LONG_BITS 64
|
||||
#define TARGET_GPR_BITS 64
|
||||
#define REGX "%016" PRIx64
|
||||
#elif defined(TARGET_E500)
|
||||
/* We can safely use PowerPC SPE extension when compiling PowerPC 64 */
|
||||
#define TARGET_PPCSPE
|
||||
#elif defined(TARGET_PPCSPE)
|
||||
/* GPR are 64 bits: used by vector extension */
|
||||
typedef uint64_t ppc_gpr_t;
|
||||
#define TARGET_LONG_BITS 32
|
||||
#define TARGET_GPR_BITS 64
|
||||
#define REGX "%08" PRIx32
|
||||
#else
|
||||
typedef uint32_t ppc_gpr_t;
|
||||
#define TARGET_LONG_BITS 32
|
||||
#define TARGET_GPR_BITS 32
|
||||
#define REGX "%08" PRIx32
|
||||
#endif
|
||||
|
||||
@@ -297,7 +302,7 @@ enum {
|
||||
/* ld/st with reservation instructions */
|
||||
/* cache control instructions */
|
||||
/* spr/msr access instructions */
|
||||
PPC_INSNS_BASE = 0x00000001,
|
||||
PPC_INSNS_BASE = 0x0000000000000001ULL,
|
||||
#define PPC_INTEGER PPC_INSNS_BASE
|
||||
#define PPC_FLOW PPC_INSNS_BASE
|
||||
#define PPC_MEM PPC_INSNS_BASE
|
||||
@@ -305,68 +310,72 @@ enum {
|
||||
#define PPC_CACHE PPC_INSNS_BASE
|
||||
#define PPC_MISC PPC_INSNS_BASE
|
||||
/* floating point operations instructions */
|
||||
PPC_FLOAT = 0x00000002,
|
||||
PPC_FLOAT = 0x0000000000000002ULL,
|
||||
/* more floating point operations instructions */
|
||||
PPC_FLOAT_EXT = 0x00000004,
|
||||
PPC_FLOAT_EXT = 0x0000000000000004ULL,
|
||||
/* external control instructions */
|
||||
PPC_EXTERN = 0x00000008,
|
||||
PPC_EXTERN = 0x0000000000000008ULL,
|
||||
/* segment register access instructions */
|
||||
PPC_SEGMENT = 0x00000010,
|
||||
PPC_SEGMENT = 0x0000000000000010ULL,
|
||||
/* Optional cache control instructions */
|
||||
PPC_CACHE_OPT = 0x00000020,
|
||||
PPC_CACHE_OPT = 0x0000000000000020ULL,
|
||||
/* Optional floating point op instructions */
|
||||
PPC_FLOAT_OPT = 0x00000040,
|
||||
PPC_FLOAT_OPT = 0x0000000000000040ULL,
|
||||
/* Optional memory control instructions */
|
||||
PPC_MEM_TLBIA = 0x00000080,
|
||||
PPC_MEM_TLBIE = 0x00000100,
|
||||
PPC_MEM_TLBSYNC = 0x00000200,
|
||||
PPC_MEM_TLBIA = 0x0000000000000080ULL,
|
||||
PPC_MEM_TLBIE = 0x0000000000000100ULL,
|
||||
PPC_MEM_TLBSYNC = 0x0000000000000200ULL,
|
||||
/* eieio & sync */
|
||||
PPC_MEM_SYNC = 0x00000400,
|
||||
PPC_MEM_SYNC = 0x0000000000000400ULL,
|
||||
/* PowerPC 6xx TLB management instructions */
|
||||
PPC_6xx_TLB = 0x00000800,
|
||||
PPC_6xx_TLB = 0x0000000000000800ULL,
|
||||
/* Altivec support */
|
||||
PPC_ALTIVEC = 0x00001000,
|
||||
PPC_ALTIVEC = 0x0000000000001000ULL,
|
||||
/* Time base support */
|
||||
PPC_TB = 0x00002000,
|
||||
PPC_TB = 0x0000000000002000ULL,
|
||||
/* Embedded PowerPC dedicated instructions */
|
||||
PPC_EMB_COMMON = 0x00004000,
|
||||
PPC_EMB_COMMON = 0x0000000000004000ULL,
|
||||
/* PowerPC 40x exception model */
|
||||
PPC_40x_EXCP = 0x00008000,
|
||||
PPC_40x_EXCP = 0x0000000000008000ULL,
|
||||
/* PowerPC 40x specific instructions */
|
||||
PPC_40x_SPEC = 0x00010000,
|
||||
PPC_40x_SPEC = 0x0000000000010000ULL,
|
||||
/* PowerPC 405 Mac instructions */
|
||||
PPC_405_MAC = 0x00020000,
|
||||
PPC_405_MAC = 0x0000000000020000ULL,
|
||||
/* PowerPC 440 specific instructions */
|
||||
PPC_440_SPEC = 0x00040000,
|
||||
PPC_440_SPEC = 0x0000000000040000ULL,
|
||||
/* Specific extensions */
|
||||
/* Power-to-PowerPC bridge (601) */
|
||||
PPC_POWER_BR = 0x00080000,
|
||||
PPC_POWER_BR = 0x0000000000080000ULL,
|
||||
/* PowerPC 602 specific */
|
||||
PPC_602_SPEC = 0x00100000,
|
||||
PPC_602_SPEC = 0x0000000000100000ULL,
|
||||
/* Deprecated instructions */
|
||||
/* Original POWER instruction set */
|
||||
PPC_POWER = 0x00200000,
|
||||
PPC_POWER = 0x0000000000200000ULL,
|
||||
/* POWER2 instruction set extension */
|
||||
PPC_POWER2 = 0x00400000,
|
||||
PPC_POWER2 = 0x0000000000400000ULL,
|
||||
/* Power RTC support */
|
||||
PPC_POWER_RTC = 0x00800000,
|
||||
PPC_POWER_RTC = 0x0000000000800000ULL,
|
||||
/* 64 bits PowerPC instructions */
|
||||
/* 64 bits PowerPC instruction set */
|
||||
PPC_64B = 0x01000000,
|
||||
PPC_64B = 0x0000000001000000ULL,
|
||||
/* 64 bits hypervisor extensions */
|
||||
PPC_64H = 0x02000000,
|
||||
PPC_64H = 0x0000000002000000ULL,
|
||||
/* 64 bits PowerPC "bridge" features */
|
||||
PPC_64_BRIDGE = 0x04000000,
|
||||
PPC_64_BRIDGE = 0x0000000004000000ULL,
|
||||
/* BookE (embedded) PowerPC specification */
|
||||
PPC_BOOKE = 0x08000000,
|
||||
PPC_BOOKE = 0x0000000008000000ULL,
|
||||
/* eieio */
|
||||
PPC_MEM_EIEIO = 0x10000000,
|
||||
PPC_MEM_EIEIO = 0x0000000010000000ULL,
|
||||
/* e500 vector instructions */
|
||||
PPC_E500_VECTOR = 0x20000000,
|
||||
PPC_E500_VECTOR = 0x0000000020000000ULL,
|
||||
/* PowerPC 4xx dedicated instructions */
|
||||
PPC_4xx_COMMON = 0x40000000,
|
||||
PPC_4xx_COMMON = 0x0000000040000000ULL,
|
||||
/* PowerPC 2.03 specification extensions */
|
||||
PPC_203 = 0x80000000,
|
||||
PPC_203 = 0x0000000080000000ULL,
|
||||
/* PowerPC 2.03 SPE extension */
|
||||
PPC_SPE = 0x0000000100000000ULL,
|
||||
/* PowerPC 2.03 SPE floating-point extension */
|
||||
PPC_SPEFPU = 0x0000000200000000ULL,
|
||||
};
|
||||
|
||||
/* CPU run-time flags (MMU and exception model) */
|
||||
@@ -618,10 +627,10 @@ struct CPUPPCState {
|
||||
/* First are the most commonly used resources
|
||||
* during translated code execution
|
||||
*/
|
||||
#if TARGET_LONG_BITS > HOST_LONG_BITS
|
||||
#if TARGET_GPR_BITS > HOST_LONG_BITS
|
||||
/* temporary fixed-point registers
|
||||
* used to emulate 64 bits target on 32 bits hosts
|
||||
*/
|
||||
*/
|
||||
target_ulong t0, t1, t2;
|
||||
#endif
|
||||
ppc_avr_t t0_avr, t1_avr, t2_avr;
|
||||
@@ -683,6 +692,7 @@ struct CPUPPCState {
|
||||
uint32_t vscr;
|
||||
/* SPE registers */
|
||||
ppc_gpr_t spe_acc;
|
||||
float_status spe_status;
|
||||
uint32_t spe_fscr;
|
||||
|
||||
/* Internal devices resources */
|
||||
@@ -1192,6 +1202,8 @@ enum {
|
||||
#define EXCP_970_MAINT 0x1600 /* Maintenance exception */
|
||||
#define EXCP_970_THRM 0x1800 /* Thermal exception */
|
||||
#define EXCP_970_VPUA 0x1700 /* VPU assist exception */
|
||||
/* SPE related exceptions */
|
||||
#define EXCP_NO_SPE 0x0F20 /* SPE unavailable exception */
|
||||
/* End of exception vectors area */
|
||||
#define EXCP_PPC_MAX 0x4000
|
||||
/* Qemu exceptions: special cases we want to stop translation */
|
||||
|
||||
+3
-3
@@ -39,10 +39,10 @@ register unsigned long T1 asm(AREG2);
|
||||
register unsigned long T2 asm(AREG3);
|
||||
#endif
|
||||
/* We may, sometime, need 64 bits registers on 32 bits target */
|
||||
#if defined(TARGET_PPC64) || (HOST_LONG_BITS == 64)
|
||||
#if defined(TARGET_PPC64) || defined(TARGET_PPCSPE) || (HOST_LONG_BITS == 64)
|
||||
#define T0_64 T0
|
||||
#define T1_64 T0
|
||||
#define T2_64 T0
|
||||
#define T1_64 T1
|
||||
#define T2_64 T2
|
||||
#else
|
||||
/* no registers can be used */
|
||||
#define T0_64 (env->t0)
|
||||
|
||||
+721
-94
File diff suppressed because it is too large
Load Diff
+868
-1
File diff suppressed because it is too large
Load Diff
@@ -100,6 +100,7 @@ void do_fctiwz (void);
|
||||
void do_fcmpu (void);
|
||||
void do_fcmpo (void);
|
||||
|
||||
/* Misc */
|
||||
void do_tw (int flags);
|
||||
#if defined(TARGET_PPC64)
|
||||
void do_td (int flags);
|
||||
@@ -157,11 +158,291 @@ void do_4xx_tlbwe_lo (void);
|
||||
void do_4xx_tlbwe_hi (void);
|
||||
#endif
|
||||
|
||||
/* PowerPC 440 specific helpers */
|
||||
void do_440_dlmzb (void);
|
||||
|
||||
/* PowerPC 403 specific helpers */
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
void do_load_403_pb (int num);
|
||||
void do_store_403_pb (int num);
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_PPCSPE)
|
||||
/* SPE extension helpers */
|
||||
void do_brinc (void);
|
||||
/* Fixed-point vector helpers */
|
||||
void do_evabs (void);
|
||||
void do_evaddw (void);
|
||||
void do_evcntlsw (void);
|
||||
void do_evcntlzw (void);
|
||||
void do_evneg (void);
|
||||
void do_evrlw (void);
|
||||
void do_evsel (void);
|
||||
void do_evrndw (void);
|
||||
void do_evslw (void);
|
||||
void do_evsrws (void);
|
||||
void do_evsrwu (void);
|
||||
void do_evsubfw (void);
|
||||
void do_evcmpeq (void);
|
||||
void do_evcmpgts (void);
|
||||
void do_evcmpgtu (void);
|
||||
void do_evcmplts (void);
|
||||
void do_evcmpltu (void);
|
||||
|
||||
/* Single precision floating-point helpers */
|
||||
void do_efscmplt (void);
|
||||
void do_efscmpgt (void);
|
||||
void do_efscmpeq (void);
|
||||
void do_efscfsf (void);
|
||||
void do_efscfuf (void);
|
||||
void do_efsctsf (void);
|
||||
void do_efsctuf (void);
|
||||
|
||||
void do_efscfsi (void);
|
||||
void do_efscfui (void);
|
||||
void do_efsctsi (void);
|
||||
void do_efsctui (void);
|
||||
void do_efsctsiz (void);
|
||||
void do_efsctuiz (void);
|
||||
|
||||
/* Double precision floating-point helpers */
|
||||
void do_efdcmplt (void);
|
||||
void do_efdcmpgt (void);
|
||||
void do_efdcmpeq (void);
|
||||
void do_efdcfsf (void);
|
||||
void do_efdcfuf (void);
|
||||
void do_efdctsf (void);
|
||||
void do_efdctuf (void);
|
||||
|
||||
void do_efdcfsi (void);
|
||||
void do_efdcfui (void);
|
||||
void do_efdctsi (void);
|
||||
void do_efdctui (void);
|
||||
void do_efdctsiz (void);
|
||||
void do_efdctuiz (void);
|
||||
|
||||
void do_efdcfs (void);
|
||||
void do_efscfd (void);
|
||||
|
||||
/* Floating-point vector helpers */
|
||||
void do_evfsabs (void);
|
||||
void do_evfsnabs (void);
|
||||
void do_evfsneg (void);
|
||||
void do_evfsadd (void);
|
||||
void do_evfssub (void);
|
||||
void do_evfsmul (void);
|
||||
void do_evfsdiv (void);
|
||||
void do_evfscmplt (void);
|
||||
void do_evfscmpgt (void);
|
||||
void do_evfscmpeq (void);
|
||||
void do_evfststlt (void);
|
||||
void do_evfststgt (void);
|
||||
void do_evfststeq (void);
|
||||
void do_evfscfsi (void);
|
||||
void do_evfscfui (void);
|
||||
void do_evfscfsf (void);
|
||||
void do_evfscfuf (void);
|
||||
void do_evfsctsf (void);
|
||||
void do_evfsctuf (void);
|
||||
void do_evfsctsi (void);
|
||||
void do_evfsctui (void);
|
||||
void do_evfsctsiz (void);
|
||||
void do_evfsctuiz (void);
|
||||
#endif /* defined(TARGET_PPCSPE) */
|
||||
|
||||
/* Inlined helpers: used in micro-operation as well as helpers */
|
||||
/* Generic fixed-point helpers */
|
||||
static inline int _do_cntlzw (uint32_t val)
|
||||
{
|
||||
int cnt = 0;
|
||||
if (!(val & 0xFFFF0000UL)) {
|
||||
cnt += 16;
|
||||
val <<= 16;
|
||||
}
|
||||
if (!(val & 0xFF000000UL)) {
|
||||
cnt += 8;
|
||||
val <<= 8;
|
||||
}
|
||||
if (!(val & 0xF0000000UL)) {
|
||||
cnt += 4;
|
||||
val <<= 4;
|
||||
}
|
||||
if (!(val & 0xC0000000UL)) {
|
||||
cnt += 2;
|
||||
val <<= 2;
|
||||
}
|
||||
if (!(val & 0x80000000UL)) {
|
||||
cnt++;
|
||||
val <<= 1;
|
||||
}
|
||||
if (!(val & 0x80000000UL)) {
|
||||
cnt++;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
static inline int _do_cntlzd (uint64_t val)
|
||||
{
|
||||
int cnt = 0;
|
||||
#if HOST_LONG_BITS == 64
|
||||
if (!(val & 0xFFFFFFFF00000000ULL)) {
|
||||
cnt += 32;
|
||||
val <<= 32;
|
||||
}
|
||||
if (!(val & 0xFFFF000000000000ULL)) {
|
||||
cnt += 16;
|
||||
val <<= 16;
|
||||
}
|
||||
if (!(val & 0xFF00000000000000ULL)) {
|
||||
cnt += 8;
|
||||
val <<= 8;
|
||||
}
|
||||
if (!(val & 0xF000000000000000ULL)) {
|
||||
cnt += 4;
|
||||
val <<= 4;
|
||||
}
|
||||
if (!(val & 0xC000000000000000ULL)) {
|
||||
cnt += 2;
|
||||
val <<= 2;
|
||||
}
|
||||
if (!(val & 0x8000000000000000ULL)) {
|
||||
cnt++;
|
||||
val <<= 1;
|
||||
}
|
||||
if (!(val & 0x8000000000000000ULL)) {
|
||||
cnt++;
|
||||
}
|
||||
#else
|
||||
uint32_t tmp;
|
||||
/* Make it easier on 32 bits host machines */
|
||||
if (!(val >> 32))
|
||||
cnt = cntlzw(val) + 32;
|
||||
else
|
||||
cnt = cntlzw(val >> 32);
|
||||
#endif
|
||||
return cnt;
|
||||
}
|
||||
|
||||
#if defined(TARGET_PPCSPE)
|
||||
/* SPE extension */
|
||||
/* Single precision floating-point helpers */
|
||||
static inline uint32_t _do_efsabs (uint32_t val)
|
||||
{
|
||||
return val & ~0x80000000;
|
||||
}
|
||||
static inline uint32_t _do_efsnabs (uint32_t val)
|
||||
{
|
||||
return val | 0x80000000;
|
||||
}
|
||||
static inline uint32_t _do_efsneg (uint32_t val)
|
||||
{
|
||||
return val ^ 0x80000000;
|
||||
}
|
||||
static inline uint32_t _do_efsadd (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
union {
|
||||
uint32_t u;
|
||||
float32 f;
|
||||
} u1, u2;
|
||||
u1.u = op1;
|
||||
u2.u = op2;
|
||||
u1.f = float32_add(u1.f, u2.f, &env->spe_status);
|
||||
return u1.u;
|
||||
}
|
||||
static inline uint32_t _do_efssub (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
union {
|
||||
uint32_t u;
|
||||
float32 f;
|
||||
} u1, u2;
|
||||
u1.u = op1;
|
||||
u2.u = op2;
|
||||
u1.f = float32_sub(u1.f, u2.f, &env->spe_status);
|
||||
return u1.u;
|
||||
}
|
||||
static inline uint32_t _do_efsmul (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
union {
|
||||
uint32_t u;
|
||||
float32 f;
|
||||
} u1, u2;
|
||||
u1.u = op1;
|
||||
u2.u = op2;
|
||||
u1.f = float32_mul(u1.f, u2.f, &env->spe_status);
|
||||
return u1.u;
|
||||
}
|
||||
static inline uint32_t _do_efsdiv (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
union {
|
||||
uint32_t u;
|
||||
float32 f;
|
||||
} u1, u2;
|
||||
u1.u = op1;
|
||||
u2.u = op2;
|
||||
u1.f = float32_div(u1.f, u2.f, &env->spe_status);
|
||||
return u1.u;
|
||||
}
|
||||
|
||||
static inline int _do_efststlt (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
union {
|
||||
uint32_t u;
|
||||
float32 f;
|
||||
} u1, u2;
|
||||
u1.u = op1;
|
||||
u2.u = op2;
|
||||
return float32_lt(u1.f, u2.f, &env->spe_status) ? 1 : 0;
|
||||
}
|
||||
static inline int _do_efststgt (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
union {
|
||||
uint32_t u;
|
||||
float32 f;
|
||||
} u1, u2;
|
||||
u1.u = op1;
|
||||
u2.u = op2;
|
||||
return float32_le(u1.f, u2.f, &env->spe_status) ? 0 : 1;
|
||||
}
|
||||
static inline int _do_efststeq (uint32_t op1, uint32_t op2)
|
||||
{
|
||||
union {
|
||||
uint32_t u;
|
||||
float32 f;
|
||||
} u1, u2;
|
||||
u1.u = op1;
|
||||
u2.u = op2;
|
||||
return float32_eq(u1.f, u2.f, &env->spe_status) ? 1 : 0;
|
||||
}
|
||||
/* Double precision floating-point helpers */
|
||||
static inline int _do_efdtstlt (uint64_t op1, uint64_t op2)
|
||||
{
|
||||
union {
|
||||
uint64_t u;
|
||||
float64 f;
|
||||
} u1, u2;
|
||||
u1.u = op1;
|
||||
u2.u = op2;
|
||||
return float64_lt(u1.f, u2.f, &env->spe_status) ? 1 : 0;
|
||||
}
|
||||
static inline int _do_efdtstgt (uint64_t op1, uint64_t op2)
|
||||
{
|
||||
union {
|
||||
uint64_t u;
|
||||
float64 f;
|
||||
} u1, u2;
|
||||
u1.u = op1;
|
||||
u2.u = op2;
|
||||
return float64_le(u1.f, u2.f, &env->spe_status) ? 0 : 1;
|
||||
}
|
||||
static inline int _do_efdtsteq (uint64_t op1, uint64_t op2)
|
||||
{
|
||||
union {
|
||||
uint64_t u;
|
||||
float64 f;
|
||||
} u1, u2;
|
||||
u1.u = op1;
|
||||
u2.u = op2;
|
||||
return float64_eq(u1.f, u2.f, &env->spe_status) ? 1 : 0;
|
||||
}
|
||||
#endif /* defined(TARGET_PPCSPE) */
|
||||
#endif
|
||||
|
||||
+267
-7
@@ -37,12 +37,7 @@ static inline uint32_t glue(ld32r, MEMSUFFIX) (target_ulong EA)
|
||||
((tmp & 0x0000FF00) << 8) | ((tmp & 0x000000FF) << 24);
|
||||
}
|
||||
|
||||
#if defined(TARGET_PPC64)
|
||||
static inline int64_t glue(ldsl, MEMSUFFIX) (target_ulong EA)
|
||||
{
|
||||
return (int32_t)glue(ldl, MEMSUFFIX)(EA);
|
||||
}
|
||||
|
||||
#if defined(TARGET_PPC64) || defined(TARGET_PPCSPE)
|
||||
static inline uint64_t glue(ld64r, MEMSUFFIX) (target_ulong EA)
|
||||
{
|
||||
uint64_t tmp = glue(ldq, MEMSUFFIX)(EA);
|
||||
@@ -55,6 +50,13 @@ static inline uint64_t glue(ld64r, MEMSUFFIX) (target_ulong EA)
|
||||
((tmp & 0x000000000000FF00ULL) << 40) |
|
||||
((tmp & 0x00000000000000FFULL) << 54);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_PPC64)
|
||||
static inline int64_t glue(ldsl, MEMSUFFIX) (target_ulong EA)
|
||||
{
|
||||
return (int32_t)glue(ldl, MEMSUFFIX)(EA);
|
||||
}
|
||||
|
||||
static inline int64_t glue(ld32rs, MEMSUFFIX) (target_ulong EA)
|
||||
{
|
||||
@@ -77,7 +79,7 @@ static inline void glue(st32r, MEMSUFFIX) (target_ulong EA, uint32_t data)
|
||||
glue(stl, MEMSUFFIX)(EA, tmp);
|
||||
}
|
||||
|
||||
#if defined(TARGET_PPC64)
|
||||
#if defined(TARGET_PPC64) || defined(TARGET_PPCSPE)
|
||||
static inline void glue(st64r, MEMSUFFIX) (target_ulong EA, uint64_t data)
|
||||
{
|
||||
uint64_t tmp = ((data & 0xFF00000000000000ULL) >> 56) |
|
||||
@@ -839,4 +841,262 @@ void OPPROTO glue(op_POWER2_stfq_le, MEMSUFFIX) (void)
|
||||
RETURN();
|
||||
}
|
||||
|
||||
#if defined(TARGET_PPCSPE)
|
||||
/* SPE extension */
|
||||
#define _PPC_SPE_LD_OP(name, op) \
|
||||
void OPPROTO glue(glue(op_spe_l, name), MEMSUFFIX) (void) \
|
||||
{ \
|
||||
T1_64 = glue(op, MEMSUFFIX)((uint32_t)T0); \
|
||||
RETURN(); \
|
||||
}
|
||||
|
||||
#if defined(TARGET_PPC64)
|
||||
#define _PPC_SPE_LD_OP_64(name, op) \
|
||||
void OPPROTO glue(glue(glue(op_spe_l, name), _64), MEMSUFFIX) (void) \
|
||||
{ \
|
||||
T1_64 = glue(op, MEMSUFFIX)((uint64_t)T0); \
|
||||
RETURN(); \
|
||||
}
|
||||
#define PPC_SPE_LD_OP(name, op) \
|
||||
_PPC_SPE_LD_OP(name, op); \
|
||||
_PPC_SPE_LD_OP_64(name, op)
|
||||
#else
|
||||
#define PPC_SPE_LD_OP(name, op) \
|
||||
_PPC_SPE_LD_OP(name, op)
|
||||
#endif
|
||||
|
||||
|
||||
#define _PPC_SPE_ST_OP(name, op) \
|
||||
void OPPROTO glue(glue(op_spe_st, name), MEMSUFFIX) (void) \
|
||||
{ \
|
||||
glue(op, MEMSUFFIX)((uint32_t)T0, T1_64); \
|
||||
RETURN(); \
|
||||
}
|
||||
|
||||
#if defined(TARGET_PPC64)
|
||||
#define _PPC_SPE_ST_OP_64(name, op) \
|
||||
void OPPROTO glue(glue(glue(op_spe_st, name), _64), MEMSUFFIX) (void) \
|
||||
{ \
|
||||
glue(op, MEMSUFFIX)((uint64_t)T0, T1_64); \
|
||||
RETURN(); \
|
||||
}
|
||||
#define PPC_SPE_ST_OP(name, op) \
|
||||
_PPC_SPE_ST_OP(name, op); \
|
||||
_PPC_SPE_ST_OP_64(name, op)
|
||||
#else
|
||||
#define PPC_SPE_ST_OP(name, op) \
|
||||
_PPC_SPE_ST_OP(name, op)
|
||||
#endif
|
||||
|
||||
#if !defined(TARGET_PPC64)
|
||||
PPC_SPE_LD_OP(dd, ldq);
|
||||
PPC_SPE_ST_OP(dd, stq);
|
||||
PPC_SPE_LD_OP(dd_le, ld64r);
|
||||
PPC_SPE_ST_OP(dd_le, st64r);
|
||||
#endif
|
||||
static inline uint64_t glue(spe_ldw, MEMSUFFIX) (target_ulong EA)
|
||||
{
|
||||
uint64_t ret;
|
||||
ret = (uint64_t)glue(ldl, MEMSUFFIX)(EA) << 32;
|
||||
ret |= (uint64_t)glue(ldl, MEMSUFFIX)(EA + 4);
|
||||
return ret;
|
||||
}
|
||||
PPC_SPE_LD_OP(dw, spe_ldw);
|
||||
static inline void glue(spe_stdw, MEMSUFFIX) (target_ulong EA, uint64_t data)
|
||||
{
|
||||
glue(stl, MEMSUFFIX)(EA, data >> 32);
|
||||
glue(stl, MEMSUFFIX)(EA + 4, data);
|
||||
}
|
||||
PPC_SPE_ST_OP(dw, spe_stdw);
|
||||
static inline uint64_t glue(spe_ldw_le, MEMSUFFIX) (target_ulong EA)
|
||||
{
|
||||
uint64_t ret;
|
||||
ret = (uint64_t)glue(ld32r, MEMSUFFIX)(EA) << 32;
|
||||
ret |= (uint64_t)glue(ld32r, MEMSUFFIX)(EA + 4);
|
||||
return ret;
|
||||
}
|
||||
PPC_SPE_LD_OP(dw_le, spe_ldw_le);
|
||||
static inline void glue(spe_stdw_le, MEMSUFFIX) (target_ulong EA,
|
||||
uint64_t data)
|
||||
{
|
||||
glue(st32r, MEMSUFFIX)(EA, data >> 32);
|
||||
glue(st32r, MEMSUFFIX)(EA + 4, data);
|
||||
}
|
||||
PPC_SPE_ST_OP(dw_le, spe_stdw_le);
|
||||
static inline uint64_t glue(spe_ldh, MEMSUFFIX) (target_ulong EA)
|
||||
{
|
||||
uint64_t ret;
|
||||
ret = (uint64_t)glue(lduw, MEMSUFFIX)(EA) << 48;
|
||||
ret |= (uint64_t)glue(lduw, MEMSUFFIX)(EA + 2) << 32;
|
||||
ret |= (uint64_t)glue(lduw, MEMSUFFIX)(EA + 4) << 16;
|
||||
ret |= (uint64_t)glue(lduw, MEMSUFFIX)(EA + 6);
|
||||
return ret;
|
||||
}
|
||||
PPC_SPE_LD_OP(dh, spe_ldh);
|
||||
static inline void glue(spe_stdh, MEMSUFFIX) (target_ulong EA, uint64_t data)
|
||||
{
|
||||
glue(stw, MEMSUFFIX)(EA, data >> 48);
|
||||
glue(stw, MEMSUFFIX)(EA + 2, data >> 32);
|
||||
glue(stw, MEMSUFFIX)(EA + 4, data >> 16);
|
||||
glue(stw, MEMSUFFIX)(EA + 6, data);
|
||||
}
|
||||
PPC_SPE_ST_OP(dh, spe_stdh);
|
||||
static inline uint64_t glue(spe_ldh_le, MEMSUFFIX) (target_ulong EA)
|
||||
{
|
||||
uint64_t ret;
|
||||
ret = (uint64_t)glue(ld16r, MEMSUFFIX)(EA) << 48;
|
||||
ret |= (uint64_t)glue(ld16r, MEMSUFFIX)(EA + 2) << 32;
|
||||
ret |= (uint64_t)glue(ld16r, MEMSUFFIX)(EA + 4) << 16;
|
||||
ret |= (uint64_t)glue(ld16r, MEMSUFFIX)(EA + 6);
|
||||
return ret;
|
||||
}
|
||||
PPC_SPE_LD_OP(dh_le, spe_ldh_le);
|
||||
static inline void glue(spe_stdh_le, MEMSUFFIX) (target_ulong EA,
|
||||
uint64_t data)
|
||||
{
|
||||
glue(st16r, MEMSUFFIX)(EA, data >> 48);
|
||||
glue(st16r, MEMSUFFIX)(EA + 2, data >> 32);
|
||||
glue(st16r, MEMSUFFIX)(EA + 4, data >> 16);
|
||||
glue(st16r, MEMSUFFIX)(EA + 6, data);
|
||||
}
|
||||
PPC_SPE_ST_OP(dh_le, spe_stdh_le);
|
||||
static inline uint64_t glue(spe_lwhe, MEMSUFFIX) (target_ulong EA)
|
||||
{
|
||||
uint64_t ret;
|
||||
ret = (uint64_t)glue(lduw, MEMSUFFIX)(EA) << 48;
|
||||
ret |= (uint64_t)glue(lduw, MEMSUFFIX)(EA + 2) << 16;
|
||||
return ret;
|
||||
}
|
||||
PPC_SPE_LD_OP(whe, spe_lwhe);
|
||||
static inline void glue(spe_stwhe, MEMSUFFIX) (target_ulong EA, uint64_t data)
|
||||
{
|
||||
glue(stw, MEMSUFFIX)(EA, data >> 48);
|
||||
glue(stw, MEMSUFFIX)(EA + 2, data >> 16);
|
||||
}
|
||||
PPC_SPE_ST_OP(whe, spe_stwhe);
|
||||
static inline uint64_t glue(spe_lwhe_le, MEMSUFFIX) (target_ulong EA)
|
||||
{
|
||||
uint64_t ret;
|
||||
ret = (uint64_t)glue(ld16r, MEMSUFFIX)(EA) << 48;
|
||||
ret |= (uint64_t)glue(ld16r, MEMSUFFIX)(EA + 2) << 16;
|
||||
return ret;
|
||||
}
|
||||
PPC_SPE_LD_OP(whe_le, spe_lwhe_le);
|
||||
static inline void glue(spe_stwhe_le, MEMSUFFIX) (target_ulong EA,
|
||||
uint64_t data)
|
||||
{
|
||||
glue(st16r, MEMSUFFIX)(EA, data >> 48);
|
||||
glue(st16r, MEMSUFFIX)(EA + 2, data >> 16);
|
||||
}
|
||||
PPC_SPE_ST_OP(whe_le, spe_stwhe_le);
|
||||
static inline uint64_t glue(spe_lwhou, MEMSUFFIX) (target_ulong EA)
|
||||
{
|
||||
uint64_t ret;
|
||||
ret = (uint64_t)glue(lduw, MEMSUFFIX)(EA) << 32;
|
||||
ret |= (uint64_t)glue(lduw, MEMSUFFIX)(EA + 2);
|
||||
return ret;
|
||||
}
|
||||
PPC_SPE_LD_OP(whou, spe_lwhou);
|
||||
static inline uint64_t glue(spe_lwhos, MEMSUFFIX) (target_ulong EA)
|
||||
{
|
||||
uint64_t ret;
|
||||
ret = ((uint64_t)((int32_t)glue(ldsw, MEMSUFFIX)(EA))) << 32;
|
||||
ret |= (uint64_t)((int32_t)glue(ldsw, MEMSUFFIX)(EA + 2));
|
||||
return ret;
|
||||
}
|
||||
PPC_SPE_LD_OP(whos, spe_lwhos);
|
||||
static inline void glue(spe_stwho, MEMSUFFIX) (target_ulong EA, uint64_t data)
|
||||
{
|
||||
glue(stw, MEMSUFFIX)(EA, data >> 32);
|
||||
glue(stw, MEMSUFFIX)(EA + 2, data);
|
||||
}
|
||||
PPC_SPE_ST_OP(who, spe_stwho);
|
||||
static inline uint64_t glue(spe_lwhou_le, MEMSUFFIX) (target_ulong EA)
|
||||
{
|
||||
uint64_t ret;
|
||||
ret = (uint64_t)glue(ld16r, MEMSUFFIX)(EA) << 32;
|
||||
ret |= (uint64_t)glue(ld16r, MEMSUFFIX)(EA + 2);
|
||||
return ret;
|
||||
}
|
||||
PPC_SPE_LD_OP(whou_le, spe_lwhou_le);
|
||||
static inline uint64_t glue(spe_lwhos_le, MEMSUFFIX) (target_ulong EA)
|
||||
{
|
||||
uint64_t ret;
|
||||
ret = ((uint64_t)((int32_t)glue(ld16rs, MEMSUFFIX)(EA))) << 32;
|
||||
ret |= (uint64_t)((int32_t)glue(ld16rs, MEMSUFFIX)(EA + 2));
|
||||
return ret;
|
||||
}
|
||||
PPC_SPE_LD_OP(whos_le, spe_lwhos_le);
|
||||
static inline void glue(spe_stwho_le, MEMSUFFIX) (target_ulong EA,
|
||||
uint64_t data)
|
||||
{
|
||||
glue(st16r, MEMSUFFIX)(EA, data >> 32);
|
||||
glue(st16r, MEMSUFFIX)(EA + 2, data);
|
||||
}
|
||||
PPC_SPE_ST_OP(who_le, spe_stwho_le);
|
||||
#if !defined(TARGET_PPC64)
|
||||
static inline void glue(spe_stwwo, MEMSUFFIX) (target_ulong EA, uint64_t data)
|
||||
{
|
||||
glue(stl, MEMSUFFIX)(EA, data);
|
||||
}
|
||||
PPC_SPE_ST_OP(wwo, spe_stwwo);
|
||||
static inline void glue(spe_stwwo_le, MEMSUFFIX) (target_ulong EA,
|
||||
uint64_t data)
|
||||
{
|
||||
glue(st32r, MEMSUFFIX)(EA, data);
|
||||
}
|
||||
PPC_SPE_ST_OP(wwo_le, spe_stwwo_le);
|
||||
#endif
|
||||
static inline uint64_t glue(spe_lh, MEMSUFFIX) (target_ulong EA)
|
||||
{
|
||||
uint16_t tmp;
|
||||
tmp = glue(lduw, MEMSUFFIX)(EA);
|
||||
return ((uint64_t)tmp << 48) | ((uint64_t)tmp << 16);
|
||||
}
|
||||
PPC_SPE_LD_OP(h, spe_lh);
|
||||
static inline uint64_t glue(spe_lh_le, MEMSUFFIX) (target_ulong EA)
|
||||
{
|
||||
uint16_t tmp;
|
||||
tmp = glue(ld16r, MEMSUFFIX)(EA);
|
||||
return ((uint64_t)tmp << 48) | ((uint64_t)tmp << 16);
|
||||
}
|
||||
PPC_SPE_LD_OP(h_le, spe_lh_le);
|
||||
static inline uint64_t glue(spe_lwwsplat, MEMSUFFIX) (target_ulong EA)
|
||||
{
|
||||
uint32_t tmp;
|
||||
tmp = glue(ldl, MEMSUFFIX)(EA);
|
||||
return ((uint64_t)tmp << 32) | (uint64_t)tmp;
|
||||
}
|
||||
PPC_SPE_LD_OP(wwsplat, spe_lwwsplat);
|
||||
static inline uint64_t glue(spe_lwwsplat_le, MEMSUFFIX) (target_ulong EA)
|
||||
{
|
||||
uint32_t tmp;
|
||||
tmp = glue(ld32r, MEMSUFFIX)(EA);
|
||||
return ((uint64_t)tmp << 32) | (uint64_t)tmp;
|
||||
}
|
||||
PPC_SPE_LD_OP(wwsplat_le, spe_lwwsplat_le);
|
||||
static inline uint64_t glue(spe_lwhsplat, MEMSUFFIX) (target_ulong EA)
|
||||
{
|
||||
uint64_t ret;
|
||||
uint16_t tmp;
|
||||
tmp = glue(lduw, MEMSUFFIX)(EA);
|
||||
ret = ((uint64_t)tmp << 48) | ((uint64_t)tmp << 32);
|
||||
tmp = glue(lduw, MEMSUFFIX)(EA + 2);
|
||||
ret |= ((uint64_t)tmp << 16) | (uint64_t)tmp;
|
||||
return ret;
|
||||
}
|
||||
PPC_SPE_LD_OP(whsplat, spe_lwhsplat);
|
||||
static inline uint64_t glue(spe_lwhsplat_le, MEMSUFFIX) (target_ulong EA)
|
||||
{
|
||||
uint64_t ret;
|
||||
uint16_t tmp;
|
||||
tmp = glue(ld16r, MEMSUFFIX)(EA);
|
||||
ret = ((uint64_t)tmp << 48) | ((uint64_t)tmp << 32);
|
||||
tmp = glue(ld16r, MEMSUFFIX)(EA + 2);
|
||||
ret |= ((uint64_t)tmp << 16) | (uint64_t)tmp;
|
||||
return ret;
|
||||
}
|
||||
PPC_SPE_LD_OP(whsplat_le, spe_lwhsplat_le);
|
||||
#endif /* defined(TARGET_PPCSPE) */
|
||||
|
||||
#undef MEMSUFFIX
|
||||
|
||||
@@ -57,6 +57,48 @@ void OPPROTO glue(op_store_T2_gpr_gpr, REG) (void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_PPCSPE)
|
||||
void OPPROTO glue(op_load_gpr64_T0_gpr, REG) (void)
|
||||
{
|
||||
T0_64 = regs->gpr[REG];
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO glue(op_load_gpr64_T1_gpr, REG) (void)
|
||||
{
|
||||
T1_64 = regs->gpr[REG];
|
||||
RETURN();
|
||||
}
|
||||
|
||||
#if 0 // unused
|
||||
void OPPROTO glue(op_load_gpr64_T2_gpr, REG) (void)
|
||||
{
|
||||
T2_64 = regs->gpr[REG];
|
||||
RETURN();
|
||||
}
|
||||
#endif
|
||||
|
||||
void OPPROTO glue(op_store_T0_gpr64_gpr, REG) (void)
|
||||
{
|
||||
regs->gpr[REG] = T0_64;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
void OPPROTO glue(op_store_T1_gpr64_gpr, REG) (void)
|
||||
{
|
||||
regs->gpr[REG] = T1_64;
|
||||
RETURN();
|
||||
}
|
||||
|
||||
#if 0 // unused
|
||||
void OPPROTO glue(op_store_T2_gpr64_gpr, REG) (void)
|
||||
{
|
||||
regs->gpr[REG] = T2_64;
|
||||
RETURN();
|
||||
}
|
||||
#endif
|
||||
#endif /* defined(TARGET_PPCSPE) */
|
||||
|
||||
#if REG <= 7
|
||||
/* Condition register moves */
|
||||
void OPPROTO glue(op_load_crf_T0_crf, REG) (void)
|
||||
|
||||
+818
-4
File diff suppressed because it is too large
Load Diff
@@ -30,7 +30,7 @@ struct ppc_def_t {
|
||||
const unsigned char *name;
|
||||
uint32_t pvr;
|
||||
uint32_t pvr_mask;
|
||||
uint32_t insns_flags;
|
||||
uint64_t insns_flags;
|
||||
uint32_t flags;
|
||||
uint64_t msr_mask;
|
||||
};
|
||||
@@ -2424,7 +2424,8 @@ static int create_ppc_opcodes (CPUPPCState *env, ppc_def_t *def)
|
||||
|
||||
fill_new_table(env->opcodes, 0x40);
|
||||
#if defined(PPC_DUMP_CPU)
|
||||
printf("* PowerPC instructions for PVR %08x: %s flags %08x %08x\n",
|
||||
printf("* PowerPC instructions for PVR %08x: %s flags %016 " PRIx64
|
||||
" %08x\n",
|
||||
def->pvr, def->name, def->insns_flags, def->flags);
|
||||
#endif
|
||||
if (&opc_start < &opc_end) {
|
||||
|
||||
Reference in New Issue
Block a user