From patchwork Sun Nov 17 01:14:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Michael Meissner X-Patchwork-Id: 2012417 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=cBV88N35; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4XrXtg70tYz1xyx for ; Sun, 17 Nov 2024 12:17:47 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id F1DB13857007 for ; Sun, 17 Nov 2024 01:17:45 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org F1DB13857007 Authentication-Results: sourceware.org; dkim=pass (2048-bit key, unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=cBV88N35 X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) by sourceware.org (Postfix) with ESMTPS id 0D80F3857007 for ; Sun, 17 Nov 2024 01:14:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0D80F3857007 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linux.ibm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 0D80F3857007 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=148.163.158.5 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1731806074; cv=none; b=EBuF811+Klvjv2dLX4D5O/iyzPJayt0lQEYiIkmbDNtAPFU2iaTH/dZGJRGd9IcVX8VS/VQZx2IR4Uf0RsBQ2JZrwW6qHx/jtCSMbhWgxAFKiuPm0qLPIqPFC+VDBR8T096GrPJJ+y0VWSQuxBITYt412FFtsmvADFtQtaul4iU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1731806074; c=relaxed/simple; bh=ymVDvEF8bnnZX7meT0luiWlR/+m7SOdl5cffogtdTeU=; h=DKIM-Signature:Date:From:To:Subject:Message-ID:MIME-Version; b=EzxK9enTpLQdPWFVXuEmXQl7Mj/B6lahY2BnePvJZLfM6gAqreduH//3Z4u1pszwNSpyg/DfdH/xc+m5kt+qq/DeNEfEw29HzYd8itlKsdJ9Z2dxKEFAIacGypYLbKCip/sB7MhPCvgfELB2S8CjDfEXv/r+6V8dCA08KFHnZzQ= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0D80F3857007 Received: from pps.filterd (m0356516.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id 4AG9lBB2023199; Sun, 17 Nov 2024 01:14:33 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h= content-type:date:from:message-id:mime-version:subject:to; s= pp1; bh=ihqlmCw0+M/k8IosylUOcvQ1JmmJksGudqPgHb1/2o0=; b=cBV88N35 AdhOCzup3xqTcWg3w0+9BzJH1PH4xhk2d4Z1/SjbrdTcts3J/FzzjMunPc6OuwS8 +2JCBkaV9Pn6eb45/oXMA6X3yFfLRdXcJAQiq0OBrdSLXn9gwQGH6jgaDrwtHGsp Od8kg0w8KxJClQe9OZ2fdvHDsP8UsG5ETpCOlFzyKghYIe/qqgmyQQeAkqyrUDzC 9t9BKPz4bbDb4bKmc36wdEFCad1grYbl2UXs/+Inrj42Df8ZrsnM/whRYk0eaLsc FpBYPK3EYoA1eJdv36GC7QtgPpbzMV/fDpssVscGGOIbRzlE7mH8Vg6/G22fR2Wo cSuL618MkJ2jAA== Received: from ppma11.dal12v.mail.ibm.com (db.9e.1632.ip4.static.sl-reverse.com [50.22.158.219]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 42xgtsum58-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 17 Nov 2024 01:14:33 +0000 (GMT) Received: from pps.filterd (ppma11.dal12v.mail.ibm.com [127.0.0.1]) by ppma11.dal12v.mail.ibm.com (8.18.1.2/8.18.1.2) with ESMTP id 4AGJfetE002761; Sun, 17 Nov 2024 01:14:32 GMT Received: from smtprelay06.dal12v.mail.ibm.com ([172.16.1.8]) by ppma11.dal12v.mail.ibm.com (PPS) with ESMTPS id 42tms1cujw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Sun, 17 Nov 2024 01:14:32 +0000 Received: from smtpav01.dal12v.mail.ibm.com (smtpav01.dal12v.mail.ibm.com [10.241.53.100]) by smtprelay06.dal12v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 4AH1EVao47710626 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Sun, 17 Nov 2024 01:14:31 GMT Received: from smtpav01.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 0D42E5805D; Sun, 17 Nov 2024 01:14:31 +0000 (GMT) Received: from smtpav01.dal12v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 2112058057; Sun, 17 Nov 2024 01:14:30 +0000 (GMT) Received: from cowardly-lion.the-meissners.org (unknown [9.61.98.188]) by smtpav01.dal12v.mail.ibm.com (Postfix) with ESMTPS; Sun, 17 Nov 2024 01:14:30 +0000 (GMT) Date: Sat, 16 Nov 2024 20:14:28 -0500 From: Michael Meissner To: gcc-patches@gcc.gnu.org, Michael Meissner , Segher Boessenkool , Peter Bergner Subject: [PATCH repost] PR target/117251 Add PowerPC XXEVAL support for fusion optimization in power10 Message-ID: Mail-Followup-To: Michael Meissner , gcc-patches@gcc.gnu.org, Segher Boessenkool , Peter Bergner MIME-Version: 1.0 Content-Disposition: inline X-TM-AS-GCONF: 00 X-Proofpoint-GUID: 3kWt6ViWPWDZYPE14497PEU3LOAx5ztH X-Proofpoint-ORIG-GUID: 3kWt6ViWPWDZYPE14497PEU3LOAx5ztH X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1051,Hydra:6.0.680,FMLib:17.12.62.30 definitions=2024-10-15_01,2024-10-11_01,2024-09-30_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 phishscore=0 mlxscore=0 malwarescore=0 mlxlogscore=999 adultscore=0 priorityscore=1501 bulkscore=0 impostorscore=0 spamscore=0 lowpriorityscore=0 suspectscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.19.0-2409260000 definitions=main-2411170007 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org I had posted this patch previously, and I am reposting it in case it got lost: The multibuff.c benchmark attached to the PR target/117251 compiled for Power10 PowerPC that implement SHA3 has a slowdown in the current trunk and GCC 14 compared to GCC 11 - GCC 13, due to excessive amounts of spilling. The main function for the multibuf.c file has 3,747 lines, all of which are using vector unsigned long long. There are 696 vector rotates (all rotates are constant), 1,824 vector xor's and 600 vector andc's. In looking at it, the main thing that steps out is the reason for either spilling or moving variables is the support in fusion.md (generated by genfusion.pl) that tries to fuse the vec_andc feeding into vec_xor, and other vec_xor's feeding into vec_xor. On the powerpc for power10, there is a special fusion mode that happens if the machine has a VANDC or VXOR instruction that is adjacent to a VXOR instruction and the VANDC/VXOR feeds into the 2nd VXOR instruction. While the Power10 has 64 vector registers (which uses the XXL prefix to do logical operations), the fusion only works with the older Altivec instruction set (which uses the V prefix). The Altivec instruction only has 32 vector registers (which are overlaid over the VSX vector registers 32-63). By having the combiner patterns fuse_vandc_vxor and fuse_vxor_vxor to do this fusion, it means that the register allocator has more register pressure for the traditional Altivec registers instead of the VSX registers. In addition, since there are vector rotates, these rotates only work on the traditional Altivec registers, which adds to the Altivec register pressure. Finally in addition to doing the explicit xor, andc, and rotates using the Altivec registers, we have to also load vector constants for the rotate amount and these registers also are allocated as Altivec registers. Current trunk and GCC 12-14 have more vector spills than GCC 11, but GCC 11 has many more vector moves that the later compilers. Thus even though it has way less spills, the vector moves are why GCC 11 have the slowest results. There is an instruction that was added in power10 (XXEVAL) that does provide fusion between VSX vectors that includes ANDC->XOR and XOR->XOR fusion. The latency of XXEVAL is slightly more than the fused VANDC/VXOR or VXOR/VXOR, so I have written the patch to prefer doing the Altivec instructions if they don't need a temporary register. Here are the results for adding support for XXEVAL for the multibuff.c benchmark attached to the PR. Note that we essentially recover the speed with this patch that were lost with GCC 14 and the current trunk: XXEVAL Trunk GCC14 GCC13 GCC12 GCC11 ------ ----- ----- ----- ----- ----- Benchmark time in seconds 5.53 6.15 6.26 5.57 5.61 9.56 Fuse VANDC -> VXOR 209 600 600 600 600 600 Fuse VXOR -> VXOR 0 240 240 120 120 120 XXEVAL to fuse ANDC -> XOR 391 0 0 0 0 0 XXEVAL to fuse XOR -> XOR 240 0 0 0 0 0 Spill vector to stack 78 364 364 172 184 110 Load spilled vector from stack 431 962 962 713 723 166 Vector moves 10 100 100 70 72 3,055 Vector rotate right 696 696 696 696 696 696 XXLANDC or VANDC 209 600 600 600 600 600 XXLXOR or VXOR 953 1,824 1,824 1,824 1,824 1,825 XXEVAL 631 0 0 0 0 0 Load vector rotate constants 24 24 24 24 24 24 Here are the results for adding support for XXEVAL for the singlebuff.c benchmark attached to the PR. Note that adding XXEVAL greatly speeds up this particular benchmark: XXEVAL Trunk GCC14 GCC13 GCC12 GCC11 ------ ----- ----- ----- ----- ----- Benchmark time in seconds 4.46 5.40 5.40 5.35 5.36 7.54 Fuse VANDC -> VXOR 210 600 600 600 600 600 Fuse VXOR -> VXOR 0 240 240 120 120 120 XXEVAL to fuse ANDC -> XOR 390 0 0 0 0 0 XXEVAL to fuse XOR -> XOR 240 0 0 0 0 0 Spill vector to stack 113 379 379 382 382 63 Load spilled vector from stack 333 796 796 757 757 68 Vector moves 34 80 80 119 119 2,409 Vector rotate right 696 696 696 696 696 696 XXLANDC or VANDC 210 600 600 600 600 600 XXLXOR or VXOR 954 1,824 1,824 1,824 1,824 1,824 XXEVAL 630 0 0 0 0 0 Load vector rotate constants 96 96 96 96 96 96 These patches add the following fusion patterns: xxland => xxland xxlandc => xxland xxlxor => xxland xxlor => xxland xxlnor => xxland xxleqv => xxland xxlorc => xxland xxlandc => xxlandc xxlnand => xxland xxlnand => xxlnor xxland => xxlxor xxland => xxlor xxlandc => xxlxor xxlandc => xxlor xxlorc => xxlnor xxlorc => xxleqv xxlorc => xxlorc xxleqv => xxlnor xxlxor => xxlxor xxlxor => xxlor xxlnor => xxlnor xxlor => xxlxor xxlor => xxlor xxlor => xxlnor xxlnor => xxlxor xxlnor => xxlor xxlxor => xxlnor xxleqv => xxlxor xxleqv => xxlor xxlorc => xxlxor xxlorc => xxlor xxlandc => xxlnor xxlandc => xxleqv xxland => xxlnor xxlnand => xxlxor xxlnand => xxlor xxlnand => xxlnand xxlorc => xxlnand xxleqv => xxlnand xxlnor => xxlnand xxlor => xxlnand xxlxor => xxlnand xxlandc => xxlnand xxland => xxlnand I have built GCC with the patches in this patch set applied on both little and big endian PowerPC systems and there were no regressions. Can I apply this patch to GCC 15? 2024-11-16 Michael Meissner gcc/ PR target/117251 * config/rs6000/fusion.md: Regenerate. * config/rs6000/genfusion.pl (gen_logical_addsubf): Add support to generate vector/vector logical fusion if XXEVAL supports the fusion. * config/rs6000/predicates.md (vector_fusion_operand): New predicate. * config/rs6000/rs6000.cc (rs6000_opt_vars): Add -mxxeval. * config/rs6000/rs6000.md (isa attribute): Add xxeval. (enabled attribute): Add support for -mxxeval. * config/rs6000/rs6000.opt (-mxxeval): New switch. gcc/testsuite/ PR target/117251 * gcc.target/powerpc/p10-vector-fused-1.c: New test. * gcc.target/powerpc/p10-vector-fused-2.c: Likewise. --- gcc/config/rs6000/fusion.md | 660 +++++++----- gcc/config/rs6000/genfusion.pl | 102 +- gcc/config/rs6000/predicates.md | 14 +- gcc/config/rs6000/rs6000.cc | 3 + gcc/config/rs6000/rs6000.md | 7 +- gcc/config/rs6000/rs6000.opt | 4 + .../gcc.target/powerpc/p10-vector-fused-1.c | 409 ++++++++ .../gcc.target/powerpc/p10-vector-fused-2.c | 936 ++++++++++++++++++ 8 files changed, 1865 insertions(+), 270 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/p10-vector-fused-1.c create mode 100644 gcc/testsuite/gcc.target/powerpc/p10-vector-fused-2.c diff --git a/gcc/config/rs6000/fusion.md b/gcc/config/rs6000/fusion.md index 4ed9ae1d69f..215a3aae074 100644 --- a/gcc/config/rs6000/fusion.md +++ b/gcc/config/rs6000/fusion.md @@ -1871,146 +1871,170 @@ (define_insn "*fuse_or_rsubf" ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vand -> vand (define_insn "*fuse_vand_vand" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (and:VM (and:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v") - (match_operand:VM 1 "altivec_register_operand" "%v,v,v,v")) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (and:VM (and:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v") + (match_operand:VM 1 "vector_fusion_operand" "%v,v,v,wa,v")) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vand %3,%1,%0\;vand %3,%3,%2 vand %3,%1,%0\;vand %3,%3,%2 vand %3,%1,%0\;vand %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,1 vand %4,%1,%0\;vand %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vandc -> vand (define_insn "*fuse_vandc_vand" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (and:VM (and:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (and:VM (and:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vandc %3,%1,%0\;vand %3,%3,%2 vandc %3,%1,%0\;vand %3,%3,%2 vandc %3,%1,%0\;vand %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,2 vandc %4,%1,%0\;vand %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector veqv -> vand (define_insn "*fuse_veqv_vand" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (and:VM (not:VM (xor:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v") - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (and:VM (not:VM (xor:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v") + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v"))) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ veqv %3,%1,%0\;vand %3,%3,%2 veqv %3,%1,%0\;vand %3,%3,%2 veqv %3,%1,%0\;vand %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,9 veqv %4,%1,%0\;vand %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vnand -> vand (define_insn "*fuse_vnand_vand" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (and:VM (ior:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (and:VM (ior:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (not:VM (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v"))) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vnand %3,%1,%0\;vand %3,%3,%2 vnand %3,%1,%0\;vand %3,%3,%2 vnand %3,%1,%0\;vand %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,14 vnand %4,%1,%0\;vand %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vnor -> vand (define_insn "*fuse_vnor_vand" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (and:VM (and:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (and:VM (and:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (not:VM (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v"))) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vnor %3,%1,%0\;vand %3,%3,%2 vnor %3,%1,%0\;vand %3,%3,%2 vnor %3,%1,%0\;vand %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,8 vnor %4,%1,%0\;vand %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vor -> vand (define_insn "*fuse_vor_vand" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (and:VM (ior:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v") - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (and:VM (ior:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v") + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vor %3,%1,%0\;vand %3,%3,%2 vor %3,%1,%0\;vand %3,%3,%2 vor %3,%1,%0\;vand %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,7 vor %4,%1,%0\;vand %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vorc -> vand (define_insn "*fuse_vorc_vand" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (and:VM (ior:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (and:VM (ior:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vorc %3,%1,%0\;vand %3,%3,%2 vorc %3,%1,%0\;vand %3,%3,%2 vorc %3,%1,%0\;vand %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,11 vorc %4,%1,%0\;vand %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vxor -> vand (define_insn "*fuse_vxor_vand" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (and:VM (xor:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v") - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (and:VM (xor:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v") + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vxor %3,%1,%0\;vand %3,%3,%2 vxor %3,%1,%0\;vand %3,%3,%2 vxor %3,%1,%0\;vand %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,6 vxor %4,%1,%0\;vand %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vand -> vandc @@ -2033,20 +2057,23 @@ (define_insn "*fuse_vand_vandc" ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vandc -> vandc (define_insn "*fuse_vandc_vandc" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (and:VM (and:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")) - (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (and:VM (and:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v")) + (not:VM (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vandc %3,%1,%0\;vandc %3,%3,%2 vandc %3,%1,%0\;vandc %3,%3,%2 vandc %3,%1,%0\;vandc %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,13 vandc %4,%1,%0\;vandc %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector veqv -> vandc @@ -2177,20 +2204,23 @@ (define_insn "*fuse_vand_veqv" ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vandc -> veqv (define_insn "*fuse_vandc_veqv" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (not:VM (xor:VM (and:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (not:VM (xor:VM (and:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vandc %3,%1,%0\;veqv %3,%3,%2 vandc %3,%1,%0\;veqv %3,%3,%2 vandc %3,%1,%0\;veqv %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,210 vandc %4,%1,%0\;veqv %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector veqv -> veqv @@ -2267,20 +2297,23 @@ (define_insn "*fuse_vor_veqv" ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vorc -> veqv (define_insn "*fuse_vorc_veqv" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (not:VM (xor:VM (ior:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (not:VM (xor:VM (ior:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vorc %3,%1,%0\;veqv %3,%3,%2 vorc %3,%1,%0\;veqv %3,%3,%2 vorc %3,%1,%0\;veqv %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,75 vorc %4,%1,%0\;veqv %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vxor -> veqv @@ -2303,434 +2336,506 @@ (define_insn "*fuse_vxor_veqv" ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vand -> vnand (define_insn "*fuse_vand_vnand" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (ior:VM (not:VM (and:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v") - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))) - (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (ior:VM (not:VM (and:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v") + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v"))) + (not:VM (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vand %3,%1,%0\;vnand %3,%3,%2 vand %3,%1,%0\;vnand %3,%3,%2 vand %3,%1,%0\;vnand %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,254 vand %4,%1,%0\;vnand %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vandc -> vnand (define_insn "*fuse_vandc_vnand" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (ior:VM (not:VM (and:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))) - (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (ior:VM (not:VM (and:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v"))) + (not:VM (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vandc %3,%1,%0\;vnand %3,%3,%2 vandc %3,%1,%0\;vnand %3,%3,%2 vandc %3,%1,%0\;vnand %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,253 vandc %4,%1,%0\;vnand %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector veqv -> vnand (define_insn "*fuse_veqv_vnand" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (ior:VM (not:VM (not:VM (xor:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v") - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))) - (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (ior:VM (not:VM (not:VM (xor:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v") + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v")))) + (not:VM (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ veqv %3,%1,%0\;vnand %3,%3,%2 veqv %3,%1,%0\;vnand %3,%3,%2 veqv %3,%1,%0\;vnand %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,246 veqv %4,%1,%0\;vnand %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vnand -> vnand (define_insn "*fuse_vnand_vnand" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (ior:VM (not:VM (ior:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))) - (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (ior:VM (not:VM (ior:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (not:VM (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v")))) + (not:VM (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vnand %3,%1,%0\;vnand %3,%3,%2 vnand %3,%1,%0\;vnand %3,%3,%2 vnand %3,%1,%0\;vnand %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,241 vnand %4,%1,%0\;vnand %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vnor -> vnand (define_insn "*fuse_vnor_vnand" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (ior:VM (not:VM (and:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))) - (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (ior:VM (not:VM (and:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (not:VM (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v")))) + (not:VM (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vnor %3,%1,%0\;vnand %3,%3,%2 vnor %3,%1,%0\;vnand %3,%3,%2 vnor %3,%1,%0\;vnand %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,247 vnor %4,%1,%0\;vnand %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vor -> vnand (define_insn "*fuse_vor_vnand" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (ior:VM (not:VM (ior:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v") - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))) - (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (ior:VM (not:VM (ior:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v") + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v"))) + (not:VM (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vor %3,%1,%0\;vnand %3,%3,%2 vor %3,%1,%0\;vnand %3,%3,%2 vor %3,%1,%0\;vnand %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,248 vor %4,%1,%0\;vnand %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vorc -> vnand (define_insn "*fuse_vorc_vnand" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (ior:VM (not:VM (ior:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))) - (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (ior:VM (not:VM (ior:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v"))) + (not:VM (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vorc %3,%1,%0\;vnand %3,%3,%2 vorc %3,%1,%0\;vnand %3,%3,%2 vorc %3,%1,%0\;vnand %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,244 vorc %4,%1,%0\;vnand %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vxor -> vnand (define_insn "*fuse_vxor_vnand" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (ior:VM (not:VM (xor:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v") - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))) - (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (ior:VM (not:VM (xor:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v") + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v"))) + (not:VM (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vxor %3,%1,%0\;vnand %3,%3,%2 vxor %3,%1,%0\;vnand %3,%3,%2 vxor %3,%1,%0\;vnand %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,249 vxor %4,%1,%0\;vnand %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vand -> vnor (define_insn "*fuse_vand_vnor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (and:VM (not:VM (and:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v") - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))) - (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (and:VM (not:VM (and:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v") + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v"))) + (not:VM (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vand %3,%1,%0\;vnor %3,%3,%2 vand %3,%1,%0\;vnor %3,%3,%2 vand %3,%1,%0\;vnor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,224 vand %4,%1,%0\;vnor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vandc -> vnor (define_insn "*fuse_vandc_vnor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (and:VM (not:VM (and:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))) - (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (and:VM (not:VM (and:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v"))) + (not:VM (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vandc %3,%1,%0\;vnor %3,%3,%2 vandc %3,%1,%0\;vnor %3,%3,%2 vandc %3,%1,%0\;vnor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,208 vandc %4,%1,%0\;vnor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector veqv -> vnor (define_insn "*fuse_veqv_vnor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (and:VM (not:VM (not:VM (xor:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v") - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))) - (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (and:VM (not:VM (not:VM (xor:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v") + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v")))) + (not:VM (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ veqv %3,%1,%0\;vnor %3,%3,%2 veqv %3,%1,%0\;vnor %3,%3,%2 veqv %3,%1,%0\;vnor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,96 veqv %4,%1,%0\;vnor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vnand -> vnor (define_insn "*fuse_vnand_vnor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (and:VM (not:VM (ior:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))) - (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (and:VM (not:VM (ior:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (not:VM (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v")))) + (not:VM (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vnand %3,%1,%0\;vnor %3,%3,%2 vnand %3,%1,%0\;vnor %3,%3,%2 vnand %3,%1,%0\;vnor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,16 vnand %4,%1,%0\;vnor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vnor -> vnor (define_insn "*fuse_vnor_vnor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (and:VM (not:VM (and:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")))) - (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (and:VM (not:VM (and:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (not:VM (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v")))) + (not:VM (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vnor %3,%1,%0\;vnor %3,%3,%2 vnor %3,%1,%0\;vnor %3,%3,%2 vnor %3,%1,%0\;vnor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,112 vnor %4,%1,%0\;vnor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vor -> vnor (define_insn "*fuse_vor_vnor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (and:VM (not:VM (ior:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v") - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))) - (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (and:VM (not:VM (ior:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v") + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v"))) + (not:VM (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vor %3,%1,%0\;vnor %3,%3,%2 vor %3,%1,%0\;vnor %3,%3,%2 vor %3,%1,%0\;vnor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,128 vor %4,%1,%0\;vnor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vorc -> vnor (define_insn "*fuse_vorc_vnor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (and:VM (not:VM (ior:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))) - (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (and:VM (not:VM (ior:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v"))) + (not:VM (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vorc %3,%1,%0\;vnor %3,%3,%2 vorc %3,%1,%0\;vnor %3,%3,%2 vorc %3,%1,%0\;vnor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,64 vorc %4,%1,%0\;vnor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vxor -> vnor (define_insn "*fuse_vxor_vnor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (and:VM (not:VM (xor:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v") - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))) - (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (and:VM (not:VM (xor:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v") + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v"))) + (not:VM (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vxor %3,%1,%0\;vnor %3,%3,%2 vxor %3,%1,%0\;vnor %3,%3,%2 vxor %3,%1,%0\;vnor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,144 vxor %4,%1,%0\;vnor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vand -> vor (define_insn "*fuse_vand_vor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (ior:VM (and:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v") - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (ior:VM (and:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v") + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vand %3,%1,%0\;vor %3,%3,%2 vand %3,%1,%0\;vor %3,%3,%2 vand %3,%1,%0\;vor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,31 vand %4,%1,%0\;vor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vandc -> vor (define_insn "*fuse_vandc_vor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (ior:VM (and:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (ior:VM (and:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vandc %3,%1,%0\;vor %3,%3,%2 vandc %3,%1,%0\;vor %3,%3,%2 vandc %3,%1,%0\;vor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,47 vandc %4,%1,%0\;vor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector veqv -> vor (define_insn "*fuse_veqv_vor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (ior:VM (not:VM (xor:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v") - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (ior:VM (not:VM (xor:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v") + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v"))) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ veqv %3,%1,%0\;vor %3,%3,%2 veqv %3,%1,%0\;vor %3,%3,%2 veqv %3,%1,%0\;vor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,159 veqv %4,%1,%0\;vor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vnand -> vor (define_insn "*fuse_vnand_vor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (ior:VM (ior:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (ior:VM (ior:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (not:VM (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v"))) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vnand %3,%1,%0\;vor %3,%3,%2 vnand %3,%1,%0\;vor %3,%3,%2 vnand %3,%1,%0\;vor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,239 vnand %4,%1,%0\;vor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vnor -> vor (define_insn "*fuse_vnor_vor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (ior:VM (and:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (ior:VM (and:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (not:VM (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v"))) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vnor %3,%1,%0\;vor %3,%3,%2 vnor %3,%1,%0\;vor %3,%3,%2 vnor %3,%1,%0\;vor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,143 vnor %4,%1,%0\;vor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vor -> vor (define_insn "*fuse_vor_vor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (ior:VM (ior:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v") - (match_operand:VM 1 "altivec_register_operand" "%v,v,v,v")) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (ior:VM (ior:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v") + (match_operand:VM 1 "vector_fusion_operand" "%v,v,v,wa,v")) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vor %3,%1,%0\;vor %3,%3,%2 vor %3,%1,%0\;vor %3,%3,%2 vor %3,%1,%0\;vor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,127 vor %4,%1,%0\;vor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vorc -> vor (define_insn "*fuse_vorc_vor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (ior:VM (ior:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (ior:VM (ior:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vorc %3,%1,%0\;vor %3,%3,%2 vorc %3,%1,%0\;vor %3,%3,%2 vorc %3,%1,%0\;vor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,191 vorc %4,%1,%0\;vor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vxor -> vor (define_insn "*fuse_vxor_vor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (ior:VM (xor:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v") - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (ior:VM (xor:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v") + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vxor %3,%1,%0\;vor %3,%3,%2 vxor %3,%1,%0\;vor %3,%3,%2 vxor %3,%1,%0\;vor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,111 vxor %4,%1,%0\;vor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vand -> vorc @@ -2843,20 +2948,23 @@ (define_insn "*fuse_vor_vorc" ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vorc -> vorc (define_insn "*fuse_vorc_vorc" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (ior:VM (ior:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")) - (not:VM (match_operand:VM 2 "altivec_register_operand" "v,v,v,v")))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (ior:VM (ior:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v")) + (not:VM (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v")))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vorc %3,%1,%0\;vorc %3,%3,%2 vorc %3,%1,%0\;vorc %3,%3,%2 vorc %3,%1,%0\;vorc %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,79 vorc %4,%1,%0\;vorc %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vxor -> vorc @@ -2879,146 +2987,170 @@ (define_insn "*fuse_vxor_vorc" ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vand -> vxor (define_insn "*fuse_vand_vxor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (xor:VM (and:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v") - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (xor:VM (and:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v") + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vand %3,%1,%0\;vxor %3,%3,%2 vand %3,%1,%0\;vxor %3,%3,%2 vand %3,%1,%0\;vxor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,30 vand %4,%1,%0\;vxor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vandc -> vxor (define_insn "*fuse_vandc_vxor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (xor:VM (and:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (xor:VM (and:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vandc %3,%1,%0\;vxor %3,%3,%2 vandc %3,%1,%0\;vxor %3,%3,%2 vandc %3,%1,%0\;vxor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,45 vandc %4,%1,%0\;vxor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector veqv -> vxor (define_insn "*fuse_veqv_vxor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (xor:VM (not:VM (xor:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v") - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (xor:VM (not:VM (xor:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v") + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v"))) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ veqv %3,%1,%0\;vxor %3,%3,%2 veqv %3,%1,%0\;vxor %3,%3,%2 veqv %3,%1,%0\;vxor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,150 veqv %4,%1,%0\;vxor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vnand -> vxor (define_insn "*fuse_vnand_vxor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (xor:VM (ior:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (xor:VM (ior:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (not:VM (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v"))) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vnand %3,%1,%0\;vxor %3,%3,%2 vnand %3,%1,%0\;vxor %3,%3,%2 vnand %3,%1,%0\;vxor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,225 vnand %4,%1,%0\;vxor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vnor -> vxor (define_insn "*fuse_vnor_vxor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (xor:VM (and:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (not:VM (match_operand:VM 1 "altivec_register_operand" "v,v,v,v"))) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (xor:VM (and:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (not:VM (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v"))) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vnor %3,%1,%0\;vxor %3,%3,%2 vnor %3,%1,%0\;vxor %3,%3,%2 vnor %3,%1,%0\;vxor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,135 vnor %4,%1,%0\;vxor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vor -> vxor (define_insn "*fuse_vor_vxor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (xor:VM (ior:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v") - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (xor:VM (ior:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v") + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vor %3,%1,%0\;vxor %3,%3,%2 vor %3,%1,%0\;vxor %3,%3,%2 vor %3,%1,%0\;vxor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,120 vor %4,%1,%0\;vxor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vorc -> vxor (define_insn "*fuse_vorc_vxor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (xor:VM (ior:VM (not:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 1 "altivec_register_operand" "v,v,v,v")) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (xor:VM (ior:VM (not:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 1 "vector_fusion_operand" "v,v,v,wa,v")) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vorc %3,%1,%0\;vxor %3,%3,%2 vorc %3,%1,%0\;vxor %3,%3,%2 vorc %3,%1,%0\;vxor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,180 vorc %4,%1,%0\;vxor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; logical-logical fusion pattern generated by gen_logical_addsubf ;; vector vxor -> vxor (define_insn "*fuse_vxor_vxor" - [(set (match_operand:VM 3 "altivec_register_operand" "=&0,&1,&v,v") - (xor:VM (xor:VM (match_operand:VM 0 "altivec_register_operand" "v,v,v,v") - (match_operand:VM 1 "altivec_register_operand" "%v,v,v,v")) - (match_operand:VM 2 "altivec_register_operand" "v,v,v,v"))) - (clobber (match_scratch:VM 4 "=X,X,X,&v"))] + [(set (match_operand:VM 3 "vector_fusion_operand" "=&0,&1,&v,wa,v") + (xor:VM (xor:VM (match_operand:VM 0 "vector_fusion_operand" "v,v,v,wa,v") + (match_operand:VM 1 "vector_fusion_operand" "%v,v,v,wa,v")) + (match_operand:VM 2 "vector_fusion_operand" "v,v,v,wa,v"))) + (clobber (match_scratch:VM 4 "=X,X,X,X,&v"))] "(TARGET_P10_FUSION)" "@ vxor %3,%1,%0\;vxor %3,%3,%2 vxor %3,%1,%0\;vxor %3,%3,%2 vxor %3,%1,%0\;vxor %3,%3,%2 + xxeval %x3,%x2,%x1,%x0,105 vxor %4,%1,%0\;vxor %3,%4,%2" [(set_attr "type" "fused_vector") (set_attr "cost" "6") - (set_attr "length" "8")]) + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) ;; add-add fusion pattern generated by gen_addadd (define_insn "*fuse_add_add" diff --git a/gcc/config/rs6000/genfusion.pl b/gcc/config/rs6000/genfusion.pl index 2271be14bfa..de1590741a6 100755 --- a/gcc/config/rs6000/genfusion.pl +++ b/gcc/config/rs6000/genfusion.pl @@ -211,25 +211,76 @@ sub gen_logical_addsubf $inner_comp, $inner_inv, $inner_rtl, $inner_op, $both_commute, $c4, $bc, $inner_arg0, $inner_arg1, $inner_exp, $outer_arg2, $outer_exp, $ftype, $insn, $is_subf, $is_rsubf, $outer_32, $outer_42,$outer_name, - $fuse_type); - KIND: foreach $kind ('scalar','vector') { + $fuse_type, $xxeval, $c5, $vect_pred, $vect_inner_arg0, $vect_inner_arg1, + $vect_inner_exp, $vect_outer_arg2, $vect_outer_exp); + + my %xxeval_fusions = ( + "vand_vand" => 1, + "vandc_vand" => 2, + "vxor_vand" => 6, + "vor_vand" => 7, + "vnor_vand" => 8, + "veqv_vand" => 9, + "vorc_vand" => 11, + "vandc_vandc" => 13, + "vnand_vand" => 14, + "vnand_vnor" => 16, + "vand_vxor" => 30, + "vand_vor" => 31, + "vandc_vxor" => 45, + "vandc_vor" => 47, + "vorc_vnor" => 64, + "vorc_veqv" => 75, + "vorc_vorc" => 79, + "veqv_vnor" => 96, + "vxor_vxor" => 105, + "vxor_vor" => 111, + "vnor_vnor" => 112, + "vor_vxor" => 120, + "vor_vor" => 127, + "vor_vnor" => 128, + "vnor_vxor" => 135, + "vnor_vor" => 143, + "vxor_vnor" => 144, + "veqv_vxor" => 150, + "veqv_vor" => 159, + "vorc_vxor" => 180, + "vorc_vor" => 191, + "vandc_vnor" => 208, + "vandc_veqv" => 210, + "vand_vnor" => 224, + "vnand_vxor" => 225, + "vnand_vor" => 239, + "vnand_vnand" => 241, + "vorc_vnand" => 244, + "veqv_vnand" => 246, + "vnor_vnand" => 247, + "vor_vnand" => 248, + "vxor_vnand" => 249, + "vandc_vnand" => 253, + "vand_vnand" => 254, + ); + + KIND: foreach $kind ('scalar','vector') { @outer_ops = @logicals; if ( $kind eq 'vector' ) { $vchr = "v"; $mode = "VM"; $pred = "altivec_register_operand"; + $vect_pred = "vector_fusion_operand"; $constraint = "v"; $fuse_type = "fused_vector"; } else { $vchr = ""; $mode = "GPR"; - $pred = "gpc_reg_operand"; + $vect_pred = $pred = "gpc_reg_operand"; $constraint = "r"; $fuse_type = "fused_arith_logical"; push (@outer_ops, @addsub); push (@outer_ops, ( "rsubf" )); } $c4 = "${constraint},${constraint},${constraint},${constraint}"; + $c5 = "${constraint},${constraint},${constraint},wa,${constraint}"; OUTER: foreach $outer ( @outer_ops ) { $outer_name = "${vchr}${outer}"; $is_subf = ( $outer eq "subf" ); @@ -257,29 +308,40 @@ sub gen_logical_addsubf $inner_inv = $invert{$inner}; $inner_rtl = $rtlop{$inner}; $inner_op = "${vchr}${inner}"; + # If both ops commute then we can specify % on operand 1 # so the pattern will let operands 1 and 2 interchange. $both_commute = ($inner eq $outer) && ($commute2{$inner} == 1); $bc = ""; if ( $both_commute ) { $bc = "%"; } $inner_arg0 = "(match_operand:${mode} 0 \"${pred}\" \"${c4}\")"; $inner_arg1 = "(match_operand:${mode} 1 \"${pred}\" \"${bc}${c4}\")"; + $vect_inner_arg0 = "(match_operand:${mode} 0 \"${vect_pred}\" \"${c5}\")"; + $vect_inner_arg1 = "(match_operand:${mode} 1 \"${vect_pred}\" \"${bc}${c5}\")"; if ( ($inner_comp & 1) == 1 ) { $inner_arg0 = "(not:${mode} $inner_arg0)"; + $vect_inner_arg0 = "(not:${mode} $vect_inner_arg0)"; } if ( ($inner_comp & 2) == 2 ) { $inner_arg1 = "(not:${mode} $inner_arg1)"; + $vect_inner_arg1 = "(not:${mode} $vect_inner_arg1)"; } $inner_exp = "(${inner_rtl}:${mode} ${inner_arg0} ${inner_arg1})"; + $vect_inner_exp = "(${inner_rtl}:${mode} ${vect_inner_arg0} + ${vect_inner_arg1})"; if ( $inner_inv == 1 ) { $inner_exp = "(not:${mode} $inner_exp)"; + $vect_inner_exp = "(not:${mode} $vect_inner_exp)"; } $outer_arg2 = "(match_operand:${mode} 2 \"${pred}\" \"${c4}\")"; + $vect_outer_arg2 = "(match_operand:${mode} 2 \"${vect_pred}\" \"${c5}\")"; if ( ($outer_comp & 1) == 1 ) { $outer_arg2 = "(not:${mode} $outer_arg2)"; + $vect_outer_arg2 = "(not:${mode} $vect_outer_arg2)"; } if ( ($outer_comp & 2) == 2 ) { $inner_exp = "(not:${mode} $inner_exp)"; + $vect_inner_exp = "(not:${mode} $vect_inner_exp)"; } if ( $is_subf ) { $outer_32 = "%2,%3"; @@ -291,15 +353,23 @@ sub gen_logical_addsubf if ( $is_rsubf == 1 ) { $outer_exp = "(${outer_rtl}:${mode} ${outer_arg2} ${inner_exp})"; + $vect_outer_exp = "(${outer_rtl}:${mode} ${vect_outer_arg2} + ${vect_inner_exp})"; } else { $outer_exp = "(${outer_rtl}:${mode} ${inner_exp} ${outer_arg2})"; + $vect_outer_exp = "(${outer_rtl}:${mode} ${vect_inner_exp} + ${vect_outer_arg2})"; } if ( $outer_inv == 1 ) { $outer_exp = "(not:${mode} $outer_exp)"; + $vect_outer_exp = "(not:${mode} $vect_outer_exp)"; } - $insn = <<"EOF"; + # See if we can use xxeval on vector fusion + $xxeval = $xxeval_fusions{"${inner_op}_${outer_name}"}; + if (!$xxeval) { + $insn = <<"EOF"; ;; $ftype fusion pattern generated by gen_logical_addsubf ;; $kind $inner_op -> $outer_name @@ -318,6 +388,30 @@ sub gen_logical_addsubf (set_attr "length" "8")]) EOF + } else { + $insn = <<"EOF"; + +;; $ftype fusion pattern generated by gen_logical_addsubf +;; $kind $inner_op -> $outer_name +(define_insn "*fuse_${inner_op}_${outer_name}" + [(set (match_operand:${mode} 3 "${vect_pred}" "=&0,&1,&${constraint},wa,${constraint}") + ${vect_outer_exp}) + (clobber (match_scratch:${mode} 4 "=X,X,X,X,&${constraint}"))] + "(TARGET_P10_FUSION)" + "@ + ${inner_op} %3,%1,%0\\;${outer_op} %3,${outer_32} + ${inner_op} %3,%1,%0\\;${outer_op} %3,${outer_32} + ${inner_op} %3,%1,%0\\;${outer_op} %3,${outer_32} + xxeval %x3,%x2,%x1,%x0,${xxeval} + ${inner_op} %4,%1,%0\\;${outer_op} %3,${outer_42}" + [(set_attr "type" "$fuse_type") + (set_attr "cost" "6") + (set_attr "length" "8") + (set_attr "prefixed" "*,*,*,yes,*") + (set_attr "isa" "*,*,*,xxeval,*")]) +EOF + } + print $insn; } } diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 0b78901e94b..1d95e34557e 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -82,7 +82,7 @@ (define_predicate "altivec_register_operand" return ALTIVEC_REGNO_P (REGNO (op)); }) -;; Return 1 if op is a VSX register. +;; Return 1 if op is a VSX register (define_predicate "vsx_register_operand" (match_operand 0 "register_operand") { @@ -119,6 +119,18 @@ (define_predicate "vsx_reg_sfsubreg_ok" return VSX_REGNO_P (REGNO (op)); }) +;; Return 1 if op is a register that can be used for vector fusion. If XXEVAL +;; is supported, return true for all VSX registers, otherwise the fusion is +;; limited to Altivec registers since the machine only fuses Altivec +;; operations. +(define_predicate "vector_fusion_operand" + (match_operand 0 "register_operand") +{ + return (TARGET_XXEVAL && TARGET_PREFIXED + ? vsx_register_operand (op, mode) + : altivec_register_operand (op, mode)); +}) + ;; Return 1 if op is a vector register that operates on floating point vectors ;; (either altivec or VSX). (define_predicate "vfloat_operand" diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index dc5b7eb74d4..bdaa6973e70 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -24721,6 +24721,9 @@ static struct rs6000_opt_var const rs6000_opt_vars[] = { "speculate-indirect-jumps", offsetof (struct gcc_options, x_rs6000_speculate_indirect_jumps), offsetof (struct cl_target_option, x_rs6000_speculate_indirect_jumps), }, + { "xxeval", + offsetof (struct gcc_options, x_TARGET_XXEVAL), + offsetof (struct cl_target_option, x_TARGET_XXEVAL), }, }; /* Inner function to handle attribute((target("..."))) and #pragma GCC target diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index d266f93ff2e..6a2268f9e04 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -369,7 +369,7 @@ (define_attr "cpu" (const (symbol_ref "(enum attr_cpu) rs6000_tune"))) ;; The ISA we implement. -(define_attr "isa" "any,p5,p6,p7,p7v,p8,p8v,p9,p9v,p9kf,p9tf,p10" +(define_attr "isa" "any,p5,p6,p7,p7v,p8,p8v,p9,p9v,p9kf,p9tf,p10,xxeval" (const_string "any")) ;; Is this alternative enabled for the current CPU/ISA/etc.? @@ -421,6 +421,11 @@ (define_attr "enabled" "" (and (eq_attr "isa" "p10") (match_test "TARGET_POWER10")) (const_int 1) + + (and (eq_attr "isa" "xxeval") + (match_test "TARGET_PREFIXED && TARGET_XXEVAL")) + (const_int 1) + ] (const_int 0))) ;; If this instruction is microcoded on the CELL processor diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt index 0d71dbaf2fc..cfd81a177a6 100644 --- a/gcc/config/rs6000/rs6000.opt +++ b/gcc/config/rs6000/rs6000.opt @@ -631,6 +631,10 @@ mieee128-constant Target Var(TARGET_IEEE128_CONSTANT) Init(1) Save Generate (do not generate) code that uses the LXVKQ instruction. +mxxeval +Target Undocumented Var(TARGET_XXEVAL) Init(1) Save +Generate (do not generate) code that uses the XXEVAL instruction. + ; Documented parameters -param=rs6000-vect-unroll-limit= diff --git a/gcc/testsuite/gcc.target/powerpc/p10-vector-fused-1.c b/gcc/testsuite/gcc.target/powerpc/p10-vector-fused-1.c new file mode 100644 index 00000000000..28e0874b345 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/p10-vector-fused-1.c @@ -0,0 +1,409 @@ +/* { dg-do run } */ +/* { dg-require-effective-target power10_hw } */ +/* { dg-options "-mdejagnu-cpu=power10 -O2" } */ + +/* Generate and check most of the vector logical instruction combinations that + may or may not generate xxeval to do a fused operation on power10. */ + +#include +#include +#include + +#ifdef DEBUG +#include + +static int errors = 0; +static int tests = 0; +#endif + +typedef vector unsigned int vector_t; +typedef unsigned int scalar_t; + +/* Vector logical functions. */ +static inline vector_t +vector_and (vector_t x, vector_t y) +{ + return x & y; +} + +static inline vector_t +vector_or (vector_t x, vector_t y) +{ + return x | y; +} + +static inline vector_t +vector_xor (vector_t x, vector_t y) +{ + return x ^ y; +} + +static inline vector_t +vector_andc (vector_t x, vector_t y) +{ + return x & ~y; +} + +static inline vector_t +vector_orc (vector_t x, vector_t y) +{ + return x | ~y; +} + +static inline vector_t +vector_nand (vector_t x, vector_t y) +{ + return ~(x & y); +} + +static inline vector_t +vector_nor (vector_t x, vector_t y) +{ + return ~(x | y); +} + +static inline vector_t +vector_eqv (vector_t x, vector_t y) +{ + return ~(x ^ y); +} + +/* Scalar logical functions. */ +static inline scalar_t +scalar_and (scalar_t x, scalar_t y) +{ + return x & y; +} + +static inline scalar_t +scalar_or (scalar_t x, scalar_t y) +{ + return x | y; +} + +static inline scalar_t +scalar_xor (scalar_t x, scalar_t y) +{ + return x ^ y; +} + +static inline scalar_t +scalar_andc (scalar_t x, scalar_t y) +{ + return x & ~y; +} + +static inline scalar_t +scalar_orc (scalar_t x, scalar_t y) +{ + return x | ~y; +} + +static inline scalar_t +scalar_nand (scalar_t x, scalar_t y) +{ + return ~(x & y); +} + +static inline scalar_t +scalar_nor (scalar_t x, scalar_t y) +{ + return ~(x | y); +} + +static inline scalar_t +scalar_eqv (scalar_t x, scalar_t y) +{ + return ~(x ^ y); +} + + +/* + * Generate one function for each combination that we are checking. Do 4 + * operations: + * + * Use FPR regs that should generate either XXEVAL or XXL* insns; + * Use Altivec registers than may generated fused V* insns; + * Use VSX registers, insure fusing it not done via asm; (and) + * Use GPR registers on scalar operations. + */ + +#ifdef DEBUG +#define TRACE(INNER, OUTER) \ + do { \ + tests++; \ + printf ("%s_%s\n", INNER, OUTER); \ + fflush (stdout); \ + } while (0) \ + +#define FAILED(INNER, OUTER) \ + do { \ + errors++; \ + printf ("%s_%s failed\n", INNER, OUTER); \ + fflush (stdout); \ + } while (0) \ + +#else +#define TRACE(INNER, OUTER) +#define FAILED(INNER, OUTER) abort () +#endif + +#define FUSED_FUNC(INNER, OUTER) \ +static void \ +INNER ## _ ## OUTER (vector_t a, vector_t b, vector_t c) \ +{ \ + vector_t f_a, f_b, f_c, f_r, f_t; \ + vector_t v_a, v_b, v_c, v_r, v_t; \ + vector_t w_a, w_b, w_c, w_r, w_t; \ + scalar_t s_a, s_b, s_c, s_r, s_t; \ + \ + TRACE (#INNER, #OUTER); \ + \ + f_a = a; \ + f_b = b; \ + f_c = c; \ + \ + __asm__ (" # fpr regs: %x0,%x1,%x2 " #INNER "_" #OUTER \ + : "+d" (f_a), \ + "+d" (f_b), \ + "+d" (f_c)); \ + \ + f_t = vector_ ## INNER (f_b, f_c); \ + f_r = vector_ ## OUTER (f_a, f_t); \ + \ + __asm__ (" # fpr regs result: %x0 " #INNER "_" #OUTER \ + : "+d" (f_r)); \ + \ + v_a = a; \ + v_b = b; \ + v_c = c; \ + \ + __asm__ (" # altivec regs: %x0,%x1,%x2 " #INNER "_" #OUTER \ + : "+v" (v_a), \ + "+v" (v_b), \ + "+v" (v_c)); \ + \ + v_t = vector_ ## INNER (v_b, v_c); \ + v_r = vector_ ## OUTER (v_a, v_t); \ + \ + __asm__ (" # altivec regs result: %x0 " #INNER "_" #OUTER \ + : "+v" (v_r)); \ + \ + w_a = a; \ + w_b = b; \ + w_c = c; \ + \ + __asm__ (" # vsx regs: %x0,%x1,%x2 " #INNER "_" #OUTER \ + : "+wa" (w_a), \ + "+wa" (w_b), \ + "+wa" (w_c)); \ + \ + w_t = vector_ ## INNER (w_b, w_c); \ + __asm__ ("nop # break vsx fusion reg %x0" : "+wa" (w_t)); \ + w_r = vector_ ## OUTER (w_a, w_t); \ + \ + __asm__ (" # vsx regs result: %x0 " #INNER "_" #OUTER \ + : "+wa" (w_r)); \ + \ + s_a = a[0]; \ + s_b = b[0]; \ + s_c = c[0]; \ + \ + __asm__ (" # gpr regs: %0,%1,%2 " #INNER "_" #OUTER \ + : "+r" (s_a), \ + "+r" (s_b), \ + "+r" (s_c)); \ + \ + s_t = scalar_ ## INNER (s_b, s_c); \ + s_r = scalar_ ## OUTER (s_a, s_t); \ + \ + __asm__ (" # gpr regs result: %0 " #INNER "_" #OUTER \ + : "+r" (s_r)); \ + \ + if (!vec_all_eq (w_r, f_r) \ + || !vec_all_eq (w_r, v_r) \ + || s_r != w_r[0]) \ + FAILED (#INNER, #OUTER); \ + \ + return; \ +} + +FUSED_FUNC (and, and) +FUSED_FUNC (andc, and) +FUSED_FUNC (eqv, and) +FUSED_FUNC (nand, and) +FUSED_FUNC (nor, and) +FUSED_FUNC (or, and) +FUSED_FUNC (orc, and) +FUSED_FUNC (xor, and) + +FUSED_FUNC (and, andc) +FUSED_FUNC (andc, andc) +FUSED_FUNC (eqv, andc) +FUSED_FUNC (nand, andc) +FUSED_FUNC (nor, andc) +FUSED_FUNC (or, andc) +FUSED_FUNC (orc, andc) +FUSED_FUNC (xor, andc) + +FUSED_FUNC (and, eqv) +FUSED_FUNC (andc, eqv) +FUSED_FUNC (eqv, eqv) +FUSED_FUNC (nand, eqv) +FUSED_FUNC (nor, eqv) +FUSED_FUNC (or, eqv) +FUSED_FUNC (orc, eqv) +FUSED_FUNC (xor, eqv) + +FUSED_FUNC (and, nand) +FUSED_FUNC (andc, nand) +FUSED_FUNC (eqv, nand) +FUSED_FUNC (nand, nand) +FUSED_FUNC (nor, nand) +FUSED_FUNC (or, nand) +FUSED_FUNC (orc, nand) +FUSED_FUNC (xor, nand) + +FUSED_FUNC (and, nor) +FUSED_FUNC (andc, nor) +FUSED_FUNC (eqv, nor) +FUSED_FUNC (nand, nor) +FUSED_FUNC (nor, nor) +FUSED_FUNC (or, nor) +FUSED_FUNC (orc, nor) +FUSED_FUNC (xor, nor) + +FUSED_FUNC (and, or) +FUSED_FUNC (andc, or) +FUSED_FUNC (eqv, or) +FUSED_FUNC (nand, or) +FUSED_FUNC (nor, or) +FUSED_FUNC (or, or) +FUSED_FUNC (orc, or) +FUSED_FUNC (xor, or) + +FUSED_FUNC (and, orc) +FUSED_FUNC (andc, orc) +FUSED_FUNC (eqv, orc) +FUSED_FUNC (nand, orc) +FUSED_FUNC (nor, orc) +FUSED_FUNC (or, orc) +FUSED_FUNC (orc, orc) +FUSED_FUNC (xor, orc) + +FUSED_FUNC (and, xor) +FUSED_FUNC (andc, xor) +FUSED_FUNC (eqv, xor) +FUSED_FUNC (nand, xor) +FUSED_FUNC (nor, xor) +FUSED_FUNC (or, xor) +FUSED_FUNC (orc, xor) +FUSED_FUNC (xor, xor) + + +/* List of functions to check. */ +typedef void func_t (vector_t, + vector_t, + vector_t); + +typedef func_t *ptr_func_t; + +static ptr_func_t functions[] = { + and_and, + andc_and, + eqv_and, + nand_and, + nor_and, + or_and, + orc_and, + xor_and, + + and_andc, + andc_andc, + eqv_andc, + nand_andc, + nor_andc, + or_andc, + orc_andc, + xor_andc, + + and_eqv, + andc_eqv, + eqv_eqv, + nand_eqv, + nor_eqv, + or_eqv, + orc_eqv, + xor_eqv, + + and_nand, + andc_nand, + eqv_nand, + nand_nand, + nor_nand, + or_nand, + orc_nand, + xor_nand, + + and_nor, + andc_nor, + eqv_nor, + nand_nor, + nor_nor, + or_nor, + orc_nor, + xor_nor, + + and_or, + andc_or, + eqv_or, + nand_or, + nor_or, + or_or, + orc_or, + xor_or, + + and_orc, + andc_orc, + eqv_orc, + nand_orc, + nor_orc, + or_orc, + orc_orc, + xor_orc, + + and_xor, + andc_xor, + eqv_xor, + nand_xor, + nor_xor, + or_xor, + orc_xor, + xor_xor, +}; + + +int +main (void) +{ + scalar_t s_a = 0x0fu; + scalar_t s_b = 0xaau; + scalar_t s_c = 0xccu; + + vector_t a = (vector_t) { s_a, s_a, ~s_a, ~s_a }; + vector_t b = (vector_t) { s_b, ~s_b, s_b, ~s_b }; + vector_t c = (vector_t) { s_c, ~s_c, ~s_c, s_c }; + + size_t i; + + for (i = 0; i < sizeof (functions) / sizeof (functions[0]); i++) + functions[i] (a, b, c); + +#ifdef DEBUG + printf ("Done, %d tests, %d failures\n", tests, errors); + return errors; + +#else + return 0; +#endif +} diff --git a/gcc/testsuite/gcc.target/powerpc/p10-vector-fused-2.c b/gcc/testsuite/gcc.target/powerpc/p10-vector-fused-2.c new file mode 100644 index 00000000000..f074622c9f6 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/p10-vector-fused-2.c @@ -0,0 +1,936 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target power10_ok } */ +/* { dg-options "-mdejagnu-cpu=power10 -O2" } */ + +/* Make sure all of the fusion cases that generate the xxeval instruction + actually generate it. */ +typedef vector unsigned int vector_t; + +static inline vector_t +vector_and (vector_t x, vector_t y) +{ + return x & y; +} + +static inline vector_t +vector_or (vector_t x, vector_t y) +{ + return x | y; +} + +static inline vector_t +vector_xor (vector_t x, vector_t y) +{ + return x ^ y; +} + +static inline vector_t +vector_andc (vector_t x, vector_t y) +{ + return x & ~y; +} + +static inline vector_t +vector_orc (vector_t x, vector_t y) +{ + return x | ~y; +} + +static inline vector_t +vector_nand (vector_t x, vector_t y) +{ + return ~(x & y); +} + +static inline vector_t +vector_nor (vector_t x, vector_t y) +{ + return ~(x | y); +} + +static inline vector_t +vector_eqv (vector_t x, vector_t y) +{ + return ~(x ^ y); +} + +void +and_and (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,1. */ + r = vector_and (a, vector_and (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +and_andc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,14. */ + r = vector_andc (a, vector_and (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +and_or (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,31. */ + r = vector_or (a, vector_and (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +and_orc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,239. */ + r = vector_orc (a, vector_and (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +and_xor (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,30. */ + r = vector_xor (a, vector_and (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +andc_and (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,14. */ + r = vector_andc (a, vector_and (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +andc_andc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,11. */ + r = vector_andc (a, vector_andc (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +andc_eqv (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,210. */ + r = vector_eqv (a, vector_andc (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +andc_nand (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,239. */ + r = vector_nand (a, vector_andc (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +andc_or (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,47. */ + r = vector_or (a, vector_andc (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +andc_orc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,191. */ + r = vector_orc (a, vector_andc (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +andc_xor (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,45. */ + r = vector_xor (a, vector_andc (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +eqv_and (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,9. */ + r = vector_and (a, vector_eqv (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +eqv_andc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,210. */ + r = vector_eqv (a, vector_andc (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +eqv_eqv (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,105. */ + r = vector_eqv (a, vector_eqv (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +eqv_or (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,159. */ + r = vector_or (a, vector_eqv (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +eqv_orc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,111. */ + r = vector_orc (a, vector_eqv (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +nand_and (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,14. */ + r = vector_and (a, vector_nand (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +nand_andc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,1. */ + r = vector_andc (a, vector_nand (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +nand_eqv (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,30. */ + r = vector_eqv (a, vector_nand (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +nand_or (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,2. */ + r = vector_nor (a, vector_nand (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +nand_orc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,31. */ + r = vector_orc (a, vector_nand (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +nor_and (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,8. */ + r = vector_and (a, vector_nor (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +nor_andc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,7. */ + r = vector_andc (a, vector_nor (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +nor_eqv (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,120. */ + r = vector_eqv (a, vector_nor (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +nor_nand (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,191. */ + r = vector_nand (a, vector_nor (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +nor_or (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,143. */ + r = vector_or (a, vector_nor (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +nor_orc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,127. */ + r = vector_orc (a, vector_nor (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +or_and (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,7. */ + r = vector_and (a, vector_or (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +or_andc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,8. */ + r = vector_andc (a, vector_or (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +or_or (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,127. */ + r = vector_or (a, vector_or (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +or_orc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,143. */ + r = vector_orc (a, vector_or (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +or_xor (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,120. */ + r = vector_xor (a, vector_or (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +orc_and (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,11. */ + r = vector_and (a, vector_orc (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +orc_andc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,2. */ + r = vector_andc (a, vector_orc (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +orc_eqv (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,75. */ + r = vector_eqv (a, vector_orc (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +orc_nor (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,8. */ + r = vector_nor (a, vector_orc (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +orc_or (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,191. */ + r = vector_or (a, vector_orc (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +orc_orc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,47. */ + r = vector_orc (a, vector_orc (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +orc_xor (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,180. */ + r = vector_xor (a, vector_orc (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +xor_and (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,6. */ + r = vector_and (a, vector_xor (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +xor_andc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,9. */ + r = vector_andc (a, vector_xor (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +xor_nand (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,249. */ + r = vector_nand (a, vector_xor (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +xor_or (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,111. */ + r = vector_or (a, vector_xor (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +xor_orc (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,159. */ + r = vector_orc (a, vector_xor (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +void +xor_xor (vector_t *p_a, vector_t *p_b, vector_t *p_c, vector_t *p_r) +{ + vector_t a = *p_a; + vector_t b = *p_b; + vector_t c = *p_c; + vector_t r; + + __asm__ (" # force fpr registers, %x0,%x1,%x2" + : "+d" (a), "+d" (b), "+d" (c)); + + /* xxeval r,a,b,c,105. */ + r = vector_xor (a, vector_xor (b, c)); + + __asm__ (" # force fpr result, %x0" : "+d" (r)); + *p_r = r; + return; +} + +/* Make sure none of traditional logical instructions are generated. Skip + checking for xxlor in case the register allocator decides to add some vector + moves. */ +/* { dg-final { scan-assembler-not {\mv(and|or|xor|andc|orc|nand|nor|eqv)\M} } } */ +/* { dg-final { scan-assembler-not {\mxxl(and|xor|andc|orc|nand|nor|eqv)\M} } } */ +/* { dg-final { scan-assembler-times {\mxxeval\M} 46 } } */