diff options
author | Kyrylo Tkachov <kyrylo.tkachov@arm.com> | 2019-11-07 10:50:23 +0000 |
---|---|---|
committer | Kyrylo Tkachov <ktkachov@gcc.gnu.org> | 2019-11-07 10:50:23 +0000 |
commit | 0775830a79bad1cdaa8fe279da7cbed123f696b6 (patch) | |
tree | d82b5a3fa03a2395ea8df222f06ab956fcfab98f /gcc | |
parent | 65dd610dcbcf5e1a952f341d0a441593bebe200f (diff) | |
download | gcc-0775830a79bad1cdaa8fe279da7cbed123f696b6.zip gcc-0775830a79bad1cdaa8fe279da7cbed123f696b6.tar.gz gcc-0775830a79bad1cdaa8fe279da7cbed123f696b6.tar.bz2 |
[arm][6/X] Add support for __[us]sat16 intrinsics
This last patch adds the the __ssat16 and __usat16 intrinsics that perform
"clipping" to a particular bitwidth on packed SIMD values, setting the Q bit
as appropriate.
* config/arm/arm.md (arm_<simd32_op>): New define_expand.
(arm_<simd32_op><add_clobber_q_name>_insn): New define_insn.
* config/arm/arm_acle.h (__ssat16, __usat16): Define.
* config/arm/arm_acle_builtins.def: Define builtins for the above.
* config/arm/iterators.md (USSAT16): New int_iterator.
(simd32_op): Handle UNSPEC_SSAT16, UNSPEC_USAT16.
(sup): Likewise.
* config/arm/predicates.md (ssat16_imm): New predicate.
(usat16_imm): Likewise.
* config/arm/unspecs.md (UNSPEC_SSAT16, UNSPEC_USAT16): Define.
* gcc.target/arm/acle/simd32.c: Update test.
From-SVN: r277919
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/config/arm/arm.md | 27 | ||||
-rw-r--r-- | gcc/config/arm/arm_acle.h | 18 | ||||
-rw-r--r-- | gcc/config/arm/arm_acle_builtins.def | 3 | ||||
-rw-r--r-- | gcc/config/arm/iterators.md | 6 | ||||
-rw-r--r-- | gcc/config/arm/predicates.md | 8 | ||||
-rw-r--r-- | gcc/config/arm/unspecs.md | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/arm/acle/simd32.c | 16 |
9 files changed, 96 insertions, 1 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d875026..3b9bae7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,18 @@ 2019-11-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + * config/arm/arm.md (arm_<simd32_op>): New define_expand. + (arm_<simd32_op><add_clobber_q_name>_insn): New define_insn. + * config/arm/arm_acle.h (__ssat16, __usat16): Define. + * config/arm/arm_acle_builtins.def: Define builtins for the above. + * config/arm/iterators.md (USSAT16): New int_iterator. + (simd32_op): Handle UNSPEC_SSAT16, UNSPEC_USAT16. + (sup): Likewise. + * config/arm/predicates.md (ssat16_imm): New predicate. + (usat16_imm): Likewise. + * config/arm/unspecs.md (UNSPEC_SSAT16, UNSPEC_USAT16): Define. + +2019-11-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + * config/arm/arm.md (arm_<simd32_op><add_clobber_q_name>_insn): New define_insns. (arm_<simd32_op>): New define_expands. diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index e0e528d..f1d27ff 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -5921,6 +5921,33 @@ } ) +(define_insn "arm_<simd32_op><add_clobber_q_name>_insn" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (unspec:SI + [(match_operand:SI 1 "s_register_operand" "r") + (match_operand:SI 2 "<sup>sat16_imm" "i")] USSAT16))] + "TARGET_INT_SIMD && <add_clobber_q_pred>" + "<simd32_op>%?\\t%0, %2, %1" + [(set_attr "predicable" "yes") + (set_attr "type" "alu_sreg")]) + +(define_expand "arm_<simd32_op>" + [(set (match_operand:SI 0 "s_register_operand") + (unspec:SI + [(match_operand:SI 1 "s_register_operand") + (match_operand:SI 2 "<sup>sat16_imm")] USSAT16))] + "TARGET_INT_SIMD" + { + if (ARM_Q_BIT_READ) + emit_insn (gen_arm_<simd32_op>_setq_insn (operands[0], operands[1], + operands[2])); + else + emit_insn (gen_arm_<simd32_op>_insn (operands[0], operands[1], + operands[2])); + DONE; + } +) + (define_insn "arm_sel" [(set (match_operand:SI 0 "s_register_operand" "=r") (unspec:SI diff --git a/gcc/config/arm/arm_acle.h b/gcc/config/arm/arm_acle.h index c30645e..9ea922f 100644 --- a/gcc/config/arm/arm_acle.h +++ b/gcc/config/arm/arm_acle.h @@ -564,6 +564,24 @@ __smuadx (int16x2_t __a, int16x2_t __b) return __builtin_arm_smuadx (__a, __b); } +#define __ssat16(__a, __sat) \ + __extension__ \ + ({ \ + int16x2_t __arg = (__a); \ + __builtin_sat_imm_check (__sat, 1, 16); \ + int16x2_t __res = __builtin_arm_ssat16 (__arg, __sat); \ + __res; \ + }) + +#define __usat16(__a, __sat) \ + __extension__ \ + ({ \ + int16x2_t __arg = (__a); \ + __builtin_sat_imm_check (__sat, 0, 15); \ + int16x2_t __res = __builtin_arm_usat16 (__arg, __sat); \ + __res; \ + }) + #endif #ifdef __ARM_FEATURE_SAT diff --git a/gcc/config/arm/arm_acle_builtins.def b/gcc/config/arm/arm_acle_builtins.def index 018d896..8a21ff7 100644 --- a/gcc/config/arm/arm_acle_builtins.def +++ b/gcc/config/arm/arm_acle_builtins.def @@ -114,3 +114,6 @@ VAR1 (TERNOP, smlsd, si) VAR1 (TERNOP, smlsdx, si) VAR1 (BINOP, smuad, si) VAR1 (BINOP, smuadx, si) + +VAR1 (SAT_BINOP_UNSIGNED_IMM, ssat16, si) +VAR1 (SAT_BINOP_UNSIGNED_IMM, usat16, si) diff --git a/gcc/config/arm/iterators.md b/gcc/config/arm/iterators.md index 72aba5e..c412851 100644 --- a/gcc/config/arm/iterators.md +++ b/gcc/config/arm/iterators.md @@ -458,6 +458,8 @@ (define_int_iterator SIMD32_BINOP_Q [UNSPEC_SMUAD UNSPEC_SMUADX]) +(define_int_iterator USSAT16 [UNSPEC_SSAT16 UNSPEC_USAT16]) + (define_int_iterator VQRDMLH_AS [UNSPEC_VQRDMLAH UNSPEC_VQRDMLSH]) (define_int_iterator VFM_LANE_AS [UNSPEC_VFMA_LANE UNSPEC_VFMS_LANE]) @@ -918,6 +920,7 @@ (UNSPEC_VRSRA_S_N "s") (UNSPEC_VRSRA_U_N "u") (UNSPEC_VCVTH_S "s") (UNSPEC_VCVTH_U "u") (UNSPEC_DOT_S "s") (UNSPEC_DOT_U "u") + (UNSPEC_SSAT16 "s") (UNSPEC_USAT16 "u") ]) (define_int_attr vfml_half @@ -1083,7 +1086,8 @@ (UNSPEC_USUB16 "usub16") (UNSPEC_SMLAD "smlad") (UNSPEC_SMLADX "smladx") (UNSPEC_SMLSD "smlsd") (UNSPEC_SMLSDX "smlsdx") (UNSPEC_SMUAD "smuad") - (UNSPEC_SMUADX "smuadx")]) + (UNSPEC_SMUADX "smuadx") (UNSPEC_SSAT16 "ssat16") + (UNSPEC_USAT16 "usat16")]) ;; Both kinds of return insn. (define_code_iterator RETURNS [return simple_return]) diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md index 267c446..c1f655c 100644 --- a/gcc/config/arm/predicates.md +++ b/gcc/config/arm/predicates.md @@ -193,6 +193,14 @@ (and (match_code "const_int") (match_test "IN_RANGE (UINTVAL (op), 1, GET_MODE_BITSIZE (mode))"))) +(define_predicate "ssat16_imm" + (and (match_code "const_int") + (match_test "IN_RANGE (INTVAL (op), 1, 16)"))) + +(define_predicate "usat16_imm" + (and (match_code "const_int") + (match_test "IN_RANGE (INTVAL (op), 0, 15)"))) + (define_predicate "ldrd_strd_offset_operand" (and (match_operand 0 "const_int_operand") (match_test "TARGET_LDRD && offset_ok_for_ldrd_strd (INTVAL (op))"))) diff --git a/gcc/config/arm/unspecs.md b/gcc/config/arm/unspecs.md index 8bf6d97..b4196b0 100644 --- a/gcc/config/arm/unspecs.md +++ b/gcc/config/arm/unspecs.md @@ -152,6 +152,8 @@ UNSPEC_SMLSDX ; Represent the SMLSDX operation. UNSPEC_SMUAD ; Represent the SMUAD operation. UNSPEC_SMUADX ; Represent the SMUADX operation. + UNSPEC_SSAT16 ; Represent the SSAT16 operation. + UNSPEC_USAT16 ; Represent the USAT16 operation. ]) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1a65f6b..05b12a8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -5,6 +5,10 @@ 2019-11-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com> * gcc.target/arm/acle/simd32.c: Update test. + +2019-11-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com> + + * gcc.target/arm/acle/simd32.c: Update test. * gcc.target/arm/acle/simd32_sel.c: New test. 2019-11-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com> diff --git a/gcc/testsuite/gcc.target/arm/acle/simd32.c b/gcc/testsuite/gcc.target/arm/acle/simd32.c index 0db560c..d9b337d 100644 --- a/gcc/testsuite/gcc.target/arm/acle/simd32.c +++ b/gcc/testsuite/gcc.target/arm/acle/simd32.c @@ -420,3 +420,19 @@ test_smuadx (int16x2_t a, int16x2_t b) } /* { dg-final { scan-assembler-times "\tsmuadx\t...?, ...?, ...?" 1 } } */ + +int16x2_t +test_ssat16 (int16x2_t a) +{ + return __ssat16 (a, 13); +} + +/* { dg-final { scan-assembler-times "\tssat16\t...?, #13, ...?" 1 } } */ + +int16x2_t +test_usat16 (int16x2_t a) +{ + return __usat16 (a, 15); +} + +/* { dg-final { scan-assembler-times "\tusat16\t...?, #15, ...?" 1 } } */ |