]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
[AArch64] Relax modes_tieable_p and cannot_change_mode_class
authorJames Greenhalgh <james.greenhalgh@arm.com>
Mon, 28 Apr 2014 21:00:38 +0000 (21:00 +0000)
committerJames Greenhalgh <jgreenhalgh@gcc.gnu.org>
Mon, 28 Apr 2014 21:00:38 +0000 (21:00 +0000)
gcc/

* config/aarch64/aarch64-protos.h (aarch64_modes_tieable_p): New.
* config/aarch64/aarch64.c
(aarch64_cannot_change_mode_class): Weaken conditions.
(aarch64_modes_tieable_p): New.
* config/aarch64/aarch64.h (MODES_TIEABLE_P): Use it.

From-SVN: r209878

gcc/ChangeLog
gcc/config/aarch64/aarch64-protos.h
gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.h

index e5f77cac18caf3e3f55ffb1f9f6921d5378ec7f0..e2adf936e437d57b09325b40c266b49d00a974d4 100644 (file)
@@ -1,3 +1,11 @@
+2014-04-28  James Greenhalgh  <james.greenhalgh@arm.com>
+
+       * config/aarch64/aarch64-protos.h (aarch64_modes_tieable_p): New.
+       * config/aarch64/aarch64.c
+       (aarch64_cannot_change_mode_class): Weaken conditions.
+       (aarch64_modes_tieable_p): New.
+       * config/aarch64/aarch64.h (MODES_TIEABLE_P): Use it.
+
 2014-04-28  Pat Haugen  <pthaugen@us.ibm.com>
 
        * config/rs6000/sync.md (AINT mode_iterator): Move definition.
index 5542f023b33d9467daa63d33185d414e89e57d2e..04cbc780da2c34acbf4763193923ddaf1dda6ac9 100644 (file)
@@ -175,6 +175,8 @@ bool aarch64_is_extend_from_extract (enum machine_mode, rtx, rtx);
 bool aarch64_is_long_call_p (rtx);
 bool aarch64_label_mentioned_p (rtx);
 bool aarch64_legitimate_pic_operand_p (rtx);
+bool aarch64_modes_tieable_p (enum machine_mode mode1,
+                             enum machine_mode mode2);
 bool aarch64_move_imm (HOST_WIDE_INT, enum machine_mode);
 bool aarch64_mov_operand_p (rtx, enum aarch64_symbol_context,
                            enum machine_mode);
index 2bb43109e736df64e45ecac8d6f5f0a32e47bf83..94e05bb5e3ff3182ee392adb0ff22dd8dc0cf7f9 100644 (file)
@@ -8316,7 +8316,8 @@ aarch64_cannot_change_mode_class (enum machine_mode from,
   /* Limited combinations of subregs are safe on FPREGs.  Particularly,
      1. Vector Mode to Scalar mode where 1 unit of the vector is accessed.
      2. Scalar to Scalar for integer modes or same size float modes.
-     3. Vector to Vector modes.  */
+     3. Vector to Vector modes.
+     4. On little-endian only, Vector-Structure to Vector modes.  */
   if (GET_MODE_SIZE (from) > GET_MODE_SIZE (to))
     {
       if (aarch64_vector_mode_supported_p (from)
@@ -8332,11 +8333,41 @@ aarch64_cannot_change_mode_class (enum machine_mode from,
       if (aarch64_vector_mode_supported_p (from)
          && aarch64_vector_mode_supported_p (to))
        return false;
+
+      /* Within an vector structure straddling multiple vector registers
+        we are in a mixed-endian representation.  As such, we can't
+        easily change modes for BYTES_BIG_ENDIAN.  Otherwise, we can
+        switch between vectors and vector structures cheaply.  */
+      if (!BYTES_BIG_ENDIAN)
+       if ((aarch64_vector_mode_supported_p (from)
+             && aarch64_vect_struct_mode_p (to))
+           || (aarch64_vector_mode_supported_p (to)
+             && aarch64_vect_struct_mode_p (from)))
+         return false;
     }
 
   return true;
 }
 
+/* Implement MODES_TIEABLE_P.  */
+
+bool
+aarch64_modes_tieable_p (enum machine_mode mode1, enum machine_mode mode2)
+{
+  if (GET_MODE_CLASS (mode1) == GET_MODE_CLASS (mode2))
+    return true;
+
+  /* We specifically want to allow elements of "structure" modes to
+     be tieable to the structure.  This more general condition allows
+     other rarer situations too.  */
+  if (TARGET_SIMD
+      && aarch64_vector_mode_p (mode1)
+      && aarch64_vector_mode_p (mode2))
+    return true;
+
+  return false;
+}
+
 #undef TARGET_ADDRESS_COST
 #define TARGET_ADDRESS_COST aarch64_address_cost
 
index e2b6c8e2908fc94001b5abe93ba75c95bd9fcf75..c9b30d0186563fc669333836bc4c84d2058ae75c 100644 (file)
@@ -365,8 +365,7 @@ extern unsigned long aarch64_tune_flags;
 
 #define HARD_REGNO_MODE_OK(REGNO, MODE)        aarch64_hard_regno_mode_ok (REGNO, MODE)
 
-#define MODES_TIEABLE_P(MODE1, MODE2)                  \
-  (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2))
+#define MODES_TIEABLE_P(MODE1, MODE2) aarch64_modes_tieable_p (MODE1, MODE2)
 
 #define DWARF2_UNWIND_INFO 1