This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: PATCH: Use PLUS instead of HIGH/LO_SUM for large constants - take 2 for PA
- To: dave at hiauly1 dot hia dot nrc dot ca (John David Anglin)
- Subject: Re: PATCH: Use PLUS instead of HIGH/LO_SUM for large constants - take 2 for PA
- From: "John David Anglin" <dave at hiauly1 dot hia dot nrc dot ca>
- Date: Wed, 31 Oct 2001 13:39:07 -0500 (EST)
- Cc: gcc-patches at gcc dot gnu dot org
> 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.
After thinking more about the above patch, I realized that it was trivial
to extend the range of constants handled by 64-bits hosts compiling for
TARGET_64BIT. This changes the previous patch to take advantage of the
full im5 format used for immediates by the depdi instruction. Checked
on hppa1.1-hp-hpux10.20 but not on 64-bit host/target.
Dave
--
J. David Anglin dave.anglin@nrc.ca
National Research Council of Canada (613) 990-0752 (FAX: 952-6605)
2001-10-31 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. Use
depdi for insertion of most significant 32-bits 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 28 16:24:36 2001
+++ pa.c Wed Oct 31 11:24:25 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))
@@ -1596,8 +1597,8 @@
else if (GET_CODE (operand1) != CONST_INT
|| ! cint_ok_for_move (INTVAL (operand1)))
{
+ rtx extend = NULL_RTX;
rtx temp;
- int need_zero_extend = 0;
if (TARGET_64BIT && GET_CODE (operand1) == CONST_INT
&& HOST_BITS_PER_WIDE_INT > 32
@@ -1606,15 +1607,18 @@
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 original value as-is. If the new value is
+ different, we use it and insert the most-significant 32-bits
+ of the original value into the final result. */
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 HOST_BITS_PER_WIDE_INT > 32
+ extend = GEN_INT (val >> 32);
+#endif
operand1 = GEN_INT (nval);
}
}
@@ -1624,19 +1628,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 != NULL_RTX)
+ emit_insn (gen_insv (operands[0], GEN_INT (32), const0_rtx,
+ extend));
+
return 1;
}
}
--- pa.h.orig Mon Sep 24 12:18:02 2001
+++ pa.h Tue Oct 30 10:33:39 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) -32 << 31 \
+ && INTVAL (X) < (HOST_WIDE_INT) 32 << 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"