diff options
author | Sofiane Naci <sofiane.naci@arm.com> | 2013-06-12 15:34:06 +0000 |
---|---|---|
committer | Sofiane Naci <sofiane@gcc.gnu.org> | 2013-06-12 15:34:06 +0000 |
commit | 8b033a8a927afab88532af22bdb7cd87d57e1f6d (patch) | |
tree | 8c37cad439e7ee4184c59064c22dc3e25a06f0a1 /gcc | |
parent | 21786a7f42d49d8a1b18bb97171ea031704f0cbd (diff) | |
download | gcc-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/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64-protos.h | 2 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64-simd.md | 24 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.c | 43 | ||||
-rw-r--r-- | gcc/config/aarch64/iterators.md | 3 |
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") |