summaryrefslogtreecommitdiff
path: root/gcc/config/mips/predicates.md
diff options
context:
space:
mode:
authorrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2006-03-16 20:24:42 +0000
committerrsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4>2006-03-16 20:24:42 +0000
commit1a4d3221103d9321241ebb18da43d5bcac3a1330 (patch)
tree0d9e288be90577a8c05e18e72391446f59072ca7 /gcc/config/mips/predicates.md
parent42102a269cf8eb42317a9132dc9d02a655c3bd79 (diff)
downloadgcc-1a4d3221103d9321241ebb18da43d5bcac3a1330.tar.gz
* config/mips/predicates.md (splittable_const_int_operand): New,
split from move_operand. (splittable_symbolic_operand): New. (move_operand): Add commentary. Use splittable_const_int_operand. Inline mips_atomic_symbolic_constant_p. * config/mips/mips.md: Add combine splitters for handling moves of splittable_const_int_operands and splittable_symbolic_operands. * config/mips/mips-protos.h (mips_atomic_symbolic_constant_p): Delete. (mips_split_symbol): Declare. (mips_move_integer): Declare. * config/mips/mips.c (mips_split_p): Make global. (TARGET_MIN_ANCHOR_OFFSET): Override default. (TARGET_MAX_ANCHOR_OFFSET): Likewise. (TARGET_USE_BLOCKS_FOR_CONSTANT_P): Likewise. (TARGET_USE_ANCHORS_FOR_SYMBOL_P): Likewise. (mips_offset_within_object_p): Handle block symbols. (mips_atomic_symbolic_constant_p): Delete. (mips_cannot_force_const_mem): Return false for constants that mips_legitimize_move can handle. (mips_use_blocks_for_constant_p): New function. (mips_split_symbol): Make global. (mips_move_integer): Likewise. Add a temporary register argument. (mips_legitimize_const_move): Use splittable_const_int_operand and splittable_symbolic_operand. (mips_use_anchors_for_symbol_p): New function. * config/mips/mips.h: Protect externs with !USED_FOR_TARGET. (mips_split_p): Declare. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@112150 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/mips/predicates.md')
-rw-r--r--gcc/config/mips/predicates.md83
1 files changed, 69 insertions, 14 deletions
diff --git a/gcc/config/mips/predicates.md b/gcc/config/mips/predicates.md
index d93621d7d72..23e85d82be8 100644
--- a/gcc/config/mips/predicates.md
+++ b/gcc/config/mips/predicates.md
@@ -125,30 +125,85 @@
(ior (match_operand 0 "const_call_insn_operand")
(match_operand 0 "register_operand")))
+;; A legitimate CONST_INT operand that takes more than one instruction
+;; to load.
+(define_predicate "splittable_const_int_operand"
+ (match_code "const_int")
+{
+ /* When generating mips16 code, LEGITIMATE_CONSTANT_P rejects
+ CONST_INTs that can't be loaded using simple insns. */
+ if (TARGET_MIPS16)
+ return false;
+
+ /* Don't handle multi-word moves this way; we don't want to introduce
+ the individual word-mode moves until after reload. */
+ if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
+ return false;
+
+ /* Otherwise check whether the constant can be loaded in a single
+ instruction. */
+ return !LUI_INT (op) && !SMALL_INT (op) && !SMALL_INT_UNSIGNED (op);
+})
+
+;; A legitimate symbolic operand that takes more than one instruction
+;; to load.
+(define_predicate "splittable_symbolic_operand"
+ (match_code "const,symbol_ref,label_ref")
+{
+ enum mips_symbol_type symbol_type;
+ return (mips_symbolic_constant_p (op, &symbol_type)
+ && mips_split_p[symbol_type]);
+})
+
(define_predicate "move_operand"
(match_operand 0 "general_operand")
{
+ enum mips_symbol_type symbol_type;
+
+ /* The thinking here is as follows:
+
+ (1) The move expanders should split complex load sequences into
+ individual instructions. Those individual instructions can
+ then be optimized by all rtl passes.
+
+ (2) The target of pre-reload load sequences should not be used
+ to store temporary results. If the target register is only
+ assigned one value, reload can rematerialize that value
+ on demand, rather than spill it to the stack.
+
+ (3) If we allowed pre-reload passes like combine and cse to recreate
+ complex load sequences, we would want to be able to split the
+ sequences before reload as well, so that the pre-reload scheduler
+ can see the individual instructions. This falls foul of (2);
+ the splitter would be forced to reuse the target register for
+ intermediate results.
+
+ (4) We want to define complex load splitters for combine. These
+ splitters can request a temporary scratch register, which avoids
+ the problem in (2). They allow things like:
+
+ (set (reg T1) (high SYM))
+ (set (reg T2) (low (reg T1) SYM))
+ (set (reg X) (plus (reg T2) (const_int OFFSET)))
+
+ to be combined into:
+
+ (set (reg T3) (high SYM+OFFSET))
+ (set (reg X) (lo_sum (reg T3) SYM+OFFSET))
+
+ if T2 is only used this once. */
switch (GET_CODE (op))
{
case CONST_INT:
- /* When generating mips16 code, LEGITIMATE_CONSTANT_P rejects
- CONST_INTs that can't be loaded using simple insns. */
- if (TARGET_MIPS16)
- return true;
-
- /* When generating 32-bit code, allow DImode move_operands to
- match arbitrary constants. We split them after reload. */
- if (!TARGET_64BIT && mode == DImode)
- return true;
-
- /* Otherwise check whether the constant can be loaded in a single
- instruction. */
- return LUI_INT (op) || SMALL_INT (op) || SMALL_INT_UNSIGNED (op);
+ return !splittable_const_int_operand (op, mode);
case CONST:
case SYMBOL_REF:
case LABEL_REF:
- return CONST_GP_P (op) || mips_atomic_symbolic_constant_p (op);
+ if (CONST_GP_P (op))
+ return true;
+ return (mips_symbolic_constant_p (op, &symbol_type)
+ && !mips_split_p[symbol_type]);
default:
return true;