Hello,

Gentle ping. The fix just consist in allocating a new TCG temp for the
address if we need to modify it.

Thanks

Luc

On 09:23 Fri 10 Jul     , Luc Michel wrote:
> Since 36a9529e60e0 the TCGv returned by compute_ldst_addr_type{a,b} for
> the address can be a target register or a constant. However
> do_{load,store} might modify it in the case of a reversed load/store.
> 
> Fix this by factoring out the reversed access logic and copying the
> address in a new TCGv_i32 if it needs to be modified.
> 
> Fixes: 36a9529e60e0 (target/microblaze: Simplify compute_ldst_addr_type{a,b})
> Signed-off-by: Luc Michel <[email protected]>
> ---
>  target/microblaze/translate.c | 56 ++++++++++++++++++++---------------
>  1 file changed, 32 insertions(+), 24 deletions(-)
> 
> diff --git a/target/microblaze/translate.c b/target/microblaze/translate.c
> index 8b219afb5dd..9fb84e1bf9f 100644
> --- a/target/microblaze/translate.c
> +++ b/target/microblaze/translate.c
> @@ -701,30 +701,47 @@ static void gen_alignment_check_ea(DisasContext *dc, 
> TCGv_i64 ea, int rb,
>  static inline MemOp mo_endian(DisasContext *dc)
>  {
>      return dc->cfg->endi ? MO_LE : MO_BE;
>  }
>  
> +static void handle_reversed_access(MemOp *mop, TCGv_i32 *addr)
> +{
> +    MemOp size = *mop & MO_SIZE;
> +
> +    /*
> +     * When doing reverse accesses we need to do two things.
> +     *
> +     * 1. Reverse the address wrt endianness.
> +     * 2. Byteswap the data lanes on the way back into the CPU core.
> +     *
> +     * Use a new TCGv_i32 to modify the address because the current one 
> might be
> +     * a register or a constant.
> +     */
> +
> +    if (size > MO_8) {
> +        *mop ^= MO_BSWAP;
> +    }
> +
> +    if (size < MO_32) {
> +        TCGv_i32 new_addr = tcg_temp_new_i32();
> +
> +        tcg_gen_xori_i32(new_addr, *addr, 3 - size);
> +        *addr = new_addr;
> +    }
> +}
> +
>  static bool do_load(DisasContext *dc, int rd, TCGv_i32 addr, MemOp mop,
>                      int mem_index, bool rev)
>  {
> +#ifndef CONFIG_USER_ONLY
>      MemOp size = mop & MO_SIZE;
> +#endif
>  
>      mop |= mo_endian(dc);
>  
> -    /*
> -     * When doing reverse accesses we need to do two things.
> -     *
> -     * 1. Reverse the address wrt endianness.
> -     * 2. Byteswap the data lanes on the way back into the CPU core.
> -     */
>      if (rev) {
> -        if (size > MO_8) {
> -            mop ^= MO_BSWAP;
> -        }
> -        if (size < MO_32) {
> -            tcg_gen_xori_i32(addr, addr, 3 - size);
> -        }
> +        handle_reversed_access(&mop, &addr);
>      }
>  
>      /*
>       * For system mode, enforce alignment if the cpu configuration
>       * requires it.  For user-mode, the Linux kernel will have fixed up
> @@ -864,27 +881,18 @@ static bool trans_lwx(DisasContext *dc, arg_typea *arg)
>  }
>  
>  static bool do_store(DisasContext *dc, int rd, TCGv_i32 addr, MemOp mop,
>                       int mem_index, bool rev)
>  {
> +#ifndef CONFIG_USER_ONLY
>      MemOp size = mop & MO_SIZE;
> +#endif
>  
>      mop |= mo_endian(dc);
>  
> -    /*
> -     * When doing reverse accesses we need to do two things.
> -     *
> -     * 1. Reverse the address wrt endianness.
> -     * 2. Byteswap the data lanes on the way back into the CPU core.
> -     */
>      if (rev) {
> -        if (size > MO_8) {
> -            mop ^= MO_BSWAP;
> -        }
> -        if (size < MO_32) {
> -            tcg_gen_xori_i32(addr, addr, 3 - size);
> -        }
> +        handle_reversed_access(&mop, &addr);
>      }
>  
>      /*
>       * For system mode, enforce alignment if the cpu configuration
>       * requires it.  For user-mode, the Linux kernel will have fixed up
> -- 
> 2.53.0
> 

-- 

Reply via email to