]> gcc.gnu.org Git - gcc.git/commitdiff
Improve TI mode address offsets - these may either use LDP of 64-bit or LDR of 128...
authorWilco Dijkstra <wdijkstr@arm.com>
Wed, 7 Dec 2016 14:44:45 +0000 (14:44 +0000)
committerWilco Dijkstra <wilco@gcc.gnu.org>
Wed, 7 Dec 2016 14:44:45 +0000 (14:44 +0000)
Improve TI mode address offsets - these may either use LDP of 64-bit or
LDR of 128-bit, so we need to use the correct intersection of offsets.
When splitting a large offset into base and offset, use a signed 9-bit
unscaled offset.

Remove the Ump constraint on movti and movtf instructions as this blocks
the reload optimizer from merging address CSEs (is this supposed to work
only on 'm' constraints?).  The result is improved codesize, especially
wrf and gamess in SPEC2006.

    gcc/
* config/aarch64/aarch64.md (movti_aarch64): Change Ump to m.
(movtf_aarch64): Likewise.
* config/aarch64/aarch64.c (aarch64_classify_address):
Use correct intersection of offsets.
(aarch64_legitimize_address_displacement): Use 9-bit signed offsets.
(aarch64_legitimize_address): Use 9-bit signed offsets for TI/TF mode.
Use 7-bit signed scaled mode for modes > 16 bytes.

From-SVN: r243346

gcc/ChangeLog
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.md

index fbe5bbedc954dc5ad770729e4f849175cdc6f2d7..c1b8784ce9d0639b9a11468fc31a905e6370fa8a 100644 (file)
@@ -1,3 +1,13 @@
+2016-12-07  Wilco Dijkstra  <wdijkstr@arm.com>
+
+       * config/aarch64/aarch64.md (movti_aarch64): Change Ump to m.
+       (movtf_aarch64): Likewise.
+       * config/aarch64/aarch64.c (aarch64_classify_address):
+       Use correct intersection of offsets.
+       (aarch64_legitimize_address_displacement): Use 9-bit signed offsets.
+       (aarch64_legitimize_address): Use 9-bit signed offsets for TI/TF mode.
+       Use 7-bit signed scaled mode for modes > 16 bytes.
+
 2016-12-07  James Greenhalgh  <james.greenhalgh@arm.com>
 
        PR rtl-optimization/78561
index dab46b59693dea3f08637792f5bf0d01c2a6d593..128f32bda238488d8ccac9d105802d9be69c48db 100644 (file)
@@ -4330,7 +4330,8 @@ aarch64_classify_address (struct aarch64_address_info *info,
             instruction memory accesses.  */
          if (mode == TImode || mode == TFmode)
            return (aarch64_offset_7bit_signed_scaled_p (DImode, offset)
-                   && offset_9bit_signed_unscaled_p (mode, offset));
+                   && (offset_9bit_signed_unscaled_p (mode, offset)
+                       || offset_12bit_unsigned_scaled_p (mode, offset)));
 
          /* A 7bit offset check because OImode will emit a ldp/stp
             instruction (only big endian will get here).
@@ -4534,18 +4535,19 @@ aarch64_legitimate_address_p (machine_mode mode, rtx x,
 /* Split an out-of-range address displacement into a base and offset.
    Use 4KB range for 1- and 2-byte accesses and a 16KB range otherwise
    to increase opportunities for sharing the base address of different sizes.
-   For TI/TFmode and unaligned accesses use a 256-byte range.  */
+   For unaligned accesses and TI/TF mode use the signed 9-bit range.  */
 static bool
 aarch64_legitimize_address_displacement (rtx *disp, rtx *off, machine_mode mode)
 {
-  HOST_WIDE_INT mask = GET_MODE_SIZE (mode) < 4 ? 0xfff : 0x3fff;
+  HOST_WIDE_INT offset = INTVAL (*disp);
+  HOST_WIDE_INT base = offset & ~(GET_MODE_SIZE (mode) < 4 ? 0xfff : 0x3ffc);
 
-  if (mode == TImode || mode == TFmode ||
-      (INTVAL (*disp) & (GET_MODE_SIZE (mode) - 1)) != 0)
-    mask = 0xff;
+  if (mode == TImode || mode == TFmode
+      || (offset & (GET_MODE_SIZE (mode) - 1)) != 0)
+    base = (offset + 0x100) & ~0x1ff;
 
-  *off = GEN_INT (INTVAL (*disp) & ~mask);
-  *disp = GEN_INT (INTVAL (*disp) & mask);
+  *off = GEN_INT (base);
+  *disp = GEN_INT (offset - base);
   return true;
 }
 
@@ -5412,12 +5414,10 @@ aarch64_legitimize_address (rtx x, rtx /* orig_x  */, machine_mode mode)
          x = gen_rtx_PLUS (Pmode, base, offset_rtx);
        }
 
-      /* Does it look like we'll need a load/store-pair operation?  */
+      /* Does it look like we'll need a 16-byte load/store-pair operation?  */
       HOST_WIDE_INT base_offset;
-      if (GET_MODE_SIZE (mode) > 16
-         || mode == TImode)
-       base_offset = ((offset + 64 * GET_MODE_SIZE (mode))
-                      & ~((128 * GET_MODE_SIZE (mode)) - 1));
+      if (GET_MODE_SIZE (mode) > 16)
+       base_offset = (offset + 0x400) & ~0x7f0;
       /* For offsets aren't a multiple of the access size, the limit is
         -256...255.  */
       else if (offset & (GET_MODE_SIZE (mode) - 1))
@@ -5431,6 +5431,8 @@ aarch64_legitimize_address (rtx x, rtx /* orig_x  */, machine_mode mode)
       /* Small negative offsets are supported.  */
       else if (IN_RANGE (offset, -256, 0))
        base_offset = 0;
+      else if (mode == TImode || mode == TFmode)
+       base_offset = (offset + 0x100) & ~0x1ff;
       /* Use 12-bit offset by access size.  */
       else
        base_offset = offset & (~0xfff * GET_MODE_SIZE (mode));
index 1e6b6f5ba7cd20778cb9550f58d4771970a59a6d..811a0785e7df1b89bde785f1541e73842b38ee6c 100644 (file)
 
 (define_insn "*movti_aarch64"
   [(set (match_operand:TI 0
-        "nonimmediate_operand"  "=r, *w,r ,*w,r  ,Ump,Ump,*w,m")
+        "nonimmediate_operand"  "=r, *w,r ,*w,r,m,m,*w,m")
        (match_operand:TI 1
-        "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r  ,Z  , m,*w"))]
+        "aarch64_movti_operand" " rn,r ,*w,*w,m,r,Z, m,*w"))]
   "(register_operand (operands[0], TImode)
     || aarch64_reg_or_zero (operands[1], TImode))"
   "@
 
 (define_insn "*movtf_aarch64"
   [(set (match_operand:TF 0
-        "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump,Ump")
+        "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r,m ,m")
        (match_operand:TF 1
-        "general_operand"      " w,?r, ?r,w ,Y,Y ,m,w,Ump,?r ,Y"))]
+        "general_operand"      " w,?r, ?r,w ,Y,Y ,m,w,m ,?r,Y"))]
   "TARGET_FLOAT && (register_operand (operands[0], TFmode)
     || aarch64_reg_or_fp_zero (operands[1], TFmode))"
   "@
This page took 0.118694 seconds and 5 git commands to generate.