Message ID | 20190819213755.26175-63-richard.henderson@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | target/arm: Convert aa32 base isa to decodetree | expand |
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
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 --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
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(-) -- 2.17.1