Re: [Qemu-devel] [PATCH v4 27/35] target-arm: Rearrange aa32 load and store functions
Richard Hendersonwrites: > 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,
[Qemu-devel] [PATCH v4 27/35] target-arm: Rearrange aa32 load and store functions
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--- 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) \ +