diff mbox series

[v2,62/68] target/arm: Convert T16, Miscellaneous 16-bit instructions

Message ID 20190819213755.26175-63-richard.henderson@linaro.org
State New
Headers show
Series target/arm: Convert aa32 base isa to decodetree | expand

Commit Message

Richard Henderson Aug. 19, 2019, 9:37 p.m. UTC
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/translate.c | 109 ++++++++++++-----------------------------
 target/arm/t16.decode  |  31 ++++++++----
 2 files changed, 54 insertions(+), 86 deletions(-)

Comments

Peter Maydell Aug. 26, 2019, 8:38 p.m. UTC | #1
On Mon, 19 Aug 2019 at 22:39, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---

> diff --git a/target/arm/t16.decode b/target/arm/t16.decode
> index 98d60952a1..4ecbabd364 100644
> --- a/target/arm/t16.decode
> +++ b/target/arm/t16.decode
> @@ -210,20 +210,33 @@ REVSH           1011 1010 11 ... ...            @rdm
>
>  # Hints
>
> +%it_cond        5:3 !function=times_2
> +
>  {
> -  YIELD         1011 1111 0001 0000
> -  WFE           1011 1111 0010 0000
> -  WFI           1011 1111 0011 0000
> +  {
> +    YIELD       1011 1111 0001 0000
> +    WFE         1011 1111 0010 0000
> +    WFI         1011 1111 0011 0000
>
> -  # TODO: Implement SEV, SEVL; may help SMP performance.
> -  # SEV         1011 1111 0100 0000
> -  # SEVL        1011 1111 0101 0000
> +    # TODO: Implement SEV, SEVL; may help SMP performance.
> +    # SEV       1011 1111 0100 0000
> +    # SEVL      1011 1111 0101 0000
>
> -  # The canonical nop has the second nibble as 0000, but the whole of the
> -  # rest of the space is a reserved hint, behaves as nop.
> -  NOP           1011 1111 ---- 0000
> +    # The canonical nop has the second nibble as 0000, but the whole of the
> +    # rest of the space is a reserved hint, behaves as nop.
> +    NOP         1011 1111 ---- 0000
> +  }
> +  IT            1011 1111 ... imm:5             &ci cond=%it_cond

This is correct (same behaviour as the old decoder, but
it looks a bit odd here because it's not the same as
the fields defined by the architecture (in particular the
'cond' field is not the same set of bits as the 'firstcond'
field). We could maybe comment it:

  # Bits 7:0 in IT are architecturally simply the
  # new PSTATE.IT bits (despite the instruction description
  # splitting them into 'firstcond' and 'mask' fields).
  # In QEMU during translation we track the IT bits using
  # the DisasContext fields condexec_cond and condexec_mask,
  # so here we massage the bits from the insn into the form
  # that that optimization requires.

(Or equivalently we could just pass a single 8 bit immediate
to the trans_IT function and split it out there, I dunno.)

>  }
>
> +# Miscellaneous 16-bit instructions
> +
> +%imm6_9_3       9:1 3:5 !function=times_2

Would it be worth adding support to the decodetree script
for letting you specify fixed bits in this kind of field-decode,
so we could write '9:1 3:5 0' rather than having to specify
a multiply-by-2 function to put the 0 bit in ? Or is it
not likely to be common enough to be worth bothering with?
(Not something for this series, anyway.)

> +
> +HLT             1011 1010 10 imm:6              &i
> +BKPT            1011 1110 imm:8                 &i
> +CBZ             1011 nz:1 0.1 ..... rn:3        imm=%imm6_9_3
> +
>  # Push and Pop
>
>  %push_list      0:9 !function=t16_push_list
> --

In any case
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM
Richard Henderson Aug. 26, 2019, 11:47 p.m. UTC | #2
On 8/26/19 1:38 PM, Peter Maydell wrote:
>> +  IT            1011 1111 ... imm:5             &ci cond=%it_cond
> 
> This is correct (same behaviour as the old decoder, but
> it looks a bit odd here because it's not the same as
> the fields defined by the architecture (in particular the
> 'cond' field is not the same set of bits as the 'firstcond'
> field). We could maybe comment it:
> 
>   # Bits 7:0 in IT are architecturally simply the
>   # new PSTATE.IT bits (despite the instruction description
>   # splitting them into 'firstcond' and 'mask' fields).
>   # In QEMU during translation we track the IT bits using
>   # the DisasContext fields condexec_cond and condexec_mask,
>   # so here we massage the bits from the insn into the form
>   # that that optimization requires.
> 
> (Or equivalently we could just pass a single 8 bit immediate
> to the trans_IT function and split it out there, I dunno.)

I think I'll just go with this latter and do everything in trans_IT.

>> +%imm6_9_3       9:1 3:5 !function=times_2
> 
> Would it be worth adding support to the decodetree script
> for letting you specify fixed bits in this kind of field-decode,
> so we could write '9:1 3:5 0' rather than having to specify
> a multiply-by-2 function to put the 0 bit in ? Or is it
> not likely to be common enough to be worth bothering with?
> (Not something for this series, anyway.)

I hadn't thought about that.

Adding 1, 2, or -1 also appears, but that's 3 of the 60 instances currently in
the tree whereas shifts make up 33 of 60.


r~
diff mbox series

Patch

diff --git a/target/arm/translate.c b/target/arm/translate.c
index 941266df14..dc670c9724 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -10074,6 +10074,18 @@  static bool trans_TBH(DisasContext *s, arg_tbranch *a)
     return op_tbranch(s, a, true);
 }
 
+static bool trans_CBZ(DisasContext *s, arg_CBZ *a)
+{
+    TCGv_i32 tmp = load_reg(s, a->rn);
+
+    arm_gen_condlabel(s);
+    tcg_gen_brcondi_i32(a->nz ? TCG_COND_EQ : TCG_COND_NE,
+                        tmp, 0, s->condlabel);
+    tcg_temp_free_i32(tmp);
+    gen_jmp(s, read_pc(s) + a->imm);
+    return true;
+}
+
 /*
  * Supervisor call
  */
@@ -10295,6 +10307,25 @@  static bool trans_PLI(DisasContext *s, arg_PLD *a)
     return ENABLE_ARCH_7;
 }
 
+/*
+ * If-then
+ */
+
+static bool trans_IT(DisasContext *s, arg_IT *a)
+{
+    /*
+     * No actual code generated for this insn, just setup state.
+     *
+     * Combinations of firstcond and mask which set up an 0b1111
+     * condition are UNPREDICTABLE; we take the CONSTRAINED
+     * UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
+     * i.e. both meaning "execute always".
+     */
+    s->condexec_cond = a->cond;
+    s->condexec_mask = a->imm;
+    return true;
+}
+
 /*
  * Legacy decoder.
  */
@@ -10661,83 +10692,8 @@  static void disas_thumb_insn(DisasContext *s, uint32_t insn)
     case 8: /* load/store halfword immediate offset, in decodetree */
     case 9: /* load/store from stack, in decodetree */
     case 10: /* add PC/SP (immediate), in decodetree */
+    case 11: /* misc, in decodetree */
     case 12: /* load/store multiple, in decodetree */
-        goto illegal_op;
-
-    case 11:
-        /* misc */
-        op = (insn >> 8) & 0xf;
-        switch (op) {
-        case 0: /* add/sub (sp, immediate), in decodetree */
-        case 2: /* sign/zero extend, in decodetree */
-            goto illegal_op;
-
-        case 4: case 5: case 0xc: case 0xd:
-            /* push/pop, in decodetree */
-            goto illegal_op;
-
-        case 1: case 3: case 9: case 11: /* czb */
-            rm = insn & 7;
-            tmp = load_reg(s, rm);
-            arm_gen_condlabel(s);
-            if (insn & (1 << 11))
-                tcg_gen_brcondi_i32(TCG_COND_EQ, tmp, 0, s->condlabel);
-            else
-                tcg_gen_brcondi_i32(TCG_COND_NE, tmp, 0, s->condlabel);
-            tcg_temp_free_i32(tmp);
-            offset = ((insn & 0xf8) >> 2) | (insn & 0x200) >> 3;
-            gen_jmp(s, read_pc(s) + offset);
-            break;
-
-        case 15: /* IT, nop-hint.  */
-            if ((insn & 0xf) == 0) {
-                goto illegal_op; /* nop hint, in decodetree */
-            }
-            /*
-             * IT (If-Then)
-             *
-             * Combinations of firstcond and mask which set up an 0b1111
-             * condition are UNPREDICTABLE; we take the CONSTRAINED
-             * UNPREDICTABLE choice to treat 0b1111 the same as 0b1110,
-             * i.e. both meaning "execute always".
-             */
-            s->condexec_cond = (insn >> 4) & 0xe;
-            s->condexec_mask = insn & 0x1f;
-            /* No actual code generated for this insn, just setup state.  */
-            break;
-
-        case 0xe: /* bkpt */
-        {
-            int imm8 = extract32(insn, 0, 8);
-            ARCH(5);
-            gen_exception_bkpt_insn(s, syn_aa32_bkpt(imm8, true));
-            break;
-        }
-
-        case 0xa: /* rev, and hlt */
-        {
-            int op1 = extract32(insn, 6, 2);
-
-            if (op1 == 2) {
-                /* HLT */
-                int imm6 = extract32(insn, 0, 6);
-
-                gen_hlt(s, imm6);
-                break;
-            }
-
-            /* Otherwise this is rev, in decodetree */
-            goto illegal_op;
-        }
-
-        case 6: /* setend, cps; in decodetree */
-            goto illegal_op;
-
-        default:
-            goto undef;
-        }
-        break;
-
     case 13: /* conditional branch or swi, in decodetree */
         goto illegal_op;
 
@@ -10793,7 +10749,6 @@  static void disas_thumb_insn(DisasContext *s, uint32_t insn)
     }
     return;
 illegal_op:
-undef:
     unallocated_encoding(s);
 }
 
diff --git a/target/arm/t16.decode b/target/arm/t16.decode
index 98d60952a1..4ecbabd364 100644
--- a/target/arm/t16.decode
+++ b/target/arm/t16.decode
@@ -210,20 +210,33 @@  REVSH           1011 1010 11 ... ...            @rdm
 
 # Hints
 
+%it_cond        5:3 !function=times_2
+
 {
-  YIELD         1011 1111 0001 0000
-  WFE           1011 1111 0010 0000
-  WFI           1011 1111 0011 0000
+  {
+    YIELD       1011 1111 0001 0000
+    WFE         1011 1111 0010 0000
+    WFI         1011 1111 0011 0000
 
-  # TODO: Implement SEV, SEVL; may help SMP performance.
-  # SEV         1011 1111 0100 0000
-  # SEVL        1011 1111 0101 0000
+    # TODO: Implement SEV, SEVL; may help SMP performance.
+    # SEV       1011 1111 0100 0000
+    # SEVL      1011 1111 0101 0000
 
-  # The canonical nop has the second nibble as 0000, but the whole of the
-  # rest of the space is a reserved hint, behaves as nop.
-  NOP           1011 1111 ---- 0000
+    # The canonical nop has the second nibble as 0000, but the whole of the
+    # rest of the space is a reserved hint, behaves as nop.
+    NOP         1011 1111 ---- 0000
+  }
+  IT            1011 1111 ... imm:5             &ci cond=%it_cond
 }
 
+# Miscellaneous 16-bit instructions
+
+%imm6_9_3       9:1 3:5 !function=times_2
+
+HLT             1011 1010 10 imm:6              &i
+BKPT            1011 1110 imm:8                 &i
+CBZ             1011 nz:1 0.1 ..... rn:3        imm=%imm6_9_3
+
 # Push and Pop
 
 %push_list      0:9 !function=t16_push_list