diff options
author | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-03-16 20:24:42 +0000 |
---|---|---|
committer | rsandifo <rsandifo@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-03-16 20:24:42 +0000 |
commit | 1a4d3221103d9321241ebb18da43d5bcac3a1330 (patch) | |
tree | 0d9e288be90577a8c05e18e72391446f59072ca7 /gcc/config/mips/predicates.md | |
parent | 42102a269cf8eb42317a9132dc9d02a655c3bd79 (diff) | |
download | gcc-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.md | 83 |
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; |