diff options
author | Greg Kurz | 2016-01-15 16:00:38 +0100 |
---|---|---|
committer | David Gibson | 2016-01-30 13:37:38 +0100 |
commit | ea499e71506c91aa259a7fdccf1d6b2022f5b530 (patch) | |
tree | b5a89a908f90ff3977feb5b093d33b4cf35f010b /target-ppc/translate_init.c | |
parent | target-ppc: gdbstub: introduce avr_need_swap() (diff) | |
download | qemu-ea499e71506c91aa259a7fdccf1d6b2022f5b530.tar.gz qemu-ea499e71506c91aa259a7fdccf1d6b2022f5b530.tar.xz qemu-ea499e71506c91aa259a7fdccf1d6b2022f5b530.zip |
target-ppc: gdbstub: fix altivec registers for little-endian guests
Altivec registers are 128-bit wide. They are stored in memory as two
64-bit values that must be byteswapped when the guest is little-endian.
Let's reuse the ppc_maybe_bswap_register() helper for this.
We also need to fix the ordering of the 64-bit elements according to
the target endianness, for both system and user mode.
Signed-off-by: Greg Kurz <gkurz@linux.vnet.ibm.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'target-ppc/translate_init.c')
-rw-r--r-- | target-ppc/translate_init.c | 12 |
1 files changed, 10 insertions, 2 deletions
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c index 0d6d1154c5..11741413e5 100644 --- a/target-ppc/translate_init.c +++ b/target-ppc/translate_init.c @@ -8753,9 +8753,9 @@ static void dump_ppc_insns (CPUPPCState *env) static bool avr_need_swap(CPUPPCState *env) { #ifdef HOST_WORDS_BIGENDIAN - return false; + return msr_le; #else - return true; + return !msr_le; #endif } @@ -8799,14 +8799,18 @@ static int gdb_get_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) stq_p(mem_buf, env->avr[n].u64[1]); stq_p(mem_buf+8, env->avr[n].u64[0]); } + ppc_maybe_bswap_register(env, mem_buf, 8); + ppc_maybe_bswap_register(env, mem_buf + 8, 8); return 16; } if (n == 32) { stl_p(mem_buf, env->vscr); + ppc_maybe_bswap_register(env, mem_buf, 4); return 4; } if (n == 33) { stl_p(mem_buf, (uint32_t)env->spr[SPR_VRSAVE]); + ppc_maybe_bswap_register(env, mem_buf, 4); return 4; } return 0; @@ -8815,6 +8819,8 @@ static int gdb_get_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) { if (n < 32) { + ppc_maybe_bswap_register(env, mem_buf, 8); + ppc_maybe_bswap_register(env, mem_buf + 8, 8); if (!avr_need_swap(env)) { env->avr[n].u64[0] = ldq_p(mem_buf); env->avr[n].u64[1] = ldq_p(mem_buf+8); @@ -8825,10 +8831,12 @@ static int gdb_set_avr_reg(CPUPPCState *env, uint8_t *mem_buf, int n) return 16; } if (n == 32) { + ppc_maybe_bswap_register(env, mem_buf, 4); env->vscr = ldl_p(mem_buf); return 4; } if (n == 33) { + ppc_maybe_bswap_register(env, mem_buf, 4); env->spr[SPR_VRSAVE] = (target_ulong)ldl_p(mem_buf); return 4; } |