diff mbox

[16/16] target-ppc: Convert to new ldst opcodes

Message ID 1378328705-23006-17-git-send-email-rth@twiddle.net
State New
Headers show

Commit Message

Richard Henderson Sept. 4, 2013, 9:05 p.m. UTC
This lets us change "le_mode" to "end_mode" and fold away nearly all
of the tests for the current cpu endianness, and removing all of the
explicitly generated bswap opcodes.

Cc: qemu-ppc@nongnu.org
Signed-off-by: Richard Henderson <rth@twiddle.net>
---
 target-ppc/translate.c | 147 +++++++++++++------------------------------------
 1 file changed, 39 insertions(+), 108 deletions(-)

Comments

Alexander Graf Sept. 5, 2013, 9:08 a.m. UTC | #1
On 04.09.2013, at 23:05, Richard Henderson wrote:

> This lets us change "le_mode" to "end_mode" and fold away nearly all
> of the tests for the current cpu endianness, and removing all of the
> explicitly generated bswap opcodes.
> 
> Cc: qemu-ppc@nongnu.org
> Signed-off-by: Richard Henderson <rth@twiddle.net>

No complaints from me, apart from the usual "LE mode isn't necessarily what you think it is on PPC" one. But the code would be as broken as before IIUC.

Ben, you had some insight in how LE mode on different PPC flavors work. Could you please make sure we're not walking into the wrong direction here?


Alex
Benjamin Herrenschmidt Sept. 5, 2013, 11:40 a.m. UTC | #2
On Thu, 2013-09-05 at 11:08 +0200, Alexander Graf wrote:
> On 04.09.2013, at 23:05, Richard Henderson wrote:
> 
> > This lets us change "le_mode" to "end_mode" and fold away nearly all
> > of the tests for the current cpu endianness, and removing all of the
> > explicitly generated bswap opcodes.

Only nit: I find "end_mode" a very confusing identifier :-) "end"
usually means something else ! Why not endian_mode ?
> > 
> > Cc: qemu-ppc@nongnu.org
> > Signed-off-by: Richard Henderson <rth@twiddle.net>
> 
> No complaints from me, apart from the usual "LE mode isn't necessarily what you think it is on PPC" one. But the code would be as broken as before IIUC.
> 
> Ben, you had some insight in how LE mode on different PPC flavors work. Could you please make sure we're not walking into the wrong direction here?

I haven't seen the patch itself for some reason (and I'm about to go off
for a few days). The early day powerpc endian mode can be safely ignored
I think, I don't even remember the details myself, I think it induced
some changes to the byte lanes ordering on the bus and thus required the
host bridge to be adjusted.

The embedded PPCs have simply a per-page E bit in the TLB controlling
the endianness of accesses through the translation, the endianness is
"clean" in that case, and the bus doesn't flip around so it's akin to
what P7 does but with a finer granularity.

Cheers,
Ben.
Alexander Graf Sept. 5, 2013, 12:59 p.m. UTC | #3
On 05.09.2013, at 13:40, Benjamin Herrenschmidt wrote:

> On Thu, 2013-09-05 at 11:08 +0200, Alexander Graf wrote:
>> On 04.09.2013, at 23:05, Richard Henderson wrote:
>> 
>>> This lets us change "le_mode" to "end_mode" and fold away nearly all
>>> of the tests for the current cpu endianness, and removing all of the
>>> explicitly generated bswap opcodes.
> 
> Only nit: I find "end_mode" a very confusing identifier :-) "end"
> usually means something else ! Why not endian_mode ?
>>> 
>>> Cc: qemu-ppc@nongnu.org
>>> Signed-off-by: Richard Henderson <rth@twiddle.net>
>> 
>> No complaints from me, apart from the usual "LE mode isn't necessarily what you think it is on PPC" one. But the code would be as broken as before IIUC.
>> 
>> Ben, you had some insight in how LE mode on different PPC flavors work. Could you please make sure we're not walking into the wrong direction here?
> 
> I haven't seen the patch itself for some reason (and I'm about to go off
> for a few days). The early day powerpc endian mode can be safely ignored
> I think, I don't even remember the details myself, I think it induced
> some changes to the byte lanes ordering on the bus and thus required the
> host bridge to be adjusted.
> 
> The embedded PPCs have simply a per-page E bit in the TLB controlling
> the endianness of accesses through the translation, the endianness is
> "clean" in that case, and the bus doesn't flip around so it's akin to
> what P7 does but with a finer granularity.

So on P7 basically everything that goes from registers out is byte-swapped, including any RAM access and MMIOs? I think that's basically what the current little endian mode implements (though it might miss a few places, like FPU or Altivec, but I'd consider that bugs).


Alex
Benjamin Herrenschmidt Sept. 5, 2013, 1:37 p.m. UTC | #4
On Thu, 2013-09-05 at 14:59 +0200, Alexander Graf wrote:

> > The embedded PPCs have simply a per-page E bit in the TLB
> controlling
> > the endianness of accesses through the translation, the endianness
> is
> > "clean" in that case, and the bus doesn't flip around so it's akin
> to
> > what P7 does but with a finer granularity.
> 
> So on P7 basically everything that goes from registers out is
> byte-swapped, including any RAM access and MMIOs? I think that's
> basically what the current little endian mode implements (though it
> might miss a few places, like FPU or Altivec, but I'd consider that
> bugs).

Yes. There are some oddities with VSX though (it does PDP endian iirc).

Cheers,
Ben.
Richard Henderson Sept. 5, 2013, 3:35 p.m. UTC | #5
On 09/05/2013 04:40 AM, Benjamin Herrenschmidt wrote:
> Only nit: I find "end_mode" a very confusing identifier :-) "end"
> usually means something else ! Why not endian_mode ?

80 column wrapping.  A poor excuse, I know...

> I haven't seen the patch itself for some reason (and I'm about to go off
> for a few days). The early day powerpc endian mode can be safely ignored
> I think, I don't even remember the details myself, I think it induced
> some changes to the byte lanes ordering on the bus and thus required the
> host bridge to be adjusted.

This sounds like the ARM BE32 mode on early arms.  Now discontinued, afaik.

> The embedded PPCs have simply a per-page E bit in the TLB controlling
> the endianness of accesses through the translation, the endianness is
> "clean" in that case, and the bus doesn't flip around so it's akin to
> what P7 does but with a finer granularity.

This would be significantly harder (and slower) to emulate.  It would
require playing games at the cputlb level, and really nothing to do with
the code generation from tcg at all.


r~
diff mbox

Patch

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 2da7bc7..b56ab87 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -192,7 +192,7 @@  typedef struct DisasContext {
     int mem_idx;
     int access_type;
     /* Translation flags */
-    int le_mode;
+    TCGMemOp end_mode;
 #if defined(TARGET_PPC64)
     int sf_mode;
     int has_cfar;
@@ -2514,99 +2514,57 @@  static inline void gen_check_align(DisasContext *ctx, TCGv EA, int mask)
 /***                             Integer load                              ***/
 static inline void gen_qemu_ld8u(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    tcg_gen_qemu_ld8u(arg1, arg2, ctx->mem_idx);
+    tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, MO_UB);
 }
 
 static inline void gen_qemu_ld8s(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    tcg_gen_qemu_ld8s(arg1, arg2, ctx->mem_idx);
+    tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, MO_SB);
 }
 
 static inline void gen_qemu_ld16u(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
-    if (unlikely(ctx->le_mode)) {
-        tcg_gen_bswap16_tl(arg1, arg1);
-    }
+    tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, MO_UW | ctx->end_mode);
 }
 
 static inline void gen_qemu_ld16s(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    if (unlikely(ctx->le_mode)) {
-        tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
-        tcg_gen_bswap16_tl(arg1, arg1);
-        tcg_gen_ext16s_tl(arg1, arg1);
-    } else {
-        tcg_gen_qemu_ld16s(arg1, arg2, ctx->mem_idx);
-    }
+    tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, MO_SW | ctx->end_mode);
 }
 
 static inline void gen_qemu_ld32u(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
-    if (unlikely(ctx->le_mode)) {
-        tcg_gen_bswap32_tl(arg1, arg1);
-    }
+    tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, MO_UL | ctx->end_mode);
 }
 
 static inline void gen_qemu_ld32s(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    if (unlikely(ctx->le_mode)) {
-        tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
-        tcg_gen_bswap32_tl(arg1, arg1);
-        tcg_gen_ext32s_tl(arg1, arg1);
-    } else
-        tcg_gen_qemu_ld32s(arg1, arg2, ctx->mem_idx);
+    tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx, MO_SL | ctx->end_mode);
 }
 
 static inline void gen_qemu_ld64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
 {
-    tcg_gen_qemu_ld64(arg1, arg2, ctx->mem_idx);
-    if (unlikely(ctx->le_mode)) {
-        tcg_gen_bswap64_i64(arg1, arg1);
-    }
+    tcg_gen_qemu_ld_i64(arg1, arg2, ctx->mem_idx, MO_Q | ctx->end_mode);
 }
 
 static inline void gen_qemu_st8(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    tcg_gen_qemu_st8(arg1, arg2, ctx->mem_idx);
+    tcg_gen_qemu_st_tl(arg1, arg2, ctx->mem_idx, MO_UB);
 }
 
 static inline void gen_qemu_st16(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    if (unlikely(ctx->le_mode)) {
-        TCGv t0 = tcg_temp_new();
-        tcg_gen_ext16u_tl(t0, arg1);
-        tcg_gen_bswap16_tl(t0, t0);
-        tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx);
-        tcg_temp_free(t0);
-    } else {
-        tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx);
-    }
+    tcg_gen_qemu_st_tl(arg1, arg2, ctx->mem_idx, MO_UW | ctx->end_mode);
 }
 
 static inline void gen_qemu_st32(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    if (unlikely(ctx->le_mode)) {
-        TCGv t0 = tcg_temp_new();
-        tcg_gen_ext32u_tl(t0, arg1);
-        tcg_gen_bswap32_tl(t0, t0);
-        tcg_gen_qemu_st32(t0, arg2, ctx->mem_idx);
-        tcg_temp_free(t0);
-    } else {
-        tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx);
-    }
+    tcg_gen_qemu_st_tl(arg1, arg2, ctx->mem_idx, MO_UL | ctx->end_mode);
 }
 
 static inline void gen_qemu_st64(DisasContext *ctx, TCGv_i64 arg1, TCGv arg2)
 {
-    if (unlikely(ctx->le_mode)) {
-        TCGv_i64 t0 = tcg_temp_new_i64();
-        tcg_gen_bswap64_i64(t0, arg1);
-        tcg_gen_qemu_st64(t0, arg2, ctx->mem_idx);
-        tcg_temp_free_i64(t0);
-    } else
-        tcg_gen_qemu_st64(arg1, arg2, ctx->mem_idx);
+    tcg_gen_qemu_st_i64(arg1, arg2, ctx->mem_idx, MO_Q | ctx->end_mode);
 }
 
 #define GEN_LD(name, ldop, opc, type)                                         \
@@ -2739,7 +2697,7 @@  static void gen_lq(DisasContext *ctx)
         gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
         return;
     }
-    if (unlikely(ctx->le_mode)) {
+    if (unlikely(ctx->end_mode == MO_LE)) {
         /* Little-endian mode is not handled */
         gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
         return;
@@ -2850,7 +2808,7 @@  static void gen_std(DisasContext *ctx)
             gen_inval_exception(ctx, POWERPC_EXCP_INVAL_INVAL);
             return;
         }
-        if (unlikely(ctx->le_mode)) {
+        if (unlikely(ctx->end_mode == MO_LE)) {
             /* Little-endian mode is not handled */
             gen_exception_err(ctx, POWERPC_EXCP_ALIGN, POWERPC_EXCP_ALIGN_LE);
             return;
@@ -2885,20 +2843,16 @@  static void gen_std(DisasContext *ctx)
 /* lhbrx */
 static inline void gen_qemu_ld16ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    tcg_gen_qemu_ld16u(arg1, arg2, ctx->mem_idx);
-    if (likely(!ctx->le_mode)) {
-        tcg_gen_bswap16_tl(arg1, arg1);
-    }
+    tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx,
+                       MO_UW | (ctx->end_mode ^ MO_BSWAP));
 }
 GEN_LDX(lhbr, ld16ur, 0x16, 0x18, PPC_INTEGER);
 
 /* lwbrx */
 static inline void gen_qemu_ld32ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    tcg_gen_qemu_ld32u(arg1, arg2, ctx->mem_idx);
-    if (likely(!ctx->le_mode)) {
-        tcg_gen_bswap32_tl(arg1, arg1);
-    }
+    tcg_gen_qemu_ld_tl(arg1, arg2, ctx->mem_idx,
+                       MO_UL | (ctx->end_mode ^ MO_BSWAP));
 }
 GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER);
 
@@ -2906,10 +2860,8 @@  GEN_LDX(lwbr, ld32ur, 0x16, 0x10, PPC_INTEGER);
 /* ldbrx */
 static inline void gen_qemu_ld64ur(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    tcg_gen_qemu_ld64(arg1, arg2, ctx->mem_idx);
-    if (likely(!ctx->le_mode)) {
-        tcg_gen_bswap64_tl(arg1, arg1);
-    }
+    tcg_gen_qemu_ld_i64(arg1, arg2, ctx->mem_idx,
+                        MO_Q | (ctx->end_mode ^ MO_BSWAP));
 }
 GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX);
 #endif  /* TARGET_PPC64 */
@@ -2917,30 +2869,16 @@  GEN_LDX_E(ldbr, ld64ur, 0x14, 0x10, PPC_NONE, PPC2_DBRX);
 /* sthbrx */
 static inline void gen_qemu_st16r(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    if (likely(!ctx->le_mode)) {
-        TCGv t0 = tcg_temp_new();
-        tcg_gen_ext16u_tl(t0, arg1);
-        tcg_gen_bswap16_tl(t0, t0);
-        tcg_gen_qemu_st16(t0, arg2, ctx->mem_idx);
-        tcg_temp_free(t0);
-    } else {
-        tcg_gen_qemu_st16(arg1, arg2, ctx->mem_idx);
-    }
+    tcg_gen_qemu_st_tl(arg1, arg2, ctx->mem_idx,
+                       MO_UW | (ctx->end_mode ^ MO_BSWAP));
 }
 GEN_STX(sthbr, st16r, 0x16, 0x1C, PPC_INTEGER);
 
 /* stwbrx */
 static inline void gen_qemu_st32r(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    if (likely(!ctx->le_mode)) {
-        TCGv t0 = tcg_temp_new();
-        tcg_gen_ext32u_tl(t0, arg1);
-        tcg_gen_bswap32_tl(t0, t0);
-        tcg_gen_qemu_st32(t0, arg2, ctx->mem_idx);
-        tcg_temp_free(t0);
-    } else {
-        tcg_gen_qemu_st32(arg1, arg2, ctx->mem_idx);
-    }
+    tcg_gen_qemu_st_tl(arg1, arg2, ctx->mem_idx,
+                       MO_UL | (ctx->end_mode ^ MO_BSWAP));
 }
 GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
 
@@ -2948,14 +2886,8 @@  GEN_STX(stwbr, st32r, 0x16, 0x14, PPC_INTEGER);
 /* stdbrx */
 static inline void gen_qemu_st64r(DisasContext *ctx, TCGv arg1, TCGv arg2)
 {
-    if (likely(!ctx->le_mode)) {
-        TCGv t0 = tcg_temp_new();
-        tcg_gen_bswap64_tl(t0, arg1);
-        tcg_gen_qemu_st64(t0, arg2, ctx->mem_idx);
-        tcg_temp_free(t0);
-    } else {
-        tcg_gen_qemu_st64(arg1, arg2, ctx->mem_idx);
-    }
+    tcg_gen_qemu_st_i64(arg1, arg2, ctx->mem_idx,
+                        MO_Q | (ctx->end_mode ^ MO_BSWAP));
 }
 GEN_STX_E(stdbr, st64r, 0x14, 0x14, PPC_NONE, PPC2_DBRX);
 #endif  /* TARGET_PPC64 */
@@ -3327,7 +3259,7 @@  static void gen_lfdp(DisasContext *ctx)
     gen_set_access_type(ctx, ACCESS_FLOAT);
     EA = tcg_temp_new();
     gen_addr_imm_index(ctx, EA, 0);                                           \
-    if (unlikely(ctx->le_mode)) {
+    if (unlikely(ctx->end_mode == MO_LE)) {
         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
         tcg_gen_addi_tl(EA, EA, 8);
         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
@@ -3350,7 +3282,7 @@  static void gen_lfdpx(DisasContext *ctx)
     gen_set_access_type(ctx, ACCESS_FLOAT);
     EA = tcg_temp_new();
     gen_addr_reg_index(ctx, EA);
-    if (unlikely(ctx->le_mode)) {
+    if (unlikely(ctx->end_mode == MO_LE)) {
         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
         tcg_gen_addi_tl(EA, EA, 8);
         gen_qemu_ld64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
@@ -3485,7 +3417,7 @@  static void gen_stfdp(DisasContext *ctx)
     gen_set_access_type(ctx, ACCESS_FLOAT);
     EA = tcg_temp_new();
     gen_addr_imm_index(ctx, EA, 0);                                           \
-    if (unlikely(ctx->le_mode)) {
+    if (unlikely(ctx->end_mode == MO_LE)) {
         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
         tcg_gen_addi_tl(EA, EA, 8);
         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
@@ -3508,7 +3440,7 @@  static void gen_stfdpx(DisasContext *ctx)
     gen_set_access_type(ctx, ACCESS_FLOAT);
     EA = tcg_temp_new();
     gen_addr_reg_index(ctx, EA);
-    if (unlikely(ctx->le_mode)) {
+    if (unlikely(ctx->end_mode == MO_LE)) {
         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode) + 1], EA);
         tcg_gen_addi_tl(EA, EA, 8);
         gen_qemu_st64(ctx, cpu_fpr[rD(ctx->opcode)], EA);
@@ -6453,7 +6385,7 @@  static void glue(gen_, name)(DisasContext *ctx)
     EA = tcg_temp_new();                                                      \
     gen_addr_reg_index(ctx, EA);                                              \
     tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
-    if (ctx->le_mode) {                                                       \
+    if (ctx->end_mode == MO_LE) {                                             \
         gen_qemu_ld64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
         tcg_gen_addi_tl(EA, EA, 8);                                           \
         gen_qemu_ld64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
@@ -6477,7 +6409,7 @@  static void gen_st##name(DisasContext *ctx)                                   \
     EA = tcg_temp_new();                                                      \
     gen_addr_reg_index(ctx, EA);                                              \
     tcg_gen_andi_tl(EA, EA, ~0xf);                                            \
-    if (ctx->le_mode) {                                                       \
+    if (ctx->end_mode == MO_LE) {                                             \
         gen_qemu_st64(ctx, cpu_avrl[rD(ctx->opcode)], EA);                    \
         tcg_gen_addi_tl(EA, EA, 8);                                           \
         gen_qemu_st64(ctx, cpu_avrh[rD(ctx->opcode)], EA);                    \
@@ -9751,7 +9683,7 @@  static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
     ctx.insns_flags = env->insns_flags;
     ctx.insns_flags2 = env->insns_flags2;
     ctx.access_type = -1;
-    ctx.le_mode = env->hflags & (1 << MSR_LE) ? 1 : 0;
+    ctx.end_mode = (env->hflags & (1 << MSR_LE) ? MO_LE : MO_BE);
 #if defined(TARGET_PPC64)
     ctx.sf_mode = msr_is_64bit(env, env->msr);
     ctx.has_cfar = !!(env->flags & POWERPC_FLAG_CFAR);
@@ -9811,14 +9743,13 @@  static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
                   ctx.nip, ctx.mem_idx, (int)msr_ir);
         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
             gen_io_start();
-        if (unlikely(ctx.le_mode)) {
-            ctx.opcode = bswap32(cpu_ldl_code(env, ctx.nip));
-        } else {
-            ctx.opcode = cpu_ldl_code(env, ctx.nip);
+        ctx.opcode = cpu_ldl_code(env, ctx.nip);
+        if (unlikely(ctx.end_mode == MO_LE)) {
+            ctx.opcode = bswap32(ctx.opcode);
         }
         LOG_DISAS("translate opcode %08x (%02x %02x %02x) (%s)\n",
-                    ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
-                    opc3(ctx.opcode), ctx.le_mode ? "little" : "big");
+                  ctx.opcode, opc1(ctx.opcode), opc2(ctx.opcode),
+                  opc3(ctx.opcode), ctx.end_mode == MO_LE ? "little" : "big");
         if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
             tcg_gen_debug_insn_start(ctx.nip);
         }
@@ -9910,7 +9841,7 @@  static inline void gen_intermediate_code_internal(PowerPCCPU *cpu,
     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
         int flags;
         flags = env->bfd_mach;
-        flags |= ctx.le_mode << 16;
+        flags |= (ctx.end_mode == MO_LE) << 16;
         qemu_log("IN: %s\n", lookup_symbol(pc_start));
         log_target_disas(env, pc_start, ctx.nip - pc_start, flags);
         qemu_log("\n");