target/arm: Split out get_zarray
Prepare for MOVA array to/from vector with multiple registers by adding a div_len parameter, herein always 1, and a vec_mod parameter, herein always 0. Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20250704142112.1018902-24-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
parent
2c43bee917
commit
7afb9855fc
1 changed files with 32 additions and 15 deletions
|
|
@ -43,7 +43,8 @@ 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,
|
||||
int vec_mod, bool vertical)
|
||||
{
|
||||
int pos, len, offset;
|
||||
TCGv_i32 tmp;
|
||||
|
|
@ -52,10 +53,23 @@ static TCGv_ptr get_tile_rowcol(DisasContext *s, int esz, int rs,
|
|||
/* Compute the final index, which is Rs+imm. */
|
||||
tmp = tcg_temp_new_i32();
|
||||
tcg_gen_trunc_tl_i32(tmp, cpu_reg(s, rs));
|
||||
/*
|
||||
* Round the vector index down to a multiple of vec_mod if necessary.
|
||||
* We do this before adding the offset, to handle cases like
|
||||
* MOVA (tile to vector, 2 registers) where we want to call this
|
||||
* several times in a loop with an increasing offset. We rely on
|
||||
* the instruction encodings always forcing the initial offset in
|
||||
* [rs + offset] to be a multiple of vec_mod. The pseudocode usually
|
||||
* does the round-down after adding the offset rather than before,
|
||||
* but MOVA is an exception.
|
||||
*/
|
||||
if (vec_mod > 1) {
|
||||
tcg_gen_andc_i32(tmp, tmp, tcg_constant_i32(vec_mod - 1));
|
||||
}
|
||||
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 +125,14 @@ 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, int vec_mod)
|
||||
{
|
||||
/* ZA[n] equates to ZA0H.B[n]. */
|
||||
return get_tile_rowcol(s, MO_8, rs, 0, imm, div_len, vec_mod, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* Resolve tile.size[0] to a host pointer.
|
||||
* Used by e.g. outer product insns where we require the entire tile.
|
||||
|
|
@ -177,7 +199,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, 0, a->v);
|
||||
t_zr = vec_full_reg_ptr(s, a->zr);
|
||||
t_pg = pred_full_reg_ptr(s, a->pg);
|
||||
|
||||
|
|
@ -259,7 +281,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, 0, a->v);
|
||||
t_pg = pred_full_reg_ptr(s, a->pg);
|
||||
addr = tcg_temp_new_i64();
|
||||
|
||||
|
|
@ -281,19 +303,14 @@ typedef void GenLdStR(DisasContext *, TCGv_ptr, int, int, int, int, MemOp);
|
|||
|
||||
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, 0);
|
||||
|
||||
if (!sme_za_enabled_check(s)) {
|
||||
return true;
|
||||
fn(s, base, 0, svl, a->rn, imm * svl,
|
||||
s->align_mem ? MO_ALIGN_16 : MO_UNALN);
|
||||
}
|
||||
|
||||
/* 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,
|
||||
s->align_mem ? MO_ALIGN_16 : MO_UNALN);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue