@@ -1447,6 +1447,16 @@ aarch64_builtin_vectorized_function (unsigned int fn, tree type_out,
return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_UNOPU_bswapv2di];
else
return NULL_TREE;
+ CASE_CFN_COPYSIGN:
+ if (AARCH64_CHECK_BUILTIN_MODE (2, S))
+ return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_BINOP_copysignv2sf];
+ else if (AARCH64_CHECK_BUILTIN_MODE (4, S))
+ return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_BINOP_copysignv4sf];
+ else if (AARCH64_CHECK_BUILTIN_MODE (2, D))
+ return aarch64_builtin_decls[AARCH64_SIMD_BUILTIN_BINOP_copysignv2df];
+ else
+ return NULL_TREE;
+
default:
return NULL_TREE;
}
@@ -362,7 +362,7 @@ rtx aarch64_final_eh_return_addr (void);
rtx aarch64_mask_from_zextract_ops (rtx, rtx);
const char *aarch64_output_move_struct (rtx *operands);
rtx aarch64_return_addr (int, rtx);
-rtx aarch64_simd_gen_const_vector_dup (machine_mode, int);
+rtx aarch64_simd_gen_const_vector_dup (machine_mode, HOST_WIDE_INT);
bool aarch64_simd_mem_operand_p (rtx);
rtx aarch64_simd_vect_par_cnst_half (machine_mode, bool);
rtx aarch64_tls_get_addr (void);
@@ -151,6 +151,9 @@
BUILTIN_VQN (TERNOP, raddhn2, 0)
BUILTIN_VQN (TERNOP, rsubhn2, 0)
+ /* Implemented by copysign<mode>3. */
+ BUILTIN_VHSDF (BINOP, copysign, 3)
+
BUILTIN_VSQN_HSDI (UNOP, sqmovun, 0)
/* Implemented by aarch64_<sur>qmovn<mode>. */
BUILTIN_VSQN_HSDI (UNOP, sqmovn, 0)
@@ -338,6 +338,24 @@
}
)
+(define_expand "copysign<mode>3"
+ [(match_operand:VHSDF 0 "register_operand")
+ (match_operand:VHSDF 1 "register_operand")
+ (match_operand:VHSDF 2 "register_operand")]
+ "TARGET_FLOAT && TARGET_SIMD"
+{
+ rtx v_bitmask = gen_reg_rtx (<V_cmp_result>mode);
+ int bits = GET_MODE_UNIT_BITSIZE (<MODE>mode) - 1;
+
+ emit_move_insn (v_bitmask,
+ aarch64_simd_gen_const_vector_dup (<V_cmp_result>mode,
+ HOST_WIDE_INT_M1 << bits));
+ emit_insn (gen_aarch64_simd_bsl<mode> (operands[0], v_bitmask,
+ operands[2], operands[1]));
+ DONE;
+}
+)
+
(define_insn "*aarch64_mul3_elt<mode>"
[(set (match_operand:VMUL 0 "register_operand" "=w")
(mult:VMUL
@@ -11244,14 +11244,16 @@ aarch64_mov_operand_p (rtx x, machine_mode mode)
/* Return a const_int vector of VAL. */
rtx
-aarch64_simd_gen_const_vector_dup (machine_mode mode, int val)
+aarch64_simd_gen_const_vector_dup (machine_mode mode, HOST_WIDE_INT val)
{
int nunits = GET_MODE_NUNITS (mode);
rtvec v = rtvec_alloc (nunits);
int i;
+ rtx cache = GEN_INT (val);
+
for (i=0; i < nunits; i++)
- RTVEC_ELT (v, i) = GEN_INT (val);
+ RTVEC_ELT (v, i) = cache;
return gen_rtx_CONST_VECTOR (mode, v);
}
similarity index 91%
rename from gcc/testsuite/gcc.target/arm/vect-copysignf.c
rename to gcc/testsuite/gcc.dg/vect/vect-copysignf.c
@@ -1,5 +1,5 @@
/* { dg-do run } */
-/* { dg-require-effective-target arm_neon_hw } */
+/* { dg-require-effective-target arm_neon_hw { target { arm*-*-* } } } */
/* { dg-options "-O2 -ftree-vectorize -fdump-tree-vect-details" } */
/* { dg-add-options "arm_neon" } */