diff options
author | Frank Chang <frank.chang@sifive.com> | 2021-12-10 15:57:03 +0800 |
---|---|---|
committer | Alistair Francis <alistair.francis@wdc.com> | 2021-12-20 14:53:31 +1000 |
commit | cc13aa3614519159e21f5bc1710c13fc79323853 (patch) | |
tree | edd9181df8fc907e474dcf3a95a5a11a70de02b0 | |
parent | 45ca2ca6bdfbfc802fde87721ff3d164ea970d3d (diff) |
target/riscv: rvv-1.0: Add ELEN checks for widening and narrowing instructions
SEW has the limitation which cannot exceed ELEN.
Widening instructions have a destination group with EEW = 2*SEW
and narrowing instructions have a source operand with EEW = 2*SEW.
Both of the instructions have the limitation of: 2*SEW <= ELEN.
Signed-off-by: Frank Chang <frank.chang@sifive.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20211210075704.23951-78-frank.chang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
-rw-r--r-- | target/riscv/insn_trans/trans_rvv.c.inc | 17 | ||||
-rw-r--r-- | target/riscv/translate.c | 2 |
2 files changed, 13 insertions, 6 deletions
diff --git a/target/riscv/insn_trans/trans_rvv.c.inc b/target/riscv/insn_trans/trans_rvv.c.inc index 47eb3119cb..5e3f7fdb77 100644 --- a/target/riscv/insn_trans/trans_rvv.c.inc +++ b/target/riscv/insn_trans/trans_rvv.c.inc @@ -386,9 +386,10 @@ static bool vext_check_mss(DisasContext *s, int vd, int vs1, int vs2) * can not be greater than 8 vector registers (Section 5.2): * => LMUL < 8. * => SEW < 64. - * 2. Destination vector register number is multiples of 2 * LMUL. + * 2. Double-width SEW cannot greater than ELEN. + * 3. Destination vector register number is multiples of 2 * LMUL. * (Section 3.4.2) - * 3. Destination vector register group for a masked vector + * 4. Destination vector register group for a masked vector * instruction cannot overlap the source mask register (v0). * (Section 5.3) */ @@ -396,6 +397,7 @@ static bool vext_wide_check_common(DisasContext *s, int vd, int vm) { return (s->lmul <= 2) && (s->sew < MO_64) && + ((s->sew + 1) <= (s->elen >> 4)) && require_align(vd, s->lmul + 1) && require_vm(vm, vd); } @@ -409,11 +411,12 @@ static bool vext_wide_check_common(DisasContext *s, int vd, int vm) * can not be greater than 8 vector registers (Section 5.2): * => LMUL < 8. * => SEW < 64. - * 2. Source vector register number is multiples of 2 * LMUL. + * 2. Double-width SEW cannot greater than ELEN. + * 3. Source vector register number is multiples of 2 * LMUL. * (Section 3.4.2) - * 3. Destination vector register number is multiples of LMUL. + * 4. Destination vector register number is multiples of LMUL. * (Section 3.4.2) - * 4. Destination vector register group for a masked vector + * 5. Destination vector register group for a masked vector * instruction cannot overlap the source mask register (v0). * (Section 5.3) */ @@ -422,6 +425,7 @@ static bool vext_narrow_check_common(DisasContext *s, int vd, int vs2, { return (s->lmul <= 2) && (s->sew < MO_64) && + ((s->sew + 1) <= (s->elen >> 4)) && require_align(vs2, s->lmul + 1) && require_align(vd, s->lmul) && require_vm(vm, vd); @@ -2806,7 +2810,8 @@ GEN_OPIVV_TRANS(vredxor_vs, reduction_check) /* Vector Widening Integer Reduction Instructions */ static bool reduction_widen_check(DisasContext *s, arg_rmrr *a) { - return reduction_check(s, a) && (s->sew < MO_64); + return reduction_check(s, a) && (s->sew < MO_64) && + ((s->sew + 1) <= (s->elen >> 4)); } GEN_OPIVV_WIDEN_TRANS(vwredsum_vs, reduction_widen_check) diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 68edaaf6ac..5df6c0d800 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -96,6 +96,7 @@ typedef struct DisasContext { int8_t lmul; uint8_t sew; uint16_t vlen; + uint16_t elen; target_ulong vstart; bool vl_eq_vlmax; uint8_t ntemp; @@ -705,6 +706,7 @@ static void riscv_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs) ctx->ext_zfh = cpu->cfg.ext_zfh; ctx->ext_zfhmin = cpu->cfg.ext_zfhmin; ctx->vlen = cpu->cfg.vlen; + ctx->elen = cpu->cfg.elen; ctx->mstatus_hs_fs = FIELD_EX32(tb_flags, TB_FLAGS, MSTATUS_HS_FS); ctx->mstatus_hs_vs = FIELD_EX32(tb_flags, TB_FLAGS, MSTATUS_HS_VS); ctx->hlsx = FIELD_EX32(tb_flags, TB_FLAGS, HLSX); |