aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJames Greenhalgh <james.greenhalgh@arm.com>2014-04-28 21:00:38 +0000
committerJames Greenhalgh <jgreenhalgh@gcc.gnu.org>2014-04-28 21:00:38 +0000
commit97e1ad78bcc2a33954e40534ccbee78ba6bdcf7c (patch)
treeeac247494ab9f73ef2bde86ee52e68e7996a35d8 /gcc
parentbf245bf4848da017739e3298121f7482c6dd2ab0 (diff)
downloadgcc-97e1ad78bcc2a33954e40534ccbee78ba6bdcf7c.zip
gcc-97e1ad78bcc2a33954e40534ccbee78ba6bdcf7c.tar.gz
gcc-97e1ad78bcc2a33954e40534ccbee78ba6bdcf7c.tar.bz2
[AArch64] Relax modes_tieable_p and cannot_change_mode_class
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/aarch64/aarch64-protos.h2
-rw-r--r--gcc/config/aarch64/aarch64.c33
-rw-r--r--gcc/config/aarch64/aarch64.h3
4 files changed, 43 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index e5f77ca..e2adf93 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 5542f02..04cbc78 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -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);
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 2bb4310..94e05bb 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -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
diff --git a/gcc/config/aarch64/aarch64.h b/gcc/config/aarch64/aarch64.h
index e2b6c8e..c9b30d0 100644
--- a/gcc/config/aarch64/aarch64.h
+++ b/gcc/config/aarch64/aarch64.h
@@ -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