target/riscv: rvv-1.0: register gather instructions

* Add vrgatherei16.vv instruction.

Signed-off-by: Frank Chang <frank.chang@sifive.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20211210075704.23951-36-frank.chang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
Frank Chang 2021-12-10 15:56:21 +08:00 committed by Alistair Francis
parent 308ee80578
commit 50bfb45b2c
4 changed files with 43 additions and 12 deletions

View file

@ -3090,7 +3090,25 @@ static bool vrgather_vv_check(DisasContext *s, arg_rmrr *a)
require_vm(a->vm, a->rd);
}
static bool vrgatherei16_vv_check(DisasContext *s, arg_rmrr *a)
{
int8_t emul = MO_16 - s->sew + s->lmul;
return require_rvv(s) &&
vext_check_isa_ill(s) &&
(emul >= -3 && emul <= 3) &&
require_align(a->rd, s->lmul) &&
require_align(a->rs1, emul) &&
require_align(a->rs2, s->lmul) &&
(a->rd != a->rs2 && a->rd != a->rs1) &&
!is_overlapped(a->rd, 1 << MAX(s->lmul, 0),
a->rs1, 1 << MAX(emul, 0)) &&
!is_overlapped(a->rd, 1 << MAX(s->lmul, 0),
a->rs2, 1 << MAX(s->lmul, 0)) &&
require_vm(a->vm, a->rd);
}
GEN_OPIVV_TRANS(vrgather_vv, vrgather_vv_check)
GEN_OPIVV_TRANS(vrgatherei16_vv, vrgatherei16_vv_check)
static bool vrgather_vx_check(DisasContext *s, arg_rmrr *a)
{
@ -3110,7 +3128,8 @@ static bool trans_vrgather_vx(DisasContext *s, arg_rmrr *a)
}
if (a->vm && s->vl_eq_vlmax) {
int vlmax = s->vlen;
int scale = s->lmul - (s->sew + 3);
int vlmax = scale < 0 ? s->vlen >> -scale : s->vlen << scale;
TCGv_i64 dest = tcg_temp_new_i64();
if (a->rs1 == 0) {
@ -3141,8 +3160,10 @@ static bool trans_vrgather_vi(DisasContext *s, arg_rmrr *a)
}
if (a->vm && s->vl_eq_vlmax) {
if (a->rs1 >= s->vlen) {
tcg_gen_gvec_dup_imm(SEW64, vreg_ofs(s, a->rd),
int scale = s->lmul - (s->sew + 3);
int vlmax = scale < 0 ? s->vlen >> -scale : s->vlen << scale;
if (a->rs1 >= vlmax) {
tcg_gen_gvec_dup_imm(MO_64, vreg_ofs(s, a->rd),
MAXSZ(s), MAXSZ(s), 0);
} else {
tcg_gen_gvec_dup_mem(s->sew, vreg_ofs(s, a->rd),