diff options
author | Richard Sandiford <richard@codesourcery.com> | 2007-03-01 09:58:12 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2007-03-01 09:58:12 +0000 |
commit | 7ffb5e78794b6d8f8094d7c928e6f0e94b62cad6 (patch) | |
tree | 81be2b5d29cc958cea52c2a7ebbe3c30b5b450ec /gcc/rtlanal.c | |
parent | 96e7e5ad47a3d455eeb64991e44b23f24c69719e (diff) | |
download | gcc-7ffb5e78794b6d8f8094d7c928e6f0e94b62cad6.zip gcc-7ffb5e78794b6d8f8094d7c928e6f0e94b62cad6.tar.gz gcc-7ffb5e78794b6d8f8094d7c928e6f0e94b62cad6.tar.bz2 |
Makefile.in (rtlanal.o): Depend on tree.h.
gcc/
* Makefile.in (rtlanal.o): Depend on tree.h.
* rtl.h (offset_within_section_p, split_const): Declare.
* rtlanal.c: Include tree.h.
(offset_within_block_p): New function, taken from
mips_offset_within_object_p.
(split_const): New function, taken from mips_split_const.
* config/m68k/m68k-protos.h (m68k_illegitimate_symbolic_constant_p):
Declare.
* config/m68k/m68k.h (M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P): Define.
(CONSTANT_ADDRESS_P): Only accept legitimate constants.
(LEGITIMATE_CONSTANT_P): Check m68k_illegitimate_symbolic_constant_p.
* config/m68k/m68k.c (TARGET_CANNOT_FORCE_CONST_MEM): Define.
(m68k_illegitimate_symbolic_constant_p): New function.
* config/m68k/m68k.md (movsi): Remove misleading predicates.
If M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P and the source is a
symbolic constant that might be outside the symbol's section,
move the symbol first and then add the offset.
* config/m68k/uclinux.h (M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P):
Override.
* config/mips/mips.c (mips_split_const): Delete.
(mips_offset_within_object_p): Delete.
(mips_symbolic_constant_p): Use offset_within_section_p and
split_const instead of mips_offset_within_object_p and
mips_split_const.
(mips_cannot_force_const_mem, mips_const_insns, mips_unspec_address)
(mips_legitimize_const_move, print_operand_reloc)
(mips_dangerous_for_la25_p): Use split_const instead of
mips_split_const.
From-SVN: r122428
Diffstat (limited to 'gcc/rtlanal.c')
-rw-r--r-- | gcc/rtlanal.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 00a996e..cf9fd1d 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -37,6 +37,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "real.h" #include "regs.h" #include "function.h" +#include "tree.h" /* Information about a subreg of a hard register. */ struct subreg_info @@ -496,6 +497,61 @@ get_related_value (rtx x) return 0; } +/* Return true if SYMBOL is a SYMBOL_REF and OFFSET + SYMBOL points + to somewhere in the same object or object_block as SYMBOL. */ + +bool +offset_within_block_p (rtx symbol, HOST_WIDE_INT offset) +{ + tree decl; + + if (GET_CODE (symbol) != SYMBOL_REF) + return false; + + if (offset == 0) + return true; + + if (offset > 0) + { + if (CONSTANT_POOL_ADDRESS_P (symbol) + && offset < (int) GET_MODE_SIZE (get_pool_mode (symbol))) + return true; + + decl = SYMBOL_REF_DECL (symbol); + if (decl && offset < int_size_in_bytes (TREE_TYPE (decl))) + return true; + } + + if (SYMBOL_REF_HAS_BLOCK_INFO_P (symbol) + && SYMBOL_REF_BLOCK (symbol) + && SYMBOL_REF_BLOCK_OFFSET (symbol) >= 0 + && ((unsigned HOST_WIDE_INT) offset + SYMBOL_REF_BLOCK_OFFSET (symbol) + < (unsigned HOST_WIDE_INT) SYMBOL_REF_BLOCK (symbol)->size)) + return true; + + return false; +} + +/* Split X into a base and a constant offset, storing them in *BASE_OUT + and *OFFSET_OUT respectively. */ + +void +split_const (rtx x, rtx *base_out, rtx *offset_out) +{ + if (GET_CODE (x) == CONST) + { + x = XEXP (x, 0); + if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT) + { + *base_out = XEXP (x, 0); + *offset_out = XEXP (x, 1); + return; + } + } + *base_out = x; + *offset_out = const0_rtx; +} + /* Return the number of places FIND appears within X. If COUNT_DEST is zero, we do not count occurrences inside the destination of a SET. */ |