From patchwork Fri Nov 6 17:05:36 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kyrylo Tkachov X-Patchwork-Id: 56139 Delivered-To: patch@linaro.org Received: by 10.112.61.134 with SMTP id p6csp1127636lbr; Fri, 6 Nov 2015 09:05:56 -0800 (PST) X-Received: by 10.68.87.161 with SMTP id az1mr19032947pbb.57.1446829556173; Fri, 06 Nov 2015 09:05:56 -0800 (PST) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id i9si1261873pbq.207.2015.11.06.09.05.55 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 06 Nov 2015 09:05:56 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-return-412970-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; spf=pass (google.com: domain of gcc-patches-return-412970-patch=linaro.org@gcc.gnu.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=gcc-patches-return-412970-patch=linaro.org@gcc.gnu.org; dkim=pass header.i=@gcc.gnu.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:content-type; q=dns; s=default; b=ewvZ/sZ00Yop0gTF7r8/A7v19Nx2sZclffJg61vbvbg eanDW6YYNUVSEAEAKPnuahOLNEhUtH8Qpj9MatvyJFZ8YD/x/DLdDEYO/sutxEXC sAkOaj+XQJ+IBgWTGMPIQvH+YcudrSMDUCs8udpIjkZVim1Q++HzPfjkZ2h4SMy8 = 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 :message-id:date:from:mime-version:to:cc:subject:content-type; s=default; bh=MRJ3Gj0jbjc3KMZvhgFPxWSeznk=; b=apllIaQuVSEZROiJx Vegh0gAknf3l4/AVPld4L5cOLfMCi8WnR3utgxhm30wmw90gOQl3Psexc9J+UDNU oRGJQjVdgKxFLThoXHFH4O7ZTUnzN8u9gjsacOEY5VFji9J0gHXMp8p4yZrSnMxg V55WJ6r79zbhKfrm9PlyvtbTc4= Received: (qmail 57805 invoked by alias); 6 Nov 2015 17:05:44 -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 57788 invoked by uid 89); 6 Nov 2015 17:05:43 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL, BAYES_00, SPF_PASS autolearn=ham version=3.3.2 X-HELO: eu-smtp-delivery-143.mimecast.com Received: from eu-smtp-delivery-143.mimecast.com (HELO eu-smtp-delivery-143.mimecast.com) (146.101.78.143) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 06 Nov 2015 17:05:42 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by eu-smtp-1.mimecast.com with ESMTP id uk-mta-35-u1vCMDCQSJSu4yFL6Ye9HQ-1; Fri, 06 Nov 2015 17:05:36 +0000 Received: from [10.2.206.200] ([10.1.2.79]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Fri, 6 Nov 2015 17:05:36 +0000 Message-ID: <563CDDE0.600@arm.com> Date: Fri, 06 Nov 2015 17:05:36 +0000 From: Kyrill Tkachov User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.2.0 MIME-Version: 1.0 To: GCC Patches CC: Ramana Radhakrishnan , Richard Earnshaw Subject: [PATCH][ARM] PR 49526: Add support for smmul, smmla, smmls instructions X-MC-Unique: u1vCMDCQSJSu4yFL6Ye9HQ-1 X-IsSubscribed: yes Hi all, This patch introduces support for the smmul, smmla and smmls instructions that appear in armv6 architecture levels and higher. To quote the SMMUL description from the ARMARM: "Signed Most Significant Word Multiply multiplies two signed 32-bit values, extracts the most significant 32 bits of the result, and writes those bits to the destination register." The smmla and smmls are the multiply-accumulate and multiply-subtract extensions of that multiply. There also exists an smmulr variant that rounds the result rather than truncating it. However, when I tried adding patterns for those forms I got an LRA ICE that I was not able to figure out. I'll try to find a testcase for that, but in the meantime there's no reason to not have patterns for the non-rounding variants. Bootstrapped and tested on arm-none-linux-gnueabihf. I've seen this trigger in quite a few places in SPEC2006 where it always made the code better. Ok for trunk? Thanks, Kyrill 2015-11-06 Kyrylo Tkachov PR target/49526 * config/arm/arm.md (*mulsidi3si_v6): New pattern. (*mulsidi3siaddsi_v6): Likewise. (*mulsidi3sisubsi_v6): Likewise. * config/arm/predicates.md (subreg_highpart_operator): New predicate. 2015-11-06 Kyrylo Tkachov PR target/49526 * gcc.target/arm/pr49526_1.c: New test. * gcc.target/arm/pr49526_2.c: Likewise. * gcc.target/arm/pr49526_3.c: Likewise. commit 88a99c0776864607f91edfb2d337894b8f698dc4 Author: Kyrylo Tkachov Date: Mon Nov 2 15:03:14 2015 +0000 [ARM] Add support for smmul,smmla,smmls instructions diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md index cf4d46e..3bed3b5 100644 --- a/gcc/config/arm/arm.md +++ b/gcc/config/arm/arm.md @@ -1559,6 +1559,53 @@ (define_insn "*mulsidi3_v6" (set_attr "predicable_short_it" "no")] ) +(define_insn "*mulsidi3si_v6" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (match_operator:SI 3 "subreg_highpart_operator" + [(mult:DI + (sign_extend:DI + (match_operand:SI 1 "s_register_operand" "%r")) + (sign_extend:DI + (match_operand:SI 2 "s_register_operand" "r")))]))] + "TARGET_32BIT && arm_arch6" + "smmul%?\t%0, %1, %2" + [(set_attr "type" "smmul") + (set_attr "predicable" "yes") + (set_attr "predicable_short_it" "no")] +) + +(define_insn "*mulsidi3siaddsi_v6" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (plus:SI + (match_operator:SI 3 "subreg_highpart_operator" + [(mult:DI + (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r")) + (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")))]) + (match_operand:SI 4 "s_register_operand" "r")))] + "TARGET_32BIT && arm_arch6" + "smmla%?\t%0, %1, %2, %4" + [(set_attr "type" "smmla") + (set_attr "predicable" "yes") + (set_attr "predicable_short_it" "no")] +) + +(define_insn "*mulsidi3sisubsi_v6" + [(set (match_operand:SI 0 "s_register_operand" "=r") + (minus:SI + (match_operand:SI 4 "s_register_operand" "r") + (match_operator:SI 3 "subreg_highpart_operator" + [(mult:DI + (sign_extend:DI + (match_operand:SI 1 "s_register_operand" "%r")) + (sign_extend:DI + (match_operand:SI 2 "s_register_operand" "r")))])))] + "TARGET_32BIT && arm_arch6" + "smmls%?\t%0, %1, %2, %4" + [(set_attr "type" "smmla") + (set_attr "predicable" "yes") + (set_attr "predicable_short_it" "no")] +) + (define_expand "umulsidi3" [(set (match_operand:DI 0 "s_register_operand" "") (mult:DI diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md index 48e4ba8..95a36e8 100644 --- a/gcc/config/arm/predicates.md +++ b/gcc/config/arm/predicates.md @@ -117,6 +117,14 @@ (define_special_predicate "subreg_lowpart_operator" (and (match_code "subreg") (match_test "subreg_lowpart_p (op)"))) +(define_special_predicate "subreg_highpart_operator" + (and (match_code "subreg") + (match_test "GET_MODE_SIZE (mode) + < GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) + && SUBREG_BYTE (op) + == subreg_highpart_offset (mode, + GET_MODE (SUBREG_REG (op)))"))) + ;; Reg, subreg(reg) or const_int. (define_predicate "reg_or_int_operand" (ior (match_code "const_int") diff --git a/gcc/testsuite/gcc.target/arm/pr49526_1.c b/gcc/testsuite/gcc.target/arm/pr49526_1.c new file mode 100644 index 0000000..c48b4ae --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr49526_1.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target arm_arch_v6_ok } */ +/* { dg-add-options arm_arch_v6 } */ + +int +foo (int a, int b) +{ + return ((long long) a * b) >> 32; +} + +/* { dg-final { scan-assembler "smmul\[ \t\]" } } */ diff --git a/gcc/testsuite/gcc.target/arm/pr49526_2.c b/gcc/testsuite/gcc.target/arm/pr49526_2.c new file mode 100644 index 0000000..1f83eab --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr49526_2.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target arm_arch_v6_ok } */ +/* { dg-add-options arm_arch_v6 } */ + +int +foo (int a, int b, int c) +{ + return c + (((long long) a * b) >> 32); +} + +/* { dg-final { scan-assembler "smmla\[ \t\]" } } */ diff --git a/gcc/testsuite/gcc.target/arm/pr49526_3.c b/gcc/testsuite/gcc.target/arm/pr49526_3.c new file mode 100644 index 0000000..b3b5f78 --- /dev/null +++ b/gcc/testsuite/gcc.target/arm/pr49526_3.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-require-effective-target arm_arch_v6_ok } */ +/* { dg-add-options arm_arch_v6 } */ + +int +foo (int a, int b, int c) +{ + return c - (((long long) a * b) >> 32); +} + +/* { dg-final { scan-assembler "smmls\[ \t\]" } } */