@@ -43,7 +43,7 @@ static bool sme2_zt0_enabled_check(DisasContext *s)
/* Resolve tile.size[rs+imm] to a host pointer. */
static TCGv_ptr get_tile_rowcol(DisasContext *s, int esz, int rs,
- int tile, int imm, bool vertical)
+ int tile, int imm, int div_len, bool vertical)
{
int pos, len, offset;
TCGv_i32 tmp;
@@ -55,7 +55,7 @@ static TCGv_ptr get_tile_rowcol(DisasContext *s, int esz, int rs,
tcg_gen_addi_i32(tmp, tmp, imm);
/* Prepare a power-of-two modulo via extraction of @len bits. */
- len = ctz32(streaming_vec_reg_size(s)) - esz;
+ len = ctz32(streaming_vec_reg_size(s) / div_len) - esz;
if (!len) {
/*
@@ -111,6 +111,13 @@ static TCGv_ptr get_tile_rowcol(DisasContext *s, int esz, int rs,
return addr;
}
+/* Resolve ZArray[rs+imm] to a host pointer. */
+static TCGv_ptr get_zarray(DisasContext *s, int rs, int imm, int div_len)
+{
+ /* ZA[n] equates to ZA0H.B[n]. */
+ return get_tile_rowcol(s, MO_8, rs, 0, imm, div_len, false);
+}
+
/*
* Resolve tile.size[0] to a host pointer.
* Used by e.g. outer product insns where we require the entire tile.
@@ -177,7 +184,7 @@ static bool do_mova_tile(DisasContext *s, arg_mova_p *a, bool to_vec)
return true;
}
- t_za = get_tile_rowcol(s, a->esz, a->rs, a->za, a->off, a->v);
+ t_za = get_tile_rowcol(s, a->esz, a->rs, a->za, a->off, 1, a->v);
t_zr = vec_full_reg_ptr(s, a->zr);
t_pg = pred_full_reg_ptr(s, a->pg);
@@ -234,7 +241,7 @@ static bool do_mova_tile_n(DisasContext *s, arg_mova_t *a, int n, bool to_vec)
for (int i = 0; i < n; ++i) {
TCGv_ptr t_zr = vec_full_reg_ptr(s, a->zr * n + i);
t_za = get_tile_rowcol(s, a->esz, a->rs, a->za,
- a->off * n + i, a->v);
+ a->off * n + i, 1, a->v);
if (to_vec) {
zc_fns[a->esz](t_zr, t_za, t_desc);
} else {
@@ -243,13 +250,13 @@ static bool do_mova_tile_n(DisasContext *s, arg_mova_t *a, int n, bool to_vec)
}
} else {
for (int i = 0; i < n; ++i) {
- int zr_ofs = vec_full_reg_offset(s, a->zr * n + i);
+ int o_zr = vec_full_reg_offset(s, a->zr * n + i);
t_za = get_tile_rowcol(s, a->esz, a->rs, a->za,
- a->off * n + i, a->v);
+ a->off * n + i, 1, a->v);
if (to_vec) {
- tcg_gen_gvec_mov_var(MO_8, tcg_env, zr_ofs, t_za, 0, svl, svl);
+ tcg_gen_gvec_mov_var(MO_8, tcg_env, o_zr, t_za, 0, svl, svl);
} else {
- tcg_gen_gvec_mov_var(MO_8, t_za, 0, tcg_env, zr_ofs, svl, svl);
+ tcg_gen_gvec_mov_var(MO_8, t_za, 0, tcg_env, o_zr, svl, svl);
}
}
}
@@ -315,7 +322,7 @@ static bool trans_LDST1(DisasContext *s, arg_LDST1 *a)
return true;
}
- t_za = get_tile_rowcol(s, a->esz, a->rs, a->za, a->off, a->v);
+ t_za = get_tile_rowcol(s, a->esz, a->rs, a->za, a->off, 1, a->v);
t_pg = pred_full_reg_ptr(s, a->pg);
addr = tcg_temp_new_i64();
@@ -337,18 +344,13 @@ typedef void GenLdStR(DisasContext *, TCGv_ptr, int, int, int, int);
static bool do_ldst_r(DisasContext *s, arg_ldstr *a, GenLdStR *fn)
{
- int svl = streaming_vec_reg_size(s);
- int imm = a->imm;
- TCGv_ptr base;
+ if (sme_za_enabled_check(s)) {
+ int svl = streaming_vec_reg_size(s);
+ int imm = a->imm;
+ TCGv_ptr base = get_zarray(s, a->rv, imm, 1);
- if (!sme_za_enabled_check(s)) {
- return true;
+ fn(s, base, 0, svl, a->rn, imm * svl);
}
-
- /* ZA[n] equates to ZA0H.B[n]. */
- base = get_tile_rowcol(s, MO_8, a->rv, 0, imm, false);
-
- fn(s, base, 0, svl, a->rn, imm * svl);
return true;
}
Prepare for MOVA array to/from vector with multiple registers by adding a div_len parameter, herein always 1. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/arm/tcg/translate-sme.c | 40 ++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 19 deletions(-)