qemu-devel
[Top][All Lists]
Advanced

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

Re: [Qemu-devel] [PATCH] target-arm: Fix UNDEF cases in Thumb load/store


From: Aurelien Jarno
Subject: Re: [Qemu-devel] [PATCH] target-arm: Fix UNDEF cases in Thumb load/store
Date: Tue, 22 Mar 2011 07:54:00 +0100
User-agent: Mutt/1.5.20 (2009-06-14)

On Thu, Mar 10, 2011 at 04:48:49PM +0000, Peter Maydell wrote:
> Decode of Thumb load/store was merging together the cases of 'bit 11==0'
> (reg+reg LSL imm) and 'bit 11==1' (reg+imm). This happens to work for
> valid instruction patterns but meant that we would not UNDEF for the
> cases the architecture mandates that we must. Make the decode actually
> look at bit 11 as well as [10..8] so that we UNDEF in the right places.
> 
> This change also removes what was a spurious unreachable 'case 8',
> and correctly frees TCG temporaries on the illegal-insn codepaths.
> 
> Signed-off-by: Peter Maydell <address@hidden>
> ---
> This patch was mostly prompted by that dodgy 'case 8' which I noted
> when doing the preload/hint space patches a month or so ago; I have
> finally added support for testing loads and stores to risu, so I
> can confirm that this patch doesn't break the non-UNDEF cases.
> 
>  target-arm/translate.c |   29 ++++++++++++++++++-----------
>  1 files changed, 18 insertions(+), 11 deletions(-)

Thanks, applied.

> diff --git a/target-arm/translate.c b/target-arm/translate.c
> index 062de5e..0afdbfb 100644
> --- a/target-arm/translate.c
> +++ b/target-arm/translate.c
> @@ -8378,39 +8378,42 @@ static int disas_thumb2_insn(CPUState *env, 
> DisasContext *s, uint16_t insn_hw1)
>                  tcg_gen_addi_i32(addr, addr, imm);
>              } else {
>                  imm = insn & 0xff;
> -                switch ((insn >> 8) & 7) {
> -                case 0: case 8: /* Shifted Register.  */
> +                switch ((insn >> 8) & 0xf) {
> +                case 0x0: /* Shifted Register.  */
>                      shift = (insn >> 4) & 0xf;
> -                    if (shift > 3)
> +                    if (shift > 3) {
> +                        tcg_temp_free_i32(addr);
>                          goto illegal_op;
> +                    }
>                      tmp = load_reg(s, rm);
>                      if (shift)
>                          tcg_gen_shli_i32(tmp, tmp, shift);
>                      tcg_gen_add_i32(addr, addr, tmp);
>                      tcg_temp_free_i32(tmp);
>                      break;
> -                case 4: /* Negative offset.  */
> +                case 0xc: /* Negative offset.  */
>                      tcg_gen_addi_i32(addr, addr, -imm);
>                      break;
> -                case 6: /* User privilege.  */
> +                case 0xe: /* User privilege.  */
>                      tcg_gen_addi_i32(addr, addr, imm);
>                      user = 1;
>                      break;
> -                case 1: /* Post-decrement.  */
> +                case 0x9: /* Post-decrement.  */
>                      imm = -imm;
>                      /* Fall through.  */
> -                case 3: /* Post-increment.  */
> +                case 0xb: /* Post-increment.  */
>                      postinc = 1;
>                      writeback = 1;
>                      break;
> -                case 5: /* Pre-decrement.  */
> +                case 0xd: /* Pre-decrement.  */
>                      imm = -imm;
>                      /* Fall through.  */
> -                case 7: /* Pre-increment.  */
> +                case 0xf: /* Pre-increment.  */
>                      tcg_gen_addi_i32(addr, addr, imm);
>                      writeback = 1;
>                      break;
>                  default:
> +                    tcg_temp_free_i32(addr);
>                      goto illegal_op;
>                  }
>              }
> @@ -8423,7 +8426,9 @@ static int disas_thumb2_insn(CPUState *env, 
> DisasContext *s, uint16_t insn_hw1)
>              case 1: tmp = gen_ld16u(addr, user); break;
>              case 5: tmp = gen_ld16s(addr, user); break;
>              case 2: tmp = gen_ld32(addr, user); break;
> -            default: goto illegal_op;
> +            default:
> +                tcg_temp_free_i32(addr);
> +                goto illegal_op;
>              }
>              if (rs == 15) {
>                  gen_bx(s, tmp);
> @@ -8437,7 +8442,9 @@ static int disas_thumb2_insn(CPUState *env, 
> DisasContext *s, uint16_t insn_hw1)
>              case 0: gen_st8(tmp, addr, user); break;
>              case 1: gen_st16(tmp, addr, user); break;
>              case 2: gen_st32(tmp, addr, user); break;
> -            default: goto illegal_op;
> +            default:
> +                tcg_temp_free_i32(addr);
> +                goto illegal_op;
>              }
>          }
>          if (postinc)
> -- 
> 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]