This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

PATCH: Use PLUS instead of HIGH/LO_SUM for large constants


Because the semantics of HIGH/LO_SUM are not well determined, it is preferable
to use PLUS to load large constants which need to be split into high and low
parts.  This allows the constant's value to be recocognized during jump
expansion and thereby improves deadcode elimination.  As a result, other
optimisers shouldn't have to work as hard.  There is the further advantage
that the "high" part may be common for several constants and pulled out
of loops, etc.

This patch adds the capability to use PLUS on the PA if the constant
can be loaded into a register with a ldil/ldo instruction sequence.
This is the most common situation.  Really large values are still handled
with the old code.

Bootstrap checked with no regressions on hppa1.1-hp-hpux10.20.

OK?

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

2001-09-15  John David Anglin  <dave@hiauly1.hia.nrc.ca>

	* pa.c (cint_split_ok): New function.
	(emit_move_sequence): When loading a constant into a register, use
	PLUS instead of HIGH/LO_SUM if the constant can be split and loaded
	with a ldil/ldo instruction sequence.
	* pa.md: New addmove pattern for adding constant_int to HImode
	register and moving result to HImode register.

--- pa.c.orig	Fri Sep 14 17:40:30 2001
+++ pa.c	Sat Sep 15 13:09:26 2001
@@ -55,6 +55,7 @@
 #endif
 #endif
 
+static int cint_split_ok PARAMS ((HOST_WIDE_INT));
 static inline rtx force_mode PARAMS ((enum machine_mode, rtx));
 static void pa_combine_instructions PARAMS ((rtx));
 static int pa_can_combine_p PARAMS ((rtx, rtx, rtx, int, rtx, rtx, rtx));
@@ -338,6 +339,22 @@
 	  || CONST_OK_FOR_LETTER_P (intval, 'K'));
 }
 
+/* Accept any constant that can be loaded into a general register using
+   a ldil/ldo sequence.  */
+static int
+cint_split_ok (intval)
+     HOST_WIDE_INT intval;
+{
+  HOST_WIDE_INT high;
+
+  if ((intval & 0x3fff) >= 0x2000)
+    high = (intval & ~ 0x3fff) + 0x4000;
+  else
+    high = (intval & ~ 0x3fff);
+
+  return (CONST_OK_FOR_LETTER_P (high, 'N'));
+}
+
 /* Accept anything that can be moved in one instruction into a general
    register.  */
 int
@@ -1394,7 +1411,9 @@
   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)))
+	  || (GET_CODE (operand1) == CONSTANT_P_RTX)
 	  || (operand1 == CONST0_RTX (mode))
 	  || (GET_CODE (operand1) == HIGH
 	      && !symbolic_operand (XEXP (operand1, 0), VOIDmode))
@@ -1405,6 +1424,26 @@
 	  emit_insn (gen_rtx_SET (VOIDmode, operand0, operand1));
 	  return 1;
 	}
+      else if (GET_CODE (operand1) == CONST_INT
+	       && ((TARGET_64BIT && mode == DImode)
+		   || mode == SImode
+		   || mode == HImode)
+	       && cint_split_ok (INTVAL (operand1)))
+        {
+	  HOST_WIDE_INT high, low;
+
+	  if ((INTVAL (operand1) & 0x3fff) >= 0x2000)
+	    high = (INTVAL (operand1) & ~ 0x3fff) + 0x4000;
+	  else
+	    high = (INTVAL (operand1) & ~ 0x3fff);
+
+	  low = INTVAL (operand1) - high;
+	  emit_insn (gen_rtx_SET (mode, operand0, GEN_INT (high)));
+	  emit_insn (gen_rtx_SET (mode, operand0,
+				  gen_rtx_PLUS (mode, operand0,
+						GEN_INT (low))));
+	  return 1;
+        }
     }
   else if (GET_CODE (operand0) == MEM)
     {
--- pa.md.orig	Fri Sep 14 23:28:18 2001
+++ pa.md	Sat Sep 15 13:04:23 2001
@@ -2619,6 +2619,16 @@
   [(set_attr "type" "move")
    (set_attr "length" "4")])
 
+(define_insn ""
+  [(set (match_operand:HI 0 "register_operand" "=r")
+	(plus:HI (match_operand:HI 1 "register_operand" "r")
+		 (match_operand 2 "const_int_operand" "J")))]
+  ""
+  "ldo %2(%1),%0"
+  [(set_attr "type" "binary")
+   (set_attr "pa_combine_type" "addmove")
+   (set_attr "length" "4")])
+
 (define_expand "movqi"
   [(set (match_operand:QI 0 "general_operand" "")
 	(match_operand:QI 1 "general_operand" ""))]


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]