Message ID | 20210112093950.17530-35-frank.chang@sifive.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | support vector extension v1.0 | expand |
On Tue, Jan 12, 2021 at 2:10 AM <frank.chang@sifive.com> wrote: > > From: Frank Chang <frank.chang@sifive.com> > > * Add vrgatherei16.vv instruction. > > Signed-off-by: Frank Chang <frank.chang@sifive.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Alistair > --- > target/riscv/helper.h | 4 ++++ > target/riscv/insn32.decode | 1 + > target/riscv/insn_trans/trans_rvv.c.inc | 27 ++++++++++++++++++++++--- > target/riscv/vector_helper.c | 23 ++++++++++++--------- > 4 files changed, 43 insertions(+), 12 deletions(-) > > diff --git a/target/riscv/helper.h b/target/riscv/helper.h > index abf08dbc710..ea6c39b49a8 100644 > --- a/target/riscv/helper.h > +++ b/target/riscv/helper.h > @@ -1100,6 +1100,10 @@ DEF_HELPER_6(vrgather_vv_b, void, ptr, ptr, ptr, ptr, env, i32) > DEF_HELPER_6(vrgather_vv_h, void, ptr, ptr, ptr, ptr, env, i32) > DEF_HELPER_6(vrgather_vv_w, void, ptr, ptr, ptr, ptr, env, i32) > DEF_HELPER_6(vrgather_vv_d, void, ptr, ptr, ptr, ptr, env, i32) > +DEF_HELPER_6(vrgatherei16_vv_b, void, ptr, ptr, ptr, ptr, env, i32) > +DEF_HELPER_6(vrgatherei16_vv_h, void, ptr, ptr, ptr, ptr, env, i32) > +DEF_HELPER_6(vrgatherei16_vv_w, void, ptr, ptr, ptr, ptr, env, i32) > +DEF_HELPER_6(vrgatherei16_vv_d, void, ptr, ptr, ptr, ptr, env, i32) > DEF_HELPER_6(vrgather_vx_b, void, ptr, ptr, tl, ptr, env, i32) > DEF_HELPER_6(vrgather_vx_h, void, ptr, ptr, tl, ptr, env, i32) > DEF_HELPER_6(vrgather_vx_w, void, ptr, ptr, tl, ptr, env, i32) > diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode > index a593938e5c8..85cb3c81be0 100644 > --- a/target/riscv/insn32.decode > +++ b/target/riscv/insn32.decode > @@ -620,6 +620,7 @@ vslidedown_vx 001111 . ..... ..... 100 ..... 1010111 @r_vm > vslidedown_vi 001111 . ..... ..... 011 ..... 1010111 @r_vm > vslide1down_vx 001111 . ..... ..... 110 ..... 1010111 @r_vm > vrgather_vv 001100 . ..... ..... 000 ..... 1010111 @r_vm > +vrgatherei16_vv 001110 . ..... ..... 000 ..... 1010111 @r_vm > vrgather_vx 001100 . ..... ..... 100 ..... 1010111 @r_vm > vrgather_vi 001100 . ..... ..... 011 ..... 1010111 @r_vm > vcompress_vm 010111 - ..... ..... 010 ..... 1010111 @r > diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc > index 72222d73e0e..bc780912b2b 100644 > --- a/target/riscv/insn_trans/trans_rvv.c.inc > +++ b/target/riscv/insn_trans/trans_rvv.c.inc > @@ -3323,7 +3323,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) > { > @@ -3343,7 +3361,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) { > @@ -3374,8 +3393,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), > diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c > index 8ccf538141c..782fe086f3e 100644 > --- a/target/riscv/vector_helper.c > +++ b/target/riscv/vector_helper.c > @@ -4666,11 +4666,11 @@ GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_w, uint32_t, H4) > GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_d, uint64_t, H8) > > /* Vector Register Gather Instruction */ > -#define GEN_VEXT_VRGATHER_VV(NAME, ETYPE, H) \ > +#define GEN_VEXT_VRGATHER_VV(NAME, TS1, TS2, HS1, HS2) \ > void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ > CPURISCVState *env, uint32_t desc) \ > { \ > - uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE))); \ > + uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(TS1))); \ > uint32_t vm = vext_vm(desc); \ > uint32_t vl = env->vl; \ > uint32_t index, i; \ > @@ -4679,20 +4679,25 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ > if (!vm && !vext_elem_mask(v0, i)) { \ > continue; \ > } \ > - index = *((ETYPE *)vs1 + H(i)); \ > + index = *((TS1 *)vs1 + HS1(i)); \ > if (index >= vlmax) { \ > - *((ETYPE *)vd + H(i)) = 0; \ > + *((TS2 *)vd + HS2(i)) = 0; \ > } else { \ > - *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(index)); \ > + *((TS2 *)vd + HS2(i)) = *((TS2 *)vs2 + HS2(index)); \ > } \ > } \ > } > > /* vd[i] = (vs1[i] >= VLMAX) ? 0 : vs2[vs1[i]]; */ > -GEN_VEXT_VRGATHER_VV(vrgather_vv_b, uint8_t, H1) > -GEN_VEXT_VRGATHER_VV(vrgather_vv_h, uint16_t, H2) > -GEN_VEXT_VRGATHER_VV(vrgather_vv_w, uint32_t, H4) > -GEN_VEXT_VRGATHER_VV(vrgather_vv_d, uint64_t, H8) > +GEN_VEXT_VRGATHER_VV(vrgather_vv_b, uint8_t, uint8_t, H1, H1) > +GEN_VEXT_VRGATHER_VV(vrgather_vv_h, uint16_t, uint16_t, H2, H2) > +GEN_VEXT_VRGATHER_VV(vrgather_vv_w, uint32_t, uint32_t, H4, H4) > +GEN_VEXT_VRGATHER_VV(vrgather_vv_d, uint64_t, uint64_t, H8, H8) > + > +GEN_VEXT_VRGATHER_VV(vrgatherei16_vv_b, uint16_t, uint8_t, H2, H1) > +GEN_VEXT_VRGATHER_VV(vrgatherei16_vv_h, uint16_t, uint16_t, H2, H2) > +GEN_VEXT_VRGATHER_VV(vrgatherei16_vv_w, uint16_t, uint32_t, H2, H4) > +GEN_VEXT_VRGATHER_VV(vrgatherei16_vv_d, uint16_t, uint64_t, H2, H8) > > #define GEN_VEXT_VRGATHER_VX(NAME, ETYPE, H) \ > void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \ > -- > 2.17.1 > >
diff --git a/target/riscv/helper.h b/target/riscv/helper.h index abf08dbc710..ea6c39b49a8 100644 --- a/target/riscv/helper.h +++ b/target/riscv/helper.h @@ -1100,6 +1100,10 @@ DEF_HELPER_6(vrgather_vv_b, void, ptr, ptr, ptr, ptr, env, i32) DEF_HELPER_6(vrgather_vv_h, void, ptr, ptr, ptr, ptr, env, i32) DEF_HELPER_6(vrgather_vv_w, void, ptr, ptr, ptr, ptr, env, i32) DEF_HELPER_6(vrgather_vv_d, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vrgatherei16_vv_b, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vrgatherei16_vv_h, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vrgatherei16_vv_w, void, ptr, ptr, ptr, ptr, env, i32) +DEF_HELPER_6(vrgatherei16_vv_d, void, ptr, ptr, ptr, ptr, env, i32) DEF_HELPER_6(vrgather_vx_b, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vrgather_vx_h, void, ptr, ptr, tl, ptr, env, i32) DEF_HELPER_6(vrgather_vx_w, void, ptr, ptr, tl, ptr, env, i32) diff --git a/target/riscv/insn32.decode b/target/riscv/insn32.decode index a593938e5c8..85cb3c81be0 100644 --- a/target/riscv/insn32.decode +++ b/target/riscv/insn32.decode @@ -620,6 +620,7 @@ vslidedown_vx 001111 . ..... ..... 100 ..... 1010111 @r_vm vslidedown_vi 001111 . ..... ..... 011 ..... 1010111 @r_vm vslide1down_vx 001111 . ..... ..... 110 ..... 1010111 @r_vm vrgather_vv 001100 . ..... ..... 000 ..... 1010111 @r_vm +vrgatherei16_vv 001110 . ..... ..... 000 ..... 1010111 @r_vm vrgather_vx 001100 . ..... ..... 100 ..... 1010111 @r_vm vrgather_vi 001100 . ..... ..... 011 ..... 1010111 @r_vm vcompress_vm 010111 - ..... ..... 010 ..... 1010111 @r diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc index 72222d73e0e..bc780912b2b 100644 --- a/target/riscv/insn_trans/trans_rvv.c.inc +++ b/target/riscv/insn_trans/trans_rvv.c.inc @@ -3323,7 +3323,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) { @@ -3343,7 +3361,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) { @@ -3374,8 +3393,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), diff --git a/target/riscv/vector_helper.c b/target/riscv/vector_helper.c index 8ccf538141c..782fe086f3e 100644 --- a/target/riscv/vector_helper.c +++ b/target/riscv/vector_helper.c @@ -4666,11 +4666,11 @@ GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_w, uint32_t, H4) GEN_VEXT_VSLIDE1DOWN_VX(vslide1down_vx_d, uint64_t, H8) /* Vector Register Gather Instruction */ -#define GEN_VEXT_VRGATHER_VV(NAME, ETYPE, H) \ +#define GEN_VEXT_VRGATHER_VV(NAME, TS1, TS2, HS1, HS2) \ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ CPURISCVState *env, uint32_t desc) \ { \ - uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(ETYPE))); \ + uint32_t vlmax = vext_max_elems(desc, ctzl(sizeof(TS1))); \ uint32_t vm = vext_vm(desc); \ uint32_t vl = env->vl; \ uint32_t index, i; \ @@ -4679,20 +4679,25 @@ void HELPER(NAME)(void *vd, void *v0, void *vs1, void *vs2, \ if (!vm && !vext_elem_mask(v0, i)) { \ continue; \ } \ - index = *((ETYPE *)vs1 + H(i)); \ + index = *((TS1 *)vs1 + HS1(i)); \ if (index >= vlmax) { \ - *((ETYPE *)vd + H(i)) = 0; \ + *((TS2 *)vd + HS2(i)) = 0; \ } else { \ - *((ETYPE *)vd + H(i)) = *((ETYPE *)vs2 + H(index)); \ + *((TS2 *)vd + HS2(i)) = *((TS2 *)vs2 + HS2(index)); \ } \ } \ } /* vd[i] = (vs1[i] >= VLMAX) ? 0 : vs2[vs1[i]]; */ -GEN_VEXT_VRGATHER_VV(vrgather_vv_b, uint8_t, H1) -GEN_VEXT_VRGATHER_VV(vrgather_vv_h, uint16_t, H2) -GEN_VEXT_VRGATHER_VV(vrgather_vv_w, uint32_t, H4) -GEN_VEXT_VRGATHER_VV(vrgather_vv_d, uint64_t, H8) +GEN_VEXT_VRGATHER_VV(vrgather_vv_b, uint8_t, uint8_t, H1, H1) +GEN_VEXT_VRGATHER_VV(vrgather_vv_h, uint16_t, uint16_t, H2, H2) +GEN_VEXT_VRGATHER_VV(vrgather_vv_w, uint32_t, uint32_t, H4, H4) +GEN_VEXT_VRGATHER_VV(vrgather_vv_d, uint64_t, uint64_t, H8, H8) + +GEN_VEXT_VRGATHER_VV(vrgatherei16_vv_b, uint16_t, uint8_t, H2, H1) +GEN_VEXT_VRGATHER_VV(vrgatherei16_vv_h, uint16_t, uint16_t, H2, H2) +GEN_VEXT_VRGATHER_VV(vrgatherei16_vv_w, uint16_t, uint32_t, H2, H4) +GEN_VEXT_VRGATHER_VV(vrgatherei16_vv_d, uint16_t, uint64_t, H2, H8) #define GEN_VEXT_VRGATHER_VX(NAME, ETYPE, H) \ void HELPER(NAME)(void *vd, void *v0, target_ulong s1, void *vs2, \