]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
Makefile.in (rtlanal.o): Depend on tree.h.
authorRichard Sandiford <richard@codesourcery.com>
Thu, 1 Mar 2007 09:58:12 +0000 (09:58 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Thu, 1 Mar 2007 09:58:12 +0000 (09:58 +0000)
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

gcc/ChangeLog
gcc/Makefile.in
gcc/config/m68k/m68k-protos.h
gcc/config/m68k/m68k.c
gcc/config/m68k/m68k.h
gcc/config/m68k/m68k.md
gcc/config/m68k/uclinux.h
gcc/config/mips/mips.c
gcc/rtl.h
gcc/rtlanal.c

index 61ffafb663cf626d4f112606d95a338ee0ccbe3f..120d963081d351376cadc1a4885461c53c5c3ae6 100644 (file)
@@ -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.
index 2331ef0343c248861115e2929815711e16d27e28..974f6b4ba3714943e8f30e3686b3500393d084ff 100644 (file)
@@ -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) \
index 85a5376826b0c289508e2b58c1218793e30f776e..d0ff670639bffc6bb716cb9b8d9e2c7efee7f7da 100644 (file)
@@ -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);
index 08ebbd20dac9536850cdffccabdbd5b5f5541f48..90e2491fb73a488368173873aa5cc312cd929a55 100644 (file)
@@ -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";
 }
 \f
+/* 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
index d832564147582574283bc29f5093a842734c4358..f960f3b4773f76e293fa446bda24f5ff1ffab1ca 100644 (file)
@@ -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)))
 \f
+/* 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
index 42e5f21dfce7d9ff6101c582e1fb6a9dad43b095..a2f0cfd7044fabc3439920bd9ecb9c85d92d12d0 100644 (file)
 ;; 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.
        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
index 992c465ce10a69f2dba5b30fbce5534da8da368a..93a9d829187a16142337c526cb63bf7497fac793 100644 (file)
@@ -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
index 37035aad58fd662b9ec1e6fd537a42574f1c08ad..82b38a795ec115098ff1ef947a48a6715abb4d98 100644 (file)
@@ -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);
 }
 
index 6bf09aa14a9aad619d80f6a7092e8252ffed36e4..41d50d4755fbb20374eded947ef1a6bc6d120187 100644 (file)
--- 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);
index 00a996e469610781a859e0b3b357a8b2aa88e7bc..cf9fd1d65af381f1fec829011ca11c0256a6842b 100644 (file)
@@ -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;
 }
 \f
+/* 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;
+}
+\f
 /* 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.  */