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.