aboutsummaryrefslogtreecommitdiff
path: root/target-ppc/translate.c
diff options
context:
space:
mode:
authorj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>2007-11-04 02:55:33 +0000
committerj_mayer <j_mayer@c046a42c-6fe2-441c-8c8c-71466251a162>2007-11-04 02:55:33 +0000
commit056401eae60953822098ff1dc30860364c9681be (patch)
treed6ec477e5ebd870c5cd091c7543034ab9c0ac883 /target-ppc/translate.c
parent7a51ad822f533472cab908d2622578d51eb97dc6 (diff)
PowerPC 601 need specific callbacks for its BATs setup.
Implement PowerPC 601 HID0 register, needed for little-endian mode support. As a consequence, we need to merge hflags coming from MSR with other ones. Use little-endian mode from hflags instead of MSR during code translation. git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3524 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-ppc/translate.c')
-rw-r--r--target-ppc/translate.c21
1 files changed, 10 insertions, 11 deletions
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index cd7a483465..1adff9fdf5 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -6801,7 +6801,7 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
opc_handler_t **table, *handler;
target_ulong pc_start;
uint16_t *gen_opc_end;
- int supervisor;
+ int supervisor, little_endian;
int single_step, branch_step;
int j, lj = -1;
@@ -6821,11 +6821,12 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
#if !defined(CONFIG_USER_ONLY)
ctx.supervisor = supervisor;
#endif
+ little_endian = env->hflags & (1 << MSR_LE) ? 1 : 0;
#if defined(TARGET_PPC64)
ctx.sf_mode = msr_sf;
- ctx.mem_idx = (supervisor << 2) | (msr_sf << 1) | msr_le;
+ ctx.mem_idx = (supervisor << 2) | (msr_sf << 1) | little_endian;
#else
- ctx.mem_idx = (supervisor << 1) | msr_le;
+ ctx.mem_idx = (supervisor << 1) | little_endian;
#endif
ctx.dcache_line_size = env->dcache_line_size;
ctx.fpu_enabled = msr_fp;
@@ -6880,18 +6881,16 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
ctx.nip, supervisor, (int)msr_ir);
}
#endif
- ctx.opcode = ldl_code(ctx.nip);
- if (msr_le) {
- ctx.opcode = ((ctx.opcode & 0xFF000000) >> 24) |
- ((ctx.opcode & 0x00FF0000) >> 8) |
- ((ctx.opcode & 0x0000FF00) << 8) |
- ((ctx.opcode & 0x000000FF) << 24);
+ if (unlikely(little_endian)) {
+ ctx.opcode = bswap32(ldl_code(ctx.nip));
+ } else {
+ ctx.opcode = ldl_code(ctx.nip);
}
#if defined PPC_DEBUG_DISAS
if (loglevel & CPU_LOG_TB_IN_ASM) {
fprintf(logfile, "translate opcode %08x (%02x %02x %02x) (%s)\n",
ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
- opc3(ctx.opcode), msr_le ? "little" : "big");
+ opc3(ctx.opcode), little_endian ? "little" : "big");
}
#endif
ctx.nip += 4;
@@ -6986,7 +6985,7 @@ static always_inline int gen_intermediate_code_internal (CPUState *env,
if (loglevel & CPU_LOG_TB_IN_ASM) {
int flags;
flags = env->bfd_mach;
- flags |= msr_le << 16;
+ flags |= little_endian << 16;
fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
target_disas(logfile, pc_start, ctx.nip - pc_start, flags);
fprintf(logfile, "\n");