mips.c (mips_offset_within_object_p): New function.
* config/mips/mips.c (mips_offset_within_object_p): New function. (mips_symbolic_constant_p): Use it in the SYMBOL_SMALL_DATA and SYMBOL_CONSTANT_POOL cases. Also use it for SYMBOL_GENERAL if the ABI has 64-bit pointers and the object file only allows 32-bit symbols. From-SVN: r76586
This commit is contained in:
parent
8e67da213d
commit
62973ffe06
@ -1,3 +1,10 @@
|
||||
2004-01-25 Richard Sandiford <rsandifo@redhat.com>
|
||||
|
||||
* config/mips/mips.c (mips_offset_within_object_p): New function.
|
||||
(mips_symbolic_constant_p): Use it in the SYMBOL_SMALL_DATA and
|
||||
SYMBOL_CONSTANT_POOL cases. Also use it for SYMBOL_GENERAL if the
|
||||
ABI has 64-bit pointers and the object file only allows 32-bit symbols.
|
||||
|
||||
2004-01-25 Kazu Hirata <kazu@cs.umass.edu>
|
||||
|
||||
* config/sh/sh.h (PROMOTE_FUNCTION_ARGS): Remove.
|
||||
|
@ -191,6 +191,7 @@ struct mips_integer_op;
|
||||
|
||||
static enum mips_symbol_type mips_classify_symbol (rtx);
|
||||
static void mips_split_const (rtx, rtx *, HOST_WIDE_INT *);
|
||||
static bool mips_offset_within_object_p (rtx, HOST_WIDE_INT);
|
||||
static bool mips_symbolic_constant_p (rtx, enum mips_symbol_type *);
|
||||
static bool mips_valid_base_register_p (rtx, enum machine_mode, int);
|
||||
static bool mips_symbolic_address_p (enum mips_symbol_type, enum machine_mode);
|
||||
@ -914,6 +915,29 @@ mips_split_const (rtx x, rtx *base, HOST_WIDE_INT *offset)
|
||||
}
|
||||
|
||||
|
||||
/* Return true if SYMBOL is a SYMBOL_REF and OFFSET + SYMBOL points
|
||||
to the same object as SYMBOL. */
|
||||
|
||||
static bool
|
||||
mips_offset_within_object_p (rtx symbol, HOST_WIDE_INT offset)
|
||||
{
|
||||
if (GET_CODE (symbol) != SYMBOL_REF)
|
||||
return false;
|
||||
|
||||
if (CONSTANT_POOL_ADDRESS_P (symbol)
|
||||
&& offset >= 0
|
||||
&& offset < (int) GET_MODE_SIZE (get_pool_mode (symbol)))
|
||||
return true;
|
||||
|
||||
if (SYMBOL_REF_DECL (symbol) != 0
|
||||
&& offset >= 0
|
||||
&& offset < int_size_in_bytes (TREE_TYPE (SYMBOL_REF_DECL (symbol))))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* Return true if X is a symbolic constant that can be calculated in
|
||||
the same way as a bare symbol. If it is, store the type of the
|
||||
symbol in *SYMBOL_TYPE. */
|
||||
@ -939,21 +963,22 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type)
|
||||
switch (*symbol_type)
|
||||
{
|
||||
case SYMBOL_GENERAL:
|
||||
/* %hi() and %lo() can handle anything. */
|
||||
/* If the target has 64-bit pointers and the object file only
|
||||
supports 32-bit symbols, the values of those symbols will be
|
||||
sign-extended. In this case we can't allow an arbitrary offset
|
||||
in case the 32-bit value X + OFFSET has a different sign from X. */
|
||||
if (Pmode == DImode && !ABI_HAS_64BIT_SYMBOLS)
|
||||
return mips_offset_within_object_p (x, offset);
|
||||
|
||||
/* In other cases the relocations can handle any offset. */
|
||||
return true;
|
||||
|
||||
case SYMBOL_SMALL_DATA:
|
||||
/* Make sure that the offset refers to something within the
|
||||
-G limit. If the offset is allowed to grow too much,
|
||||
it could overflow the range of %gp_rel(). */
|
||||
return (offset > 0 && offset < mips_section_threshold);
|
||||
|
||||
case SYMBOL_CONSTANT_POOL:
|
||||
/* Similarly check the range of offsets for mips16 constant
|
||||
pool entries. */
|
||||
return (CONSTANT_POOL_ADDRESS_P (x)
|
||||
&& offset > 0
|
||||
&& offset < (int) GET_MODE_SIZE (get_pool_mode (x)));
|
||||
/* Make sure that the offset refers to something within the
|
||||
underlying object. This should guarantee that the final
|
||||
PC- or GP-relative offset is within the 16-bit limit. */
|
||||
return mips_offset_within_object_p (x, offset);
|
||||
|
||||
case SYMBOL_GOT_LOCAL:
|
||||
case SYMBOL_GOTOFF_PAGE:
|
||||
|
Loading…
Reference in New Issue
Block a user