qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] target-arm: Don't update base register on abort


From: Aurelien Jarno
Subject: Re: [Qemu-devel] [PATCH] target-arm: Don't update base register on abort in Thumb T1 LDM
Date: Wed, 27 Apr 2011 20:18:05 +0200
User-agent: Mutt/1.5.20 (2009-06-14)

On Tue, Apr 26, 2011 at 06:17:20PM +0100, Peter Maydell wrote:
> Make sure the base register isn't updated if it is in the load list
> for a Thumb LDM (T1 encoding) which aborts partway through the load.
> 
> Signed-off-by: Peter Maydell <address@hidden>
> ---
>  target-arm/translate.c |   17 ++++++++++++++---
>  1 files changed, 14 insertions(+), 3 deletions(-)

Thanks, applied.

> diff --git a/target-arm/translate.c b/target-arm/translate.c
> index d8da514..a1af436 100644
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -9454,7 +9454,10 @@ static void disas_thumb_insn(CPUState *env, 
> DisasContext *s)
>          break;
>  
>      case 12:
> +    {
>          /* load/store multiple */
> +        TCGv loaded_var;
> +        TCGV_UNUSED(loaded_var);
>          rn = (insn >> 8) & 0x7;
>          addr = load_reg(s, rn);
>          for (i = 0; i < 8; i++) {
> @@ -9462,7 +9465,11 @@ static void disas_thumb_insn(CPUState *env, 
> DisasContext *s)
>                  if (insn & (1 << 11)) {
>                      /* load */
>                      tmp = gen_ld32(addr, IS_USER(s));
> -                    store_reg(s, i, tmp);
> +                    if (i == rn) {
> +                        loaded_var = tmp;
> +                    } else {
> +                        store_reg(s, i, tmp);
> +                    }
>                  } else {
>                      /* store */
>                      tmp = load_reg(s, i);
> @@ -9472,14 +9479,18 @@ static void disas_thumb_insn(CPUState *env, 
> DisasContext *s)
>                  tcg_gen_addi_i32(addr, addr, 4);
>              }
>          }
> -        /* Base register writeback.  */
>          if ((insn & (1 << rn)) == 0) {
> +            /* base reg not in list: base register writeback */
>              store_reg(s, rn, addr);
>          } else {
> +            /* base reg in list: if load, complete it now */
> +            if (insn & (1 << 11)) {
> +                store_reg(s, rn, loaded_var);
> +            }
>              tcg_temp_free_i32(addr);
>          }
>          break;
> -
> +    }
>      case 13:
>          /* conditional branch or swi */
>          cond = (insn >> 8) & 0xf;
> -- 
> 1.7.1
> 
> 
> 

-- 
Aurelien Jarno                          GPG: 1024D/F1BCDB73
address@hidden                 http://www.aurel32.net



reply via email to

[Prev in Thread] Current Thread [Next in Thread]