2014-12-04 Yvan Roux <yvan.roux@linaro.org>
authoryroux <yroux@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 4 Dec 2014 14:57:02 +0000 (14:57 +0000)
committerDongkyun, Son <dongkyun.s@samsung.com>
Sat, 6 Jun 2015 14:26:54 +0000 (23:26 +0900)
Backport from trunk r216336.
2014-10-16  Richard Earnshaw  <rearnsha@arm.com>

* config/aarch64/aarch64.c (aarch64_legitimize_address): New function.
(TARGET_LEGITIMIZE_ADDRESS): Redefine.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/linaro/gcc-4_9-branch@218375 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog.linaro
gcc/config/aarch64/aarch64.c

index 4dcc60f..f5440eb 100644 (file)
@@ -1,5 +1,13 @@
 2014-12-04  Yvan Roux  <yvan.roux@linaro.org>
 
+       Backport from trunk r216336.
+       2014-10-16  Richard Earnshaw  <rearnsha@arm.com>
+
+       * config/aarch64/aarch64.c (aarch64_legitimize_address): New function.
+       (TARGET_LEGITIMIZE_ADDRESS): Redefine.
+
+2014-12-04  Yvan Roux  <yvan.roux@linaro.org>
+
        Backport from trunk r216253.
        2014-10-15  Renlin Li <renlin.li@arm.com>
 
index c481350..0ead2b5 100644 (file)
@@ -4135,6 +4135,47 @@ aarch64_regno_regclass (unsigned regno)
   return NO_REGS;
 }
 
+static rtx
+aarch64_legitimize_address (rtx x, rtx /* orig_x  */, enum machine_mode mode)
+{
+  /* Try to split X+CONST into Y=X+(CONST & ~mask), Y+(CONST&mask),
+     where mask is selected by alignment and size of the offset.
+     We try to pick as large a range for the offset as possible to
+     maximize the chance of a CSE.  However, for aligned addresses
+     we limit the range to 4k so that structures with different sized
+     elements are likely to use the same base.  */
+
+  if (GET_CODE (x) == PLUS && CONST_INT_P (XEXP (x, 1)))
+    {
+      HOST_WIDE_INT offset = INTVAL (XEXP (x, 1));
+      HOST_WIDE_INT base_offset;
+
+      /* Does it look like we'll need a load/store-pair operation?  */
+      if (GET_MODE_SIZE (mode) > 16
+         || mode == TImode)
+       base_offset = ((offset + 64 * GET_MODE_SIZE (mode))
+                      & ~((128 * GET_MODE_SIZE (mode)) - 1));
+      /* For offsets aren't a multiple of the access size, the limit is
+        -256...255.  */
+      else if (offset & (GET_MODE_SIZE (mode) - 1))
+       base_offset = (offset + 0x100) & ~0x1ff;
+      else
+       base_offset = offset & ~0xfff;
+
+      if (base_offset == 0)
+       return x;
+
+      offset -= base_offset;
+      rtx base_reg = gen_reg_rtx (Pmode);
+      rtx val = force_operand (plus_constant (Pmode, XEXP (x, 0), base_offset),
+                          NULL_RTX);
+      emit_move_insn (base_reg, val);
+      x = plus_constant (Pmode, base_reg, offset);
+    }
+
+  return x;
+}
+
 /* Try a machine-dependent way of reloading an illegitimate address
    operand.  If we find one, push the reload and return the new rtx.  */
 
@@ -10119,6 +10160,9 @@ aarch64_expand_movmem (rtx *operands)
 #undef TARGET_FLAGS_REGNUM
 #define TARGET_FLAGS_REGNUM CC_REGNUM
 
+#undef TARGET_LEGITIMIZE_ADDRESS
+#define TARGET_LEGITIMIZE_ADDRESS aarch64_legitimize_address
+
 struct gcc_target targetm = TARGET_INITIALIZER;
 
 #include "gt-aarch64.h"