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. Richard