diff options
author | James Greenhalgh <james.greenhalgh@arm.com> | 2014-04-28 21:00:38 +0000 |
---|---|---|
committer | James Greenhalgh <jgreenhalgh@gcc.gnu.org> | 2014-04-28 21:00:38 +0000 |
commit | 97e1ad78bcc2a33954e40534ccbee78ba6bdcf7c (patch) | |
tree | eac247494ab9f73ef2bde86ee52e68e7996a35d8 /gcc | |
parent | bf245bf4848da017739e3298121f7482c6dd2ab0 (diff) | |
download | gcc-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/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.c | 33 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.h | 3 |
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 |