diff mbox series

[v2,66/68] target/arm: Convert T16, long branches

Message ID 20190819213755.26175-67-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 | 89 +++++++++++++++++++-----------------------
 target/arm/t16.decode  |  3 ++
 2 files changed, 43 insertions(+), 49 deletions(-)

Comments

Peter Maydell Aug. 27, 2019, 9:34 a.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>
> ---
>  target/arm/translate.c | 89 +++++++++++++++++++-----------------------
>  target/arm/t16.decode  |  3 ++
>  2 files changed, 43 insertions(+), 49 deletions(-)

> +static bool trans_BLX_suffix(DisasContext *s, arg_BLX_suffix *a)
> +{
> +    TCGv_i32 tmp;
> +
> +    assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
> +    if (!ENABLE_ARCH_5) {
> +        return false;
> +    }
> +    tmp = tcg_temp_new_i32();
> +    tcg_gen_addi_i32(tmp, cpu_R[14], a->imm << 1);
> +    tcg_gen_andi_i32(tmp, tmp, -4);

Minor nit, but can we use 0xfffffffc like the old code did,
to avoid the reader having to do 2s-complement arithmetic
in their head to figure out that we're clearing the low 2 bits?

> +    tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
> +    gen_bx(s, tmp);
> +    return true;
> +}

> diff --git a/target/arm/t16.decode b/target/arm/t16.decode
> index 35a5b03118..5ee8457efb 100644
> --- a/target/arm/t16.decode
> +++ b/target/arm/t16.decode
> @@ -274,3 +274,6 @@ LDM_t16         1011 110 ......... \
>  %imm11_0x2      0:s11 !function=times_2
>
>  B               11100 ...........               &i imm=%imm11_0x2

This would be a good place to put a comment equivalent to that
in the old decoder:

# thumb_insn_is_16bit() ensures we won't be decoding these as
# T16 instructions for a Thumb2 CPU, so these patterns must be
# a Thumb1 split BL/BLX.

> +BLX_suffix      11101 imm:11                    &i
> +BL_BLX_prefix   11110 imm:s11                   &i
> +BL_suffix       11111 imm:11                    &i

Otherwise
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM
Richard Henderson Aug. 28, 2019, 12:07 a.m. UTC | #2
On 8/27/19 2:34 AM, Peter Maydell wrote:
>> +    tcg_gen_andi_i32(tmp, tmp, -4);
> 
> Minor nit, but can we use 0xfffffffc like the old code did,
> to avoid the reader having to do 2s-complement arithmetic
> in their head to figure out that we're clearing the low 2 bits?

I always preferred "x & -c" for exactly the same reason:
to avoid the reader having to do 2s compliment arithmetic
in their head to figure out that we're aligning to c.

But, sure, if you like.

> This would be a good place to put a comment equivalent to that
> in the old decoder:
> 
> # thumb_insn_is_16bit() ensures we won't be decoding these as
> # T16 instructions for a Thumb2 CPU, so these patterns must be
> # a Thumb1 split BL/BLX.
> 
>> +BLX_suffix      11101 imm:11                    &i
>> +BL_BLX_prefix   11110 imm:s11                   &i
>> +BL_suffix       11111 imm:11                    &i

I had placed that with trans_BL_BLX_prefix, but I suppose this
is a better place.


r~
Peter Maydell Sept. 3, 2019, 8:23 a.m. UTC | #3
On Wed, 28 Aug 2019 at 01:07, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 8/27/19 2:34 AM, Peter Maydell wrote:
> >> +    tcg_gen_andi_i32(tmp, tmp, -4);
> >
> > Minor nit, but can we use 0xfffffffc like the old code did,
> > to avoid the reader having to do 2s-complement arithmetic
> > in their head to figure out that we're clearing the low 2 bits?
>
> I always preferred "x & -c" for exactly the same reason:
> to avoid the reader having to do 2s compliment arithmetic
> in their head to figure out that we're aligning to c.

I guess this is mostly a personal thing -- I don't
have in my head any idea of what doing a logical
operation on a negative number does, so I always
have to convert it back to "what are the actual
bits here" before I understand it.

thanks
-- PMM
Aleksandar Markovic Sept. 3, 2019, 9:40 a.m. UTC | #4
28.08.2019. 02.07, "Richard Henderson" <richard.henderson@linaro.org> је
написао/ла:
>
> On 8/27/19 2:34 AM, Peter Maydell wrote:
> >> +    tcg_gen_andi_i32(tmp, tmp, -4);
> >
> > Minor nit, but can we use 0xfffffffc like the old code did,
> > to avoid the reader having to do 2s-complement arithmetic
> > in their head to figure out that we're clearing the low 2 bits?
>
> I always preferred "x & -c" for exactly the same reason:
> to avoid the reader having to do 2s compliment arithmetic
> in their head to figure out that we're aligning to c.
>
> But, sure, if you like.
>

I vote for 0xfffffffc.

Aleksandar

> > This would be a good place to put a comment equivalent to that
> > in the old decoder:
> >
> > # thumb_insn_is_16bit() ensures we won't be decoding these as
> > # T16 instructions for a Thumb2 CPU, so these patterns must be
> > # a Thumb1 split BL/BLX.
> >
> >> +BLX_suffix      11101 imm:11                    &i
> >> +BL_BLX_prefix   11110 imm:s11                   &i
> >> +BL_suffix       11111 imm:11                    &i
>
> I had placed that with trans_BL_BLX_prefix, but I suppose this
> is a better place.
>
>
> r~
>
diff mbox series

Patch

diff --git a/target/arm/translate.c b/target/arm/translate.c
index 51b14d409f..f8997a8424 100644
--- a/target/arm/translate.c
+++ b/target/arm/translate.c
@@ -10025,6 +10025,44 @@  static bool trans_BLX_i(DisasContext *s, arg_BLX_i *a)
     return true;
 }
 
+static bool trans_BL_BLX_prefix(DisasContext *s, arg_BL_BLX_prefix *a)
+{
+    /*
+     * thumb_insn_is_16bit() ensures we can't get here for
+     * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
+     */
+    assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
+    tcg_gen_movi_i32(cpu_R[14], read_pc(s) + (a->imm << 12));
+    return true;
+}
+
+static bool trans_BL_suffix(DisasContext *s, arg_BL_suffix *a)
+{
+    TCGv_i32 tmp = tcg_temp_new_i32();
+
+    assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
+    tcg_gen_addi_i32(tmp, cpu_R[14], (a->imm << 1) | 1);
+    tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
+    gen_bx(s, tmp);
+    return true;
+}
+
+static bool trans_BLX_suffix(DisasContext *s, arg_BLX_suffix *a)
+{
+    TCGv_i32 tmp;
+
+    assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
+    if (!ENABLE_ARCH_5) {
+        return false;
+    }
+    tmp = tcg_temp_new_i32();
+    tcg_gen_addi_i32(tmp, cpu_R[14], a->imm << 1);
+    tcg_gen_andi_i32(tmp, tmp, -4);
+    tcg_gen_movi_i32(cpu_R[14], s->base.pc_next | 1);
+    gen_bx(s, tmp);
+    return true;
+}
+
 static bool op_tbranch(DisasContext *s, arg_tbranch *a, bool half)
 {
     TCGv_i32 addr, tmp;
@@ -10612,10 +10650,6 @@  static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
 
 static void disas_thumb_insn(DisasContext *s, uint32_t insn)
 {
-    int32_t offset;
-    TCGv_i32 tmp;
-    TCGv_i32 tmp2;
-
     if (disas_t16(s, insn)) {
         return;
     }
@@ -10634,53 +10668,10 @@  static void disas_thumb_insn(DisasContext *s, uint32_t insn)
     case 11: /* misc, in decodetree */
     case 12: /* load/store multiple, in decodetree */
     case 13: /* conditional branch or swi, in decodetree */
-        goto illegal_op;
-
     case 14:
-        if (insn & (1 << 11)) {
-            /* thumb_insn_is_16bit() ensures we can't get here for
-             * a Thumb2 CPU, so this must be a thumb1 split BL/BLX:
-             * 0b1110_1xxx_xxxx_xxxx : BLX suffix (or UNDEF)
-             */
-            assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
-            ARCH(5);
-            offset = ((insn & 0x7ff) << 1);
-            tmp = load_reg(s, 14);
-            tcg_gen_addi_i32(tmp, tmp, offset);
-            tcg_gen_andi_i32(tmp, tmp, 0xfffffffc);
-
-            tmp2 = tcg_temp_new_i32();
-            tcg_gen_movi_i32(tmp2, s->base.pc_next | 1);
-            store_reg(s, 14, tmp2);
-            gen_bx(s, tmp);
-            break;
-        }
-        /* unconditional branch, in decodetree */
-        goto illegal_op;
-
     case 15:
-        /* thumb_insn_is_16bit() ensures we can't get here for
-         * a Thumb2 CPU, so this must be a thumb1 split BL/BLX.
-         */
-        assert(!arm_dc_feature(s, ARM_FEATURE_THUMB2));
-
-        if (insn & (1 << 11)) {
-            /* 0b1111_1xxx_xxxx_xxxx : BL suffix */
-            offset = ((insn & 0x7ff) << 1) | 1;
-            tmp = load_reg(s, 14);
-            tcg_gen_addi_i32(tmp, tmp, offset);
-
-            tmp2 = tcg_temp_new_i32();
-            tcg_gen_movi_i32(tmp2, s->base.pc_next | 1);
-            store_reg(s, 14, tmp2);
-            gen_bx(s, tmp);
-        } else {
-            /* 0b1111_0xxx_xxxx_xxxx : BL/BLX prefix */
-            uint32_t uoffset = ((int32_t)insn << 21) >> 9;
-
-            tcg_gen_movi_i32(cpu_R[14], read_pc(s) + uoffset);
-        }
-        break;
+        /* branches, in decodetree */
+        goto illegal_op;
     }
     return;
 illegal_op:
diff --git a/target/arm/t16.decode b/target/arm/t16.decode
index 35a5b03118..5ee8457efb 100644
--- a/target/arm/t16.decode
+++ b/target/arm/t16.decode
@@ -274,3 +274,6 @@  LDM_t16         1011 110 ......... \
 %imm11_0x2      0:s11 !function=times_2
 
 B               11100 ...........               &i imm=%imm11_0x2
+BLX_suffix      11101 imm:11                    &i
+BL_BLX_prefix   11110 imm:s11                   &i
+BL_suffix       11111 imm:11                    &i