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-...@nongnu.org Signed-off-by: Richard Henderson <r...@twiddle.net> --- target-ppc/translate.c | 147 +++++++++++++------------------------------------ 1 file changed, 39 insertions(+), 108 deletions(-) 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"); -- 1.8.1.4