diff mbox series

[v5,27/35] target/arm: Implement SVE MOVPRFX

Message ID 20180621015359.12018-28-richard.henderson@linaro.org
State Superseded
Headers show
Series target/arm SVE patches | expand

Commit Message

Richard Henderson June 21, 2018, 1:53 a.m. UTC
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

---
 target/arm/translate-sve.c | 60 +++++++++++++++++++++++++++++++++++++-
 target/arm/sve.decode      |  7 +++++
 2 files changed, 66 insertions(+), 1 deletion(-)

-- 
2.17.1

Comments

Peter Maydell June 26, 2018, 12:24 p.m. UTC | #1
On 21 June 2018 at 02:53, Richard Henderson
<richard.henderson@linaro.org> wrote:
> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>

> ---

>  target/arm/translate-sve.c | 60 +++++++++++++++++++++++++++++++++++++-

>  target/arm/sve.decode      |  7 +++++

>  2 files changed, 66 insertions(+), 1 deletion(-)


> +/*

> + * Move Prefix

> + *

> + * TODO: The implementation so far could handle predicated merging movprfx.

> + * The helper functions as written take an extra source register to

> + * use in the operation, but the result is only written when predication

> + * succeeds.  For unpredicated movprfx, we need to rearrange the helpers

> + * to allow the final write back to the destination to be unconditional.

> + * For predicated zering movprfz, we need to rearrange the helpers to


"zeroing". Should that be "movprfx" or is "movprfz" a thing? (the SVE
spec doesn't mention it.)

> + * allow the final write back to zero inactives.

> + *

> + * In the meantime, just emit the moves.

> + */

> +

> +static bool trans_MOVPRFX(DisasContext *s, arg_MOVPRFX *a, uint32_t insn)

> +{

> +    return do_mov_z(s, a->rd, a->rn);

> +}


A bit confusing that do_mov_z() does the sve_access_check() for us
but do_sel_z() and do_movz_zpz() do not...

> +

> +static bool trans_MOVPRFX_m(DisasContext *s, arg_rpr_esz *a, uint32_t insn)

> +{

> +    if (sve_access_check(s)) {

> +        do_sel_z(s, a->rd, a->rn, a->rd, a->pg, a->esz);

> +    }

> +    return true;

> +}

> +

> +static bool trans_MOVPRFX_z(DisasContext *s, arg_rpr_esz *a, uint32_t insn)

> +{

> +    if (sve_access_check(s)) {

> +        do_movz_zpz(s, a->rd, a->rn, a->pg, a->esz);

> +    }

> +    return true;

> +}


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


thanks
-- PMM
Richard Henderson June 26, 2018, 2:57 p.m. UTC | #2
On 06/26/2018 05:24 AM, Peter Maydell wrote:
>> + * TODO: The implementation so far could handle predicated merging movprfx.

>> + * The helper functions as written take an extra source register to

>> + * use in the operation, but the result is only written when predication

>> + * succeeds.  For unpredicated movprfx, we need to rearrange the helpers

>> + * to allow the final write back to the destination to be unconditional.

>> + * For predicated zering movprfz, we need to rearrange the helpers to

> 

> "zeroing". Should that be "movprfx" or is "movprfz" a thing? (the SVE

> spec doesn't mention it.)


Yes, typo for movprfx.

> 

>> + * allow the final write back to zero inactives.

>> + *

>> + * In the meantime, just emit the moves.

>> + */

>> +

>> +static bool trans_MOVPRFX(DisasContext *s, arg_MOVPRFX *a, uint32_t insn)

>> +{

>> +    return do_mov_z(s, a->rd, a->rn);

>> +}

> 

> A bit confusing that do_mov_z() does the sve_access_check() for us

> but do_sel_z() and do_movz_zpz() do not...


Yes.  I regret do_mov_z does the check, but that patch is already in mainline,
and fixing it up isn't a necessity or a priority.


r~
diff mbox series

Patch

diff --git a/target/arm/translate-sve.c b/target/arm/translate-sve.c
index 308c04de89..067c219b54 100644
--- a/target/arm/translate-sve.c
+++ b/target/arm/translate-sve.c
@@ -351,6 +351,23 @@  static bool do_zpzz_ool(DisasContext *s, arg_rprr_esz *a, gen_helper_gvec_4 *fn)
     return true;
 }
 
+/* Select active elememnts from Zn and inactive elements from Zm,
+ * storing the result in Zd.
+ */
+static void do_sel_z(DisasContext *s, int rd, int rn, int rm, int pg, int esz)
+{
+    static gen_helper_gvec_4 * const fns[4] = {
+        gen_helper_sve_sel_zpzz_b, gen_helper_sve_sel_zpzz_h,
+        gen_helper_sve_sel_zpzz_s, gen_helper_sve_sel_zpzz_d
+    };
+    unsigned vsz = vec_full_reg_size(s);
+    tcg_gen_gvec_4_ool(vec_full_reg_offset(s, rd),
+                       vec_full_reg_offset(s, rn),
+                       vec_full_reg_offset(s, rm),
+                       pred_full_reg_offset(s, pg),
+                       vsz, vsz, 0, fns[esz]);
+}
+
 #define DO_ZPZZ(NAME, name) \
 static bool trans_##NAME##_zpzz(DisasContext *s, arg_rprr_esz *a,         \
                                 uint32_t insn)                            \
@@ -401,7 +418,13 @@  static bool trans_UDIV_zpzz(DisasContext *s, arg_rprr_esz *a, uint32_t insn)
     return do_zpzz_ool(s, a, fns[a->esz]);
 }
 
-DO_ZPZZ(SEL, sel)
+static bool trans_SEL_zpzz(DisasContext *s, arg_rprr_esz *a, uint32_t insn)
+{
+    if (sve_access_check(s)) {
+        do_sel_z(s, a->rd, a->rn, a->rm, a->pg, a->esz);
+    }
+    return true;
+}
 
 #undef DO_ZPZZ
 
@@ -5038,3 +5061,38 @@  static bool trans_PRF_rr(DisasContext *s, arg_PRF_rr *a, uint32_t insn)
     sve_access_check(s);
     return true;
 }
+
+/*
+ * Move Prefix
+ *
+ * TODO: The implementation so far could handle predicated merging movprfx.
+ * The helper functions as written take an extra source register to
+ * use in the operation, but the result is only written when predication
+ * succeeds.  For unpredicated movprfx, we need to rearrange the helpers
+ * to allow the final write back to the destination to be unconditional.
+ * For predicated zering movprfz, we need to rearrange the helpers to
+ * allow the final write back to zero inactives.
+ *
+ * In the meantime, just emit the moves.
+ */
+
+static bool trans_MOVPRFX(DisasContext *s, arg_MOVPRFX *a, uint32_t insn)
+{
+    return do_mov_z(s, a->rd, a->rn);
+}
+
+static bool trans_MOVPRFX_m(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
+{
+    if (sve_access_check(s)) {
+        do_sel_z(s, a->rd, a->rn, a->rd, a->pg, a->esz);
+    }
+    return true;
+}
+
+static bool trans_MOVPRFX_z(DisasContext *s, arg_rpr_esz *a, uint32_t insn)
+{
+    if (sve_access_check(s)) {
+        do_movz_zpz(s, a->rd, a->rn, a->pg, a->esz);
+    }
+    return true;
+}
diff --git a/target/arm/sve.decode b/target/arm/sve.decode
index 94d7b157b4..85f2b39776 100644
--- a/target/arm/sve.decode
+++ b/target/arm/sve.decode
@@ -266,6 +266,10 @@  ORV             00000100 .. 011 000 001 ... ..... .....         @rd_pg_rn
 EORV            00000100 .. 011 001 001 ... ..... .....         @rd_pg_rn
 ANDV            00000100 .. 011 010 001 ... ..... .....         @rd_pg_rn
 
+# SVE constructive prefix (predicated)
+MOVPRFX_z       00000100 .. 010 000 001 ... ..... .....         @rd_pg_rn
+MOVPRFX_m       00000100 .. 010 001 001 ... ..... .....         @rd_pg_rn
+
 # SVE integer add reduction (predicated)
 # Note that saddv requires size != 3.
 UADDV           00000100 .. 000 001 001 ... ..... .....         @rd_pg_rn
@@ -414,6 +418,9 @@  ADR_p64         00000100 11 1 ..... 1010 .. ..... .....         @rd_rn_msz_rm
 
 ### SVE Integer Misc - Unpredicated Group
 
+# SVE constructive prefix (unpredicated)
+MOVPRFX         00000100 00 1 00000 101111 rn:5 rd:5
+
 # SVE floating-point exponential accelerator
 # Note esz != 0
 FEXPA           00000100 .. 1 00000 101110 ..... .....          @rd_rn