aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSofiane Naci <sofiane.naci@arm.com>2013-05-09 08:25:30 +0000
committerSofiane Naci <sofiane@gcc.gnu.org>2013-05-09 08:25:30 +0000
commit12dc6974799424cb128bd3c25d2bcb1d9f5492c7 (patch)
treeeb7af063206d6704bc35474b92d1c2ee9eb20cf1
parent227eb3436021c366d97c34f0bd6ad8de7a854b63 (diff)
downloadgcc-12dc6974799424cb128bd3c25d2bcb1d9f5492c7.zip
gcc-12dc6974799424cb128bd3c25d2bcb1d9f5492c7.tar.gz
gcc-12dc6974799424cb128bd3c25d2bcb1d9f5492c7.tar.bz2
aarch64.md: New movtf split.
* config/aarch64/aarch64.md: New movtf split. (*movtf_aarch64): Update. (aarch64_movdi_tilow): Handle TF modes and rename to aarch64_movdi_<mode>low. (aarch64_movdi_tihigh): Handle TF modes and rename to aarch64_movdi_<mode>high (aarch64_movtihigh_di): Handle TF modes and rename to aarch64_mov<mode>high_di (aarch64_movtilow_di): Handle TF modes and rename to aarch64_mov<mode>low_di (aarch64_movtilow_tilow): Remove spurious whitespace. * config/aarch64/aarch64.c (aarch64_split_128bit_move): Handle TFmode splits. (aarch64_print_operand): Update. From-SVN: r198735
-rw-r--r--gcc/ChangeLog17
-rw-r--r--gcc/config/aarch64/aarch64.c114
-rw-r--r--gcc/config/aarch64/aarch64.md40
3 files changed, 106 insertions, 65 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1bd866d..4c04ea4 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,20 @@
+2013-05-09 Sofiane Naci <sofiane.naci@arm.com>
+
+ * config/aarch64/aarch64.md: New movtf split.
+ (*movtf_aarch64): Update.
+ (aarch64_movdi_tilow): Handle TF modes and rename to
+ aarch64_movdi_<mode>low.
+ (aarch64_movdi_tihigh): Handle TF modes and rename to
+ aarch64_movdi_<mode>high
+ (aarch64_movtihigh_di): Handle TF modes and rename to
+ aarch64_mov<mode>high_di
+ (aarch64_movtilow_di): Handle TF modes and rename to
+ aarch64_mov<mode>low_di
+ (aarch64_movtilow_tilow): Remove spurious whitespace.
+ * config/aarch64/aarch64.c (aarch64_split_128bit_move): Handle TFmode
+ splits.
+ (aarch64_print_operand): Update.
+
2013-05-09 Alan Modra <amodra@gmail.com>
* configure.ac (HAVE_AS_TLS): Enable tests for powerpcle and
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index d32563d..b57416c 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -604,49 +604,85 @@ aarch64_split_128bit_move (rtx dst, rtx src)
{
rtx low_dst;
- gcc_assert (GET_MODE (dst) == TImode);
+ enum machine_mode src_mode = GET_MODE (src);
+ enum machine_mode dst_mode = GET_MODE (dst);
+ int src_regno = REGNO (src);
+ int dst_regno = REGNO (dst);
+
+ gcc_assert (dst_mode == TImode || dst_mode == TFmode);
if (REG_P (dst) && REG_P (src))
{
- int src_regno = REGNO (src);
- int dst_regno = REGNO (dst);
-
- gcc_assert (GET_MODE (src) == TImode);
+ gcc_assert (src_mode == TImode || src_mode == TFmode);
/* Handle r -> w, w -> r. */
if (FP_REGNUM_P (dst_regno) && GP_REGNUM_P (src_regno))
{
- emit_insn (gen_aarch64_movtilow_di (dst,
- gen_lowpart (word_mode, src)));
- emit_insn (gen_aarch64_movtihigh_di (dst,
- gen_highpart (word_mode, src)));
- return;
+ switch (src_mode) {
+ case TImode:
+ emit_insn
+ (gen_aarch64_movtilow_di (dst, gen_lowpart (word_mode, src)));
+ emit_insn
+ (gen_aarch64_movtihigh_di (dst, gen_highpart (word_mode, src)));
+ return;
+ case TFmode:
+ emit_insn
+ (gen_aarch64_movtflow_di (dst, gen_lowpart (word_mode, src)));
+ emit_insn
+ (gen_aarch64_movtfhigh_di (dst, gen_highpart (word_mode, src)));
+ return;
+ default:
+ gcc_unreachable ();
+ }
}
else if (GP_REGNUM_P (dst_regno) && FP_REGNUM_P (src_regno))
{
- emit_insn (gen_aarch64_movdi_tilow (gen_lowpart (word_mode, dst),
- src));
- emit_insn (gen_aarch64_movdi_tihigh (gen_highpart (word_mode, dst),
- src));
- return;
+ switch (src_mode) {
+ case TImode:
+ emit_insn
+ (gen_aarch64_movdi_tilow (gen_lowpart (word_mode, dst), src));
+ emit_insn
+ (gen_aarch64_movdi_tihigh (gen_highpart (word_mode, dst), src));
+ return;
+ case TFmode:
+ emit_insn
+ (gen_aarch64_movdi_tflow (gen_lowpart (word_mode, dst), src));
+ emit_insn
+ (gen_aarch64_movdi_tfhigh (gen_highpart (word_mode, dst), src));
+ return;
+ default:
+ gcc_unreachable ();
+ }
}
/* Fall through to r -> r cases. */
}
- low_dst = gen_lowpart (word_mode, dst);
- if (REG_P (low_dst)
- && reg_overlap_mentioned_p (low_dst, src))
- {
- aarch64_emit_move (gen_highpart (word_mode, dst),
- gen_highpart_mode (word_mode, TImode, src));
- aarch64_emit_move (low_dst, gen_lowpart (word_mode, src));
- }
- else
- {
- aarch64_emit_move (low_dst, gen_lowpart (word_mode, src));
- aarch64_emit_move (gen_highpart (word_mode, dst),
- gen_highpart_mode (word_mode, TImode, src));
- }
+ switch (dst_mode) {
+ case TImode:
+ low_dst = gen_lowpart (word_mode, dst);
+ if (REG_P (low_dst)
+ && reg_overlap_mentioned_p (low_dst, src))
+ {
+ aarch64_emit_move (gen_highpart (word_mode, dst),
+ gen_highpart_mode (word_mode, TImode, src));
+ aarch64_emit_move (low_dst, gen_lowpart (word_mode, src));
+ }
+ else
+ {
+ aarch64_emit_move (low_dst, gen_lowpart (word_mode, src));
+ aarch64_emit_move (gen_highpart (word_mode, dst),
+ gen_highpart_mode (word_mode, TImode, src));
+ }
+ return;
+ case TFmode:
+ emit_move_insn (gen_rtx_REG (DFmode, dst_regno),
+ gen_rtx_REG (DFmode, src_regno));
+ emit_move_insn (gen_rtx_REG (DFmode, dst_regno + 1),
+ gen_rtx_REG (DFmode, src_regno + 1));
+ return;
+ default:
+ gcc_unreachable ();
+ }
}
bool
@@ -3324,26 +3360,6 @@ aarch64_print_operand (FILE *f, rtx x, char code)
asm_fprintf (f, "%s", reg_names [REGNO (x) + 1]);
break;
- case 'Q':
- /* Print the least significant register of a pair (TImode) of regs. */
- if (GET_CODE (x) != REG || !GP_REGNUM_P (REGNO (x) + 1))
- {
- output_operand_lossage ("invalid operand for '%%%c'", code);
- return;
- }
- asm_fprintf (f, "%s", reg_names [REGNO (x) + (WORDS_BIG_ENDIAN ? 1 : 0)]);
- break;
-
- case 'R':
- /* Print the most significant register of a pair (TImode) of regs. */
- if (GET_CODE (x) != REG || !GP_REGNUM_P (REGNO (x) + 1))
- {
- output_operand_lossage ("invalid operand for '%%%c'", code);
- return;
- }
- asm_fprintf (f, "%s", reg_names [REGNO (x) + (WORDS_BIG_ENDIAN ? 0 : 1)]);
- break;
-
case 'm':
/* Print a condition (eq, ne, etc). */
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index 797cc9b..b27bcda 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -997,9 +997,9 @@
|| register_operand (operands[1], TFmode))"
"@
orr\\t%0.16b, %1.16b, %1.16b
- mov\\t%0, %1\;mov\\t%H0, %H1
- fmov\\t%d0, %Q1\;fmov\\t%0.d[1], %R1
- fmov\\t%Q0, %d1\;fmov\\t%R0, %1.d[1]
+ #
+ #
+ #
movi\\t%0.2d, #0
fmov\\t%s0, wzr
ldr\\t%q0, %1
@@ -1013,6 +1013,17 @@
(set_attr "simd" "yes,*,*,*,yes,*,*,*,*,*")]
)
+(define_split
+ [(set (match_operand:TF 0 "register_operand" "")
+ (match_operand:TF 1 "aarch64_reg_or_imm" ""))]
+ "reload_completed && aarch64_split_128bit_move_p (operands[0], operands[1])"
+ [(const_int 0)]
+ {
+ aarch64_split_128bit_move (operands[0], operands[1]);
+ DONE;
+ }
+)
+
;; Operands 1 and 3 are tied together by the final condition; so we allow
;; fairly lax checking on the second memory operation.
(define_insn "load_pair<mode>"
@@ -3550,9 +3561,9 @@
;; after or during reload as we don't want these patterns to start
;; kicking in during the combiner.
-(define_insn "aarch64_movdi_tilow"
+(define_insn "aarch64_movdi_<mode>low"
[(set (match_operand:DI 0 "register_operand" "=r")
- (truncate:DI (match_operand:TI 1 "register_operand" "w")))]
+ (truncate:DI (match_operand:TX 1 "register_operand" "w")))]
"reload_completed || reload_in_progress"
"fmov\\t%x0, %d1"
[(set_attr "v8type" "fmovf2i")
@@ -3560,10 +3571,10 @@
(set_attr "length" "4")
])
-(define_insn "aarch64_movdi_tihigh"
+(define_insn "aarch64_movdi_<mode>high"
[(set (match_operand:DI 0 "register_operand" "=r")
(truncate:DI
- (lshiftrt:TI (match_operand:TI 1 "register_operand" "w")
+ (lshiftrt:TX (match_operand:TX 1 "register_operand" "w")
(const_int 64))))]
"reload_completed || reload_in_progress"
"fmov\\t%x0, %1.d[1]"
@@ -3572,24 +3583,22 @@
(set_attr "length" "4")
])
-(define_insn "aarch64_movtihigh_di"
- [(set (zero_extract:TI (match_operand:TI 0 "register_operand" "+w")
+(define_insn "aarch64_mov<mode>high_di"
+ [(set (zero_extract:TX (match_operand:TX 0 "register_operand" "+w")
(const_int 64) (const_int 64))
- (zero_extend:TI (match_operand:DI 1 "register_operand" "r")))]
+ (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
"reload_completed || reload_in_progress"
"fmov\\t%0.d[1], %x1"
-
[(set_attr "v8type" "fmovi2f")
(set_attr "mode" "DI")
(set_attr "length" "4")
])
-(define_insn "aarch64_movtilow_di"
- [(set (match_operand:TI 0 "register_operand" "=w")
- (zero_extend:TI (match_operand:DI 1 "register_operand" "r")))]
+(define_insn "aarch64_mov<mode>low_di"
+ [(set (match_operand:TX 0 "register_operand" "=w")
+ (zero_extend:TX (match_operand:DI 1 "register_operand" "r")))]
"reload_completed || reload_in_progress"
"fmov\\t%d0, %x1"
-
[(set_attr "v8type" "fmovi2f")
(set_attr "mode" "DI")
(set_attr "length" "4")
@@ -3601,7 +3610,6 @@
(truncate:DI (match_operand:TI 1 "register_operand" "w"))))]
"reload_completed || reload_in_progress"
"fmov\\t%d0, %d1"
-
[(set_attr "v8type" "fmovi2f")
(set_attr "mode" "DI")
(set_attr "length" "4")