mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-06 17:23:56 -06:00
target-ppc: Allow little-endian user mode.
This allows running PPC64 little-endian in user mode if target is configured that way. In PPC64 LE user mode we set MSR.LE during initialization. Signed-off-by: Doug Kwan <dougkwan@google.com> Signed-off-by: Tom Musta <tommusta@gmail.com> Signed-off-by: Alexander Graf <agraf@suse.de>
This commit is contained in:
parent
d90b94cd78
commit
e22c357b3e
4 changed files with 92 additions and 96 deletions
|
@ -25,6 +25,15 @@
|
|||
|
||||
//#define DEBUG_OP
|
||||
|
||||
static inline bool needs_byteswap(const CPUPPCState *env)
|
||||
{
|
||||
#if defined(TARGET_WORDS_BIGENDIAN)
|
||||
return msr_le;
|
||||
#else
|
||||
return !msr_le;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* Memory load and stores */
|
||||
|
||||
|
@ -44,7 +53,7 @@ static inline target_ulong addr_add(CPUPPCState *env, target_ulong addr,
|
|||
void helper_lmw(CPUPPCState *env, target_ulong addr, uint32_t reg)
|
||||
{
|
||||
for (; reg < 32; reg++) {
|
||||
if (msr_le) {
|
||||
if (needs_byteswap(env)) {
|
||||
env->gpr[reg] = bswap32(cpu_ldl_data(env, addr));
|
||||
} else {
|
||||
env->gpr[reg] = cpu_ldl_data(env, addr);
|
||||
|
@ -56,7 +65,7 @@ void helper_lmw(CPUPPCState *env, target_ulong addr, uint32_t reg)
|
|||
void helper_stmw(CPUPPCState *env, target_ulong addr, uint32_t reg)
|
||||
{
|
||||
for (; reg < 32; reg++) {
|
||||
if (msr_le) {
|
||||
if (needs_byteswap(env)) {
|
||||
cpu_stl_data(env, addr, bswap32((uint32_t)env->gpr[reg]));
|
||||
} else {
|
||||
cpu_stl_data(env, addr, (uint32_t)env->gpr[reg]);
|
||||
|
@ -199,6 +208,11 @@ target_ulong helper_lscbx(CPUPPCState *env, target_ulong addr, uint32_t reg,
|
|||
#define LO_IDX 0
|
||||
#endif
|
||||
|
||||
/* We use msr_le to determine index ordering in a vector. However,
|
||||
byteswapping is not simply controlled by msr_le. We also need to take
|
||||
into account endianness of the target. This is done for the little-endian
|
||||
PPC64 user-mode target. */
|
||||
|
||||
#define LVE(name, access, swap, element) \
|
||||
void helper_##name(CPUPPCState *env, ppc_avr_t *r, \
|
||||
target_ulong addr) \
|
||||
|
@ -207,9 +221,11 @@ target_ulong helper_lscbx(CPUPPCState *env, target_ulong addr, uint32_t reg,
|
|||
int adjust = HI_IDX*(n_elems - 1); \
|
||||
int sh = sizeof(r->element[0]) >> 1; \
|
||||
int index = (addr & 0xf) >> sh; \
|
||||
\
|
||||
if (msr_le) { \
|
||||
index = n_elems - index - 1; \
|
||||
} \
|
||||
\
|
||||
if (needs_byteswap(env)) { \
|
||||
r->element[LO_IDX ? index : (adjust - index)] = \
|
||||
swap(access(env, addr)); \
|
||||
} else { \
|
||||
|
@ -232,9 +248,11 @@ LVE(lvewx, cpu_ldl_data, bswap32, u32)
|
|||
int adjust = HI_IDX * (n_elems - 1); \
|
||||
int sh = sizeof(r->element[0]) >> 1; \
|
||||
int index = (addr & 0xf) >> sh; \
|
||||
\
|
||||
if (msr_le) { \
|
||||
index = n_elems - index - 1; \
|
||||
} \
|
||||
\
|
||||
if (needs_byteswap(env)) { \
|
||||
access(env, addr, swap(r->element[LO_IDX ? index : \
|
||||
(adjust - index)])); \
|
||||
} else { \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue