qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Richard Henderson <richard.henderson@linaro.org>
To: frank.chang@sifive.com, qemu-devel@nongnu.org, qemu-riscv@nongnu.org
Cc: Palmer Dabbelt <palmer@dabbelt.com>,
	Alistair Francis <Alistair.Francis@wdc.com>,
	Sagar Karandikar <sagark@eecs.berkeley.edu>,
	Bastian Koppelmann <kbastian@mail.uni-paderborn.de>
Subject: Re: [RFC v4 14/70] target/riscv: rvv-1.0: update check functions
Date: Sat, 29 Aug 2020 10:50:18 -0700	[thread overview]
Message-ID: <b0ae63fe-cd92-5048-f74e-3a155001e00d@linaro.org> (raw)
In-Reply-To: <20200817084955.28793-15-frank.chang@sifive.com>

On 8/17/20 1:48 AM, frank.chang@sifive.com wrote:
> +static inline bool is_aligned(const uint8_t val, const uint8_t pos)
> +{
> +    return pos ? (val & (pos - 1)) == 0 : true;
> +}

The truncation to uint8_t from int is odd.  Can we drop all of that and just
use int?

Looking at the uses, I think that you should pass lmul directly instead of
requiring the callers to all compute 1 << lmul, and also verify that lmul is
positive.

That change makes this function look like

    return lmul <= 0 || extract32(val, 0, lmul) == 0;


> +static inline bool is_overlapped(const uint8_t astart, uint8_t asize,
> +                                 const uint8_t bstart, uint8_t bsize)
> +{
> +    asize = asize == 0 ? 1 : asize;
> +    bsize = bsize == 0 ? 1 : bsize;

This looks odd.  Again, I think passing in lmul would be better than size.
Then compute size here locally:

    int asize = amul <= 0 ? 1 : 1 << amul;

> +
> +    const int aend = astart + asize;
> +    const int bend = bstart + bsize;
> +
> +    return MAX(aend, bend) - MIN(astart, bstart) < asize + bsize;
> +}
> +
> +static inline bool is_overlapped_widen(const uint8_t astart, uint8_t asize,
> +                                       const uint8_t bstart, uint8_t bsize)

This needs more comments, I think.  It's not obvious why this is (or needs to
be) different from is_overlapped.

I think you're trying to implement the

  * destination eew smaller than source eew,
    and overlap is allowed at the beginning.
  * destination eew larger than source eew,
    and overlap is allowed at the end.

rule from section 5.2.  But since you're not comparing asize vs bsize, that's
not what you're doing.

Anyway, I think all of these rules can be put into require_noover, and there
need not be a separate require_noover_widen.

> +static bool require_rvv(DisasContext *s)
> +{
> +    if (s->mstatus_vs == 0) {
> +        return false;
> +    }
> +    return true;

    return s->mstatus_vs != 0;

> +static bool vext_check_sss(DisasContext *s, int vd, int vs1,
> +                           int vs2, int vm, bool is_vs1)
> +{
> +    bool ret = require_vm(vm, vd);
> +    if (s->lmul > 0) {
> +        ret &= require_align(vd, 1 << s->lmul) &&
> +               require_align(vs2, 1 << s->lmul);
> +        if (is_vs1) {
> +            ret &= require_align(vs1, 1 << s->lmul);
> +        }
> +    }
> +    return ret;
> +}

I think this (and similar function taking is_vs1) should be split.  All callers
pass a constant value, and thus can just as easily call a different function.

Perhaps

static bool vext_check_ss(DisasContext *s, int vd,
                          int vs2, int vm)
{
    return (require_vm(vm, vd) &&
            require_align(vd, s->lmul) &&
            require_align(vs2, s->lmul));
}

static bool vext_check_sss(DisasContext *s, int vd, int vs1,
                           int vs2, int vm)
{
    return (vext_check_ss(s, vd, vs2, vm) &&
            require_align(vs1, s->lmul));
}

> +/*
> + * Check function for maskable vector instruction with format:
> + * single-width result and single-width sources (SEW = SEW op SEW)
> + *
> + * is_vs1: indicates whether insn[19:15] is a vs1 field or not.
> + *
> + * Rules to be checked here:
> + *   1. Source (vs2, vs1) vector register number are multiples of LMUL.
> + *      (Section 3.3.2)
> + *   2. Destination vector register cannot overlap a source vector
> + *      register (vs2, vs1) group.
> + *      (Section 5.2)
> + */
> +static bool vext_check_mss(DisasContext *s, int vd, int vs1,
> +                           int vs2, bool is_vs1)
>  {
> +    bool ret = require_align(vs2, 1 << s->lmul);
> +    if (vd != vs2) {
> +        ret &= require_noover(vd, 1, vs2, 1 << s->lmul);
> +    }
> +    if (is_vs1) {
> +        if (vd != vs1) {
> +            ret &= require_noover(vd, 1, vs1, 1 << s->lmul);
> +        }
> +        ret &= require_align(vs1, 1 << s->lmul);
> +    }
> +    return ret;
> +}

If require_noover implements all of the overlap rules, as suggested, this
simplifies to

static bool vext_check_ms(DisasContext *s, int vd, int vs2)
{
    return (require_align(vs2, s->lmul) &&
            require_noover(vd, 0, vs2, s->lmul);
}

static bool vext_check_mss(DisasContext *s, int vd,
                           int vs1, int vs2)
{
    return (vext_check_ms(s, vd, vs2) &&
            require_align(vs1, s->lmul) &&
            require_noover(vd, 0, vs1, s->lmul));
}

> +/*
> + * Common check function for vector widening instructions
> + * of double-width result (2*SEW).
> + *
> + * Rules to be checked here:
> + *   1. The largest vector register group used by an instruction
> + *      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.
> + *      (Section 3.3.2, 11.2)
> + *   3. Destination vector register group for a masked vector
> + *      instruction cannot overlap the source mask register (v0).
> + *      (Section 5.3)
> + */
> +static bool vext_wide_check_common(DisasContext *s, int vd, int vm)
> +{
> +    return (s->lmul <= 2) &&
> +           (s->sew < 3) &&

Use MO_64 here for clarity.

> +static bool vext_narrow_check_common(DisasContext *s, int vd, int vs2,
> +                                     int vm)
> +{
> +    return (s->lmul <= 2) &&
> +           (s->sew < 3) &&

Likewise.

> +/*
> + * Check function for vector instruction with format:
> + * double-width result and single-width sources (2*SEW = SEW op SEW)
>   *
> + * is_vs1: indicates whether insn[19:15] is a vs1 field or not.
>   *
> + * Rules to be checked here:
> + *   1. All rules in defined in widen common rules are applied.
> + *   2. Source (vs2, vs1) vector register number are multiples of LMUL.
> + *      (Section 3.3.2)
> + *   3. Destination vector register cannot overlap a source vector
> + *      register (vs2, vs1) group.
> + *      (Section 5.2)
>   */
> +static bool vext_check_dss(DisasContext *s, int vd, int vs1, int vs2,
> +                           int vm, bool is_vs1)
>  {
> +    bool ret = (vext_wide_check_common(s, vd, vm) &&
> +                require_align(vs2, 1 << s->lmul));
> +    if (s->lmul < 0) {
> +        ret &= require_noover(vd, 1 << (s->lmul + 1), vs2, 1 << s->lmul);
> +    } else {
> +        ret &= require_noover_widen(vd, 1 << (s->lmul + 1), vs2, 1 << s->lmul);
> +    }

This is buggy, with (1 << negative_number), and is exactly why I think
require_noover needs to be passed the emul of each operand and implement all of
the rules.

This should just be

static bool vext_check_ds(DisasContext *s, int vd, int vs2)
{
    return (vext_wide_check_common(s, vd, vm) &&
            require_align(vs2, s->lmul) &&
            require_noover(vd, s->lmul + 1, vs2, s->lmul));
}

static bool vext_check_dss(DisasContext *s, int vd,
                           int vs1, int vs2)
{
    return (vext_check_ds(s, vd, vs2) &&
            require_align(vs1, s->lmul) &&
            require_noover(vd, s->lmul + 1, vs1, s->lmul));
}

static bool vext_check_dds(DisasContext *s, int vd,
                           int vs1, int vs2)
{
    return (vext_check_ds(s, vd, vs1) &&
            require_align(vs2, s->lmul + 1) &&
            require_noover(vd, s->lmul + 1, vs1, s->lmul + 1));
}

>  /*
> + * Check function for vector reduction instructions.
> + *
> + * Rules to be checked here:
> + *   1. Source 1 (vs2) vector register number is multiples of LMUL.
> + *      (Section 3.3.2)
> + *   2. For widening reduction instructions, SEW < 64.
> + *
> + * TODO: Check vstart == 0
>   */
> +static bool vext_check_reduction(DisasContext *s, int vs2, bool is_wide)
>  {
> +    bool ret = require_align(vs2, 1 << s->lmul);
> +    if (is_wide) {
> +        ret &= s->sew < 3;
> +    }
> +    return ret;
>  }

Again, should be split.  But in this case probably into the only callers...

> +static bool reduction_widen_check(DisasContext *s, arg_rmrr *a)
> +{
> +    return require_rvv(s) &&
> +           vext_check_isa_ill(s) &&
> +           vext_check_reduction(s, a->rs2, true);
> +}

This could simplify to

    return reduction_check(s, a) && s->sew < MO_64;


r~


  reply	other threads:[~2020-08-29 17:51 UTC|newest]

Thread overview: 126+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-17  8:48 [RFC v4 00/70] support vector extension v1.0 frank.chang
2020-08-17  8:48 ` [RFC v4 01/70] target/riscv: drop vector 0.7.1 and add 1.0 support frank.chang
2020-08-17  8:48 ` [RFC v4 02/70] target/riscv: Use FIELD_EX32() to extract wd field frank.chang
2020-08-17  8:48 ` [RFC v4 03/70] target/riscv: rvv-1.0: add mstatus VS field frank.chang
2020-08-17  8:48 ` [RFC v4 04/70] target/riscv: rvv-1.0: add sstatus " frank.chang
2020-08-17  8:48 ` [RFC v4 05/70] target/riscv: rvv-1.0: introduce writable misa.v field frank.chang
2020-08-17  8:48 ` [RFC v4 06/70] target/riscv: rvv-1.0: add translation-time vector context status frank.chang
2020-08-17  8:48 ` [RFC v4 07/70] target/riscv: rvv-1.0: remove rvv related codes from fcsr registers frank.chang
2020-08-29 15:49   ` Richard Henderson
2020-08-17  8:48 ` [RFC v4 08/70] target/riscv: rvv-1.0: add vcsr register frank.chang
2020-08-17  8:48 ` [RFC v4 09/70] target/riscv: rvv-1.0: add vlenb register frank.chang
2020-08-17  8:48 ` [RFC v4 10/70] target/riscv: rvv-1.0: check MSTATUS_VS when accessing vector csr registers frank.chang
2020-08-17  8:48 ` [RFC v4 11/70] target/riscv: rvv-1.0: remove MLEN calculations frank.chang
2020-08-17  8:48 ` [RFC v4 12/70] target/riscv: rvv-1.0: add fractional LMUL frank.chang
2020-08-29 15:51   ` Richard Henderson
2020-08-17  8:48 ` [RFC v4 13/70] target/riscv: rvv-1.0: add VMA and VTA frank.chang
2020-08-17  8:48 ` [RFC v4 14/70] target/riscv: rvv-1.0: update check functions frank.chang
2020-08-29 17:50   ` Richard Henderson [this message]
2020-08-17  8:49 ` [RFC v4 15/70] target/riscv: introduce more imm value modes in translator functions frank.chang
2020-08-29 17:51   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 16/70] target/riscv: rvv:1.0: add translation-time nan-box helper function frank.chang
2020-08-29 17:53   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 17/70] target/riscv: rvv-1.0: configure instructions frank.chang
2020-09-25  8:51   ` Frank Chang
2020-09-25 18:28     ` Richard Henderson
2020-09-26  5:05       ` Frank Chang
2020-08-17  8:49 ` [RFC v4 18/70] target/riscv: rvv-1.0: stride load and store instructions frank.chang
2020-08-29 18:10   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 19/70] target/riscv: rvv-1.0: index " frank.chang
2020-08-29 18:33   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 20/70] target/riscv: rvv-1.0: fix address index overflow bug of indexed load/store insns frank.chang
2020-08-29 18:34   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 21/70] target/riscv: rvv-1.0: fault-only-first unit stride load frank.chang
2020-08-29 18:36   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 22/70] target/riscv: rvv-1.0: amo operations frank.chang
2020-08-29 18:50   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 23/70] target/riscv: rvv-1.0: load/store whole register instructions frank.chang
2020-08-29 19:13   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 24/70] target/riscv: rvv-1.0: update vext_max_elems() for load/store insns frank.chang
2020-08-29 19:30   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 25/70] target/riscv: rvv-1.0: take fractional LMUL into vector max elements calculation frank.chang
2020-08-29 19:36   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 26/70] target/riscv: rvv-1.0: floating-point square-root instruction frank.chang
2020-08-17  8:49 ` [RFC v4 27/70] target/riscv: rvv-1.0: floating-point classify instructions frank.chang
2020-08-17  8:49 ` [RFC v4 28/70] target/riscv: rvv-1.0: mask population count instruction frank.chang
2020-08-17  8:49 ` [RFC v4 29/70] target/riscv: rvv-1.0: find-first-set mask bit instruction frank.chang
2020-08-17  8:49 ` [RFC v4 30/70] target/riscv: rvv-1.0: set-X-first mask bit instructions frank.chang
2020-08-17  8:49 ` [RFC v4 31/70] target/riscv: rvv-1.0: iota instruction frank.chang
2020-08-17  8:49 ` [RFC v4 32/70] target/riscv: rvv-1.0: element index instruction frank.chang
2020-08-17  8:49 ` [RFC v4 33/70] target/riscv: rvv-1.0: allow load element with sign-extended frank.chang
2020-08-17  8:49 ` [RFC v4 34/70] target/riscv: rvv-1.0: register gather instructions frank.chang
2020-08-29 19:52   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 35/70] target/riscv: rvv-1.0: integer scalar move instructions frank.chang
2020-08-17  8:49 ` [RFC v4 36/70] target/riscv: rvv-1.0: floating-point move instruction frank.chang
2020-08-29 20:00   ` Richard Henderson
2020-08-29 20:03     ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 37/70] target/riscv: rvv-1.0: floating-point scalar move instructions frank.chang
2020-08-29 20:07   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 38/70] target/riscv: rvv-1.0: whole register " frank.chang
2020-08-29 20:08   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 39/70] target/riscv: rvv-1.0: integer extension instructions frank.chang
2020-08-17  8:49 ` [RFC v4 40/70] target/riscv: rvv-1.0: single-width averaging add and subtract instructions frank.chang
2020-08-29 20:11   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 41/70] target/riscv: rvv-1.0: single-width bit shift instructions frank.chang
2020-08-17  8:49 ` [RFC v4 42/70] target/riscv: rvv-1.0: integer add-with-carry/subtract-with-borrow frank.chang
2020-08-29 20:16   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 43/70] target/riscv: rvv-1.0: narrowing integer right shift instructions frank.chang
2020-08-17  8:49 ` [RFC v4 44/70] target/riscv: rvv-1.0: widening integer multiply-add instructions frank.chang
2020-08-17  8:49 ` [RFC v4 45/70] target/riscv: rvv-1.0: add Zvqmac extension frank.chang
2020-08-29 20:17   ` Richard Henderson
2020-08-29 20:21     ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 46/70] target/riscv: rvv-1.0: quad-widening integer multiply-add instructions frank.chang
2020-08-29 20:22   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 47/70] target/riscv: rvv-1.0: single-width saturating add and subtract instructions frank.chang
2020-08-29 20:23   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 48/70] target/riscv: rvv-1.0: integer comparison instructions frank.chang
2020-08-29 20:23   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 49/70] target/riscv: use softfloat lib float16 comparison functions frank.chang
2020-08-17  8:49 ` [RFC v4 50/70] target/riscv: rvv-1.0: floating-point compare instructions frank.chang
2020-08-29 20:25   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 51/70] target/riscv: rvv-1.0: mask-register logical instructions frank.chang
2020-08-29 20:25   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 52/70] target/riscv: rvv-1.0: slide instructions frank.chang
2020-08-29 20:28   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 53/70] target/riscv: rvv-1.0: floating-point " frank.chang
2020-08-29 20:33   ` Richard Henderson
2020-09-25  8:21     ` Frank Chang
2020-09-25 18:31       ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 54/70] target/riscv: rvv-1.0: narrowing fixed-point clip instructions frank.chang
2020-08-17  8:49 ` [RFC v4 55/70] target/riscv: rvv-1.0: single-width floating-point reduction frank.chang
2020-08-29 23:50   ` Richard Henderson
2020-08-29 23:58     ` Richard Henderson
2020-08-31 18:50       ` Chih-Min Chao
2020-08-17  8:49 ` [RFC v4 56/70] target/riscv: rvv-1.0: widening floating-point reduction instructions frank.chang
2020-08-29 23:50   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 57/70] target/riscv: rvv-1.0: single-width scaling shift instructions frank.chang
2020-08-29 23:54   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 58/70] target/riscv: rvv-1.0: remove widening saturating scaled multiply-add frank.chang
2020-08-17  8:49 ` [RFC v4 59/70] target/riscv: rvv-1.0: remove vmford.vv and vmford.vf frank.chang
2020-08-17  8:49 ` [RFC v4 60/70] target/riscv: rvv-1.0: remove integer extract instruction frank.chang
2020-08-17  8:49 ` [RFC v4 61/70] target/riscv: rvv-1.0: floating-point min/max instructions frank.chang
2020-08-29 23:58   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 62/70] target/riscv: introduce floating-point rounding mode enum frank.chang
2020-08-30  0:02   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 63/70] target/riscv: rvv-1.0: floating-point/integer type-convert instructions frank.chang
2020-08-30  0:06   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 64/70] target/riscv: rvv-1.0: widening floating-point/integer type-convert frank.chang
2020-08-30  0:14   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 65/70] target/riscv: add "set round to odd" rounding mode helper function frank.chang
2020-08-30  0:18   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 66/70] target/riscv: rvv-1.0: narrowing floating-point/integer type-convert frank.chang
2020-08-30  0:21   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 67/70] target/riscv: rvv-1.0: relax RV_VLEN_MAX to 512-bits frank.chang
2020-08-30  1:39   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 68/70] target/riscv: gdb: modify gdb csr xml file to align with csr register map frank.chang
2020-08-30  2:16   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 69/70] target/riscv: gdb: support vector registers for rv64 frank.chang
2020-08-30  1:57   ` Richard Henderson
2020-08-17  8:49 ` [RFC v4 70/70] target/riscv: gdb: support vector registers for rv32 frank.chang
2020-08-30  1:57   ` Richard Henderson
2020-08-25  8:28 ` [RFC v4 00/70] support vector extension v1.0 Frank Chang
2020-08-26 16:45   ` Alistair Francis
2020-08-26 17:39     ` Frank Chang
2020-08-26 17:52       ` Alistair Francis
2020-08-26 18:12         ` Frank Chang
2020-08-26 21:17           ` Alistair Francis

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=b0ae63fe-cd92-5048-f74e-3a155001e00d@linaro.org \
    --to=richard.henderson@linaro.org \
    --cc=Alistair.Francis@wdc.com \
    --cc=frank.chang@sifive.com \
    --cc=kbastian@mail.uni-paderborn.de \
    --cc=palmer@dabbelt.com \
    --cc=qemu-devel@nongnu.org \
    --cc=qemu-riscv@nongnu.org \
    --cc=sagark@eecs.berkeley.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).