Hi!

On Wed, Jun 10, 2020 at 09:14:07AM -0700, Carl Love wrote:
> On Wed, 2020-06-10 at 10:46 -0500, will schmidt wrote:
> > Compare that to the other predicates (config/rs6000/predicates.md)
> > 
> > Those have explicit checks against both ends of the valid range of
> > values.   i.e.
> > 
> > ;; Return 1 if op is a signed 5-bit constant integer.
> > (define_predicate "s5bit_cint_operand"
> >   (and (match_code "const_int")
> >        (match_test "INTVAL (op) >= -16 && INTVAL (op) <= 15")))
> 
> Well, that is what I did originally.  But if you see your comment
> above, "There probably is a nicer way to write this than with big
> decimal numbers." so I was trying to figure out how to do it without
> using big numbers.

Big *decimal* numbers aren't great.  But you could use hex :-)
2147483647 looks like it could be 0x7fffffff, but so does 2147438647,
and that one is 0x7fff5037.

> I seemed like shifting the value right 32 bits and
> checking if the result was zero would tell us that op fits in 32-bits
> but it doesn't seem to work.  So, now I have conflicting feedback.  :-)

For signed you could do

((0x80000000 + UINTVAL (op)) >> 32) == 0

(or INTVAL even, makes no difference here), but that is much less
readable :-)

Maybe for signed it is neatest if you use trunc_int_for_mode for it?

INTVAL (op) == INTVAL (trunc_int_for_mode (op, SImode))

(which neatly uses the _target_ SImode).

trunc_int_for_mode always sign-extends; we don't have one that zero-
extends afaik, but that one is much easier to write anyway:

IN_RANGE (UINTVAL (op), 0, 0xffffffff)


Segher

Reply via email to