diff options
author | Richard Sandiford <richard@codesourcery.com> | 2007-07-18 09:44:21 +0000 |
---|---|---|
committer | Richard Sandiford <rsandifo@gcc.gnu.org> | 2007-07-18 09:44:21 +0000 |
commit | 8426b956021a24315114670483f2aa5d230fde5c (patch) | |
tree | f265953e69b78d5f07f6dcd4e973c24c2e324993 /gcc | |
parent | 12b36be2c05306f295304061bb199209274cd917 (diff) | |
download | gcc-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/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/config/arm/arm-protos.h | 1 | ||||
-rw-r--r-- | gcc/config/arm/arm.c | 19 | ||||
-rw-r--r-- | gcc/config/arm/arm.h | 6 | ||||
-rw-r--r-- | gcc/config/arm/arm.md | 15 | ||||
-rw-r--r-- | gcc/config/arm/vxworks.h | 8 |
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 |