diff mbox series

[11/26] target/arm: Rearrange decode in disas_uncond_b_reg

Message ID 20181207103631.28193-12-richard.henderson@linaro.org
State New
Headers show
Series target/arm: Implement ARMv8.3-PAuth | expand

Commit Message

Richard Henderson Dec. 7, 2018, 10:36 a.m. UTC
This will enable PAuth decode in a subsequent patch.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

---
 target/arm/translate-a64.c | 34 +++++++++++++++++++++++-----------
 1 file changed, 23 insertions(+), 11 deletions(-)

-- 
2.17.2

Comments

Peter Maydell Dec. 11, 2018, 3:40 p.m. UTC | #1
On Fri, 7 Dec 2018 at 10:36, Richard Henderson
<richard.henderson@linaro.org> wrote:
>

> This will enable PAuth decode in a subsequent patch.

>

> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

> ---

>  target/arm/translate-a64.c | 34 +++++++++++++++++++++++-----------

>  1 file changed, 23 insertions(+), 11 deletions(-)

>

> diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c

> index c84c2dbb66..5fa2647771 100644

> --- a/target/arm/translate-a64.c

> +++ b/target/arm/translate-a64.c

> @@ -1989,32 +1989,41 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)

>      rn = extract32(insn, 5, 5);

>      op4 = extract32(insn, 0, 5);

>

> -    if (op4 != 0x0 || op3 != 0x0 || op2 != 0x1f) {

> -        unallocated_encoding(s);

> -        return;

> +    if (op2 != 0x1f) {

> +        goto do_unallocated;

>      }

>

>      switch (opc) {

>      case 0: /* BR */

>      case 1: /* BLR */

>      case 2: /* RET */

> -        gen_a64_set_pc(s, cpu_reg(s, rn));

> +        if (op3 == 0 && op4 == 0) {

> +            dst = cpu_reg(s, rn);

> +        } else {

> +            goto do_unallocated;

> +        }

> +        gen_a64_set_pc(s, dst);

>          /* BLR also needs to load return address */

>          if (opc == 1) {

>              tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);

>          }

>          break;

> +

>      case 4: /* ERET */

>          if (s->current_el == 0) {

> -            unallocated_encoding(s);

> -            return;

> -        }

> -        if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {

> -            gen_io_start();

> +            goto do_unallocated;

>          }

>          dst = tcg_temp_new_i64();

>          tcg_gen_ld_i64(dst, cpu_env,

>                         offsetof(CPUARMState, elr_el[s->current_el]));

> +        if (op3 == 0 && op4 == 0) {

> +            ;

> +        } else {

> +            goto do_unallocated;



This decode check should go before any code has been
emittede (ie before the tcg_gen_ld_i64 above it).

> +        }

> +        if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {

> +            gen_io_start();

> +        }

>          gen_helper_exception_return(cpu_env, dst);

>          tcg_temp_free_i64(dst);

>          if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {

> @@ -2023,14 +2032,17 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)

>          /* Must exit loop to check un-masked IRQs */

>          s->base.is_jmp = DISAS_EXIT;

>          return;

> +

>      case 5: /* DRPS */

> -        if (rn != 0x1f) {

> -            unallocated_encoding(s);

> +        if (op3 != 0 || op4 != 0 || rn != 0x1f) {

> +            goto do_unallocated;

>          } else {

>              unsupported_encoding(s, insn);

>          }

>          return;

> +

>      default:

> +    do_unallocated:

>          unallocated_encoding(s);

>          return;

>      }


thanks
-- PMM
Richard Henderson Dec. 12, 2018, 7:20 p.m. UTC | #2
On 12/11/18 9:40 AM, Peter Maydell wrote:
> On Fri, 7 Dec 2018 at 10:36, Richard Henderson

> <richard.henderson@linaro.org> wrote:

>>

>> This will enable PAuth decode in a subsequent patch.

>>

>> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

>> ---

>>  target/arm/translate-a64.c | 34 +++++++++++++++++++++++-----------

>>  1 file changed, 23 insertions(+), 11 deletions(-)

>>

>> diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c

>> index c84c2dbb66..5fa2647771 100644

>> --- a/target/arm/translate-a64.c

>> +++ b/target/arm/translate-a64.c

>> @@ -1989,32 +1989,41 @@ static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)

>>      rn = extract32(insn, 5, 5);

>>      op4 = extract32(insn, 0, 5);

>>

>> -    if (op4 != 0x0 || op3 != 0x0 || op2 != 0x1f) {

>> -        unallocated_encoding(s);

>> -        return;

>> +    if (op2 != 0x1f) {

>> +        goto do_unallocated;

>>      }

>>

>>      switch (opc) {

>>      case 0: /* BR */

>>      case 1: /* BLR */

>>      case 2: /* RET */

>> -        gen_a64_set_pc(s, cpu_reg(s, rn));

>> +        if (op3 == 0 && op4 == 0) {

>> +            dst = cpu_reg(s, rn);

>> +        } else {

>> +            goto do_unallocated;

>> +        }

>> +        gen_a64_set_pc(s, dst);

>>          /* BLR also needs to load return address */

>>          if (opc == 1) {

>>              tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);

>>          }

>>          break;

>> +

>>      case 4: /* ERET */

>>          if (s->current_el == 0) {

>> -            unallocated_encoding(s);

>> -            return;

>> -        }

>> -        if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {

>> -            gen_io_start();

>> +            goto do_unallocated;

>>          }

>>          dst = tcg_temp_new_i64();

>>          tcg_gen_ld_i64(dst, cpu_env,

>>                         offsetof(CPUARMState, elr_el[s->current_el]));

>> +        if (op3 == 0 && op4 == 0) {

>> +            ;

>> +        } else {

>> +            goto do_unallocated;

> 

> 

> This decode check should go before any code has been

> emittede (ie before the tcg_gen_ld_i64 above it).


Well, it could, but only if we duplicate the ld_i64 in the various branches
that require it.  E.g.

  if (op3 == 0 && op4 == 0) {
      tcg_gen_ld_i64(...);
  } else if (dc_ir_feature(aa64_pauth, s) && ...) {
      tcg_gen_ld_i64(...);
      if (s->pauth_active) {
          gen_helper_auti*(...);
      }
  } else {
      goto do_unallocated;
  }

which I suppose isn't so bad.

What I have isn't an error because the ld_i64 will simply be deleted as dead
code by the tcg optimizer.  But I'll rearrange anyway.


r~
Peter Maydell Dec. 12, 2018, 9:18 p.m. UTC | #3
On Wed, 12 Dec 2018 at 19:20, Richard Henderson
<richard.henderson@linaro.org> wrote:
>

> On 12/11/18 9:40 AM, Peter Maydell wrote:

> > On Fri, 7 Dec 2018 at 10:36, Richard Henderson

> > <richard.henderson@linaro.org> wrote:

> >>

> >> This will enable PAuth decode in a subsequent patch.

> >>

> >> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>


> > This decode check should go before any code has been

> > emittede (ie before the tcg_gen_ld_i64 above it).

>

> Well, it could, but only if we duplicate the ld_i64 in the various branches

> that require it.  E.g.

>

>   if (op3 == 0 && op4 == 0) {

>       tcg_gen_ld_i64(...);

>   } else if (dc_ir_feature(aa64_pauth, s) && ...) {

>       tcg_gen_ld_i64(...);

>       if (s->pauth_active) {

>           gen_helper_auti*(...);

>       }

>   } else {

>       goto do_unallocated;

>   }

>

> which I suppose isn't so bad.

>

> What I have isn't an error because the ld_i64 will simply be deleted as dead

> code by the tcg optimizer.  But I'll rearrange anyway.


You'd also need to manually free the 'dst' TCG temp before the goto.
The A32/T32 decoder is full of (harmless) "leaked" TCG temps in
error-exit paths, which is one reason I think it's nicer to
fully decode before proceeding to codegen.

thanks
-- PMM
diff mbox series

Patch

diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index c84c2dbb66..5fa2647771 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1989,32 +1989,41 @@  static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
     rn = extract32(insn, 5, 5);
     op4 = extract32(insn, 0, 5);
 
-    if (op4 != 0x0 || op3 != 0x0 || op2 != 0x1f) {
-        unallocated_encoding(s);
-        return;
+    if (op2 != 0x1f) {
+        goto do_unallocated;
     }
 
     switch (opc) {
     case 0: /* BR */
     case 1: /* BLR */
     case 2: /* RET */
-        gen_a64_set_pc(s, cpu_reg(s, rn));
+        if (op3 == 0 && op4 == 0) {
+            dst = cpu_reg(s, rn);
+        } else {
+            goto do_unallocated;
+        }
+        gen_a64_set_pc(s, dst);
         /* BLR also needs to load return address */
         if (opc == 1) {
             tcg_gen_movi_i64(cpu_reg(s, 30), s->pc);
         }
         break;
+
     case 4: /* ERET */
         if (s->current_el == 0) {
-            unallocated_encoding(s);
-            return;
-        }
-        if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
-            gen_io_start();
+            goto do_unallocated;
         }
         dst = tcg_temp_new_i64();
         tcg_gen_ld_i64(dst, cpu_env,
                        offsetof(CPUARMState, elr_el[s->current_el]));
+        if (op3 == 0 && op4 == 0) {
+            ;
+        } else {
+            goto do_unallocated;
+        }
+        if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
+            gen_io_start();
+        }
         gen_helper_exception_return(cpu_env, dst);
         tcg_temp_free_i64(dst);
         if (tb_cflags(s->base.tb) & CF_USE_ICOUNT) {
@@ -2023,14 +2032,17 @@  static void disas_uncond_b_reg(DisasContext *s, uint32_t insn)
         /* Must exit loop to check un-masked IRQs */
         s->base.is_jmp = DISAS_EXIT;
         return;
+
     case 5: /* DRPS */
-        if (rn != 0x1f) {
-            unallocated_encoding(s);
+        if (op3 != 0 || op4 != 0 || rn != 0x1f) {
+            goto do_unallocated;
         } else {
             unsupported_encoding(s, insn);
         }
         return;
+
     default:
+    do_unallocated:
         unallocated_encoding(s);
         return;
     }