Re: [Qemu-devel] [PATCH v4 27/35] target-arm: Rearrange aa32 load and store functions

2016-10-05 Thread Alex Bennée

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, 

[Qemu-devel] [PATCH v4 27/35] target-arm: Rearrange aa32 load and store functions

2016-09-16 Thread Richard Henderson
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)   \
+