OSDN Git Service

* config/arm/arm.c (arm_legitimize_address): Split absolute addresses
authornico <nico@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 1 Sep 2005 19:01:20 +0000 (19:01 +0000)
committernico <nico@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 1 Sep 2005 19:01:20 +0000 (19:01 +0000)
to alow matching ARM pre-indexed addressing mode.
(arm_override_options): Remove now irrelevant comment.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@103742 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/arm/arm.c

index ef2be93..5c8abe5 100644 (file)
@@ -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.
index 9037838..128edb6 100644 (file)
@@ -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