aboutsummaryrefslogtreecommitdiff
path: root/gcc/rtlanal.c
diff options
context:
space:
mode:
authorRichard Sandiford <richard@codesourcery.com>2007-03-01 09:58:12 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2007-03-01 09:58:12 +0000
commit7ffb5e78794b6d8f8094d7c928e6f0e94b62cad6 (patch)
tree81be2b5d29cc958cea52c2a7ebbe3c30b5b450ec /gcc/rtlanal.c
parent96e7e5ad47a3d455eeb64991e44b23f24c69719e (diff)
downloadgcc-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.c56
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. */