aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTejas Belagod <tejas.belagod@arm.com>2014-01-20 12:34:13 +0000
committerTejas Belagod <belagod@gcc.gnu.org>2014-01-20 12:34:13 +0000
commit69675d50f68e63d603b33d0d225686d136546a09 (patch)
tree470dd9a2241c08e0ab9949c6a9eabf5db74ab79d
parentffee7aa91a16a2a037aee7f96dd635df18cd7109 (diff)
downloadgcc-69675d50f68e63d603b33d0d225686d136546a09.zip
gcc-69675d50f68e63d603b33d0d225686d136546a09.tar.gz
gcc-69675d50f68e63d603b33d0d225686d136546a09.tar.bz2
[AArch64] Relax CANNOT_CHANGE_MODE_CLASS
gcc/ * config/aarch64/aarch64-protos.h (aarch64_cannot_change_mode_class_ptr): Declare. * config/aarch64/aarch64.c (aarch64_cannot_change_mode_class, aarch64_cannot_change_mode_class_ptr): New. * config/aarch64/aarch64.h (CANNOT_CHANGE_MODE_CLASS): Change to call backend hook aarch64_cannot_change_mode_class. From-SVN: r206804
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/aarch64/aarch64-protos.h3
-rw-r--r--gcc/config/aarch64/aarch64.c36
-rw-r--r--gcc/config/aarch64/aarch64.h7
4 files changed, 49 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f3e09e8..de8322b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2014-01-20 Tejas Belagod <tejas.belagod@arm.com>
+
+ * config/aarch64/aarch64-protos.h
+ (aarch64_cannot_change_mode_class_ptr): Declare.
+ * config/aarch64/aarch64.c (aarch64_cannot_change_mode_class,
+ aarch64_cannot_change_mode_class_ptr): New.
+ * config/aarch64/aarch64.h (CANNOT_CHANGE_MODE_CLASS): Change to call
+ backend hook aarch64_cannot_change_mode_class.
+
2014-01-20 James Greenhalgh <james.greenhalgh@arm.com>
* common/config/aarch64/aarch64-common.c
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index c5ac48b..5542f02 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -161,6 +161,9 @@ struct tune_params
HOST_WIDE_INT aarch64_initial_elimination_offset (unsigned, unsigned);
bool aarch64_bitmask_imm (HOST_WIDE_INT val, enum machine_mode);
+bool aarch64_cannot_change_mode_class (enum machine_mode,
+ enum machine_mode,
+ enum reg_class);
enum aarch64_symbol_type
aarch64_classify_symbolic_expression (rtx, enum aarch64_symbol_context);
bool aarch64_constant_address_p (rtx);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 7091d3e..57b6645 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -8259,6 +8259,42 @@ aarch64_vectorize_vec_perm_const_ok (enum machine_mode vmode,
return ret;
}
+/* Implement target hook CANNOT_CHANGE_MODE_CLASS. */
+bool
+aarch64_cannot_change_mode_class (enum machine_mode from,
+ enum machine_mode to,
+ enum reg_class rclass)
+{
+ /* Full-reg subregs are allowed on general regs or any class if they are
+ the same size. */
+ if (GET_MODE_SIZE (from) == GET_MODE_SIZE (to)
+ || !reg_classes_intersect_p (FP_REGS, rclass))
+ return false;
+
+ /* 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. */
+ if (GET_MODE_SIZE (from) > GET_MODE_SIZE (to))
+ {
+ if (aarch64_vector_mode_supported_p (from)
+ && GET_MODE_SIZE (GET_MODE_INNER (from)) == GET_MODE_SIZE (to))
+ return false;
+
+ if (GET_MODE_NUNITS (from) == 1
+ && GET_MODE_NUNITS (to) == 1
+ && (GET_MODE_CLASS (from) == MODE_INT
+ || from == to))
+ return false;
+
+ if (aarch64_vector_mode_supported_p (from)
+ && aarch64_vector_mode_supported_p (to))
+ return false;
+ }
+
+ return true;
+}
+
#undef TARGET_ADDRESS_COST
#define TARGET_ADDRESS_COST aarch64_address_cost
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index 4aa1bfd..a08dee0 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -822,13 +822,8 @@ do { \
extern void __aarch64_sync_cache_range (void *, void *); \
__aarch64_sync_cache_range (beg, end)
-/* VFP registers may only be accessed in the mode they
- were set. */
#define CANNOT_CHANGE_MODE_CLASS(FROM, TO, CLASS) \
- (GET_MODE_SIZE (FROM) != GET_MODE_SIZE (TO) \
- ? reg_classes_intersect_p (FP_REGS, (CLASS)) \
- : 0)
-
+ aarch64_cannot_change_mode_class (FROM, TO, CLASS)
#define SHIFT_COUNT_TRUNCATED !TARGET_SIMD