diff mbox series

[v3,23/51] target/arm: Implement SME RDSVL, ADDSVL, ADDSPL

Message ID 20220620175235.60881-24-richard.henderson@linaro.org
State New
Headers show
Series target/arm: Scalable Matrix Extension | expand

Commit Message

Richard Henderson June 20, 2022, 5:52 p.m. UTC
These SME instructions are nominally within the SVE decode space,
so we add them to sve.decode and translate-sve.c.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
 target/arm/translate-a64.h |  1 +
 target/arm/sve.decode      |  5 ++++-
 target/arm/translate-a64.c | 15 +++++++++++++++
 target/arm/translate-sve.c | 38 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 58 insertions(+), 1 deletion(-)

Comments

Peter Maydell June 21, 2022, 5:23 p.m. UTC | #1
On Mon, 20 Jun 2022 at 19:13, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> These SME instructions are nominally within the SVE decode space,
> so we add them to sve.decode and translate-sve.c.
>
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  target/arm/translate-a64.h |  1 +
>  target/arm/sve.decode      |  5 ++++-
>  target/arm/translate-a64.c | 15 +++++++++++++++
>  target/arm/translate-sve.c | 38 ++++++++++++++++++++++++++++++++++++++
>  4 files changed, 58 insertions(+), 1 deletion(-)

> diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
> index 62b5f3040c..13bdd027a5 100644
> --- a/target/arm/translate-sve.c
> +++ b/target/arm/translate-sve.c
> @@ -1286,6 +1286,19 @@ static bool trans_ADDVL(DisasContext *s, arg_ADDVL *a)
>      return true;
>  }
>
> +static bool trans_ADDSVL(DisasContext *s, arg_ADDSVL *a)
> +{
> +    if (!dc_isar_feature(aa64_sme, s)) {
> +        return false;
> +    }
> +    if (sme_enabled_check(s)) {
> +        TCGv_i64 rd = cpu_reg_sp(s, a->rd);
> +        TCGv_i64 rn = cpu_reg_sp(s, a->rn);
> +        tcg_gen_addi_i64(rd, rn, a->imm * s->svl);
> +    }
> +    return true;
> +}
> +
>  static bool trans_ADDPL(DisasContext *s, arg_ADDPL *a)
>  {
>      if (!dc_isar_feature(aa64_sve, s)) {
> @@ -1299,6 +1312,19 @@ static bool trans_ADDPL(DisasContext *s, arg_ADDPL *a)
>      return true;
>  }
>
> +static bool trans_ADDSPL(DisasContext *s, arg_ADDSPL *a)
> +{
> +    if (!dc_isar_feature(aa64_sme, s)) {
> +        return false;
> +    }
> +    if (sme_enabled_check(s)) {
> +        TCGv_i64 rd = cpu_reg_sp(s, a->rd);
> +        TCGv_i64 rn = cpu_reg_sp(s, a->rn);
> +        tcg_gen_addi_i64(rd, rn, a->imm * (s->svl / 8));
> +    }
> +    return true;
> +}
> +
>  static bool trans_RDVL(DisasContext *s, arg_RDVL *a)
>  {
>      if (!dc_isar_feature(aa64_sve, s)) {
> @@ -1311,6 +1337,18 @@ static bool trans_RDVL(DisasContext *s, arg_RDVL *a)
>      return true;
>  }
>
> +static bool trans_RDSVL(DisasContext *s, arg_RDSVL *a)
> +{
> +    if (!dc_isar_feature(aa64_sme, s)) {
> +        return false;
> +    }
> +    if (sme_enabled_check(s)) {
> +        TCGv_i64 reg = cpu_reg(s, a->rd);
> +        tcg_gen_movi_i64(reg, a->imm * s->svl);
> +    }
> +    return true;
> +}

I think we should define functions that parallel the SVE
vec_full_reg_size() and pred_full_reg_size() rather than directly
looking at s->svl, for consistency with how we did the SVE code.

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

thanks
-- PMM
Richard Henderson June 22, 2022, 12:58 a.m. UTC | #2
On 6/21/22 10:23, Peter Maydell wrote:
>> +static bool trans_RDSVL(DisasContext *s, arg_RDSVL *a)
>> +{
>> +    if (!dc_isar_feature(aa64_sme, s)) {
>> +        return false;
>> +    }
>> +    if (sme_enabled_check(s)) {
>> +        TCGv_i64 reg = cpu_reg(s, a->rd);
>> +        tcg_gen_movi_i64(reg, a->imm * s->svl);
>> +    }
>> +    return true;
>> +}
> 
> I think we should define functions that parallel the SVE
> vec_full_reg_size() and pred_full_reg_size() rather than directly
> looking at s->svl, for consistency with how we did the SVE code.

I had actually been thinking of removing vec_full_reg_size, at least within SVE. 
However... done.  I've propagated the new predicates forward through the following patches 
as well.


r~
Peter Maydell June 23, 2022, 10:12 a.m. UTC | #3
On Wed, 22 Jun 2022 at 01:58, Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 6/21/22 10:23, Peter Maydell wrote:
> >> +static bool trans_RDSVL(DisasContext *s, arg_RDSVL *a)
> >> +{
> >> +    if (!dc_isar_feature(aa64_sme, s)) {
> >> +        return false;
> >> +    }
> >> +    if (sme_enabled_check(s)) {
> >> +        TCGv_i64 reg = cpu_reg(s, a->rd);
> >> +        tcg_gen_movi_i64(reg, a->imm * s->svl);
> >> +    }
> >> +    return true;
> >> +}
> >
> > I think we should define functions that parallel the SVE
> > vec_full_reg_size() and pred_full_reg_size() rather than directly
> > looking at s->svl, for consistency with how we did the SVE code.
>
> I had actually been thinking of removing vec_full_reg_size, at least within SVE.
> However... done.  I've propagated the new predicates forward through the following patches
> as well.

I don't strongly care whether we use vec_full_reg_size() or
look at s->vl, as long as we do the same thing in both SVE
and SME.

I do think that it's worth wrapping up the '/ 8' in a
function that describes what it's doing, so the other
option I guess would be to use s->vl and s->svl directly
when we want the vector length, and have a function like

/* Predicates have 1 bit per byte in the vector */
static int veclen_to_predlen(int veclen)
{
    return veclen / 8;
}

and then use veclen_to_predlen(s->svl);
(Adjust function name, types, / 8 vs >> 3, to taste.)

thanks
-- PMM
diff mbox series

Patch

diff --git a/target/arm/translate-a64.h b/target/arm/translate-a64.h
index 789b6e8e78..6bd1b2eb4b 100644
--- a/target/arm/translate-a64.h
+++ b/target/arm/translate-a64.h
@@ -29,6 +29,7 @@  void write_fp_dreg(DisasContext *s, int reg, TCGv_i64 v);
 bool logic_imm_decode_wmask(uint64_t *result, unsigned int immn,
                             unsigned int imms, unsigned int immr);
 bool sve_access_check(DisasContext *s);
+bool sme_enabled_check(DisasContext *s);
 TCGv_i64 clean_data_tbi(DisasContext *s, TCGv_i64 addr);
 TCGv_i64 gen_mte_check1(DisasContext *s, TCGv_i64 addr, bool is_write,
                         bool tag_checked, int log2_size);
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
index a54feb2f61..bbdaac6ac7 100644
--- a/target/arm/sve.decode
+++ b/target/arm/sve.decode
@@ -449,14 +449,17 @@  INDEX_ri        00000100 esz:2 1 imm:s5 010001 rn:5 rd:5
 # SVE index generation (register start, register increment)
 INDEX_rr        00000100 .. 1 ..... 010011 ..... .....          @rd_rn_rm
 
-### SVE Stack Allocation Group
+### SVE / Streaming SVE Stack Allocation Group
 
 # SVE stack frame adjustment
 ADDVL           00000100 001 ..... 01010 ...... .....           @rd_rn_i6
+ADDSVL          00000100 001 ..... 01011 ...... .....           @rd_rn_i6
 ADDPL           00000100 011 ..... 01010 ...... .....           @rd_rn_i6
+ADDSPL          00000100 011 ..... 01011 ...... .....           @rd_rn_i6
 
 # SVE stack frame size
 RDVL            00000100 101 11111 01010 imm:s6 rd:5
+RDSVL           00000100 101 11111 01011 imm:s6 rd:5
 
 ### SVE Bitwise Shift - Unpredicated Group
 
diff --git a/target/arm/translate-a64.c b/target/arm/translate-a64.c
index efcfb919ff..498970f653 100644
--- a/target/arm/translate-a64.c
+++ b/target/arm/translate-a64.c
@@ -1216,6 +1216,21 @@  static bool sme_access_check(DisasContext *s)
     return true;
 }
 
+/* Note that this function corresponds to CheckSMEEnabled. */
+bool sme_enabled_check(DisasContext *s)
+{
+    /*
+     * Note that unlike sve_excp_el, we have not constrained sme_excp_el
+     * to be zero when fp_excp_el has priority.  This is because we need
+     * sme_excp_el by itself for cpregs access checks.
+     */
+    if (!s->fp_excp_el || s->sme_excp_el < s->fp_excp_el) {
+        s->fp_access_checked = true;
+        return sme_access_check(s);
+    }
+    return fp_access_check_only(s);
+}
+
 /*
  * This utility function is for doing register extension with an
  * optional shift. You will likely want to pass a temporary for the
diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 62b5f3040c..13bdd027a5 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -1286,6 +1286,19 @@  static bool trans_ADDVL(DisasContext *s, arg_ADDVL *a)
     return true;
 }
 
+static bool trans_ADDSVL(DisasContext *s, arg_ADDSVL *a)
+{
+    if (!dc_isar_feature(aa64_sme, s)) {
+        return false;
+    }
+    if (sme_enabled_check(s)) {
+        TCGv_i64 rd = cpu_reg_sp(s, a->rd);
+        TCGv_i64 rn = cpu_reg_sp(s, a->rn);
+        tcg_gen_addi_i64(rd, rn, a->imm * s->svl);
+    }
+    return true;
+}
+
 static bool trans_ADDPL(DisasContext *s, arg_ADDPL *a)
 {
     if (!dc_isar_feature(aa64_sve, s)) {
@@ -1299,6 +1312,19 @@  static bool trans_ADDPL(DisasContext *s, arg_ADDPL *a)
     return true;
 }
 
+static bool trans_ADDSPL(DisasContext *s, arg_ADDSPL *a)
+{
+    if (!dc_isar_feature(aa64_sme, s)) {
+        return false;
+    }
+    if (sme_enabled_check(s)) {
+        TCGv_i64 rd = cpu_reg_sp(s, a->rd);
+        TCGv_i64 rn = cpu_reg_sp(s, a->rn);
+        tcg_gen_addi_i64(rd, rn, a->imm * (s->svl / 8));
+    }
+    return true;
+}
+
 static bool trans_RDVL(DisasContext *s, arg_RDVL *a)
 {
     if (!dc_isar_feature(aa64_sve, s)) {
@@ -1311,6 +1337,18 @@  static bool trans_RDVL(DisasContext *s, arg_RDVL *a)
     return true;
 }
 
+static bool trans_RDSVL(DisasContext *s, arg_RDSVL *a)
+{
+    if (!dc_isar_feature(aa64_sme, s)) {
+        return false;
+    }
+    if (sme_enabled_check(s)) {
+        TCGv_i64 reg = cpu_reg(s, a->rd);
+        tcg_gen_movi_i64(reg, a->imm * s->svl);
+    }
+    return true;
+}
+
 /*
  *** SVE Compute Vector Address Group
  */