aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Greenhalgh <james.greenhalgh@arm.com>2013-04-29 10:57:59 +0000
committerJames Greenhalgh <jgreenhalgh@gcc.gnu.org>2013-04-29 10:57:59 +0000
commit4c871069f963dbed380aaa1d452118181b195e7b (patch)
tree7a4aba12d9808ac260a5ab25b993455a50d9e366
parent1709ff9b5c53b13140819feae5e381fac22f6416 (diff)
downloadgcc-4c871069f963dbed380aaa1d452118181b195e7b.zip
gcc-4c871069f963dbed380aaa1d452118181b195e7b.tar.gz
gcc-4c871069f963dbed380aaa1d452118181b195e7b.tar.bz2
[AArch64] Implement vector float->double widening and double->float narrowing.
gcc/ * config/aarch64/aarch64-simd-builtins.def (vec_unpacks_hi_): New. (float_truncate_hi_): Likewise. (float_extend_lo_): Likewise. (float_truncate_lo_): Likewise. * config/aarch64/aarch64-simd.md (vec_unpacks_lo_v4sf): New. (aarch64_float_extend_lo_v2df): Likewise. (vec_unpacks_hi_v4sf): Likewise. (aarch64_float_truncate_lo_v2sf): Likewise. (aarch64_float_truncate_hi_v4sf): Likewise. (vec_pack_trunc_v2df): Likewise. (vec_pack_trunc_df): Likewise. From-SVN: r198400
-rw-r--r--gcc/ChangeLog14
-rw-r--r--gcc/config/aarch64/aarch64-simd-builtins.def6
-rw-r--r--gcc/config/aarch64/aarch64-simd.md102
3 files changed, 122 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2e21471..5f0e495 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,19 @@
2013-04-29 James Greenhalgh <james.greenhalgh@arm.com>
+ * config/aarch64/aarch64-simd-builtins.def (vec_unpacks_hi_): New.
+ (float_truncate_hi_): Likewise.
+ (float_extend_lo_): Likewise.
+ (float_truncate_lo_): Likewise.
+ * config/aarch64/aarch64-simd.md (vec_unpacks_lo_v4sf): New.
+ (aarch64_float_extend_lo_v2df): Likewise.
+ (vec_unpacks_hi_v4sf): Likewise.
+ (aarch64_float_truncate_lo_v2sf): Likewise.
+ (aarch64_float_truncate_hi_v4sf): Likewise.
+ (vec_pack_trunc_v2df): Likewise.
+ (vec_pack_trunc_df): Likewise.
+
+2013-04-29 James Greenhalgh <james.greenhalgh@arm.com>
+
* config/aarch64/aarch64-builtins.c
(aarch64_fold_builtin): Fold float conversions.
* config/aarch64/aarch64-simd-builtins.def
diff --git a/gcc/config/aarch64/aarch64-simd-builtins.def b/gcc/config/aarch64/aarch64-simd-builtins.def
index 8df3dac..6093341 100644
--- a/gcc/config/aarch64/aarch64-simd-builtins.def
+++ b/gcc/config/aarch64/aarch64-simd-builtins.def
@@ -338,3 +338,9 @@
BUILTIN_VDQF (BINOP, frecps, 0)
BUILTIN_VDQF (UNOP, abs, 2)
+
+ VAR1 (UNOP, vec_unpacks_hi_, 10, v4sf)
+ VAR1 (BINOP, float_truncate_hi_, 0, v4sf)
+
+ VAR1 (UNOP, float_extend_lo_, 0, v2df)
+ VAR1 (UNOP, float_truncate_lo_, 0, v2sf)
diff --git a/gcc/config/aarch64/aarch64-simd.md b/gcc/config/aarch64/aarch64-simd.md
index 067c849..4546094 100644
--- a/gcc/config/aarch64/aarch64-simd.md
+++ b/gcc/config/aarch64/aarch64-simd.md
@@ -1267,6 +1267,108 @@
(set_attr "simd_mode" "<MODE>")]
)
+;; Conversions between vectors of floats and doubles.
+;; Contains a mix of patterns to match standard pattern names
+;; and those for intrinsics.
+
+;; Float widening operations.
+
+(define_insn "vec_unpacks_lo_v4sf"
+ [(set (match_operand:V2DF 0 "register_operand" "=w")
+ (float_extend:V2DF
+ (vec_select:V2SF
+ (match_operand:V4SF 1 "register_operand" "w")
+ (parallel [(const_int 0) (const_int 1)])
+ )))]
+ "TARGET_SIMD"
+ "fcvtl\\t%0.2d, %1.2s"
+ [(set_attr "simd_type" "simd_fcvtl")
+ (set_attr "simd_mode" "V2DF")]
+)
+
+(define_insn "aarch64_float_extend_lo_v2df"
+ [(set (match_operand:V2DF 0 "register_operand" "=w")
+ (float_extend:V2DF
+ (match_operand:V2SF 1 "register_operand" "w")))]
+ "TARGET_SIMD"
+ "fcvtl\\t%0.2d, %1.2s"
+ [(set_attr "simd_type" "simd_fcvtl")
+ (set_attr "simd_mode" "V2DF")]
+)
+
+(define_insn "vec_unpacks_hi_v4sf"
+ [(set (match_operand:V2DF 0 "register_operand" "=w")
+ (float_extend:V2DF
+ (vec_select:V2SF
+ (match_operand:V4SF 1 "register_operand" "w")
+ (parallel [(const_int 2) (const_int 3)])
+ )))]
+ "TARGET_SIMD"
+ "fcvtl2\\t%0.2d, %1.4s"
+ [(set_attr "simd_type" "simd_fcvtl")
+ (set_attr "simd_mode" "V2DF")]
+)
+
+;; Float narrowing operations.
+
+(define_insn "aarch64_float_truncate_lo_v2sf"
+ [(set (match_operand:V2SF 0 "register_operand" "=w")
+ (float_truncate:V2SF
+ (match_operand:V2DF 1 "register_operand" "w")))]
+ "TARGET_SIMD"
+ "fcvtn\\t%0.2s, %1.2d"
+ [(set_attr "simd_type" "simd_fcvtl")
+ (set_attr "simd_mode" "V2SF")]
+)
+
+(define_insn "aarch64_float_truncate_hi_v4sf"
+ [(set (match_operand:V4SF 0 "register_operand" "=w")
+ (vec_concat:V4SF
+ (match_operand:V2SF 1 "register_operand" "0")
+ (float_truncate:V2SF
+ (match_operand:V2DF 2 "register_operand" "w"))))]
+ "TARGET_SIMD"
+ "fcvtn2\\t%0.4s, %2.2d"
+ [(set_attr "simd_type" "simd_fcvtl")
+ (set_attr "simd_mode" "V4SF")]
+)
+
+(define_expand "vec_pack_trunc_v2df"
+ [(set (match_operand:V4SF 0 "register_operand")
+ (vec_concat:V4SF
+ (float_truncate:V2SF
+ (match_operand:V2DF 1 "register_operand"))
+ (float_truncate:V2SF
+ (match_operand:V2DF 2 "register_operand"))
+ ))]
+ "TARGET_SIMD"
+ {
+ rtx tmp = gen_reg_rtx (V2SFmode);
+ emit_insn (gen_aarch64_float_truncate_lo_v2sf (tmp, operands[1]));
+ emit_insn (gen_aarch64_float_truncate_hi_v4sf (operands[0],
+ tmp, operands[2]));
+ DONE;
+ }
+)
+
+(define_expand "vec_pack_trunc_df"
+ [(set (match_operand:V2SF 0 "register_operand")
+ (vec_concat:V2SF
+ (float_truncate:SF
+ (match_operand:DF 1 "register_operand"))
+ (float_truncate:SF
+ (match_operand:DF 2 "register_operand"))
+ ))]
+ "TARGET_SIMD"
+ {
+ rtx tmp = gen_reg_rtx (V2SFmode);
+ emit_insn (gen_move_lo_quad_v2df (tmp, operands[1]));
+ emit_insn (gen_move_hi_quad_v2df (tmp, operands[2]));
+ emit_insn (gen_aarch64_float_truncate_lo_v2sf (operands[0], tmp));
+ DONE;
+ }
+)
+
(define_insn "aarch64_vmls<mode>"
[(set (match_operand:VDQF 0 "register_operand" "=w")
(minus:VDQF (match_operand:VDQF 1 "register_operand" "0")