diff options
author | DJ Delorie <dj@redhat.com> | 2007-05-18 17:15:50 -0400 |
---|---|---|
committer | DJ Delorie <dj@gcc.gnu.org> | 2007-05-18 17:15:50 -0400 |
commit | 8b5fb3a36f12edc290b5a2c90db551d406df4edf (patch) | |
tree | fef9a3ec65178bef08656cfbe3309ae6f361e725 /gcc | |
parent | e7e0aaeca8ab3390677fa3a950504c93d75c2060 (diff) | |
download | gcc-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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/config/mips/mips.c | 36 |
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: |