Segher Boessenkool <seg...@kernel.crashing.org> writes:
> Hi!
>
> On Mon, Sep 07, 2020 at 09:20:59PM +0100, Richard Sandiford wrote:
>> This is just personal opinion, but in general (from the point of view
>> of a new port, or a new subport like SVE), I think the best approach
>> to handling the "type" attribute is to start with the coarsest
>> classification that makes sense, then split these relatively coarse
>> types up whenever there's a specific need.
>
> Agreed.
>
>> When taking that approach, it's OK (and perhaps even a good sign)
>> for an existing type to sometimes be too coarse for a new CPU.
>> 
>> So thanks for asking about this, and please don't feel constrained
>> by the existing "type" classification.  IMO we should split existing
>> types wherever that makes sense for new CPUs.
>
> You can also use some other attributes to classify instructions, you
> don't have to put it all in one "type" attribute.  This can of course be
> done later, at a time when it is clearer what a good design will be.
> Sometimes it is obvious from the start though :-)
>
> (This primarily makes the pipeline descriptions much simpler, but also
> custom scheduling code and the like.  If one core has two types of "A"
> insn, say "Aa" and "Ab", it isn't nice if all other cores now have to
> handle both "Aa" and "Ab" instead of just "A").

I guess it makes the description of other cores more verbose, but it
doesn't IMO make them more complicated.  It's still just one test
against one attribute.  And updating existing descriptions can be
done automatically by sed.

The difficulty with splitting into subattributes is that the tests in
the cores that *do* care then become more complicated.  E.g. you have
to do:

   (ior (and (eq_attr "type" "foo")
             (eq_attr "foo_subtype" "foo1"))
        (eq_attr "type" "...others.."))

and:

   (ior (and (eq_attr "type" "foo")
             (eq_attr "foo_subtype" "!foo1"))
        (eq_attr "type" "...others.."))

instead of just:

   (eq_attr "type" "...")

in both cases.

It's not too bad when it's just one subtype (like above), but it could
easily get out of hand.

Perhaps in this case there's an argument in favour of having a separate
attribute due to combinatorial explosion.  E.g. we have:

- alu_shift_imm
- alus_shift_imm
- logic_shift_imm
- logics_shift_imm

so having one attribute that describes the shift in all four cases
would perhaps be better than splitting each of them into two.
Arguments in the other direction:

- Once we have a separate attribute, it isn't clear where the line
  should be drawn.  Alternatives include:

  (1) keeping the new attribute specific to shift immediates only

  (2) also having a “register” value, and folding:
      alu_shift_imm, alu_shift_reg -> alu_shift

  (3) also having a “none” value, and doing away with the *_shift
      type variants altogether:
      alu_sreg, alu_shift_imm, alu_shift_reg -> alu_reg

  I think we should have a clear reason for whichever we pick,
  otherwise we could be creating technical debt for later.

- That approach is the opposite of what we did for the neon_* attributes:
  every type has a q variant, rather than the size being a separate
  attribute.

FWIW, we shouldn't assume that this distinction is specific to a64fx. :-)

Thanks,
Richard

Reply via email to