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:
Richard Sandiford 2004-01-25 21:27:37 +00:00 committed by Richard Sandiford
parent 8e67da213d
commit 62973ffe06
2 changed files with 43 additions and 11 deletions

View File

@ -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.

View File

@ -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: