aboutsummaryrefslogtreecommitdiff
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
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
-rw-r--r--gcc/ChangeLog31
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/config/m68k/m68k-protos.h1
-rw-r--r--gcc/config/m68k/m68k.c20
-rw-r--r--gcc/config/m68k/m68k.h18
-rw-r--r--gcc/config/m68k/m68k.md18
-rw-r--r--gcc/config/m68k/uclinux.h6
-rw-r--r--gcc/config/mips/mips.c114
-rw-r--r--gcc/rtl.h2
-rw-r--r--gcc/rtlanal.c56
10 files changed, 175 insertions, 93 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 61ffafb..120d963 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,34 @@
+2007-03-01 Richard Sandiford <richard@codesourcery.com>
+
+ * 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.
+
2007-02-28 Eric Christopher <echristo@apple.com>
* Makefile.in (install-include-dir): Don't rm -rf include.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 2331ef0..974f6b4 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2314,7 +2314,7 @@ print-rtl.o : print-rtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(BCONFIG_H) $(REAL_H)
rtlanal.o : rtlanal.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h \
$(RTL_H) hard-reg-set.h $(TM_P_H) insn-config.h $(RECOG_H) $(REAL_H) \
- $(FLAGS_H) $(REGS_H) output.h $(TARGET_H) $(FUNCTION_H)
+ $(FLAGS_H) $(REGS_H) output.h $(TARGET_H) $(FUNCTION_H) $(TREE_H)
varasm.o : varasm.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
$(RTL_H) $(FLAGS_H) $(FUNCTION_H) $(EXPR_H) hard-reg-set.h $(REGS_H) \
diff --git a/gcc/config/m68k/m68k-protos.h b/gcc/config/m68k/m68k-protos.h
index 85a5376..d0ff670 100644
--- a/gcc/config/m68k/m68k-protos.h
+++ b/gcc/config/m68k/m68k-protos.h
@@ -50,6 +50,7 @@ extern int standard_68881_constant_p (rtx);
extern void print_operand_address (FILE *, rtx);
extern void print_operand (FILE *, rtx, int);
extern void notice_update_cc (rtx, rtx);
+extern bool m68k_illegitimate_symbolic_constant_p (rtx);
extern rtx legitimize_pic_address (rtx, enum machine_mode, rtx);
extern int valid_dbcc_comparison_p_2 (rtx, enum machine_mode);
extern rtx m68k_libcall_value (enum machine_mode);
diff --git a/gcc/config/m68k/m68k.c b/gcc/config/m68k/m68k.c
index 08ebbd2..90e2491 100644
--- a/gcc/config/m68k/m68k.c
+++ b/gcc/config/m68k/m68k.c
@@ -191,6 +191,9 @@ int m68k_last_compare_had_fp_operands;
#undef TARGET_STRUCT_VALUE_RTX
#define TARGET_STRUCT_VALUE_RTX m68k_struct_value_rtx
+#undef TARGET_CANNOT_FORCE_CONST_MEM
+#define TARGET_CANNOT_FORCE_CONST_MEM m68k_illegitimate_symbolic_constant_p
+
static const struct attribute_spec m68k_attribute_table[] =
{
/* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
@@ -1663,6 +1666,23 @@ output_btst (rtx *operands, rtx countop, rtx dataop, rtx insn, int signpos)
return "btst %0,%1";
}
+/* Return true if X is an illegitimate symbolic constant. */
+
+bool
+m68k_illegitimate_symbolic_constant_p (rtx x)
+{
+ rtx base, offset;
+
+ if (M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
+ {
+ split_const (x, &base, &offset);
+ if (GET_CODE (base) == SYMBOL_REF
+ && !offset_within_block_p (base, INTVAL (offset)))
+ return true;
+ }
+ return false;
+}
+
/* Legitimize PIC addresses. If the address is already
position-independent, we return ORIG. Newly generated
position-independent addresses go to REG. If we need more
diff --git a/gcc/config/m68k/m68k.h b/gcc/config/m68k/m68k.h
index d832564..f960f3b 100644
--- a/gcc/config/m68k/m68k.h
+++ b/gcc/config/m68k/m68k.h
@@ -786,17 +786,25 @@ __transfer_from_trampoline () \
/* 1 if X is an address register */
#define ADDRESS_REG_P(X) (REG_P (X) && REGNO_OK_FOR_BASE_P (REGNO (X)))
+/* True if SYMBOL + OFFSET constants must refer to something within
+ SYMBOL's section. */
+#ifndef M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P
+#define M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P 0
+#endif
#define MAX_REGS_PER_ADDRESS 2
-#define CONSTANT_ADDRESS_P(X) \
- (GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
- || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \
- || GET_CODE (X) == HIGH)
+#define CONSTANT_ADDRESS_P(X) \
+ ((GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
+ || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \
+ || GET_CODE (X) == HIGH) \
+ && LEGITIMATE_CONSTANT_P (X))
/* Nonzero if the constant value X is a legitimate general operand.
It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
-#define LEGITIMATE_CONSTANT_P(X) (GET_MODE (X) != XFmode)
+#define LEGITIMATE_CONSTANT_P(X) \
+ (GET_MODE (X) != XFmode \
+ && !m68k_illegitimate_symbolic_constant_p (X))
#ifndef REG_OK_STRICT
#define PCREL_GENERAL_OPERAND_OK 0
diff --git a/gcc/config/m68k/m68k.md b/gcc/config/m68k/m68k.md
index 42e5f21..a2f0cfd 100644
--- a/gcc/config/m68k/m68k.md
+++ b/gcc/config/m68k/m68k.md
@@ -627,10 +627,12 @@
;; In both the PIC and non-PIC cases the patterns generated will
;; matched by the next define_insn.
(define_expand "movsi"
- [(set (match_operand:SI 0 "nonimmediate_operand" "")
- (match_operand:SI 1 "general_operand" ""))]
+ [(set (match_operand:SI 0 "" "")
+ (match_operand:SI 1 "" ""))]
""
{
+ rtx tmp, base, offset;
+
if (flag_pic && !TARGET_PCREL && symbolic_operand (operands[1], SImode))
{
/* The source is an address which requires PIC relocation.
@@ -651,6 +653,18 @@
operands[0] = gen_rtx_MEM (SImode,
force_reg (SImode, XEXP (operands[0], 0)));
}
+ if (M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P)
+ {
+ split_const (operands[1], &base, &offset);
+ if (GET_CODE (base) == SYMBOL_REF
+ && !offset_within_block_p (base, INTVAL (offset)))
+ {
+ tmp = no_new_pseudos ? operands[0] : gen_reg_rtx (SImode);
+ emit_move_insn (tmp, base);
+ emit_insn (gen_addsi3 (operands[0], tmp, offset));
+ DONE;
+ }
+ }
})
;; General case of fullword move. The register constraints
diff --git a/gcc/config/m68k/uclinux.h b/gcc/config/m68k/uclinux.h
index 992c465..93a9d82 100644
--- a/gcc/config/m68k/uclinux.h
+++ b/gcc/config/m68k/uclinux.h
@@ -65,3 +65,9 @@ Boston, MA 02110-1301, USA. */
/* -msep-data is the default PIC mode on this target. */
#define DRIVER_SELF_SPECS \
"%{fpie|fPIE|fpic|fPIC:%{!msep-data:%{!mid-shared-library: -msep-data}}}"
+
+/* The uclinux binary format relies on relocations against a segment being
+ within that segment. Conservatively apply this rule to individual
+ sections. */
+#undef M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P
+#define M68K_OFFSETS_MUST_BE_WITHIN_SECTIONS_P 1
diff --git a/gcc/config/mips/mips.c b/gcc/config/mips/mips.c
index 37035aa..82b38a7 100644
--- a/gcc/config/mips/mips.c
+++ b/gcc/config/mips/mips.c
@@ -267,8 +267,6 @@ struct mips_integer_op;
struct mips_sim;
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_valid_base_register_p (rtx, enum machine_mode, int);
static bool mips_symbolic_address_p (enum mips_symbol_type, enum machine_mode);
static bool mips_classify_address (struct mips_address_info *, rtx,
@@ -1292,58 +1290,6 @@ mips_classify_symbol (rtx x)
return SYMBOL_GENERAL;
}
-
-/* Split X into a base and a constant offset, storing them in *BASE
- and *OFFSET respectively. */
-
-static void
-mips_split_const (rtx x, rtx *base, HOST_WIDE_INT *offset)
-{
- *offset = 0;
-
- if (GET_CODE (x) == CONST)
- {
- x = XEXP (x, 0);
- if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 1)) == CONST_INT)
- {
- *offset += INTVAL (XEXP (x, 1));
- x = XEXP (x, 0);
- }
- }
- *base = x;
-}
-
-
-/* Return true if SYMBOL is a SYMBOL_REF and OFFSET + SYMBOL points
- to the same object as SYMBOL, or to the same object_block. */
-
-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;
-
- 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;
-}
-
-
/* 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. */
@@ -1351,9 +1297,9 @@ mips_offset_within_object_p (rtx symbol, HOST_WIDE_INT offset)
bool
mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type)
{
- HOST_WIDE_INT offset;
+ rtx offset;
- mips_split_const (x, &x, &offset);
+ split_const (x, &x, &offset);
if (UNSPEC_ADDRESS_P (x))
*symbol_type = UNSPEC_ADDRESS_TYPE (x);
else if (GET_CODE (x) == SYMBOL_REF || GET_CODE (x) == LABEL_REF)
@@ -1365,7 +1311,7 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type)
else
return false;
- if (offset == 0)
+ if (offset == const0_rtx)
return true;
/* Check whether a nonzero offset is valid for the underlying
@@ -1381,7 +1327,7 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type)
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);
+ return offset_within_block_p (x, INTVAL (offset));
/* In other cases the relocations can handle any offset. */
return true;
@@ -1397,15 +1343,15 @@ mips_symbolic_constant_p (rtx x, enum mips_symbol_type *symbol_type)
case SYMBOL_SMALL_DATA:
/* Make sure that the offset refers to something within the
- underlying object. This should guarantee that the final
+ same object block. 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);
+ return offset_within_block_p (x, INTVAL (offset));
case SYMBOL_GOT_LOCAL:
case SYMBOL_GOTOFF_PAGE:
/* The linker should provide enough local GOT entries for a
16-bit offset. Larger offsets may lead to GOT overflow. */
- return SMALL_OPERAND (offset);
+ return SMALL_INT (offset);
case SYMBOL_GOT_GLOBAL:
case SYMBOL_GOTOFF_GLOBAL:
@@ -1595,8 +1541,7 @@ mips_tls_symbol_ref_1 (rtx *x, void *data ATTRIBUTE_UNUSED)
static bool
mips_cannot_force_const_mem (rtx x)
{
- rtx base;
- HOST_WIDE_INT offset;
+ rtx base, offset;
if (!TARGET_MIPS16)
{
@@ -1612,8 +1557,8 @@ mips_cannot_force_const_mem (rtx x)
if (GET_CODE (x) == CONST_INT)
return true;
- mips_split_const (x, &base, &offset);
- if (symbolic_operand (base, VOIDmode) && SMALL_OPERAND (offset))
+ split_const (x, &base, &offset);
+ if (symbolic_operand (base, VOIDmode) && SMALL_INT (offset))
return true;
}
@@ -1800,7 +1745,7 @@ mips_const_insns (rtx x)
{
struct mips_integer_op codes[MIPS_MAX_INTEGER_OPS];
enum mips_symbol_type symbol_type;
- HOST_WIDE_INT offset;
+ rtx offset;
switch (GET_CODE (x))
{
@@ -1841,16 +1786,16 @@ mips_const_insns (rtx x)
/* Otherwise try splitting the constant into a base and offset.
16-bit offsets can be added using an extra addiu. Larger offsets
must be calculated separately and then added to the base. */
- mips_split_const (x, &x, &offset);
+ split_const (x, &x, &offset);
if (offset != 0)
{
int n = mips_const_insns (x);
if (n != 0)
{
- if (SMALL_OPERAND (offset))
+ if (SMALL_INT (offset))
return n + 1;
else
- return n + 1 + mips_build_integer (codes, offset);
+ return n + 1 + mips_build_integer (codes, INTVAL (offset));
}
}
return 0;
@@ -1949,13 +1894,14 @@ mips_split_symbol (rtx temp, rtx addr)
rtx
mips_unspec_address (rtx address, enum mips_symbol_type symbol_type)
{
- rtx base;
- HOST_WIDE_INT offset;
+ rtx base, offset;
- mips_split_const (address, &base, &offset);
+ split_const (address, &base, &offset);
base = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, base),
UNSPEC_ADDRESS_FIRST + symbol_type);
- return plus_constant (gen_rtx_CONST (Pmode, base), offset);
+ if (offset != const0_rtx)
+ base = gen_rtx_PLUS (Pmode, base, offset);
+ return gen_rtx_CONST (Pmode, base);
}
@@ -2303,8 +2249,7 @@ mips_move_integer (rtx dest, rtx temp, unsigned HOST_WIDE_INT value)
static void
mips_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src)
{
- rtx base;
- HOST_WIDE_INT offset;
+ rtx base, offset;
/* Split moves of big integers into smaller pieces. */
if (splittable_const_int_operand (src, mode))
@@ -2329,13 +2274,13 @@ mips_legitimize_const_move (enum machine_mode mode, rtx dest, rtx src)
/* If we have (const (plus symbol offset)), load the symbol first
and then add in the offset. This is usually better than forcing
the constant into memory, at least in non-mips16 code. */
- mips_split_const (src, &base, &offset);
+ split_const (src, &base, &offset);
if (!TARGET_MIPS16
- && offset != 0
- && (!no_new_pseudos || SMALL_OPERAND (offset)))
+ && offset != const0_rtx
+ && (!no_new_pseudos || SMALL_INT (offset)))
{
base = mips_force_temporary (dest, base);
- emit_move_insn (dest, mips_add_offset (0, base, offset));
+ emit_move_insn (dest, mips_add_offset (0, base, INTVAL (offset)));
return;
}
@@ -5709,16 +5654,15 @@ print_operand_reloc (FILE *file, rtx op, const char **relocs)
{
enum mips_symbol_type symbol_type;
const char *p;
- rtx base;
- HOST_WIDE_INT offset;
+ rtx base, offset;
if (!mips_symbolic_constant_p (op, &symbol_type) || relocs[symbol_type] == 0)
fatal_insn ("PRINT_OPERAND, invalid operand for relocation", op);
/* If OP uses an UNSPEC address, we want to print the inner symbol. */
- mips_split_const (op, &base, &offset);
+ split_const (op, &base, &offset);
if (UNSPEC_ADDRESS_P (base))
- op = plus_constant (UNSPEC_ADDRESS (base), offset);
+ op = plus_constant (UNSPEC_ADDRESS (base), INTVAL (offset));
fputs (relocs[symbol_type], file);
output_addr_const (file, op);
@@ -7640,12 +7584,12 @@ mips_cannot_change_mode_class (enum machine_mode from,
bool
mips_dangerous_for_la25_p (rtx x)
{
- HOST_WIDE_INT offset;
+ rtx offset;
if (TARGET_EXPLICIT_RELOCS)
return false;
- mips_split_const (x, &x, &offset);
+ split_const (x, &x, &offset);
return global_got_operand (x, VOIDmode);
}
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 6bf09aa..41d50d4 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1672,6 +1672,8 @@ extern int rtx_varies_p (rtx, int);
extern int rtx_addr_varies_p (rtx, int);
extern HOST_WIDE_INT get_integer_term (rtx);
extern rtx get_related_value (rtx);
+extern bool offset_within_block_p (rtx, HOST_WIDE_INT);
+extern void split_const (rtx, rtx *, rtx *);
extern int reg_mentioned_p (rtx, rtx);
extern int count_occurrences (rtx, rtx, int);
extern int reg_referenced_p (rtx, rtx);
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. */