From patchwork Thu Nov 7 10:27:15 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Kyrill Tkachov X-Patchwork-Id: 1191042 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-512690-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=foss.arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="KprPZd96"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 47803c0c4xz9sPT for ; Thu, 7 Nov 2019 21:28:11 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; q=dns; s=default; b=smHhqGilI2okUHJkIEWWqUd7YiHSLGGNfSQLSynOWM3hwEvXyU 9vpffJriEVB9+Ju0HO7V27S3Lgoyn5dLUEVPWNGxJ6yGOgt3EL2EJu62lFDz3Bvq MYHITdOUyYVQAjUVZaunIZR18a0RkeUzivaCkGxz3a5CmzQhGtiHWLOMs= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:to :from:subject:message-id:date:mime-version:content-type; s= default; bh=nwlR0N7rgcElW/PO9W4H452dtoM=; b=KprPZd966ir0r6y4HC5N F2Sbnww7mRK/FNYdmdm3LKrse/evxPdAdD8GGyN3hWjASeIvnSjLkV7bBNXKmPPV i/CNUOka9BlesdR8i6jGfZXsK1idr8qpeMbwFOoWafKoIC+xPlT8ReqWoDVFEijd Gdezqo+USuzVfjSojg91LOg= Received: (qmail 46552 invoked by alias); 7 Nov 2019 10:27:22 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 46458 invoked by uid 89); 7 Nov 2019 10:27:21 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-19.0 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LOTSOFHASH autolearn=ham version=3.3.1 spammy= X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.110.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 07 Nov 2019 10:27:19 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id D63E37A7 for ; Thu, 7 Nov 2019 02:27:16 -0800 (PST) Received: from [10.2.206.47] (e120808-lin.cambridge.arm.com [10.2.206.47]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 9C9293F71A for ; Thu, 7 Nov 2019 02:27:16 -0800 (PST) To: "gcc-patches@gcc.gnu.org" From: Kyrill Tkachov Subject: [PATCH][arm][6/X] Add support for __[us]sat16 intrinsics Message-ID: Date: Thu, 7 Nov 2019 10:27:15 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.7.1 MIME-Version: 1.0 Hi all, 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. Bootstrapped and tested on arm-none-linux-gnueabihf. Committing to trunk. Thanks, Kyrill 2019-11-07  Kyrylo Tkachov      * config/arm/arm.md (arm_): New define_expand.     (arm__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      * gcc.target/arm/acle/simd32.c: Update test. diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index 7717f547ab4706183d2727013496c249edbe7abf..f2f5094f9e2a802557e5c19db1edbc028a91cbd8 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -5921,6 +5921,33 @@ } ) +(define_insn "arm__insn" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (unspec:SI + [(match_operand:SI 1 "s_register_operand" "r") + (match_operand:SI 2 "sat16_imm" "i")] USSAT16))] + "TARGET_INT_SIMD && " + "%?\\t%0, %2, %1" + [(set_attr "predicable" "yes") + (set_attr "type" "alu_sreg")]) + +(define_expand "arm_" + [(set (match_operand:SI 0 "s_register_operand") + (unspec:SI + [(match_operand:SI 1 "s_register_operand") + (match_operand:SI 2 "sat16_imm")] USSAT16))] + "TARGET_INT_SIMD" + { + if (ARM_Q_BIT_READ) + emit_insn (gen_arm__setq_insn (operands[0], operands[1], + operands[2])); + else + emit_insn (gen_arm__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 c30645e3949f84321fb1dfe3afd06167ef859d62..9ea922f2d096870d2c2d34ac43f03e3bc9dc4741 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 018d89682c61a963961515823420f1b986cd40db..8a21ff74f41840dd793221e079627055d379c474 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 72aba5e86fc20216bcba74f5cfa5b9f744497a6e..c412851843f4468c2c18bce264288705e076ac50 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 267c446c03e8903c21a0d74e43ae589ffcf689f4..c1f655c704011bbe8bac82c24a3234a23bf6b242 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 8bf6d9712054808143d308726c5c0f1d613c6ed4..b4196b0e5cd939c3ee5e3f9bd19622fcc963adae 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/gcc.target/arm/acle/simd32.c b/gcc/testsuite/gcc.target/arm/acle/simd32.c index 0db560c690e98cbf1c9e642a7a626a1a2ff8ece4..d9b337da35bae5a7eedf17bcd05c8fc065557425 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 } } */