PATCH: Use PLUS instead of HIGH/LO_SUM for large constants - take 2 for PA

John David Anglin dave@hiauly1.hia.nrc.ca
Mon Oct 29 10:16:00 GMT 2001


Here is a revised version of the patch to change the handling of immediate
constants to use PLUS instead of HIGH/LO_SUM on the PA.  I have addressed
the issue raised by Richard and removed the HImode HIGH/LO_SUM patterns.
I have extended the range of constants handled on 64-bit hosts by providing
both zero and one extension.  Previously, only zero extension was done.
I tweaked the single instruction load to accept class 'N' constants.

Bootstrapped and checked on hppa1.1-hp-hpux10.20.  It probably would be
a good idea to check that the 64-bit extensions work but I am not currently
capable of doing this.  Jeff could you do it?

OK?

Dave
-- 
J. David Anglin                                  dave.anglin@nrc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6605)

2001-10-29  John David Anglin  <dave@hiauly1.hia.nrc.ca>

	* pa.c (emit_move_sequence): Use cint_ok_for_move to check whether a
	constant can be loaded in a single instruction to a register.  When
	loading immediate constants, use PLUS instead of HIGH/LO_SUM.  Handle
	both zero and one extension of "32-bit" constants on 64-bit hosts.
	* pa.h (LEGITIMATE_CONSTANT_P): Accept constants that can be built
	with ldil/ldo/depdi instruction sequence on 64-bit hosts.
	* pa.md: New addmove pattern for adding constant_int to HImode
	register and moving result to HImode register.  Remove HImode HIGH
	and LO_SUM patterns.

--- pa.c.orig	Sun Oct  7 16:14:17 2001
+++ pa.c	Fri Oct 26 18:19:54 2001
@@ -1394,7 +1394,8 @@
   else if (register_operand (operand0, mode))
     {
       if (register_operand (operand1, mode)
-	  || (GET_CODE (operand1) == CONST_INT && INT_14_BITS (operand1))
+	  || (GET_CODE (operand1) == CONST_INT
+	      && cint_ok_for_move (INTVAL (operand1)))
 	  || (operand1 == CONST0_RTX (mode))
 	  || (GET_CODE (operand1) == HIGH
 	      && !symbolic_operand (XEXP (operand1, 0), VOIDmode))
@@ -1597,7 +1598,7 @@
 	       || ! cint_ok_for_move (INTVAL (operand1)))
 	{
 	  rtx temp;
-	  int need_zero_extend = 0;
+	  int extend = 0;
 
 	  if (TARGET_64BIT && GET_CODE (operand1) == CONST_INT
 	      && HOST_BITS_PER_WIDE_INT > 32
@@ -1606,15 +1607,20 @@
 	      HOST_WIDE_INT val = INTVAL (operand1);
 	      HOST_WIDE_INT nval;
 
-	      /* If the value is the same after a 32->64bit sign
-		 extension, then we can use it as-is.  Else we will
-		 need to sign extend the constant from 32->64bits
-		 then zero extend the result from 32->64bits.  */
+	      /* Extract the low order 32 bits of the value and sign extend.
+		 If the new value is the same as the original value, we can
+		 can use the value as-is.  If the new value is different, we
+		 use it, and either zero or one extend the final result
+		 depending on whether the original value was positive or
+		 negative.  */
 	      nval = ((val & (((HOST_WIDE_INT) 2 << 31) - 1))
 		      ^ ((HOST_WIDE_INT) 1 << 31)) - ((HOST_WIDE_INT) 1 << 31);
 	      if (val != nval)
 		{
-		  need_zero_extend = 1;
+		  if (val >= 0)
+		    extend = 1;
+		  else
+		    extend = 2;
 		  operand1 = GEN_INT (nval);
 		}
 	    }
@@ -1624,19 +1630,44 @@
 	  else
 	    temp = gen_reg_rtx (mode);
 
-	  emit_insn (gen_rtx_SET (VOIDmode, temp,
-				  gen_rtx_HIGH (mode, operand1)));
-	  operands[1] = gen_rtx_LO_SUM (mode, temp, operand1);
-	  emit_move_insn (operands[0], operands[1]);
+	  if (GET_CODE (operand1) == CONST_INT)
+	    {
+	      /* Directly break constant into low and high parts.  This
+		 provides better optimization opportunities because various
+		 passes recognize constants split with PLUS but not LO_SUM.
+		 We use a 14-bit signed low part except when the addition
+		 of 0x4000 to the high part might change the sign of the
+		 high part.  */
+	      HOST_WIDE_INT value = INTVAL (operand1);
+	      HOST_WIDE_INT low = value & 0x3fff;
+	      HOST_WIDE_INT high = value & ~ 0x3fff;
+
+	      if (low >= 0x2000)
+		{
+		  if (high == 0x7fffc000 || (mode == HImode && high == 0x4000))
+		    high += 0x2000;
+		  else
+		    high += 0x4000;
+		}
+
+	      low = value - high;
 
-	  if (need_zero_extend)
+	      emit_insn (gen_rtx_SET (VOIDmode, temp, GEN_INT (high)));
+	      operands[1] = gen_rtx_PLUS (mode, temp, GEN_INT (low));
+	    }
+	  else
 	    {
-	      emit_insn (gen_zero_extendsidi2 (operands[0],
-					       gen_rtx_SUBREG (SImode,
-							       operands[0],
-							       0)));
+	      emit_insn (gen_rtx_SET (VOIDmode, temp,
+				      gen_rtx_HIGH (mode, operand1)));
+	      operands[1] = gen_rtx_LO_SUM (mode, temp, operand1);
 	    }
 
+	  emit_move_insn (operands[0], operands[1]);
+
+	  if (extend)
+	    emit_insn (gen_insv (operands[0], GEN_INT (32), const0_rtx,
+		       extend == 1 ? const0_rtx : constm1_rtx));
+
 	  return 1;
 	}
     }
--- pa.h.orig	Mon Sep 24 12:18:02 2001
+++ pa.h	Fri Oct 26 14:08:52 2001
@@ -1106,8 +1106,8 @@
    && !(TARGET_64BIT && GET_CODE (X) == CONST_DOUBLE)		\
    && !(TARGET_64BIT && GET_CODE (X) == CONST_INT		\
 	&& !(HOST_BITS_PER_WIDE_INT <= 32			\
-	     || (INTVAL (X) >= (HOST_WIDE_INT) -1 << 31		\
-		 && INTVAL (X) < (HOST_WIDE_INT) 1 << 32)	\
+	     || (INTVAL (X) >= (HOST_WIDE_INT) -2 << 31		\
+		 && INTVAL (X) < (HOST_WIDE_INT) 2 << 31)	\
 	     || cint_ok_for_move (INTVAL (X))))			\
    && !function_label_operand (X, VOIDmode))
 
--- pa.md.orig	Sat Jul 14 20:54:21 2001
+++ pa.md	Fri Oct 26 16:03:12 2001
@@ -2604,19 +2604,12 @@
 
 (define_insn ""
   [(set (match_operand:HI 0 "register_operand" "=r")
-	(high:HI (match_operand 1 "const_int_operand" "")))]
+	(plus:HI (match_operand:HI 1 "register_operand" "r")
+		 (match_operand 2 "const_int_operand" "J")))]
   ""
-  "ldil L'%G1,%0"
-  [(set_attr "type" "move")
-   (set_attr "length" "4")])
-
-(define_insn ""
-  [(set (match_operand:HI 0 "register_operand" "=r")
-	(lo_sum:HI (match_operand:HI 1 "register_operand" "r")
-		   (match_operand 2 "const_int_operand" "")))]
-  ""
-  "ldo R'%G2(%1),%0"
-  [(set_attr "type" "move")
+  "ldo %2(%1),%0"
+  [(set_attr "type" "binary")
+   (set_attr "pa_combine_type" "addmove")
    (set_attr "length" "4")])
 
 (define_expand "movqi"



More information about the Gcc-patches mailing list