Mike Stump <mikest...@comcast.net> writes:
>> Sorry, with this bit, I meant that the current svn code is correct
>> for GET_MODE_BITSIZE (op_mode) == HOST_BITS_PER_WIDE_INT * 2.
>> In that case, hv < 0 can just mean that we have a uint128_t
>> (or whatever) whose high bit happens to be set.

(To be clear, I was using uint128_t as an example of a 2-HWI type,
assuming we're using 64-bit HWIs -- which I hope we are for targets
where this assert matters.)

> Well, according to the spec, one cannot use CONST_DOUBLE to represent
> a uint128 value with the high bit set.

We can!  And do now, even without your patch.  Because...

> The C frontend type plays this game, but they can, because they track
> the type with the constant the the values of the constant are
> interpreted exclusively in the context of the type.  Since we don't
> have the unsigned bit, we can't, so, either, they are speced to be
> values on their own, or values dependent upon some external notion.
> By changing the spec to say sign extending, we mean if the high bit is
> set, the value is negative.

...it doesn't mean that we interpret the value as a negative _rtx_.
As with all rtx calculations, things like signedness and saturation are
decided by the operation rather than the "type" ("type" == rtx mode).
For things like addition where signed vs. unsigned interpretation
doesn't matter, we have a single rtx op like PLUS.  For things like
multiplication where it does matter, we have separate signed and
unsigned variants.  There is nothing to distinguish a uint128_t
_register_ (i.e. TImode REG) that has the upper bit set from an
int128_t register that happens to be negative.  Instead the
interpretation is decided by the operation.  And the same principle
applies to constants.  There isn't, and doesn't need to be,
a separate CONST_DOUBLE representation for:

  - an unsigned 2-HWI value that has the upper bit set and
  - a signed 2-HWI value that is negative

The sign-extending thing is simply there to specify what happens when an
N>2 HWI value is represented as a 2-HWI rtx.  I.e. it's simply there to
say what the implicit N-2 HWIs are.  (That's why the definition only
matters now that we're allowing N>2 by removing the assert.)

In this context we're interpreting the value as unsigned because we have
an UNSIGNED_FLOAT operation.  So if the mode of the operand is exactly
2 HWIs in size, a negative high HWI simply indicates an unsigned value
that has the high bit set.

The same principle already applies to CONST_INT.  We have long defined
CONST_INT to be a sign-extending representation, in the sense that it
is allowed to represent 2-HWI modes in which the upper HWI happens
to be a sign extension of the lower HWI.  That doesn't mean the 2-HWI
constant itself is negative: it can just as easily be a high unsigned
value.  Whether it is signed, unsigned or neutral depends on the context
of the rtx operation.

All we're doing here is extending that principle to CONST_DOUBLE
and modes wider than 2 HWIs.

Sorry for the rather rambling explanation :-)  I still think the
version I suggested for this hunk is right though.


Reply via email to