PATCH: Fix failure of arith-rand-ll.c on hppa 32-bit targets

John David Anglin dave@hiauly1.hia.nrc.ca
Wed Jul 10 23:56:00 GMT 2002


This patch fixes a regression introduced by the constant splitting code
on hppa 32-bit targets.  DImode constants were being split with a 14-bit
signed low part but the pattern that handles PLUS only accepts an 11-bit
immediate.  Oops.

After installing this patch, I realized that the predicate for the adddi3
expander can be improved rather than forcing constants that don't fit
into a register.

Tested on hppa-linux, hppa2.0w-hp-hpux11.11 (3.1.1 and 3.2).  Installed
on main.  After I checkout the predicate fix, I will install a similar
patch to the 3.1.1 branch and update the main.

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

2002-07-11  John David Anglin  <dave@hiauly1.hia.nrc.ca>

	* pa.md (adddi3): For 32-bit targets, force constants to a register
	if they don't fit in an 11-bit immediate.  Change insn predicate to
	arith11_operand.  Remove comment.
	* pa.c (cint_ok_for_move): Fix comment.
	(emit_move_sequence):  Don't directly split DImode constants on 32-bit
	targets.

Index: config/pa/pa.md
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/pa/pa.md,v
retrieving revision 1.107
diff -u -3 -p -r1.107 pa.md
--- config/pa/pa.md	13 May 2002 04:50:15 -0000	1.107
+++ config/pa/pa.md	10 Jul 2002 22:46:13 -0000
@@ -3815,20 +3815,18 @@
 	(plus:DI (match_operand:DI 1 "register_operand" "")
 		 (match_operand:DI 2 "arith_operand" "")))]
   ""
-  "")
-
-;; We allow arith_operand for operands2, even though strictly speaking it
-;; we would prefer to us arith11_operand since that's what the hardware
-;; can actually support.
-;;
-;; But the price of the extra reload in that case is worth the simplicity
-;; we get by allowing a trivial adddi3 expander to be used for both
-;; PA64 and PA32.
+  "
+{
+  if (!TARGET_64BIT
+      && GET_CODE (operands[2]) == CONST_INT
+      && !VAL_11_BITS_P (INTVAL (operands[2])))
+    operands[2] = force_reg (DImode, operands[2]);
+}")
 
 (define_insn ""
   [(set (match_operand:DI 0 "register_operand" "=r")
 	(plus:DI (match_operand:DI 1 "register_operand" "%r")
-		 (match_operand:DI 2 "arith_operand" "rI")))]
+		 (match_operand:DI 2 "arith11_operand" "rI")))]
   "!TARGET_64BIT"
   "*
 {
Index: config/pa/pa.c
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/pa/pa.c,v
retrieving revision 1.170
diff -u -3 -p -r1.170 pa.c
--- config/pa/pa.c	21 Jun 2002 01:37:47 -0000	1.170
+++ config/pa/pa.c	10 Jul 2002 22:46:14 -0000
@@ -442,7 +442,7 @@ reg_before_reload_operand (op, mode)
   return 0;
 }
 
-/* Accept any constant that can be moved in one instructions into a
+/* Accept any constant that can be moved in one instruction into a
    general register.  */
 int
 cint_ok_for_move (intval)
@@ -1744,9 +1744,13 @@ emit_move_sequence (operands, mode, scra
 	  else
 	    temp = gen_reg_rtx (mode);
 
-	  if (GET_CODE (operand1) == CONST_INT)
+	  /* We don't directly split DImode constants on 32-bit targets
+	     because PLUS uses an 11-bit immediate and the insn sequence
+	     generated is not as efficient as the one using HIGH/LO_SUM.  */
+	  if (GET_CODE (operand1) == CONST_INT
+	      && GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT)
 	    {
-	      /* Directly break constant into low and high parts.  This
+	      /* Directly break constant into high and low 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



More information about the Gcc-patches mailing list