@@ -2953,3 +2953,5 @@ DEF_HELPER_FLAGS_4(sve2p1_uminqv_b, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(sve2p1_uminqv_h, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(sve2p1_uminqv_s, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
DEF_HELPER_FLAGS_4(sve2p1_uminqv_d, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
+
+DEF_HELPER_FLAGS_3(pext, TCG_CALL_NO_RWG, void, ptr, i32, i32)
@@ -7839,3 +7839,85 @@ DO_FCVTLT(sve2_fcvtlt_sd, uint64_t, uint32_t, H1_8, H1_4, float32_to_float64)
#undef DO_FCVTLT
#undef DO_FCVTNT
+
+void HELPER(pext)(void *vd, uint32_t png, uint32_t desc)
+{
+ int pl = FIELD_EX32(desc, PREDDESC, OPRSZ);
+ int vl = pl * 8;
+ unsigned v_esz = FIELD_EX32(desc, PREDDESC, ESZ);
+ int part = FIELD_EX32(desc, PREDDESC, DATA);
+ unsigned p_esz;
+ uint64_t p_mask;
+ int p_count;
+ bool p_invert;
+
+ /* C.f. Arm pseudocode CounterToPredicate. */
+ if ((png & 0xf) == 0) {
+ /* Canonical false predicate. */
+ goto zeros;
+ }
+ p_esz = ctz32(png);
+
+ /*
+ * maxbit = log2(pl * 4)
+ * = log2(vl / 8 * 4)
+ * = log2(vl / 2)
+ * = log2(vl) - 1
+ * maxbit_mask = ones<maxbit:0>
+ * = (1 << (maxbit + 1)) - 1
+ * = (1 << (log2(vl) - 1 + 1)) - 1
+ * = (1 << log2(vl)) - 1
+ * = pow2ceil(vl) - 1
+ * Note that we keep count in bytes, not elements.
+ */
+ p_count = (png & (pow2ceil(vl) - 1)) >> 1;
+ p_invert = (png >> 15) & 1;
+
+ /*
+ * If the esz encoded into the predicate is not larger than the
+ * vector operation esz, then the expanded predicate bit will
+ * be true for all vector elements. If the predicate esz is
+ * larger than the vector esz, then only even multiples can be
+ * true, and the rest will be false. This can be easily represented
+ * by taking the maximum esz for the pred_esz_mask.
+ */
+ p_mask = pred_esz_masks[MAX(v_esz, p_esz)];
+
+ if (p_count == 0) {
+ if (p_invert) {
+ /* Canonical true predicate: invert count zero. */
+ goto ones;
+ }
+ /* Non-canonical false predicate. */
+ goto zeros;
+ }
+
+ /* Adjust for the portion of the 4*VL counter to be extracted. */
+ p_count -= vl * part;
+
+ if (p_invert) {
+ if (p_count >= 0) {
+ goto ones;
+ }
+ if (p_count + vl <= 0) {
+ goto zeros;
+ }
+ do_whileg(vd, p_mask, p_count + vl, vl);
+ } else {
+ if (p_count <= 0) {
+ goto zeros;
+ }
+ if (p_count >= vl) {
+ goto ones;
+ }
+ do_whilel(vd, p_mask, p_count, vl);
+ }
+ return;
+
+ ones:
+ do_whilel(vd, p_mask, vl, vl);
+ return;
+ zeros:
+ memset(vd, 0, ROUND_UP(pl, 8));
+ return;
+}
@@ -3319,6 +3319,42 @@ static bool trans_WHILE_ptr(DisasContext *s, arg_WHILE_ptr *a)
return true;
}
+static bool do_pext(DisasContext *s, arg_pext *a, int n)
+{
+ TCGv_i32 t_png;
+ TCGv_ptr t_pd;
+ int pl;
+
+ if (!sve_access_check(s)) {
+ return true;
+ }
+
+ t_png = tcg_temp_new_i32();
+ tcg_gen_ld16u_i32(t_png, tcg_env,
+ pred_full_reg_offset(s, a->rn) ^
+ (HOST_BIG_ENDIAN ? 6 : 0));
+
+ t_pd = tcg_temp_new_ptr();
+ pl = pred_full_reg_size(s);
+
+ for (int i = 0; i < n; ++i) {
+ int rd = (a->rd + i) % 16;
+ int part = a->imm * n + i;
+ unsigned desc = 0;
+
+ desc = FIELD_DP32(desc, PREDDESC, OPRSZ, pl);
+ desc = FIELD_DP32(desc, PREDDESC, ESZ, a->esz);
+ desc = FIELD_DP32(desc, PREDDESC, DATA, part);
+
+ tcg_gen_addi_ptr(t_pd, tcg_env, pred_full_reg_offset(s, rd));
+ gen_helper_pext(t_pd, t_png, tcg_constant_i32(desc));
+ }
+ return true;
+}
+
+TRANS_FEAT(PEXT_1, aa64_sme2_or_sve2p1, do_pext, a, 1)
+TRANS_FEAT(PEXT_2, aa64_sme2_or_sve2p1, do_pext, a, 2)
+
/*
*** SVE Integer Wide Immediate - Unpredicated Group
*/
@@ -60,6 +60,7 @@
%rn_ax2 6:4 !function=times_2
%pnd 0:3 !function=plus_8
+%pnn 5:3 !function=plus_8
###########################################################################
# Named attribute sets. These are used to make nice(er) names
@@ -823,6 +824,11 @@ WHILE_lt_cnt4 00100101 .. 1 ..... 0110 . 1 ..... 1 . ... @while_cnt
WHILE_gt_cnt2 00100101 .. 1 ..... 0100 . 0 ..... 1 . ... @while_cnt
WHILE_gt_cnt4 00100101 .. 1 ..... 0110 . 0 ..... 1 . ... @while_cnt
+# SVE2.1 extract mask predicate from predicate-as-counter
+&pext rd rn esz imm
+PEXT_1 00100101 esz:2 1 00000 0111 00 imm:2 ... 1 rd:4 &pext rn=%pnn
+PEXT_2 00100101 esz:2 1 00000 0111 010 imm:1 ... 1 rd:4 &pext rn=%pnn
+
### SVE Integer Wide Immediate - Unpredicated Group
# SVE broadcast floating-point immediate (unpredicated)
Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/arm/tcg/helper-sve.h | 2 + target/arm/tcg/sve_helper.c | 82 ++++++++++++++++++++++++++++++++++ target/arm/tcg/translate-sve.c | 36 +++++++++++++++ target/arm/tcg/sve.decode | 6 +++ 4 files changed, 126 insertions(+)