mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-04 08:13:54 -06:00
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:
parent
308ee80578
commit
50bfb45b2c
4 changed files with 43 additions and 12 deletions
|
@ -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),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue