[arm] Implement non-GE-setting SIMD32 intrinsics

This patch is part of a series to implement the SIMD32 ACLE intrinsics [1].
The interesting parts implementation-wise involve adding support for setting and reading
the Q bit for saturation and the GE-bits for the packed SIMD instructions.
That will come in a later patch.

For now, this patch implements the other intrinsics that don't need anything special ;
just a mapping from arm_acle.h function to builtin to RTL expander+unspec.

I've compressed as many as I could with iterators so that we end up needing only 3
new define_insns.

Bootstrapped and tested on arm-none-linux-gnueabihf.

[1] https://developer.arm.com/docs/101028/latest/data-processing-intrinsics

	* config/arm/arm.md (arm_<simd32_op>): New define_insn.
	(arm_<sup>xtb16): Likewise.
	(arm_usada8): Likewise.
	* config/arm/arm_acle.h (__qadd8, __qsub8, __shadd8, __shsub8,
	__uhadd8, __uhsub8, __uqadd8, __uqsub8, __qadd16, __qasx, __qsax,
	__qsub16, __shadd16, __shasx, __shsax, __shsub16, __uhadd16, __uhasx,
	__uhsax, __uhsub16, __uqadd16, __uqasx, __uqsax, __uqsub16, __sxtab16,
	__sxtb16, __uxtab16, __uxtb16): Define.
	* config/arm/arm_acle_builtins.def: Define builtins for the above.
	* config/arm/unspecs.md: Define unspecs for the above.
	* config/arm/iterators.md (SIMD32_NOGE_BINOP): New int_iterator.
	(USXTB16): Likewise.
	(simd32_op): New int_attribute.
	(sup): Handle UNSPEC_SXTB16, UNSPEC_UXTB16.
	* doc/sourcebuild.exp (arm_simd32_ok): Document.

	* lib/target-supports.exp
	(check_effective_target_arm_simd32_ok_nocache): New procedure.
	(check_effective_target_arm_simd32_ok): Likewise.
	(add_options_for_arm_simd32): Likewise.
	* gcc.target/arm/acle/simd32.c: New test.

From-SVN: r276146
This commit is contained in:
Kyrylo Tkachov 2019-09-26 10:46:14 +00:00 committed by Kyrylo Tkachov
parent 1275a541a5
commit 53cd0ac643
10 changed files with 677 additions and 0 deletions

View File

@ -1,3 +1,21 @@
2019-09-26 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/arm/arm.md (arm_<simd32_op>): New define_insn.
(arm_<sup>xtb16): Likewise.
(arm_usada8): Likewise.
* config/arm/arm_acle.h (__qadd8, __qsub8, __shadd8, __shsub8,
__uhadd8, __uhsub8, __uqadd8, __uqsub8, __qadd16, __qasx, __qsax,
__qsub16, __shadd16, __shasx, __shsax, __shsub16, __uhadd16, __uhasx,
__uhsax, __uhsub16, __uqadd16, __uqasx, __uqsax, __uqsub16, __sxtab16,
__sxtb16, __uxtab16, __uxtb16): Define.
* config/arm/arm_acle_builtins.def: Define builtins for the above.
* config/arm/unspecs.md: Define unspecs for the above.
* config/arm/iterators.md (SIMD32_NOGE_BINOP): New int_iterator.
(USXTB16): Likewise.
(simd32_op): New int_attribute.
(sup): Handle UNSPEC_SXTB16, UNSPEC_UXTB16.
* doc/sourcebuild.exp (arm_simd32_ok): Document.
2019-09-26 Martin Jambor <mjambor@suse.cz>
* ipa-sra.c (verify_splitting_accesses): Fix quoting in a call to

View File

@ -5058,6 +5058,36 @@
(set_attr "predicable" "yes")]
)
(define_insn "arm_<sup>xtb16"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(unspec:SI
[(match_operand:SI 1 "s_register_operand" "r")] USXTB16))]
"TARGET_INT_SIMD"
"<sup>xtb16%?\\t%0, %1"
[(set_attr "predicable" "yes")
(set_attr "type" "alu_dsp_reg")])
(define_insn "arm_<simd32_op>"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(unspec:SI
[(match_operand:SI 1 "s_register_operand" "r")
(match_operand:SI 2 "s_register_operand" "r")] SIMD32_NOGE_BINOP))]
"TARGET_INT_SIMD"
"<simd32_op>%?\\t%0, %1, %2"
[(set_attr "predicable" "yes")
(set_attr "type" "alu_dsp_reg")])
(define_insn "arm_usada8"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(unspec:SI
[(match_operand:SI 1 "s_register_operand" "r")
(match_operand:SI 2 "s_register_operand" "r")
(match_operand:SI 3 "s_register_operand" "r")] UNSPEC_USADA8))]
"TARGET_INT_SIMD"
"usada8%?\\t%0, %1, %2, %3"
[(set_attr "predicable" "yes")
(set_attr "type" "alu_dsp_reg")])
(define_expand "extendsfdf2"
[(set (match_operand:DF 0 "s_register_operand")
(float_extend:DF (match_operand:SF 1 "s_register_operand")))]

View File

@ -173,6 +173,238 @@ __arm_mrrc2 (const unsigned int __coproc, const unsigned int __opc1,
#endif /* __ARM_ARCH >= 5. */
#endif /* (!__thumb__ || __thumb2__) && __ARM_ARCH >= 4. */
#ifdef __ARM_FEATURE_SIMD32
typedef int32_t int16x2_t;
typedef uint32_t uint16x2_t;
typedef int32_t int8x4_t;
typedef uint32_t uint8x4_t;
__extension__ extern __inline int16x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__sxtab16 (int16x2_t __a, int8x4_t __b)
{
return __builtin_arm_sxtab16 (__a, __b);
}
__extension__ extern __inline int16x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__sxtb16 (int8x4_t __a)
{
return __builtin_arm_sxtb16 (__a);
}
__extension__ extern __inline uint16x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__uxtab16 (uint16x2_t __a, uint8x4_t __b)
{
return __builtin_arm_uxtab16 (__a, __b);
}
__extension__ extern __inline uint16x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__uxtb16 (uint8x4_t __a)
{
return __builtin_arm_uxtb16 (__a);
}
__extension__ extern __inline int8x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__qadd8 (int8x4_t __a, int8x4_t __b)
{
return __builtin_arm_qadd8 (__a, __b);
}
__extension__ extern __inline int8x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__qsub8 (int8x4_t __a, int8x4_t __b)
{
return __builtin_arm_qsub8 (__a, __b);
}
__extension__ extern __inline int8x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__shadd8 (int8x4_t __a, int8x4_t __b)
{
return __builtin_arm_shadd8 (__a, __b);
}
__extension__ extern __inline int8x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__shsub8 (int8x4_t __a, int8x4_t __b)
{
return __builtin_arm_shsub8 (__a, __b);
}
__extension__ extern __inline uint8x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__uhadd8 (uint8x4_t __a, uint8x4_t __b)
{
return __builtin_arm_uhadd8 (__a, __b);
}
__extension__ extern __inline uint8x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__uhsub8 (uint8x4_t __a, uint8x4_t __b)
{
return __builtin_arm_uhsub8 (__a, __b);
}
__extension__ extern __inline uint8x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__uqadd8 (uint8x4_t __a, uint8x4_t __b)
{
return __builtin_arm_uqadd8 (__a, __b);
}
__extension__ extern __inline uint8x4_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__uqsub8 (uint8x4_t __a, uint8x4_t __b)
{
return __builtin_arm_uqsub8 (__a, __b);
}
__extension__ extern __inline int16x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__qadd16 (int16x2_t __a, int16x2_t __b)
{
return __builtin_arm_qadd16 (__a, __b);
}
__extension__ extern __inline int16x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__qasx (int16x2_t __a, int16x2_t __b)
{
return __builtin_arm_qasx (__a, __b);
}
__extension__ extern __inline int16x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__qsax (int16x2_t __a, int16x2_t __b)
{
return __builtin_arm_qsax (__a, __b);
}
__extension__ extern __inline int16x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__qsub16 (int16x2_t __a, int16x2_t __b)
{
return __builtin_arm_qsub16 (__a, __b);
}
__extension__ extern __inline int16x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__shadd16 (int16x2_t __a, int16x2_t __b)
{
return __builtin_arm_shadd16 (__a, __b);
}
__extension__ extern __inline int16x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__shasx (int16x2_t __a, int16x2_t __b)
{
return __builtin_arm_shasx (__a, __b);
}
__extension__ extern __inline int16x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__shsax (int16x2_t __a, int16x2_t __b)
{
return __builtin_arm_shsax (__a, __b);
}
__extension__ extern __inline int16x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__shsub16 (int16x2_t __a, int16x2_t __b)
{
return __builtin_arm_shsub16 (__a, __b);
}
__extension__ extern __inline uint16x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__uhadd16 (uint16x2_t __a, uint16x2_t __b)
{
return __builtin_arm_uhadd16 (__a, __b);
}
__extension__ extern __inline uint16x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__uhasx (uint16x2_t __a, uint16x2_t __b)
{
return __builtin_arm_uhasx (__a, __b);
}
__extension__ extern __inline uint16x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__uhsax (uint16x2_t __a, uint16x2_t __b)
{
return __builtin_arm_uhsax (__a, __b);
}
__extension__ extern __inline uint16x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__uhsub16 (uint16x2_t __a, uint16x2_t __b)
{
return __builtin_arm_uhsub16 (__a, __b);
}
__extension__ extern __inline uint16x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__uqadd16 (uint16x2_t __a, uint16x2_t __b)
{
return __builtin_arm_uqadd16 (__a, __b);
}
__extension__ extern __inline uint16x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__uqasx (uint16x2_t __a, uint16x2_t __b)
{
return __builtin_arm_uqasx (__a, __b);
}
__extension__ extern __inline uint16x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__uqsax (uint16x2_t __a, uint16x2_t __b)
{
return __builtin_arm_uqsax (__a, __b);
}
__extension__ extern __inline uint16x2_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__uqsub16 (uint16x2_t __a, uint16x2_t __b)
{
return __builtin_arm_uqsub16 (__a, __b);
}
__extension__ extern __inline int32_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__smusd (int16x2_t __a, int16x2_t __b)
{
return __builtin_arm_smusd (__a, __b);
}
__extension__ extern __inline int32_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__smusdx (int16x2_t __a, int16x2_t __b)
{
return __builtin_arm_smusdx (__a, __b);
}
__extension__ extern __inline uint32_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__usad8 (uint8x4_t __a, uint8x4_t __b)
{
return __builtin_arm_usad8 (__a, __b);
}
__extension__ extern __inline uint32_t
__attribute__ ((__always_inline__, __gnu_inline__, __artificial__))
__usada8 (uint8x4_t __a, uint8x4_t __b, uint32_t __c)
{
return __builtin_arm_usada8 (__a, __b, __c);
}
#endif
#pragma GCC push_options
#ifdef __ARM_FEATURE_CRC32
#ifdef __ARM_FP

View File

@ -42,3 +42,36 @@ VAR1 (MCRR, mcrr, void)
VAR1 (MCRR, mcrr2, void)
VAR1 (MRRC, mrrc, di)
VAR1 (MRRC, mrrc2, di)
VAR1 (BINOP, sxtab16, si)
VAR1 (UBINOP, uxtab16, si)
VAR1 (UNOP, sxtb16, si)
VAR1 (BSWAP, uxtb16, si)
VAR1 (BINOP, qadd8, si)
VAR1 (BINOP, qsub8, si)
VAR1 (BINOP, shadd8, si)
VAR1 (BINOP, shsub8, si)
VAR1 (UBINOP, uhadd8, si)
VAR1 (UBINOP, uhsub8, si)
VAR1 (UBINOP, uqadd8, si)
VAR1 (UBINOP, uqsub8, si)
VAR1 (BINOP, qadd16, si)
VAR1 (BINOP, qasx, si)
VAR1 (BINOP, qsax, si)
VAR1 (BINOP, qsub16, si)
VAR1 (BINOP, shadd16, si)
VAR1 (BINOP, shasx, si)
VAR1 (BINOP, shsax, si)
VAR1 (BINOP, shsub16, si)
VAR1 (UBINOP, uhadd16, si)
VAR1 (UBINOP, uhasx, si)
VAR1 (UBINOP, uhsax, si)
VAR1 (UBINOP, uhsub16, si)
VAR1 (UBINOP, uqadd16, si)
VAR1 (UBINOP, uqasx, si)
VAR1 (UBINOP, uqsax, si)
VAR1 (UBINOP, uqsub16, si)
VAR1 (BINOP, smusd, si)
VAR1 (BINOP, smusdx, si)
VAR1 (UBINOP, usad8, si)
VAR1 (UBINOP, usada8, si)

View File

@ -430,6 +430,19 @@
(define_int_iterator CRYPTO_SELECTING [UNSPEC_SHA1C UNSPEC_SHA1M
UNSPEC_SHA1P])
(define_int_iterator USXTB16 [UNSPEC_SXTB16 UNSPEC_UXTB16])
(define_int_iterator SIMD32_NOGE_BINOP
[UNSPEC_QADD8 UNSPEC_QSUB8 UNSPEC_SHADD8
UNSPEC_SHSUB8 UNSPEC_UHADD8 UNSPEC_UHSUB8
UNSPEC_UQADD8 UNSPEC_UQSUB8
UNSPEC_QADD16 UNSPEC_QASX UNSPEC_QSAX
UNSPEC_QSUB16 UNSPEC_SHADD16 UNSPEC_SHASX
UNSPEC_SHSAX UNSPEC_SHSUB16 UNSPEC_UHADD16
UNSPEC_UHASX UNSPEC_UHSAX UNSPEC_UHSUB16
UNSPEC_UQADD16 UNSPEC_UQASX UNSPEC_UQSAX
UNSPEC_UQSUB16 UNSPEC_SMUSD UNSPEC_SMUSDX
UNSPEC_SXTAB16 UNSPEC_UXTAB16 UNSPEC_USAD8])
(define_int_iterator VQRDMLH_AS [UNSPEC_VQRDMLAH UNSPEC_VQRDMLSH])
(define_int_iterator VFM_LANE_AS [UNSPEC_VFMA_LANE UNSPEC_VFMS_LANE])
@ -835,6 +848,7 @@
;; Mapping between vector UNSPEC operations and the signed ('s'),
;; unsigned ('u'), poly ('p') or float ('f') nature of their data type.
(define_int_attr sup [
(UNSPEC_SXTB16 "s") (UNSPEC_UXTB16 "u")
(UNSPEC_VADDL_S "s") (UNSPEC_VADDL_U "u")
(UNSPEC_VADDW_S "s") (UNSPEC_VADDW_U "u")
(UNSPEC_VRHADD_S "s") (UNSPEC_VRHADD_U "u")
@ -1023,6 +1037,22 @@
(UNSPEC_VCMLA180 "180")
(UNSPEC_VCMLA270 "270")])
(define_int_attr simd32_op [(UNSPEC_QADD8 "qadd8") (UNSPEC_QSUB8 "qsub8")
(UNSPEC_SHADD8 "shadd8") (UNSPEC_SHSUB8 "shsub8")
(UNSPEC_UHADD8 "uhadd8") (UNSPEC_UHSUB8 "uhsub8")
(UNSPEC_UQADD8 "uqadd8") (UNSPEC_UQSUB8 "uqsub8")
(UNSPEC_QADD16 "qadd16") (UNSPEC_QASX "qasx")
(UNSPEC_QSAX "qsax") (UNSPEC_QSUB16 "qsub16")
(UNSPEC_SHADD16 "shadd16") (UNSPEC_SHASX "shasx")
(UNSPEC_SHSAX "shsax") (UNSPEC_SHSUB16 "shsub16")
(UNSPEC_UHADD16 "uhadd16") (UNSPEC_UHASX "uhasx")
(UNSPEC_UHSAX "uhsax") (UNSPEC_UHSUB16 "uhsub16")
(UNSPEC_UQADD16 "uqadd16") (UNSPEC_UQASX "uqasx")
(UNSPEC_UQSAX "uqsax") (UNSPEC_UQSUB16 "uqsub16")
(UNSPEC_SMUSD "smusd") (UNSPEC_SMUSDX "smusdx")
(UNSPEC_SXTAB16 "sxtab16") (UNSPEC_UXTAB16 "uxtab16")
(UNSPEC_USAD8 "usad8")])
;; Both kinds of return insn.
(define_code_iterator RETURNS [return simple_return])
(define_code_attr return_str [(return "") (simple_return "simple_")])

View File

@ -90,8 +90,42 @@
UNSPEC_SP_TEST ; Represent the testing of stack protector's canary
; against the guard.
UNSPEC_PIC_RESTORE ; Use to restore fdpic register
UNSPEC_SXTAB16 ; Represent the SXTAB16 operation.
UNSPEC_UXTAB16 ; Represent the UXTAB16 operation.
UNSPEC_SXTB16 ; Represent the SXTB16 operation.
UNSPEC_UXTB16 ; Represent the UXTB16 operation.
UNSPEC_QADD8 ; Represent the QADD8 operation.
UNSPEC_QSUB8 ; Represent the QSUB8 operation.
UNSPEC_SHADD8 ; Represent the SHADD8 operation.
UNSPEC_SHSUB8 ; Represent the SHSUB8 operation.
UNSPEC_UHADD8 ; Represent the UHADD8 operation.
UNSPEC_UHSUB8 ; Represent the UHSUB8 operation.
UNSPEC_UQADD8 ; Represent the UQADD8 operation.
UNSPEC_UQSUB8 ; Represent the UQSUB8 operation.
UNSPEC_QADD16 ; Represent the QADD16 operation.
UNSPEC_QASX ; Represent the QASX operation.
UNSPEC_QSAX ; Represent the QSAX operation.
UNSPEC_QSUB16 ; Represent the QSUB16 operation.
UNSPEC_SHADD16 ; Represent the SHADD16 operation.
UNSPEC_SHASX ; Represent the SHASX operation.
UNSPEC_SHSAX ; Represent the SSAX operation.
UNSPEC_SHSUB16 ; Represent the SHSUB16 operation.
UNSPEC_UHADD16 ; Represent the UHADD16 operation.
UNSPEC_UHASX ; Represent the UHASX operation.
UNSPEC_UHSAX ; Represent the USAX operation.
UNSPEC_UHSUB16 ; Represent the UHSUB16 operation.
UNSPEC_UQADD16 ; Represent the UQADD16 operation.
UNSPEC_UQASX ; Represent the UQASX operation.
UNSPEC_UQSAX ; Represent the UQSAX operation.
UNSPEC_UQSUB16 ; Represent the UQSUB16 operation.
UNSPEC_SMUSD ; Represent the SMUSD operation.
UNSPEC_SMUSDX ; Represent the SMUSDX operation.
UNSPEC_USAD8 ; Represent the USAD8 operation.
UNSPEC_USADA8 ; Represent the USADA8 operation.
])
(define_c_enum "unspec" [
UNSPEC_WADDC ; Used by the intrinsic form of the iWMMXt WADDC instruction.
UNSPEC_WABS ; Used by the intrinsic form of the iWMMXt WABS instruction.

View File

@ -1900,6 +1900,13 @@ in @ref{arm_coproc2_ok} in addition the following: @code{MCRR} and @code{MRRC}.
@item arm_coproc4_ok
ARM target supports all the coprocessor instructions also listed as supported
in @ref{arm_coproc3_ok} in addition the following: @code{MCRR2} and @code{MRRC2}.
@item arm_simd32_ok
@anchor{arm_simd32_ok}
ARM Target supports options suitable for accessing the SIMD32 intrinsics from
@code{arm_acle.h}.
Some multilibs may be incompatible with these options.
@end table
@subsubsection AArch64-specific attributes

View File

@ -1,3 +1,11 @@
2019-09-26 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* lib/target-supports.exp
(check_effective_target_arm_simd32_ok_nocache): New procedure.
(check_effective_target_arm_simd32_ok): Likewise.
(add_options_for_arm_simd32): Likewise.
* gcc.target/arm/acle/simd32.c: New test.
2019-09-26 Richard Sandiford <richard.sandiford@arm.com>
* gcc.target/arm/fp16-compile-alt-3.c: Expect (__fp16) -2.0

View File

@ -0,0 +1,246 @@
/* { dg-do compile } */
/* { dg-require-effective-target arm_simd32_ok } */
/* { dg-add-options arm_simd32 } */
#include <arm_acle.h>
int16x2_t
test_sxtab16 (int16x2_t a, int8x4_t b)
{
return __sxtab16 (a, b);
}
/* { dg-final { scan-assembler-times "sxtab16\t...?, ...?, ...?" 1 } } */
int16x2_t
test_sxtb16 (int8x4_t a)
{
return __sxtb16 (a);
}
/* { dg-final { scan-assembler-times "sxtab16\t...?, ...?" 1 } } */
int8x4_t
test_qadd8 (int8x4_t a, int8x4_t b)
{
return __qadd8 (a, b);
}
/* { dg-final { scan-assembler-times "\tqadd8\t...?, ...?, ...?" 1 } } */
int8x4_t
test_qsub8 (int8x4_t a, int8x4_t b)
{
return __qsub8 (a, b);
}
/* { dg-final { scan-assembler-times "\tqsub8\t...?, ...?, ...?" 1 } } */
int8x4_t
test_shadd8 (int8x4_t a, int8x4_t b)
{
return __shadd8 (a, b);
}
/* { dg-final { scan-assembler-times "\tshadd8\t...?, ...?, ...?" 1 } } */
int8x4_t
test_shsub8 (int8x4_t a, int8x4_t b)
{
return __shsub8 (a, b);
}
/* { dg-final { scan-assembler-times "\tshsub8\t...?, ...?, ...?" 1 } } */
uint8x4_t
test_uhadd8 (uint8x4_t a, uint8x4_t b)
{
return __uhadd8 (a, b);
}
/* { dg-final { scan-assembler-times "\tuhadd8\t...?, ...?, ...?" 1 } } */
uint8x4_t
test_uhsub8 (uint8x4_t a, uint8x4_t b)
{
return __uhsub8 (a, b);
}
/* { dg-final { scan-assembler-times "\tuhsub8\t...?, ...?, ...?" 1 } } */
uint8x4_t
test_uqadd8 (uint8x4_t a, uint8x4_t b)
{
return __uqadd8 (a, b);
}
/* { dg-final { scan-assembler-times "\tuqadd8\t...?, ...?, ...?" 1 } } */
uint8x4_t
test_uqsub8 (uint8x4_t a, uint8x4_t b)
{
return __uqsub8 (a, b);
}
/* { dg-final { scan-assembler-times "\tuqsub8\t...?, ...?, ...?" 1 } } */
int16x2_t
test_qadd16 (int16x2_t a, int16x2_t b)
{
return __qadd16 (a, b);
}
/* { dg-final { scan-assembler-times "\tqadd16\t...?, ...?, ...?" 1 } } */
int16x2_t
test_qasx (int16x2_t a, int16x2_t b)
{
return __qasx (a, b);
}
/* { dg-final { scan-assembler-times "\tqasx\t...?, ...?, ...?" 1 } } */
int16x2_t
test_qsax (int16x2_t a, int16x2_t b)
{
return __qsax (a, b);
}
/* { dg-final { scan-assembler-times "\tqsax\t...?, ...?, ...?" 1 } } */
int16x2_t
test_qsub16 (int16x2_t a, int16x2_t b)
{
return __qsub16 (a, b);
}
/* { dg-final { scan-assembler-times "\tqsub16\t...?, ...?, ...?" 1 } } */
int16x2_t
test_shadd16 (int16x2_t a, int16x2_t b)
{
return __shadd16 (a, b);
}
/* { dg-final { scan-assembler-times "\tshadd16\t...?, ...?, ...?" 1 } } */
int16x2_t
test_shasx (int16x2_t a, int16x2_t b)
{
return __shasx (a, b);
}
/* { dg-final { scan-assembler-times "\tshasx\t...?, ...?, ...?" 1 } } */
int16x2_t
test_shsax (int16x2_t a, int16x2_t b)
{
return __shsax (a, b);
}
/* { dg-final { scan-assembler-times "\tshsax\t...?, ...?, ...?" 1 } } */
int16x2_t
test_shsub16 (int16x2_t a, int16x2_t b)
{
return __shsub16 (a, b);
}
/* { dg-final { scan-assembler-times "\tshsub16\t...?, ...?, ...?" 1 } } */
uint16x2_t
test_uhadd16 (uint16x2_t a, uint16x2_t b)
{
return __uhadd16 (a, b);
}
/* { dg-final { scan-assembler-times "\tuhadd16\t...?, ...?, ...?" 1 } } */
uint16x2_t
test_uhasx (uint16x2_t a, uint16x2_t b)
{
return __uhasx (a, b);
}
/* { dg-final { scan-assembler-times "\tuhasx\t...?, ...?, ...?" 1 } } */
uint16x2_t
test_uhsax (uint16x2_t a, uint16x2_t b)
{
return __uhsax (a, b);
}
/* { dg-final { scan-assembler-times "\tuhsax\t...?, ...?, ...?" 1 } } */
uint16x2_t
test_uhsub16 (uint16x2_t a, uint16x2_t b)
{
return __uhsub16 (a, b);
}
/* { dg-final { scan-assembler-times "\tuhsub16\t...?, ...?, ...?" 1 } } */
uint16x2_t
test_uqadd16 (uint16x2_t a, uint16x2_t b)
{
return __uqadd16 (a, b);
}
/* { dg-final { scan-assembler-times "\tuqadd16\t...?, ...?, ...?" 1 } } */
uint16x2_t
test_uqasx (uint16x2_t a, uint16x2_t b)
{
return __uqasx (a, b);
}
/* { dg-final { scan-assembler-times "\tuqasx\t...?, ...?, ...?" 1 } } */
uint16x2_t
test_uqsax (uint16x2_t a, uint16x2_t b)
{
return __uqsax (a, b);
}
/* { dg-final { scan-assembler-times "\tuqsax\t...?, ...?, ...?" 1 } } */
uint16x2_t
test_uqsub16 (uint16x2_t a, uint16x2_t b)
{
return __uqsub16 (a, b);
}
/* { dg-final { scan-assembler-times "\tuqsub16\t...?, ...?, ...?" 1 } } */
int32_t
test_smusd (int16x2_t a, int16x2_t b)
{
return __smusd (a, b);
}
/* { dg-final { scan-assembler-times "\tsmusd\t...?, ...?, ...?" 1 } } */
int32_t
test_smusdx (int16x2_t a, int16x2_t b)
{
return __smusdx (a, b);
}
/* { dg-final { scan-assembler-times "\tsmusdx\t...?, ...?, ...?" 1 } } */
uint32_t
test_usad8 (uint8x4_t a, uint8x4_t b)
{
return __usad8 (a, b);
}
/* { dg-final { scan-assembler-times "\tusad8\t...?, ...?, ...?" 1 } } */
uint32_t
test_usada8 (uint8x4_t a, uint8x4_t b, uint32_t c)
{
return __usada8 (a, b, c);
}
/* { dg-final { scan-assembler-times "\tusada8\t...?, ...?, ...?, ...?" 1 } } */

View File

@ -3806,6 +3806,45 @@ proc check_effective_target_arm_neon_ok { } {
check_effective_target_arm_neon_ok_nocache]
}
# Return 1 if this is an ARM target supporting the SIMD32 intrinsics
# from arm_acle.h. Some multilibs may be incompatible with these options.
# Also set et_arm_simd32_flags to the best options to add.
# arm_acle.h includes stdint.h which can cause trouble with incompatible
# -mfloat-abi= options.
proc check_effective_target_arm_simd32_ok_nocache { } {
global et_arm_simd32_flags
set et_arm_simd32_flags ""
foreach flags {"" "-march=armv6" "-march=armv6 -mfloat-abi=softfp" "-march=armv6 -mfloat-abi=hard"} {
if { [check_no_compiler_messages_nocache arm_simd32_ok object {
#include <arm_acle.h>
int dummy;
#ifndef __ARM_FEATURE_SIMD32
#error not SIMD32
#endif
} "$flags"] } {
set et_arm_simd32_flags $flags
return 1
}
}
return 0
}
proc check_effective_target_arm_simd32_ok { } {
return [check_cached_effective_target arm_simd32_ok \
check_effective_target_arm_simd32_ok_nocache]
}
proc add_options_for_arm_simd32 { flags } {
if { ! [check_effective_target_arm_simd32_ok] } {
return "$flags"
}
global et_arm_simd32_flags
return "$flags $et_arm_simd32_flags"
}
# Return 1 if this is an ARM target supporting -mfpu=neon without any
# -mfloat-abi= option. Useful in tests where add_options is not
# supported (such as lto tests).