64-bit powerpc compare with constant problem

David Edelsohn dje@watson.ibm.com
Wed Feb 9 15:46:00 GMT 2000


	Marc pointed out to me which part of the instruction sequence was
incorrect which allowed me to track down the error.

	Some PowerPC logical operation instructions have two forms that
allow a constant operand: a 16-bit value in the least significant bits and
a 16-bit value shifted up by 16 bits.  For logical operations involving
larger constants, the GCC PowerPC machine description tries to combine the
two instructions to synthesize the operation.

	The problem is that I created the DImode patterns by translating
the SImode patterns too naively -- the current DImode patterns specify a
predicate for the operand which may be a register or any constant.  When
GCC is built to run on a 32-bit host, its internal constant ints are
limited to 32 bits, which would seem to be okay, except the constant ints
are signed.  For small constants less than zero, the synthesized
instruction does not operate on the upper bits all replicating the sign
bit.

	I think the following new predicate should describe the
synthesized operation the pattern can perform:

Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.109
diff -c -p -r1.109 rs6000.c
*** rs6000.c	2000/01/07 18:33:12	1.109
--- rs6000.c	2000/02/09 23:36:51
*************** reg_or_cint_operand (op, mode)
*** 640,645 ****
--- 640,661 ----
  	     || gpc_reg_operand (op, mode));
  }
  
+ /* Return 1 is the operand is either a non-special register or ANY
+    32-bit unsigned constant integer.  */
+ 
+ int
+ reg_or_u_cint_operand (op, mode)
+     register rtx op;
+     enum machine_mode mode;
+ {
+      return ((GET_CODE (op) == CONST_INT
+ #if HOST_BITS_PER_WIDE_INT == 64
+ 	      && INTVAL (op) < ((HOST_WIDE_INT) 1 << 32)
+ #endif
+ 	      && INTVAL (op) > 0)
+ 	     || gpc_reg_operand (op, mode));
+ }
+ 
  /* Return 1 if the operand is an operand that can be loaded via the GOT */
  
  int


	I think that utilizing this new pattern (possibly a different name
other than "cint" would be more descriptive?) in iori3 and xordi3 patterns
would correct this problem.  Does this look correct to you, Geoff?

Thanks, David
===============================================================================
David Edelsohn                                      T.J. Watson Research Center
dje@watson.ibm.com                                  P.O. Box 218
+1 914 945 4364 (TL 862)                            Yorktown Heights, NY 10598


More information about the Gcc-bugs mailing list