aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorSofiane Naci <sofiane.naci@arm.com>2013-06-12 15:34:06 +0000
committerSofiane Naci <sofiane@gcc.gnu.org>2013-06-12 15:34:06 +0000
commit8b033a8a927afab88532af22bdb7cd87d57e1f6d (patch)
tree8c37cad439e7ee4184c59064c22dc3e25a06f0a1 /gcc
parent21786a7f42d49d8a1b18bb97171ea031704f0cbd (diff)
downloadgcc-8b033a8a927afab88532af22bdb7cd87d57e1f6d.zip
gcc-8b033a8a927afab88532af22bdb7cd87d57e1f6d.tar.gz
gcc-8b033a8a927afab88532af22bdb7cd87d57e1f6d.tar.bz2
aarch64-simd.md (aarch64_combine<mode>): convert to split.
* config/aarch64/aarch64-simd.md (aarch64_combine<mode>): convert to split. (aarch64_simd_combine<mode>): New instruction expansion. * config/aarch64/aarch64-protos.h (aarch64_split_simd_combine): New function prototype. * config/aarch64/aarch64.c (aarch64_split_combine): New function. * config/aarch64/iterators.md (Vdbl): Add entry for DF. From-SVN: r200020
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/aarch64/aarch64-protos.h2
-rw-r--r--gcc/config/aarch64/aarch64-simd.md24
-rw-r--r--gcc/config/aarch64/aarch64.c43
-rw-r--r--gcc/config/aarch64/iterators.md3
5 files changed, 75 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index bd2d37b..0b15431 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2013-06-12 Sofiane Naci <sofiane.naci@arm.com>
+
+ * config/aarch64/aarch64-simd.md (aarch64_combine<mode>): convert to split.
+ (aarch64_simd_combine<mode>): New instruction expansion.
+ * config/aarch64/aarch64-protos.h (aarch64_split_simd_combine): New
+ function prototype.
+ * config/aarch64/aarch64.c (aarch64_split_combine): New function.
+ * config/aarch64/iterators.md (Vdbl): Add entry for DF.
+
2013-06-12 Jan Hubicka <jh@suse.cz>
* cgraph.c (verify_edge_corresponds_to_fndecl): Be lax about
diff --git a/gcc/config/aarch64/aarch64-protos.h b/gcc/config/aarch64/aarch64-protos.h
index 8e099bf..12f3c3a 100644
--- a/gcc/config/aarch64/aarch64-protos.h
+++ b/gcc/config/aarch64/aarch64-protos.h
@@ -226,6 +226,8 @@ void aarch64_split_128bit_move (rtx, rtx);
bool aarch64_split_128bit_move_p (rtx, rtx);
+void aarch64_split_simd_combine (rtx, rtx, rtx);
+
void aarch64_split_simd_move (rtx, rtx);
/* Check for a legitimate floating point constant for FMOV. */
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 63c48b5..8e3f5c2 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -2218,15 +2218,29 @@
(set_attr "simd_mode" "<MODE>")]
)
-(define_insn "aarch64_combine<mode>"
+(define_insn_and_split "aarch64_combine<mode>"
[(set (match_operand:<VDBL> 0 "register_operand" "=&w")
(vec_concat:<VDBL> (match_operand:VDC 1 "register_operand" "w")
(match_operand:VDC 2 "register_operand" "w")))]
"TARGET_SIMD"
- "mov\\t%0.d[0], %1.d[0]\;ins\\t%0.d[1], %2.d[0]"
- [(set_attr "simd_type" "simd_ins")
- (set_attr "simd_mode" "<MODE>")]
-)
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+{
+ aarch64_split_simd_combine (operands[0], operands[1], operands[2]);
+ DONE;
+})
+
+(define_expand "aarch64_simd_combine<mode>"
+ [(set (match_operand:<VDBL> 0 "register_operand" "=&w")
+ (vec_concat:<VDBL> (match_operand:VDC 1 "register_operand" "w")
+ (match_operand:VDC 2 "register_operand" "w")))]
+ "TARGET_SIMD"
+ {
+ emit_insn (gen_move_lo_quad_<Vdbl> (operands[0], operands[1]));
+ emit_insn (gen_move_hi_quad_<Vdbl> (operands[0], operands[2]));
+ DONE;
+ })
;; <su><addsub>l<q>.
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 4471ee1..527b00d 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -700,6 +700,49 @@ aarch64_split_128bit_move_p (rtx dst, rtx src)
|| ! (FP_REGNUM_P (REGNO (dst)) && FP_REGNUM_P (REGNO (src))));
}
+/* Split a complex SIMD combine. */
+
+void
+aarch64_split_simd_combine (rtx dst, rtx src1, rtx src2)
+{
+ enum machine_mode src_mode = GET_MODE (src1);
+ enum machine_mode dst_mode = GET_MODE (dst);
+
+ gcc_assert (VECTOR_MODE_P (dst_mode));
+
+ if (REG_P (dst) && REG_P (src1) && REG_P (src2))
+ {
+ rtx (*gen) (rtx, rtx, rtx);
+
+ switch (src_mode)
+ {
+ case V8QImode:
+ gen = gen_aarch64_simd_combinev8qi;
+ break;
+ case V4HImode:
+ gen = gen_aarch64_simd_combinev4hi;
+ break;
+ case V2SImode:
+ gen = gen_aarch64_simd_combinev2si;
+ break;
+ case V2SFmode:
+ gen = gen_aarch64_simd_combinev2sf;
+ break;
+ case DImode:
+ gen = gen_aarch64_simd_combinedi;
+ break;
+ case DFmode:
+ gen = gen_aarch64_simd_combinedf;
+ break;
+ default:
+ gcc_unreachable ();
+ }
+
+ emit_insn (gen (dst, src1, src2));
+ return;
+ }
+}
+
/* Split a complex SIMD move. */
void
diff --git a/gcc/config/aarch64/iterators.md b/gcc/config/aarch64/iterators.md
index 860d4d9..8e40c5d 100644
--- a/gcc/config/aarch64/iterators.md
+++ b/gcc/config/aarch64/iterators.md
@@ -385,7 +385,8 @@
;; Double modes of vector modes (lower case).
(define_mode_attr Vdbl [(V8QI "v16qi") (V4HI "v8hi")
(V2SI "v4si") (V2SF "v4sf")
- (SI "v2si") (DI "v2di")])
+ (SI "v2si") (DI "v2di")
+ (DF "v2df")])
;; Narrowed modes for VDN.
(define_mode_attr VNARROWD [(V4HI "V8QI") (V2SI "V4HI")