This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: Use PLUS instead of HIGH/LO_SUM for large constants
- To: gcc-patches at gcc dot gnu dot org
- Subject: PATCH: Use PLUS instead of HIGH/LO_SUM for large constants
- From: "John David Anglin" <dave at hiauly1 dot hia dot nrc dot ca>
- Date: Sat, 22 Sep 2001 15:11:12 -0400 (EDT)
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" ""))]