From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:47879) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1brmNn-00068i-Il for qemu-devel@nongnu.org; Wed, 05 Oct 2016 09:37:17 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1brmNh-0006CC-Pi for qemu-devel@nongnu.org; Wed, 05 Oct 2016 09:37:14 -0400 Received: from mail-wm0-x22a.google.com ([2a00:1450:400c:c09::22a]:36124) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1brmNh-0006Bz-EV for qemu-devel@nongnu.org; Wed, 05 Oct 2016 09:37:09 -0400 Received: by mail-wm0-x22a.google.com with SMTP id k125so268213316wma.1 for ; Wed, 05 Oct 2016 06:37:09 -0700 (PDT) References: <1474048017-26696-1-git-send-email-rth@twiddle.net> <1474048017-26696-28-git-send-email-rth@twiddle.net> From: Alex =?utf-8?Q?Benn=C3=A9e?= In-reply-to: <1474048017-26696-28-git-send-email-rth@twiddle.net> Date: Wed, 05 Oct 2016 14:37:06 +0100 Message-ID: <87d1jesyrh.fsf@linaro.org> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Subject: Re: [Qemu-devel] [PATCH v4 27/35] target-arm: Rearrange aa32 load and store functions List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Richard Henderson Cc: qemu-devel@nongnu.org Richard Henderson writes: > Stop specializing on TARGET_LONG_BITS == 32; unconditionally allocate > a temp and expand with tcg_gen_extu_i32_tl. Split out gen_aa32_addr, > gen_aa32_frob64, gen_aa32_ld_i32 and gen_aa32_st_i32 as separate interfaces. > > Signed-off-by: Richard Henderson Reviewed-by: Alex Bennée > --- > target-arm/translate.c | 171 +++++++++++++++++++------------------------------ > 1 file changed, 66 insertions(+), 105 deletions(-) > > diff --git a/target-arm/translate.c b/target-arm/translate.c > index 693d4bc..bcd2958 100644 > --- a/target-arm/translate.c > +++ b/target-arm/translate.c > @@ -926,145 +926,106 @@ static inline void store_reg_from_load(DisasContext *s, int reg, TCGv_i32 var) > * These functions work like tcg_gen_qemu_{ld,st}* except > * that the address argument is TCGv_i32 rather than TCGv. > */ > -#if TARGET_LONG_BITS == 32 > > -#define DO_GEN_LD(SUFF, OPC, BE32_XOR) \ > -static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \ > - TCGv_i32 addr, int index) \ > -{ \ > - TCGMemOp opc = (OPC) | s->be_data; \ > - /* Not needed for user-mode BE32, where we use MO_BE instead. */ \ > - if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \ > - TCGv addr_be = tcg_temp_new(); \ > - tcg_gen_xori_i32(addr_be, addr, BE32_XOR); \ > - tcg_gen_qemu_ld_i32(val, addr_be, index, opc); \ > - tcg_temp_free(addr_be); \ > - return; \ > - } \ > - tcg_gen_qemu_ld_i32(val, addr, index, opc); \ > -} > - > -#define DO_GEN_ST(SUFF, OPC, BE32_XOR) \ > -static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \ > - TCGv_i32 addr, int index) \ > -{ \ > - TCGMemOp opc = (OPC) | s->be_data; \ > - /* Not needed for user-mode BE32, where we use MO_BE instead. */ \ > - if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \ > - TCGv addr_be = tcg_temp_new(); \ > - tcg_gen_xori_i32(addr_be, addr, BE32_XOR); \ > - tcg_gen_qemu_st_i32(val, addr_be, index, opc); \ > - tcg_temp_free(addr_be); \ > - return; \ > - } \ > - tcg_gen_qemu_st_i32(val, addr, index, opc); \ > -} > - > -static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val, > - TCGv_i32 addr, int index) > +static inline TCGv gen_aa32_addr(DisasContext *s, TCGv_i32 a32, TCGMemOp op) > { > - TCGMemOp opc = MO_Q | s->be_data; > - tcg_gen_qemu_ld_i64(val, addr, index, opc); > + TCGv addr = tcg_temp_new(); > + tcg_gen_extu_i32_tl(addr, a32); > + > /* Not needed for user-mode BE32, where we use MO_BE instead. */ > - if (!IS_USER_ONLY && s->sctlr_b) { > - tcg_gen_rotri_i64(val, val, 32); > + if (!IS_USER_ONLY && s->sctlr_b && (op & MO_SIZE) < MO_32) { > + tcg_gen_xori_tl(addr, addr, 4 - (1 << (op & MO_SIZE))); > } > + return addr; > } > > -static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val, > - TCGv_i32 addr, int index) > +static void gen_aa32_ld_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32, > + int index, TCGMemOp opc) > { > - TCGMemOp opc = MO_Q | s->be_data; > - /* Not needed for user-mode BE32, where we use MO_BE instead. */ > - if (!IS_USER_ONLY && s->sctlr_b) { > - TCGv_i64 tmp = tcg_temp_new_i64(); > - tcg_gen_rotri_i64(tmp, val, 32); > - tcg_gen_qemu_st_i64(tmp, addr, index, opc); > - tcg_temp_free_i64(tmp); > - return; > - } > - tcg_gen_qemu_st_i64(val, addr, index, opc); > + TCGv addr = gen_aa32_addr(s, a32, opc); > + tcg_gen_qemu_ld_i32(val, addr, index, opc); > + tcg_temp_free(addr); > } > > -#else > +static void gen_aa32_st_i32(DisasContext *s, TCGv_i32 val, TCGv_i32 a32, > + int index, TCGMemOp opc) > +{ > + TCGv addr = gen_aa32_addr(s, a32, opc); > + tcg_gen_qemu_st_i32(val, addr, index, opc); > + tcg_temp_free(addr); > +} > > -#define DO_GEN_LD(SUFF, OPC, BE32_XOR) \ > +#define DO_GEN_LD(SUFF, OPC) \ > static inline void gen_aa32_ld##SUFF(DisasContext *s, TCGv_i32 val, \ > - TCGv_i32 addr, int index) \ > + TCGv_i32 a32, int index) \ > { \ > - TCGMemOp opc = (OPC) | s->be_data; \ > - TCGv addr64 = tcg_temp_new(); \ > - tcg_gen_extu_i32_i64(addr64, addr); \ > - /* Not needed for user-mode BE32, where we use MO_BE instead. */ \ > - if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \ > - tcg_gen_xori_i64(addr64, addr64, BE32_XOR); \ > - } \ > - tcg_gen_qemu_ld_i32(val, addr64, index, opc); \ > - tcg_temp_free(addr64); \ > -} > - > -#define DO_GEN_ST(SUFF, OPC, BE32_XOR) \ > + gen_aa32_ld_i32(s, val, a32, index, OPC | s->be_data); \ > +} > + > +#define DO_GEN_ST(SUFF, OPC) \ > static inline void gen_aa32_st##SUFF(DisasContext *s, TCGv_i32 val, \ > - TCGv_i32 addr, int index) \ > + TCGv_i32 a32, int index) \ > { \ > - TCGMemOp opc = (OPC) | s->be_data; \ > - TCGv addr64 = tcg_temp_new(); \ > - tcg_gen_extu_i32_i64(addr64, addr); \ > - /* Not needed for user-mode BE32, where we use MO_BE instead. */ \ > - if (!IS_USER_ONLY && s->sctlr_b && BE32_XOR) { \ > - tcg_gen_xori_i64(addr64, addr64, BE32_XOR); \ > - } \ > - tcg_gen_qemu_st_i32(val, addr64, index, opc); \ > - tcg_temp_free(addr64); \ > + gen_aa32_st_i32(s, val, a32, index, OPC | s->be_data); \ > } > > -static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val, > - TCGv_i32 addr, int index) > +static inline void gen_aa32_frob64(DisasContext *s, TCGv_i64 val) > { > - TCGMemOp opc = MO_Q | s->be_data; > - TCGv addr64 = tcg_temp_new(); > - tcg_gen_extu_i32_i64(addr64, addr); > - tcg_gen_qemu_ld_i64(val, addr64, index, opc); > - > /* Not needed for user-mode BE32, where we use MO_BE instead. */ > if (!IS_USER_ONLY && s->sctlr_b) { > tcg_gen_rotri_i64(val, val, 32); > } > - tcg_temp_free(addr64); > } > > -static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val, > - TCGv_i32 addr, int index) > +static void gen_aa32_ld_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32, > + int index, TCGMemOp opc) > { > - TCGMemOp opc = MO_Q | s->be_data; > - TCGv addr64 = tcg_temp_new(); > - tcg_gen_extu_i32_i64(addr64, addr); > + TCGv addr = gen_aa32_addr(s, a32, opc); > + tcg_gen_qemu_ld_i64(val, addr, index, opc); > + gen_aa32_frob64(s, val); > + tcg_temp_free(addr); > +} > + > +static inline void gen_aa32_ld64(DisasContext *s, TCGv_i64 val, > + TCGv_i32 a32, int index) > +{ > + gen_aa32_ld_i64(s, val, a32, index, MO_Q | s->be_data); > +} > + > +static void gen_aa32_st_i64(DisasContext *s, TCGv_i64 val, TCGv_i32 a32, > + int index, TCGMemOp opc) > +{ > + TCGv addr = gen_aa32_addr(s, a32, opc); > > /* Not needed for user-mode BE32, where we use MO_BE instead. */ > if (!IS_USER_ONLY && s->sctlr_b) { > - TCGv tmp = tcg_temp_new(); > + TCGv_i64 tmp = tcg_temp_new_i64(); > tcg_gen_rotri_i64(tmp, val, 32); > - tcg_gen_qemu_st_i64(tmp, addr64, index, opc); > - tcg_temp_free(tmp); > + tcg_gen_qemu_st_i64(tmp, addr, index, opc); > + tcg_temp_free_i64(tmp); > } else { > - tcg_gen_qemu_st_i64(val, addr64, index, opc); > + tcg_gen_qemu_st_i64(val, addr, index, opc); > } > - tcg_temp_free(addr64); > + tcg_temp_free(addr); > } > > -#endif > +static inline void gen_aa32_st64(DisasContext *s, TCGv_i64 val, > + TCGv_i32 a32, int index) > +{ > + gen_aa32_st_i64(s, val, a32, index, MO_Q | s->be_data); > +} > > -DO_GEN_LD(8s, MO_SB, 3) > -DO_GEN_LD(8u, MO_UB, 3) > -DO_GEN_LD(16s, MO_SW, 2) > -DO_GEN_LD(16u, MO_UW, 2) > -DO_GEN_LD(32u, MO_UL, 0) > +DO_GEN_LD(8s, MO_SB) > +DO_GEN_LD(8u, MO_UB) > +DO_GEN_LD(16s, MO_SW) > +DO_GEN_LD(16u, MO_UW) > +DO_GEN_LD(32u, MO_UL) > /* 'a' variants include an alignment check */ > -DO_GEN_LD(16ua, MO_UW | MO_ALIGN, 2) > -DO_GEN_LD(32ua, MO_UL | MO_ALIGN, 0) > -DO_GEN_ST(8, MO_UB, 3) > -DO_GEN_ST(16, MO_UW, 2) > -DO_GEN_ST(32, MO_UL, 0) > +DO_GEN_LD(16ua, MO_UW | MO_ALIGN) > +DO_GEN_LD(32ua, MO_UL | MO_ALIGN) > +DO_GEN_ST(8, MO_UB) > +DO_GEN_ST(16, MO_UW) > +DO_GEN_ST(32, MO_UL) > > static inline void gen_set_pc_im(DisasContext *s, target_ulong val) > { -- Alex Bennée