aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn David Anglin <dave@hiauly1.hia.nrc.ca>2001-11-10 00:22:52 +0000
committerJeff Law <law@gcc.gnu.org>2001-11-09 17:22:52 -0700
commitb8e42321fb18771c9b259b8c21d683cd9acafa21 (patch)
tree79a5af00c32d7c55a013dc57aa81ba569b45c19b
parent5d69f816bcfd32f2171b31e09249a8e03acedd5e (diff)
downloadgcc-b8e42321fb18771c9b259b8c21d683cd9acafa21.zip
gcc-b8e42321fb18771c9b259b8c21d683cd9acafa21.tar.gz
gcc-b8e42321fb18771c9b259b8c21d683cd9acafa21.tar.bz2
pa.c (emit_move_sequence): Use cint_ok_for_move to check whether a constant can be loaded in a single...
* 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. From-SVN: r46908
-rw-r--r--gcc/ChangeLog12
-rw-r--r--gcc/config/pa/pa.c61
-rw-r--r--gcc/config/pa/pa.h4
-rw-r--r--gcc/config/pa/pa.md17
4 files changed, 64 insertions, 30 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6b78f4f..783c2de 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2001-11-09 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.
+
2001-11-09 Neil Booth <neil@daikokuya.demon.co.uk>
* Makefile.in: Update.
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
index f3d9070..4a7e7dc 100644
--- a/gcc/config/pa/pa.c
+++ b/gcc/config/pa/pa.c
@@ -1394,7 +1394,8 @@ emit_move_sequence (operands, mode, scratch_reg)
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 @@ emit_move_sequence (operands, mode, scratch_reg)
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 @@ emit_move_sequence (operands, mode, scratch_reg)
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 @@ emit_move_sequence (operands, mode, scratch_reg)
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;
+ }
- if (need_zero_extend)
+ low = value - high;
+
+ 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],
- 4)));
+ 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;
}
}
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index 09f5bbc..7abded2 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -1106,8 +1106,8 @@ extern int may_call_alloca;
&& !(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))
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
index f375720..3c86b27 100644
--- a/gcc/config/pa/pa.md
+++ b/gcc/config/pa/pa.md
@@ -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"