mips-protos.h (mips_split_symbol): Add a mode and an "rtx *" argument.

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.

From-SVN: r127298
This commit is contained in:
Richard Sandiford 2007-08-08 15:40:27 +00:00 committed by Richard Sandiford
parent fbb96ac51d
commit 390ea488c1
5 changed files with 68 additions and 40 deletions

View File

@ -1,3 +1,20 @@
2007-08-08 Richard Sandiford <richard@codesourcery.com>
* 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.
2007-08-08 Richard Sandiford <richard@codesourcery.com>
* config/mips/mips.c (mips_symbolic_address_p): Delete.

View File

@ -171,7 +171,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);

View File

@ -2113,24 +2113,50 @@ mips_force_temporary (rtx dest, rtx value)
}
/* 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;
}
@ -2321,8 +2347,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);
@ -2330,13 +2354,8 @@ mips_legitimize_address (rtx *xloc, enum machine_mode mode)
}
/* 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)
{
@ -2505,9 +2524,9 @@ mips_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src)
}
/* 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;
}
@ -2534,8 +2553,7 @@ mips_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src)
/* 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);
}

View File

@ -3299,11 +3299,14 @@
;; 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

View File

@ -154,16 +154,6 @@
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")
{