aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <rsandifo@redhat.com>2004-01-25 21:27:37 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2004-01-25 21:27:37 +0000
commit62973ffe06db2e092d17cecd2e1db44500ac986f (patch)
tree013d98ff4c4b1fc8222ad86d9776d57120d7e799 /gcc
parent8e67da213d262d9636501e9e96ec9894ed33f8ae (diff)
downloadgcc-62973ffe06db2e092d17cecd2e1db44500ac986f.zip
gcc-62973ffe06db2e092d17cecd2e1db44500ac986f.tar.gz
gcc-62973ffe06db2e092d17cecd2e1db44500ac986f.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/mips/mips.c47
2 files changed, 43 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b949273..ccad5da 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 1c87e11..df338f7 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -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: