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:
parent
fbb96ac51d
commit
390ea488c1
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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")
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue