qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Richard Henderson <rth@twiddle.net>
To: qemu-devel@nongnu.org
Cc: qemu-ppc@nongnu.org, aurelien@aurel32.net
Subject: [Qemu-devel] [PATCH 16/16] target-ppc: Convert to new ldst opcodes
Date: Wed,  4 Sep 2013 14:05:05 -0700	[thread overview]
Message-ID: <1378328705-23006-17-git-send-email-rth@twiddle.net> (raw)
In-Reply-To: <1378328705-23006-1-git-send-email-rth@twiddle.net>

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(-)

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

  parent reply	other threads:[~2013-09-04 21:06 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-09-04 21:04 [Qemu-devel] [PATCH 00/16] Streamlining endian handling in TCG Richard Henderson
2013-09-04 21:04 ` [Qemu-devel] [PATCH 01/16] tcg: Add TCGMemOp Richard Henderson
2013-09-04 21:04 ` [Qemu-devel] [PATCH 02/16] tcg-i386: Use TCGMemOp within qemu_ldst routines Richard Henderson
2013-09-04 21:04 ` [Qemu-devel] [PATCH 03/16] tcg-aarch64: " Richard Henderson
2013-09-04 21:04 ` [Qemu-devel] [PATCH 04/16] tcg-arm: " Richard Henderson
2013-09-04 21:04 ` [Qemu-devel] [PATCH 05/16] tcg-s390: " Richard Henderson
2013-09-04 21:04 ` [Qemu-devel] [PATCH 06/16] tcg-ppc: " Richard Henderson
2013-09-04 21:04 ` [Qemu-devel] [PATCH 07/16] tcg-ppc64: " Richard Henderson
2013-09-04 21:04 ` [Qemu-devel] [PATCH 08/16] tcg-hppa: " Richard Henderson
2013-09-04 21:04 ` [Qemu-devel] [PATCH 09/16] tcg-mips: " Richard Henderson
2013-09-04 21:04 ` [Qemu-devel] [PATCH 10/16] tcg-sparc: " Richard Henderson
2013-09-04 21:05 ` [Qemu-devel] [PATCH 11/16] tcg: Add qemu_ld_st_i32/64 Richard Henderson
2013-09-04 21:05 ` [Qemu-devel] [PATCH 12/16] exec: Add both big- and little-endian memory helpers Richard Henderson
2013-09-04 21:05 ` [Qemu-devel] [PATCH 13/16] tcg-i386: Tidy softmmu routines Richard Henderson
2013-09-04 21:05 ` [Qemu-devel] [PATCH 14/16] tcg-i386: Remove "cb" output restriction from qemu_st8 for i386 Richard Henderson
2013-09-04 21:05 ` [Qemu-devel] [PATCH 15/16] tcg-i386: Support new ldst opcodes Richard Henderson
2013-09-04 21:05 ` Richard Henderson [this message]
2013-09-05  9:08   ` [Qemu-devel] [Qemu-ppc] [PATCH 16/16] target-ppc: Convert to " Alexander Graf
2013-09-05 11:40     ` Benjamin Herrenschmidt
2013-09-05 12:59       ` Alexander Graf
2013-09-05 13:37         ` Benjamin Herrenschmidt
2013-09-05 15:35       ` Richard Henderson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1378328705-23006-17-git-send-email-rth@twiddle.net \
    --to=rth@twiddle.net \
    --cc=aurelien@aurel32.net \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-ppc@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).