aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <richard@codesourcery.com>2007-07-18 09:44:21 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2007-07-18 09:44:21 +0000
commit8426b956021a24315114670483f2aa5d230fde5c (patch)
treef265953e69b78d5f07f6dcd4e973c24c2e324993 /gcc
parent12b36be2c05306f295304061bb199209274cd917 (diff)
downloadgcc-8426b956021a24315114670483f2aa5d230fde5c.zip
gcc-8426b956021a24315114670483f2aa5d230fde5c.tar.gz
gcc-8426b956021a24315114670483f2aa5d230fde5c.tar.bz2
arm-protos.h (arm_cannot_force_const_mem): Declare.
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/config/arm/arm-protos.h1
-rw-r--r--gcc/config/arm/arm.c19
-rw-r--r--gcc/config/arm/arm.h6
-rw-r--r--gcc/config/arm/arm.md15
-rw-r--r--gcc/config/arm/vxworks.h8
6 files changed, 60 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index a6abc7a..6ef674d 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,18 @@
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.
2007-07-18 Richard Sandiford <richard@codesourcery.com>
diff --git a/gcc/config/arm/arm-protos.h b/gcc/config/arm/arm-protos.h
index 3f928b8..98cb5ef 100644
--- a/gcc/config/arm/arm-protos.h
+++ b/gcc/config/arm/arm-protos.h
@@ -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);
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 5569d4a..36fba5b 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -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);
+}
#define REG_OR_SUBREG_REG(X) \
(GET_CODE (X) == REG \
diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h
index 8aa88ab..b9c6e85 100644
--- a/gcc/config/arm/arm.h
+++ b/gcc/config/arm/arm.h
@@ -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)))
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 3a90b0a..661ab04 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -4649,6 +4649,8 @@
(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. */
@@ -4674,6 +4676,19 @@
}
}
+ 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]))
diff --git a/gcc/config/arm/vxworks.h b/gcc/config/arm/vxworks.h
index 58fea14..fb6c79b 100644
--- a/gcc/config/arm/vxworks.h
+++ b/gcc/config/arm/vxworks.h
@@ -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