aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNicolas Pitre <nico@cam.org>2005-09-01 19:01:20 +0000
committerNicolas Pitre <nico@gcc.gnu.org>2005-09-01 19:01:20 +0000
commit868057591bdfd7240ad49c388933e04e67b938cd (patch)
tree3ed7820625fdf8f37679f4b8e034f9c1d176c700 /gcc
parentd442d7d9dd849cf41b0a287662dfa8384a5fa8fb (diff)
downloadgcc-868057591bdfd7240ad49c388933e04e67b938cd.zip
gcc-868057591bdfd7240ad49c388933e04e67b938cd.tar.gz
gcc-868057591bdfd7240ad49c388933e04e67b938cd.tar.bz2
arm.c (arm_legitimize_address): Split absolute addresses to alow matching ARM pre-indexed addressing mode.
* config/arm/arm.c (arm_legitimize_address): Split absolute addresses to alow matching ARM pre-indexed addressing mode. (arm_override_options): Remove now irrelevant comment. From-SVN: r103742
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/arm/arm.c32
2 files changed, 34 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ef2be93..5c8abe5 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2005-09-01 Nicolas Pitre <nico@cam.org>
+
+ * config/arm/arm.c (arm_legitimize_address): Split absolute addresses
+ to alow matching ARM pre-indexed addressing mode.
+ (arm_override_options): Remove now irrelevant comment.
+
2005-09-01 Phil Edwards <phil@codesourcery.com>
* config.gcc (i*86-wrs-vxworks): Update. Split out vxworksae target.
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 9037838..128edb6 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -1234,10 +1234,6 @@ arm_override_options (void)
if (optimize_size)
{
- /* There's some dispute as to whether this should be 1 or 2. However,
- experiments seem to show that in pathological cases a setting of
- 1 degrades less severely than a setting of 2. This could change if
- other parts of the compiler change their behavior. */
arm_constant_limit = 1;
/* If optimizing for size, bump the number of instructions that we
@@ -3759,6 +3755,34 @@ arm_legitimize_address (rtx x, rtx orig_x, enum machine_mode mode)
x = gen_rtx_MINUS (SImode, xop0, xop1);
}
+ /* Make sure to take full advantage of the pre-indexed addressing mode
+ with absolute addresses which often allows for the base register to
+ be factorized for multiple adjacent memory references, and it might
+ even allows for the mini pool to be avoided entirely. */
+ else if (GET_CODE (x) == CONST_INT && optimize > 0)
+ {
+ unsigned int bits;
+ HOST_WIDE_INT mask, base, index;
+ rtx base_reg;
+
+ /* ldr and ldrb can use a 12 bit index, ldrsb and the rest can only
+ use a 8 bit index. So let's use a 12 bit index for SImode only and
+ hope that arm_gen_constant will enable ldrb to use more bits. */
+ bits = (mode == SImode) ? 12 : 8;
+ mask = (1 << bits) - 1;
+ base = INTVAL (x) & ~mask;
+ index = INTVAL (x) & mask;
+ if (bit_count (base) > (32 - bits)/2)
+ {
+ /* It'll most probably be more efficient to generate the base
+ with more bits set and use a negative index instead. */
+ base |= mask;
+ index -= mask;
+ }
+ base_reg = force_reg (SImode, GEN_INT (base));
+ x = gen_rtx_PLUS (SImode, base_reg, GEN_INT (index));
+ }
+
if (flag_pic)
{
/* We need to find and carefully transform any SYMBOL and LABEL