]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
arm-protos.h (arm_cannot_force_const_mem): Declare.
authorRichard Sandiford <richard@codesourcery.com>
Wed, 18 Jul 2007 09:44:21 +0000 (09:44 +0000)
committerRichard Sandiford <rsandifo@gcc.gnu.org>
Wed, 18 Jul 2007 09:44:21 +0000 (09:44 +0000)
gcc/
* config/arm/arm-protos.h (arm_cannot_force_const_mem): Declare.
* config/arm/arm.c (TARGET_CANNOT_FORCE_CONST_MEM): Redefine to
arm_cannot_force_const_mem.
(arm_cannot_force_const_mem): New function.
* config/arm/arm.h (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P): New macro.
(LEGITIMATE_CONSTANT_P): Test arm_cannot_force_const_mem instead
of arm_tls_referenced_p.
* config/arm/arm.md (movsi): Split out-of-section constants when
ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P.
* config/arm/vxworks.h (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P): Define.

From-SVN: r126718

gcc/ChangeLog
gcc/config/arm/arm-protos.h
gcc/config/arm/arm.c
gcc/config/arm/arm.h
gcc/config/arm/arm.md
gcc/config/arm/vxworks.h

index a6abc7a30fe53b4a5804e8d75bb7d1d10f52895e..6ef674d9ecd95a7f0493927a53b98a2b7151b8c7 100644 (file)
@@ -1,3 +1,16 @@
+2007-07-18  Richard Sandiford  <richard@codesourcery.com>
+
+       * config/arm/arm-protos.h (arm_cannot_force_const_mem): Declare.
+       * config/arm/arm.c (TARGET_CANNOT_FORCE_CONST_MEM): Redefine to
+       arm_cannot_force_const_mem.
+       (arm_cannot_force_const_mem): New function.
+       * config/arm/arm.h (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P): New macro.
+       (LEGITIMATE_CONSTANT_P): Test arm_cannot_force_const_mem instead
+       of arm_tls_referenced_p.
+       * config/arm/arm.md (movsi): Split out-of-section constants when
+       ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P.
+       * config/arm/vxworks.h (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P): Define.
+
 2007-07-18  Richard Sandiford  <richard@codesourcery.com>
 
        * config/mips/mips.md (clear_cache): Treat the size argument as Pmode.
index 3f928b853a8f09bcef1a43572a50176f563880ce..98cb5ef2d0c54f25bc402df086121830db634fca 100644 (file)
@@ -71,6 +71,7 @@ extern int vfp3_const_double_rtx (rtx);
 extern enum reg_class coproc_secondary_reload_class (enum machine_mode, rtx,
                                                     bool);
 extern bool arm_tls_referenced_p (rtx);
+extern bool arm_cannot_force_const_mem (rtx);
 
 extern int cirrus_memory_offset (rtx);
 extern int arm_coproc_mem_operand (rtx, bool);
index 5569d4a615b742fcc6f15bfdb0f7059cbde23de8..36fba5b9cf0fe87a2070b6a2e7596924f26c99cd 100644 (file)
@@ -380,7 +380,7 @@ static void arm_output_dwarf_dtprel (FILE *, int, rtx) ATTRIBUTE_UNUSED;
 #endif
 
 #undef TARGET_CANNOT_FORCE_CONST_MEM
-#define TARGET_CANNOT_FORCE_CONST_MEM arm_tls_referenced_p
+#define TARGET_CANNOT_FORCE_CONST_MEM arm_cannot_force_const_mem
 
 #ifdef HAVE_AS_TLS
 #undef TARGET_ASM_OUTPUT_DWARF_DTPREL
@@ -4672,6 +4672,23 @@ arm_tls_referenced_p (rtx x)
 
   return for_each_rtx (&x, arm_tls_operand_p_1, NULL);
 }
+
+/* Implement TARGET_CANNOT_FORCE_CONST_MEM.  */
+
+bool
+arm_cannot_force_const_mem (rtx x)
+{
+  rtx base, offset;
+
+  if (ARM_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 arm_tls_referenced_p (x);
+}
 \f
 #define REG_OR_SUBREG_REG(X)                                           \
   (GET_CODE (X) == REG                                                 \
index 8aa88ab35a232fe75012311eab21cfc7ccf4c545..b9c6e851f135ca107068746d61bcb4b742687ff0 100644 (file)
@@ -1888,6 +1888,10 @@ typedef struct
 
 #endif /* AOF_ASSEMBLER */
 
+/* True if SYMBOL + OFFSET constants must refer to something within
+   SYMBOL's section.  */
+#define ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P 0
+
 /* Nonzero if the constant value X is a legitimate general operand.
    It is given that X satisfies CONSTANT_P or is a CONST_DOUBLE.
 
@@ -1905,7 +1909,7 @@ typedef struct
   || flag_pic)
 
 #define LEGITIMATE_CONSTANT_P(X)                       \
-  (!arm_tls_referenced_p (X)                           \
+  (!arm_cannot_force_const_mem (X)                     \
    && (TARGET_32BIT ? ARM_LEGITIMATE_CONSTANT_P (X)    \
                    : THUMB_LEGITIMATE_CONSTANT_P (X)))
 
index 3a90b0a110c9d167c8a3f52518658221277002b0..661ab044c026124561b541bc411e0c9ac15b3268 100644 (file)
         (match_operand:SI 1 "general_operand" ""))]
   "TARGET_EITHER"
   "
+  rtx base, offset, tmp;
+
   if (TARGET_32BIT)
     {
       /* Everything except mem = const or mem = mem can be done easily.  */
         }
     }
 
+  if (ARM_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;
+       }
+    }
+
   /* Recognize the case where operand[1] is a reference to thread-local
      data and load its address to a register.  */
   if (arm_tls_referenced_p (operands[1]))
index 58fea14f9854827e62aeef7d3d1135d907d5af8d..fb6c79b03319196818be2617d67960b323242352 100644 (file)
@@ -106,3 +106,11 @@ Boston, MA 02110-1301, USA.  */
    the past before this macro was changed.  */
 #undef DEFAULT_STRUCTURE_SIZE_BOUNDARY
 #define DEFAULT_STRUCTURE_SIZE_BOUNDARY 8
+
+/* The kernel loader does not allow relocations to overflow, so we
+   cannot allow arbitrary relocation addends in kernel modules or RTP
+   executables.  Also, the dynamic loader uses the resolved relocation
+   value to distinguish references to the text and data segments, so we
+   cannot allow arbitrary offsets for shared libraries either.  */
+#undef ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P
+#define ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P 1