aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorDJ Delorie <dj@redhat.com>2007-05-18 17:15:50 -0400
committerDJ Delorie <dj@gcc.gnu.org>2007-05-18 17:15:50 -0400
commit8b5fb3a36f12edc290b5a2c90db551d406df4edf (patch)
treefef9a3ec65178bef08656cfbe3309ae6f361e725 /gcc
parente7e0aaeca8ab3390677fa3a950504c93d75c2060 (diff)
downloadgcc-8b5fb3a36f12edc290b5a2c90db551d406df4edf.zip
gcc-8b5fb3a36f12edc290b5a2c90db551d406df4edf.tar.gz
gcc-8b5fb3a36f12edc290b5a2c90db551d406df4edf.tar.bz2
mips.c (mips_offset_within_alignment_p): New.
* config/mips/mips.c (mips_offset_within_alignment_p): New. (mips_symbolic_constant_p): Call it for TPREL and DTPREL symbols. From-SVN: r124833
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/config/mips/mips.c36
2 files changed, 38 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e0c6b5f..630e06d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2007-05-18 DJ Delorie <dj@redhat.com>
+
+ * config/mips/mips.c (mips_offset_within_alignment_p): New.
+ (mips_symbolic_constant_p): Call it for TPREL and DTPREL symbols.
+
2007-05-18 Uros Bizjak <ubizjak@gmail.com>
* longlong.h (__x86_64__): Add definitions for add_ssaaaa,
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index a719a10..ff83eb7 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -412,6 +412,7 @@ static rtx mips_expand_builtin_bposge (enum mips_builtin_type, rtx);
static void mips_encode_section_info (tree, rtx, int);
static void mips_extra_live_on_entry (bitmap);
static int mips_mode_rep_extended (enum machine_mode, enum machine_mode);
+static bool mips_offset_within_alignment_p (rtx, HOST_WIDE_INT);
/* Structure to be filled in by compute_frame_size with register
save masks, and offsets for the current function. */
@@ -1350,6 +1351,28 @@ mips_classify_symbol (rtx x)
return SYMBOL_GENERAL;
}
+/* Returns true if OFFSET is within the range [0, ALIGN), where ALIGN
+ is the alignment (in bytes) of SYMBOL_REF X. */
+
+static bool
+mips_offset_within_alignment_p (rtx x, HOST_WIDE_INT offset)
+{
+ /* If for some reason we can't get the alignment for the
+ symbol, initializing this to one means we won't accept any
+ offset. */
+ HOST_WIDE_INT align = 1;
+ tree t;
+
+ /* Get the alignment of the symbol we're referring to. */
+ t = SYMBOL_REF_DECL (x);
+ if (t)
+ align = DECL_ALIGN_UNIT (t);
+
+ if (offset >= 0 && offset < align)
+ 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. */
@@ -1361,7 +1384,10 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type)
split_const (x, &x, &offset);
if (UNSPEC_ADDRESS_P (x))
- *symbol_type = UNSPEC_ADDRESS_TYPE (x);
+ {
+ *symbol_type = UNSPEC_ADDRESS_TYPE (x);
+ x = UNSPEC_ADDRESS (x);
+ }
else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
{
*symbol_type = mips_classify_symbol (x);
@@ -1416,14 +1442,18 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type)
to GOT overflow. */
return SMALL_INT (offset);
+ case SYMBOL_TPREL:
+ case SYMBOL_DTPREL:
+ /* There is no carry between the HI and LO REL relocations, so the
+ offset is only valid if we know it won't lead to such a carry. */
+ return mips_offset_within_alignment_p (x, INTVAL (offset));
+
case SYMBOL_GOT_DISP:
case SYMBOL_GOTOFF_DISP:
case SYMBOL_GOTOFF_CALL:
case SYMBOL_GOTOFF_LOADGP:
case SYMBOL_TLSGD:
case SYMBOL_TLSLDM:
- case SYMBOL_DTPREL:
- case SYMBOL_TPREL:
case SYMBOL_GOTTPREL:
case SYMBOL_TLS:
case SYMBOL_HALF: