* [committed, 5/7] MIPS -mcode-readable support
@ 2007-08-08 15:42 Richard Sandiford
0 siblings, 0 replies; only message in thread
From: Richard Sandiford @ 2007-08-08 15:42 UTC (permalink / raw)
To: gcc-patches
This is the fifth patch in the -mcode-readable series.
Life used to be simple for mips_split_symbol: when generating MIPS16 code,
the high part of a symbol was a copy of the $gp constant; when generating
non-MIPS16 code, the high part of a symbol was a HIGH expression.
However, we now need to use HIGH for MIPS16 too. mips_split_symbol must
therefore choose the high part based on the symbol type rather than the
MIPS16 mode.
mips_split_symbol is currently defined in such a way that the caller
checks whether a split is needed. This check involves determining the
symbol type, so rather than pass the type down to mips_split_symbol,
it seemed better to move the "is a split needed?" check to
mips_split_symbol itself. The patch below does that.
Tested in the same way as the first patch. Applied.
Richard
gcc/
* config/mips/mips-protos.h (mips_split_symbol): Add a mode and
an "rtx *" argument. Return a bool.
* config/mips/mips.c (mips_split_symbol): Accept arbitrary source
values and return true if they can be split. Take the same kind of
mode argument as mips_symbol_insns. Add a "lo_sum_out" parameter
and store the lo_sum there if nonnull. Use the symbol type to
determine whether a $gp or HIGH is needed.
(mips_legitimize_address): Update call to mips_split_symbol and
simplify accordingly.
(mips_legitimize_const_move): Likewise.
* config/mips/mips.md: In the combine define_split,
check mips_split_symbol instead of splittable_symbolic_operand.
Update use of mips_split_symbol in the generator code.
* config/mips/predicates.md (splittable_symbolic_operand): Delete.
Index: gcc/config/mips/mips-protos.h
===================================================================
--- gcc/config/mips/mips-protos.h 2007-07-28 12:41:01.000000000 -0700
+++ gcc/config/mips/mips-protos.h 2007-07-31 02:57:35.000000000 -0700
@@ -172,7 +172,7 @@ extern int mips_idiv_insns (void);
extern int fp_register_operand (rtx, enum machine_mode);
extern int lo_operand (rtx, enum machine_mode);
extern bool mips_legitimate_address_p (enum machine_mode, rtx, int);
-extern rtx mips_split_symbol (rtx, rtx);
+extern bool mips_split_symbol (rtx, rtx, enum machine_mode, rtx *);
extern rtx mips_unspec_address (rtx, enum mips_symbol_type);
extern bool mips_legitimize_address (rtx *, enum machine_mode);
extern void mips_move_integer (rtx, rtx, unsigned HOST_WIDE_INT);
Index: gcc/config/mips/mips.c
===================================================================
--- gcc/config/mips/mips.c 2007-07-28 12:41:02.000000000 -0700
+++ gcc/config/mips/mips.c 2007-07-31 02:58:08.000000000 -0700
@@ -2114,24 +2114,50 @@ mips_force_temporary (rtx dest, rtx valu
}
-/* Return a LO_SUM expression for ADDR. TEMP is as for mips_force_temporary
- and is used to load the high part into a register. */
+/* If MODE is MAX_MACHINE_MODE, ADDR appears as a move operand, otherwise
+ it appears in a MEM of that mode. Return true if ADDR is a legitimate
+ constant in that context and can be split into a high part and a LO_SUM.
+ If so, and if LO_SUM_OUT is nonnull, emit the high part and return
+ the LO_SUM in *LO_SUM_OUT. Leave *LO_SUM_OUT unchanged otherwise.
-rtx
-mips_split_symbol (rtx temp, rtx addr)
+ TEMP is as for mips_force_temporary and is used to load the high
+ part into a register. */
+
+bool
+mips_split_symbol (rtx temp, rtx addr, enum machine_mode mode, rtx *lo_sum_out)
{
+ enum mips_symbol_context context;
+ enum mips_symbol_type symbol_type;
rtx high;
- if (!TARGET_MIPS16)
- high = mips_force_temporary (temp, gen_rtx_HIGH (Pmode, copy_rtx (addr)));
- else if (!can_create_pseudo_p ())
+ context = (mode == MAX_MACHINE_MODE
+ ? SYMBOL_CONTEXT_LEA
+ : SYMBOL_CONTEXT_MEM);
+ if (!mips_symbolic_constant_p (addr, context, &symbol_type)
+ || mips_symbol_insns (symbol_type, mode) == 0
+ || !mips_split_p[symbol_type])
+ return false;
+
+ if (lo_sum_out)
{
- emit_insn (gen_load_const_gp (copy_rtx (temp)));
- high = temp;
+ if (symbol_type == SYMBOL_GP_RELATIVE)
+ {
+ if (!can_create_pseudo_p ())
+ {
+ emit_insn (gen_load_const_gp (copy_rtx (temp)));
+ high = temp;
+ }
+ else
+ high = mips16_gp_pseudo_reg ();
+ }
+ else
+ {
+ high = gen_rtx_HIGH (Pmode, copy_rtx (addr));
+ high = mips_force_temporary (temp, high);
+ }
+ *lo_sum_out = gen_rtx_LO_SUM (Pmode, high, addr);
}
- else
- high = mips16_gp_pseudo_reg ();
- return gen_rtx_LO_SUM (Pmode, high, addr);
+ return true;
}
@@ -2322,8 +2348,6 @@ mips_legitimize_tls_address (rtx loc)
bool
mips_legitimize_address (rtx *xloc, enum machine_mode mode)
{
- enum mips_symbol_type symbol_type;
-
if (mips_tls_operand_p (*xloc))
{
*xloc = mips_legitimize_tls_address (*xloc);
@@ -2331,13 +2355,8 @@ mips_legitimize_address (rtx *xloc, enum
}
/* See if the address can split into a high part and a LO_SUM. */
- if (mips_symbolic_constant_p (*xloc, SYMBOL_CONTEXT_MEM, &symbol_type)
- && mips_symbol_insns (symbol_type, mode) > 0
- && mips_split_p[symbol_type])
- {
- *xloc = mips_split_symbol (0, *xloc);
- return true;
- }
+ if (mips_split_symbol (NULL, *xloc, mode, xloc))
+ return true;
if (GET_CODE (*xloc) == PLUS && GET_CODE (XEXP (*xloc, 1)) == CONST_INT)
{
@@ -2506,9 +2525,9 @@ mips_legitimize_const_move (enum machine
}
/* Split moves of symbolic constants into high/low pairs. */
- if (splittable_symbolic_operand (src, mode))
+ if (mips_split_symbol (dest, src, MAX_MACHINE_MODE, &src))
{
- emit_insn (gen_rtx_SET (VOIDmode, dest, mips_split_symbol (dest, src)));
+ emit_insn (gen_rtx_SET (VOIDmode, dest, src));
return;
}
@@ -2535,8 +2554,7 @@ mips_legitimize_const_move (enum machine
/* When using explicit relocs, constant pool references are sometimes
not legitimate addresses. */
- if (!memory_operand (src, VOIDmode))
- src = replace_equiv_address (src, mips_split_symbol (dest, XEXP (src, 0)));
+ mips_split_symbol (dest, XEXP (src, 0), mode, &XEXP (src, 0));
emit_move_insn (dest, src);
}
Index: gcc/config/mips/mips.md
===================================================================
--- gcc/config/mips/mips.md 2007-07-28 12:30:41.000000000 -0700
+++ gcc/config/mips/mips.md 2007-07-31 02:57:56.000000000 -0700
@@ -3300,11 +3300,14 @@ (define_split
;; Likewise, for symbolic operands.
(define_split
[(set (match_operand:P 0 "register_operand")
- (match_operand:P 1 "splittable_symbolic_operand"))
+ (match_operand:P 1))
(clobber (match_operand:P 2 "register_operand"))]
- ""
- [(set (match_dup 0) (match_dup 1))]
- { operands[1] = mips_split_symbol (operands[2], operands[1]); })
+ "mips_split_symbol (operands[2], operands[1], MAX_MACHINE_MODE, NULL)"
+ [(set (match_dup 0) (match_dup 3))]
+{
+ mips_split_symbol (operands[2], operands[1],
+ MAX_MACHINE_MODE, &operands[3]);
+})
;; 64-bit integer moves
Index: gcc/config/mips/predicates.md
===================================================================
--- gcc/config/mips/predicates.md 2007-07-28 12:38:49.000000000 -0700
+++ gcc/config/mips/predicates.md 2007-07-31 02:23:13.000000000 -0700
@@ -155,16 +155,6 @@ (define_predicate "splittable_const_int_
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_CONTEXT_LEA, &symbol_type)
- && mips_split_p[symbol_type]);
-})
-
(define_predicate "move_operand"
(match_operand 0 "general_operand")
{
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2007-08-08 15:42 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-08-08 15:42 [committed, 5/7] MIPS -mcode-readable support Richard Sandiford
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).