From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 2257 invoked by alias); 21 Jun 2016 17:46:18 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 2213 invoked by uid 89); 21 Jun 2016 17:46:17 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=1.1 required=5.0 tests=BAYES_40,KAM_ASCII_DIVIDERS,KAM_LAZY_DOMAIN_SECURITY,RCVD_IN_DNSWL_LOW autolearn=no version=3.3.2 spammy=sch, narrower, sk:PROCESS, 3rd X-HELO: mx0a-001b2d01.pphosted.com Received: from mx0b-001b2d01.pphosted.com (HELO mx0a-001b2d01.pphosted.com) (148.163.158.5) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-SHA encrypted) ESMTPS; Tue, 21 Jun 2016 17:46:07 +0000 Received: from pps.filterd (m0098416.ppops.net [127.0.0.1]) by mx0b-001b2d01.pphosted.com (8.16.0.11/8.16.0.11) with SMTP id u5LHk2qN083334 for ; Tue, 21 Jun 2016 13:46:04 -0400 Received: from e34.co.us.ibm.com (e34.co.us.ibm.com [32.97.110.152]) by mx0b-001b2d01.pphosted.com with ESMTP id 23q701yn5s-1 (version=TLSv1.2 cipher=AES256-SHA bits=256 verify=NOT) for ; Tue, 21 Jun 2016 13:46:03 -0400 Received: from localhost by e34.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 21 Jun 2016 11:45:46 -0600 Received: from d03dlp02.boulder.ibm.com (9.17.202.178) by e34.co.us.ibm.com (192.168.1.134) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Tue, 21 Jun 2016 11:45:44 -0600 X-IBM-Helo: d03dlp02.boulder.ibm.com X-IBM-MailFrom: pthaugen@linux.vnet.ibm.com Received: from b03cxnp08028.gho.boulder.ibm.com (b03cxnp08028.gho.boulder.ibm.com [9.17.130.20]) by d03dlp02.boulder.ibm.com (Postfix) with ESMTP id 6AEEB3E40085; Tue, 21 Jun 2016 11:45:30 -0600 (MDT) Received: from b03ledav001.gho.boulder.ibm.com (b03ledav001.gho.boulder.ibm.com [9.17.130.232]) by b03cxnp08028.gho.boulder.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id u5LHjUJa62718094; Tue, 21 Jun 2016 10:45:30 -0700 Received: from b03ledav001.gho.boulder.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 41A1E6E015; Tue, 21 Jun 2016 11:45:30 -0600 (MDT) Received: from oc1687012634.ibm.com (unknown [9.77.141.169]) by b03ledav001.gho.boulder.ibm.com (Postfix) with ESMTP id 7ACB16E010; Tue, 21 Jun 2016 11:45:29 -0600 (MDT) From: Pat Haugen Subject: [PATCH, rs6000] Scheduling update To: GCC Patches , Segher Boessenkool , David Edelsohn Date: Tue, 21 Jun 2016 17:46:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.7.0 MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="------------040402040002000509040706" X-TM-AS-GCONF: 00 X-Content-Scanned: Fidelis XPS MAILER x-cbid: 16062117-0016-0000-0000-000004012175 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 16062117-0017-0000-0000-00003068F2CC Message-Id: <57697D36.3040704@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2016-06-21_09:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=2 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1604210000 definitions=main-1606210200 X-IsSubscribed: yes X-SW-Source: 2016-06/txt/msg01527.txt.bz2 This is a multi-part message in MIME format. --------------040402040002000509040706 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 7bit Content-length: 2389 This patch adds instruction scheduling support for the Power9 processor. Bootstrap/regression tested on powerpc64/powerpc64le with no new failures. Ok for trunk? Ok for backport to GCC 6 branch after successful bootstrap/regtest there? -Pat 2016-06-21 Pat Haugen * config/rs6000/power8.md (power8-fp): Include dfp type. * config/rs6000/power6.md (power6-fp): Likewise. * config/rs6000/htm.md (various insns): Change type atribute to htmsimple and set power9_alu2 appropriately. * config/rs6000/power9.md: New file. * config/rs6000/t-rs6000 (MD_INCLUDES): Add power9.md. * config/rs6000/power7.md (power7-fp): Include dfp type. * config/rs6000/rs6000.c (power9_cost): Update costs, cache size and prefetch streams. (rs6000_option_override_internal): Remove temporary code setting tuning to power8. Don't set rs6000_sched_groups for power9. (last_scheduled_insn): Change to rtx_insn *. (divCnt, vec_load_pendulum): New variables. (rs6000_adjust_cost): Add Power9 to test for store->load separation. (rs6000_issue_rate): Set issue rate for Power9. (is_power9_pairable_vec_type): New. (rs6000_sched_reorder2): Add Power9 code to group fixed point divide insns and group/alternate vector operations with vector loads. (insn_must_be_first_in_group): Remove Power9. (insn_must_be_last_in_group): Likewise. (force_new_group): Likewise. (rs6000_sched_init): Fix initialization of last_scheduled_insn. Initialize divCnt/vec_load_pendulum. (_rs6000_sched_context, rs6000_init_sched_context, rs6000_set_sched_context): Handle context save/restore of new variables. * config/rs6000/vsx.md (various insns): Set power9_alu2 attribute. * config/rs6000/altivec.md (various insns): Likewise. * config/rs6000/dfp.md (various insns): Change type attribute to dfp. * config/rs6000/crypto.md (crypto_vshasigma): Change type and set power9_alu2. * config/rs6000/rs6000.md ('type' attribute): Add htmsimple/dfp types. Define "power9_alu2" and "mnemonic" attributes. Include power9.md. (*cmp_fpr, *fpmask): Set power9_alu2 attribute. (*cmp_hw): Change type to veccmp. --------------040402040002000509040706 Content-Type: text/x-patch; name="scheduling.diff" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="scheduling.diff" Content-length: 57597 Index: config/rs6000/power8.md =================================================================== --- config/rs6000/power8.md (revision 237621) +++ config/rs6000/power8.md (working copy) @@ -317,7 +317,7 @@ (define_bypass 4 "power8-branch" "power8 ; VS Unit (includes FP/VSX/VMX/DFP/Crypto) (define_insn_reservation "power8-fp" 6 - (and (eq_attr "type" "fp,dmul") + (and (eq_attr "type" "fp,dmul,dfp") (eq_attr "cpu" "power8")) "DU_any_power8,VSU_power8") Index: config/rs6000/power6.md =================================================================== --- config/rs6000/power6.md (revision 237621) +++ config/rs6000/power6.md (working copy) @@ -500,7 +500,7 @@ (define_insn_reservation "power6-mtcr" 4 (define_bypass 9 "power6-mtcr" "power6-branch") (define_insn_reservation "power6-fp" 6 - (and (eq_attr "type" "fp,dmul") + (and (eq_attr "type" "fp,dmul,dfp") (eq_attr "cpu" "power6")) "FPU_power6") Index: config/rs6000/htm.md =================================================================== --- config/rs6000/htm.md (revision 237621) +++ config/rs6000/htm.md (working copy) @@ -72,7 +72,8 @@ (define_insn "*tabort" (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))] "TARGET_HTM" "tabort. %0" - [(set_attr "type" "htm") + [(set_attr "type" "htmsimple") + (set_attr "power9_alu2" "yes") (set_attr "length" "4")]) (define_expand "tabortc" @@ -98,7 +99,8 @@ (define_insn "*tabortc" (set (match_operand:BLK 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))] "TARGET_HTM" "tabortc. %0,%1,%2" - [(set_attr "type" "htm") + [(set_attr "type" "htmsimple") + (set_attr "power9_alu2" "yes") (set_attr "length" "4")]) (define_expand "tabortci" @@ -124,7 +126,8 @@ (define_insn "*tabortci" (set (match_operand:BLK 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))] "TARGET_HTM" "tabortci. %0,%1,%2" - [(set_attr "type" "htm") + [(set_attr "type" "htmsimple") + (set_attr "power9_alu2" "yes") (set_attr "length" "4")]) (define_expand "tbegin" @@ -146,7 +149,7 @@ (define_insn "*tbegin" (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))] "TARGET_HTM" "tbegin. %0" - [(set_attr "type" "htm") + [(set_attr "type" "htmsimple") (set_attr "length" "4")]) (define_expand "tcheck" @@ -208,7 +211,7 @@ (define_insn "*trechkpt" (set (match_operand:BLK 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))] "TARGET_HTM" "trechkpt." - [(set_attr "type" "htm") + [(set_attr "type" "htmsimple") (set_attr "length" "4")]) (define_expand "treclaim" @@ -230,7 +233,7 @@ (define_insn "*treclaim" (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))] "TARGET_HTM" "treclaim. %0" - [(set_attr "type" "htm") + [(set_attr "type" "htmsimple") (set_attr "length" "4")]) (define_expand "tsr" @@ -252,7 +255,7 @@ (define_insn "*tsr" (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))] "TARGET_HTM" "tsr. %0" - [(set_attr "type" "htm") + [(set_attr "type" "htmsimple") (set_attr "length" "4")]) (define_expand "ttest" @@ -272,7 +275,8 @@ (define_insn "*ttest" (set (match_operand:BLK 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))] "TARGET_HTM" "tabortwci. 0,1,0" - [(set_attr "type" "htm") + [(set_attr "type" "htmsimple") + (set_attr "power9_alu2" "yes") (set_attr "length" "4")]) (define_insn "htm_mfspr_" Index: config/rs6000/power9.md =================================================================== --- config/rs6000/power9.md (revision 0) +++ config/rs6000/power9.md (revision 0) @@ -0,0 +1,525 @@ +;; Scheduling description for IBM POWER9 processor. +;; Copyright (C) 2016 Free Software Foundation, Inc. +;; +;; Contributed by Pat Haugen (pthaugen@us.ibm.com). + +;; This file is part of GCC. +;; +;; GCC is free software; you can redistribute it and/or modify it +;; under the terms of the GNU General Public License as published +;; by the Free Software Foundation; either version 3, or (at your +;; option) any later version. +;; +;; GCC is distributed in the hope that it will be useful, but WITHOUT +;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +;; License for more details. +;; +;; You should have received a copy of the GNU General Public License +;; along with GCC; see the file COPYING3. If not see +;; . + +(define_automaton "power9dsp,power9lsu,power9vsu,power9misc") + +(define_cpu_unit "lsu0_power9,lsu1_power9,lsu2_power9,lsu3_power9" "power9lsu") +(define_cpu_unit "vsu0_power9,vsu1_power9,vsu2_power9,vsu3_power9" "power9vsu") +; Two vector permute units, part of vsu +(define_cpu_unit "prm0_power9,prm1_power9" "power9vsu") +; Two fixed point divide units, not pipelined +(define_cpu_unit "fx_div0_power9,fx_div1_power9" "power9misc") +(define_cpu_unit "bru_power9,cryptu_power9,dfu_power9" "power9misc") + +(define_cpu_unit "x0_power9,x1_power9,xa0_power9,xa1_power9,\ + x2_power9,x3_power9,xb0_power9,xb1_power9, + br0_power9,br1_power9" "power9dsp") + + +; Dispatch port reservations +; +; Power9 can dispatch a maximum of 6 iops per cycle with the following +; general restrictions (other restrictions also apply): +; 1) At most 2 iops per execution slice +; 2) At most 2 iops to the branch unit +; Note that insn position in a dispatch group of 6 insns does not infer which +; execution slice the insn is routed to. The units are used to infer the +; conflicts that exist (i.e. an 'even' requirement will preclude dispatch +; with 2 insns with 'superslice' requirement). + +; The xa0/xa1 units really represent the 3rd dispatch port for a superslice but +; are listed as separate units to allow those insns that preclude its use to +; still be scheduled two to a superslice while reserving the 3rd slot. The +; same applies for xb0/xb1. +(define_reservation "DU_xa_power9" "xa0_power9+xa1_power9") +(define_reservation "DU_xb_power9" "xb0_power9+xb1_power9") + +; Any execution slice dispatch +(define_reservation "DU_any_power9" + "x0_power9|x1_power9|DU_xa_power9|x2_power9|x3_power9|\ + DU_xb_power9") + +; Even slice, actually takes even/odd slots +(define_reservation "DU_even_power9" "x0_power9+x1_power9|x2_power9+x3_power9") + +; Slice plus 3rd slot +(define_reservation "DU_slice_3_power9" + "x0_power9+xa0_power9|x1_power9+xa1_power9|\ + x2_power9+xb0_power9|x3_power9+xb1_power9") + +; Superslice +(define_reservation "DU_super_power9" + "x0_power9+x1_power9|x2_power9+x3_power9") + +; 2-way cracked +(define_reservation "DU_C2_power9" "(x0_power9+x1_power9)|\ + (x1_power9+DU_xa_power9)|\ + (x1_power9+x2_power9)|\ + (DU_xa_power9+x2_power9)|\ + (x2_power9+x3_power9)|\ + (x3_power9+DU_xb_power9)") + +; 2-way cracked plus 3rd slot +(define_reservation "DU_C2_3_power9" "(x0_power9+x1_power9+xa0_power9)|\ + (x1_power9+x2_power9+xa0_power9)|\ + (x1_power9+x2_power9+xb0_power9)|\ + (x2_power9+x3_power9+xb0_power9)") + +; 3-way cracked (consumes whole decode/dispatch cycle) +(define_reservation "DU_C3_power9" + "x0_power9+x1_power9+xa0_power9+xa1_power9+x2_power9+\ + x3_power9+xb0_power9+xb1_power9+br0_power9+br1_power9") + +; Branch ports +(define_reservation "DU_branch_power9" "br0_power9|br1_power9") + + +; Execution unit reservations +(define_reservation "LSU_power9" + "lsu0_power9|lsu1_power9|lsu2_power9|lsu3_power9") + +(define_reservation "LSU_pair_power9" + "lsu0_power9+lsu1_power9|lsu1_power9+lsu2_power9|\ + lsu2_power9+lsu3_power9|lsu3_power9+lsu1_power9") + +(define_reservation "VSU_power9" + "vsu0_power9|vsu1_power9|vsu2_power9|vsu3_power9") + +(define_reservation "VSU_super_power9" + "vsu0_power9+vsu1_power9|vsu2_power9+vsu3_power9") + +(define_reservation "VSU_PRM_power9" "prm0_power9|prm1_power9") + + +; 2 cycle FP ops +(define_attr "power9_fp_2cyc" "no,yes" + (cond [(eq_attr "mnemonic" "fabs,fcpsgn,fmr,fmrgow,fnabs,fneg,\ + xsabsdp,xscpsgndp,xsnabsdp,xsnegdp,\ + xsabsqp,xscpsgnqp,xsnabsqp,xsnegqp") + (const_string "yes")] + (const_string "no"))) + +; Quad-precision FP ops, execute in DFU +(define_attr "power9_qp" "no,yes" + (if_then_else (ior (match_operand:KF 0 "" "") + (match_operand:TF 0 "" "") + (match_operand:KF 1 "" "") + (match_operand:TF 1 "" "")) + (const_string "yes") + (const_string "no"))) + + +; LS Unit +(define_insn_reservation "power9-load" 4 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "no") + (eq_attr "update" "no") + (eq_attr "cpu" "power9")) + "DU_any_power9,LSU_power9") + +(define_insn_reservation "power9-load-update" 4 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "no") + (eq_attr "update" "yes") + (eq_attr "cpu" "power9")) + "DU_C2_power9,LSU_power9+VSU_power9") + +(define_insn_reservation "power9-load-ext" 6 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "yes") + (eq_attr "update" "no") + (eq_attr "cpu" "power9")) + "DU_C2_power9,LSU_power9") + +(define_insn_reservation "power9-load-ext-update" 6 + (and (eq_attr "type" "load") + (eq_attr "sign_extend" "yes") + (eq_attr "update" "yes") + (eq_attr "cpu" "power9")) + "DU_C3_power9,LSU_power9+VSU_power9") + +(define_insn_reservation "power9-fpload-double" 4 + (and (eq_attr "type" "fpload") + (eq_attr "update" "no") + (match_operand:DF 0 "" "") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,LSU_power9") + +(define_insn_reservation "power9-fpload-update-double" 4 + (and (eq_attr "type" "fpload") + (eq_attr "update" "yes") + (match_operand:DF 0 "" "") + (eq_attr "cpu" "power9")) + "DU_C2_3_power9,LSU_power9+VSU_power9") + +; SFmode loads are cracked and have additional 2 cycles over DFmode +(define_insn_reservation "power9-fpload-single" 6 + (and (eq_attr "type" "fpload") + (eq_attr "update" "no") + (match_operand:SF 0 "" "") + (eq_attr "cpu" "power9")) + "DU_C2_3_power9,LSU_power9") + +(define_insn_reservation "power9-fpload-update-single" 6 + (and (eq_attr "type" "fpload") + (eq_attr "update" "yes") + (match_operand:SF 0 "" "") + (eq_attr "cpu" "power9")) + "DU_C3_power9,LSU_power9+VSU_power9") + +(define_insn_reservation "power9-vecload" 5 + (and (eq_attr "type" "vecload") + (eq_attr "cpu" "power9")) + "DU_any_power9,LSU_pair_power9") + +; Store data can issue 2 cycles after AGEN issue, 3 cycles for vector store +(define_insn_reservation "power9-store" 0 + (and (eq_attr "type" "store") + (not (and (eq_attr "update" "yes") + (eq_attr "indexed" "yes"))) + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,LSU_power9") + +(define_insn_reservation "power9-store-indexed" 0 + (and (eq_attr "type" "store") + (eq_attr "update" "no") + (eq_attr "indexed" "yes") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,LSU_power9") + +; Update forms have 2 cycle latency for updated addr reg +(define_insn_reservation "power9-store-update" 2 + (and (eq_attr "type" "store") + (eq_attr "update" "yes") + (eq_attr "indexed" "no") + (eq_attr "cpu" "power9")) + "DU_C2_3_power9,LSU_power9+VSU_power9") + +; Update forms have 2 cycle latency for updated addr reg +(define_insn_reservation "power9-store-update-indexed" 2 + (and (eq_attr "type" "store") + (eq_attr "update" "yes") + (eq_attr "indexed" "yes") + (eq_attr "cpu" "power9")) + "DU_C2_3_power9,LSU_power9+VSU_power9") + +(define_insn_reservation "power9-fpstore" 0 + (and (eq_attr "type" "fpstore") + (eq_attr "update" "no") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,LSU_power9") + +; Update forms have 2 cycle latency for updated addr reg +(define_insn_reservation "power9-fpstore-update" 2 + (and (eq_attr "type" "fpstore") + (eq_attr "update" "yes") + (eq_attr "cpu" "power9")) + "DU_C2_3_power9,LSU_power9+VSU_power9") + +(define_insn_reservation "power9-vecstore" 0 + (and (eq_attr "type" "vecstore") + (eq_attr "cpu" "power9")) + "DU_super_power9,LSU_pair_power9") + +(define_insn_reservation "power9-larx" 4 + (and (eq_attr "type" "load_l") + (eq_attr "cpu" "power9")) + "DU_any_power9,LSU_power9") + +(define_insn_reservation "power9-stcx" 2 + (and (eq_attr "type" "store_c") + (eq_attr "cpu" "power9")) + "DU_C2_3_power9,LSU_power9+VSU_power9") + +(define_insn_reservation "power9-sync" 4 + (and (eq_attr "type" "sync,isync") + (eq_attr "cpu" "power9")) + "DU_any_power9,LSU_power9") + + +; VSU Execution Unit + +; Fixed point ops + +; Most ALU insns are simple 2 cycl, including record form +(define_insn_reservation "power9-alu" 2 + (and (ior (eq_attr "type" "add,cmp,exts,integer,logical,trap,isel") + (and (eq_attr "type" "insert,shift") + (eq_attr "dot" "no"))) + (eq_attr "cpu" "power9")) + "DU_any_power9,VSU_power9") + +; Record form rotate/shift are cracked +(define_insn_reservation "power9-cracked-alu" 2 + (and (eq_attr "type" "insert,shift") + (eq_attr "dot" "yes") + (eq_attr "cpu" "power9")) + "DU_C2_power9,VSU_power9") +; 4 cycle CR latency +(define_bypass 4 "power9-cracked-alu" + "power9-crlogical,power9-mfcr,power9-mfcrf,power9-branch") + +(define_insn_reservation "power9-alu2" 3 + (and (eq_attr "type" "cntlz,popcnt") + (eq_attr "cpu" "power9")) + "DU_any_power9,VSU_power9") + +; Treat 'two' and 'three' types as 2 or 3 way cracked +(define_insn_reservation "power9-two" 4 + (and (eq_attr "type" "two") + (eq_attr "cpu" "power9")) + "DU_C2_power9,VSU_power9") + +(define_insn_reservation "power9-three" 6 + (and (eq_attr "type" "three") + (eq_attr "cpu" "power9")) + "DU_C3_power9,VSU_power9") + +(define_insn_reservation "power9-mul" 4 + (and (eq_attr "type" "mul") + (eq_attr "dot" "no") + (eq_attr "cpu" "power9")) + "DU_any_power9,VSU_power9") + +(define_insn_reservation "power9-mul-compare" 4 + (and (eq_attr "type" "mul") + (eq_attr "dot" "yes") + (eq_attr "cpu" "power9")) + "DU_C2_power9,VSU_power9") +; 6 cycle CR latency +(define_bypass 6 "power9-mul-compare" + "power9-crlogical,power9-mfcr,power9-mfcrf,power9-branch") + +; Fixed point divides reserve the divide units for a minimum of 8 cycles +(define_insn_reservation "power9-idiv" 16 + (and (eq_attr "type" "div") + (eq_attr "size" "32") + (eq_attr "cpu" "power9")) + "DU_even_power9,fx_div0_power9*8|fx_div1_power9*8") + +(define_insn_reservation "power9-ldiv" 24 + (and (eq_attr "type" "div") + (eq_attr "size" "64") + (eq_attr "cpu" "power9")) + "DU_even_power9,fx_div0_power9*8|fx_div1_power9*8") + +(define_insn_reservation "power9-crlogical" 2 + (and (eq_attr "type" "cr_logical,delayed_cr") + (eq_attr "cpu" "power9")) + "DU_any_power9,VSU_power9") + +(define_insn_reservation "power9-mfcrf" 2 + (and (eq_attr "type" "mfcrf") + (eq_attr "cpu" "power9")) + "DU_any_power9,VSU_power9") + +(define_insn_reservation "power9-mfcr" 6 + (and (eq_attr "type" "mfcr") + (eq_attr "cpu" "power9")) + "DU_C3_power9,VSU_power9") + +; Should differentiate between 1 cr field and > 1 since target of > 1 cr +; is cracked +(define_insn_reservation "power9-mtcr" 2 + (and (eq_attr "type" "mtcr") + (eq_attr "cpu" "power9")) + "DU_any_power9,VSU_power9") + +; Move to LR/CTR are executed in VSU +(define_insn_reservation "power9-mtjmpr" 5 + (and (eq_attr "type" "mtjmpr") + (eq_attr "cpu" "power9")) + "DU_any_power9,VSU_power9") + +; Floating point/Vector ops +(define_insn_reservation "power9-fp" 7 + (and (eq_attr "type" "fp,dmul") + (eq_attr "power9_fp_2cyc" "no") + (eq_attr "power9_alu2" "no") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,VSU_power9") + +(define_insn_reservation "power9-fp2" 2 + (and (eq_attr "type" "fp,dmul") + (eq_attr "power9_fp_2cyc" "yes") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,VSU_power9") + +(define_insn_reservation "power9-fp-alu2" 3 + (and (eq_attr "type" "fp,dmul") + (eq_attr "power9_alu2" "yes") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,VSU_power9") + +(define_insn_reservation "power9-fpcompare" 3 + (and (eq_attr "type" "fpcompare") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,VSU_power9") + +; FP div/sqrt are executed in VSU slices, not pipelined for other divides, but for the +; most part do not block pipelined ops. +(define_insn_reservation "power9-sdiv" 22 + (and (eq_attr "type" "sdiv") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,VSU_power9") + +(define_insn_reservation "power9-ddiv" 33 + (and (eq_attr "type" "ddiv") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,VSU_power9") + +(define_insn_reservation "power9-sqrt" 26 + (and (eq_attr "type" "ssqrt") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,VSU_power9") + +(define_insn_reservation "power9-dsqrt" 36 + (and (eq_attr "type" "dsqrt") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,VSU_power9") + +(define_insn_reservation "power9-veccmp" 3 + (and (eq_attr "type" "veccmp") + (eq_attr "cpu" "power9")) + "DU_super_power9,VSU_super_power9") + +(define_insn_reservation "power9-vecsimple" 2 + (and (eq_attr "type" "vecsimple") + (eq_attr "power9_alu2" "no") + (eq_attr "cpu" "power9")) + "DU_super_power9,VSU_super_power9") + +(define_insn_reservation "power9-vecsimple-alu2" 3 + (and (eq_attr "type" "vecsimple") + (eq_attr "power9_alu2" "yes") + (eq_attr "cpu" "power9")) + "DU_super_power9,VSU_super_power9") + +(define_insn_reservation "power9-vecnormal" 7 + (and (eq_attr "type" "vecfloat,vecdouble") + (eq_attr "power9_fp_2cyc" "no") + (eq_attr "power9_alu2" "no") + (eq_attr "power9_qp" "no") + (eq_attr "cpu" "power9")) + "DU_super_power9,VSU_super_power9") + +(define_insn_reservation "power9-vecnormal2" 2 + (and (eq_attr "type" "vecfloat") + (eq_attr "power9_fp_2cyc" "yes") + (eq_attr "cpu" "power9")) + "DU_super_power9,VSU_super_power9") + +(define_insn_reservation "power9-vecnormal-alu2" 3 + (and (eq_attr "type" "vecfloat,vecdouble") + (eq_attr "power9_alu2" "yes") + (eq_attr "cpu" "power9")) + "DU_super_power9,VSU_super_power9") + +(define_insn_reservation "power9-qp" 12 + (and (eq_attr "type" "vecfloat,vecdouble") + (eq_attr "power9_qp" "yes") + (eq_attr "cpu" "power9")) + "DU_super_power9,dfu_power9") + +(define_insn_reservation "power9-vecperm" 2 + (and (eq_attr "type" "vecperm") + (eq_attr "cpu" "power9")) + "DU_super_power9,VSU_PRM_power9") + +(define_insn_reservation "power9-veccomplex" 7 + (and (eq_attr "type" "veccomplex") + (eq_attr "cpu" "power9")) + "DU_super_power9,VSU_super_power9") + +(define_insn_reservation "power9-vecfdiv" 28 + (and (eq_attr "type" "vecfdiv") + (eq_attr "cpu" "power9")) + "DU_super_power9,VSU_super_power9") + +(define_insn_reservation "power9-vecdiv" 32 + (and (eq_attr "type" "vecdiv") + (eq_attr "power9_qp" "no") + (eq_attr "cpu" "power9")) + "DU_super_power9,VSU_super_power9") + +(define_insn_reservation "power9-qpdiv" 56 + (and (eq_attr "type" "vecdiv") + (eq_attr "power9_qp" "yes") + (eq_attr "cpu" "power9")) + "DU_super_power9,dfu_power9") + +(define_insn_reservation "power9-mffgpr" 2 + (and (eq_attr "type" "mffgpr") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,VSU_power9") + +(define_insn_reservation "power9-mftgpr" 2 + (and (eq_attr "type" "mftgpr") + (eq_attr "cpu" "power9")) + "DU_slice_3_power9,VSU_power9") + + +; Branch Unit +; Move from LR/CTR are executed in BRU but consume a writeback port from an +; execution slice. +(define_insn_reservation "power9-mfjmpr" 6 + (and (eq_attr "type" "mfjmpr") + (eq_attr "cpu" "power9")) + "DU_branch_power9,bru_power9+VSU_power9") + +; Branch is 2 cycles +(define_insn_reservation "power9-branch" 2 + (and (eq_attr "type" "jmpreg,branch") + (eq_attr "cpu" "power9")) + "DU_branch_power9,bru_power9") + + +; Crytpo Unit +(define_insn_reservation "power9-crypto" 6 + (and (eq_attr "type" "crypto") + (eq_attr "cpu" "power9")) + "DU_super_power9,cryptu_power9") + + +; HTM Unit +(define_insn_reservation "power9-htm" 6 + (and (eq_attr "type" "htm") + (eq_attr "cpu" "power9")) + "DU_C2_power9,LSU_power9") + +(define_insn_reservation "power9-htm-simple" 2 + (and (eq_attr "type" "htmsimple") + (eq_attr "power9_alu2" "no") + (eq_attr "cpu" "power9")) + "DU_any_power9,VSU_power9") + +(define_insn_reservation "power9-htm-simple-alu2" 3 + (and (eq_attr "type" "htmsimple") + (eq_attr "power9_alu2" "yes") + (eq_attr "cpu" "power9")) + "DU_any_power9,VSU_power9") + +; DFP Unit +(define_insn_reservation "power9-dfp" 12 + (and (eq_attr "type" "dfp") + (eq_attr "cpu" "power9")) + "DU_even_power9,dfu_power9") + Index: config/rs6000/t-rs6000 =================================================================== --- config/rs6000/t-rs6000 (revision 237621) +++ config/rs6000/t-rs6000 (working copy) @@ -50,6 +50,7 @@ MD_INCLUDES = $(srcdir)/config/rs6000/rs $(srcdir)/config/rs6000/power6.md \ $(srcdir)/config/rs6000/power7.md \ $(srcdir)/config/rs6000/power8.md \ + $(srcdir)/config/rs6000/power9.md \ $(srcdir)/config/rs6000/cell.md \ $(srcdir)/config/rs6000/xfpu.md \ $(srcdir)/config/rs6000/a2.md \ Index: config/rs6000/power7.md =================================================================== --- config/rs6000/power7.md (revision 237621) +++ config/rs6000/power7.md (working copy) @@ -292,7 +292,7 @@ (define_insn_reservation "power7-branch" ; VS Unit (includes FP/VSX/VMX/DFP) (define_insn_reservation "power7-fp" 6 - (and (eq_attr "type" "fp,dmul") + (and (eq_attr "type" "fp,dmul,dfp") (eq_attr "cpu" "power7")) "DU_power7,VSU_power7") Index: config/rs6000/rs6000.c =================================================================== --- config/rs6000/rs6000.c (revision 237621) +++ config/rs6000/rs6000.c (working copy) @@ -1104,16 +1104,16 @@ struct processor_costs power9_cost = { COSTS_N_INSNS (3), /* mulsi_const */ COSTS_N_INSNS (3), /* mulsi_const9 */ COSTS_N_INSNS (3), /* muldi */ - COSTS_N_INSNS (19), /* divsi */ - COSTS_N_INSNS (35), /* divdi */ + COSTS_N_INSNS (8), /* divsi */ + COSTS_N_INSNS (12), /* divdi */ COSTS_N_INSNS (3), /* fp */ COSTS_N_INSNS (3), /* dmul */ - COSTS_N_INSNS (14), /* sdiv */ - COSTS_N_INSNS (17), /* ddiv */ + COSTS_N_INSNS (13), /* sdiv */ + COSTS_N_INSNS (18), /* ddiv */ 128, /* cache line size */ 32, /* l1 cache */ - 256, /* l2 cache */ - 12, /* prefetch streams */ + 512, /* l2 cache */ + 8, /* prefetch streams */ COSTS_N_INSNS (3), /* SF->DF convert */ }; @@ -3841,22 +3841,7 @@ rs6000_option_override_internal (bool gl if (rs6000_tune_index >= 0) tune_index = rs6000_tune_index; else if (have_cpu) - { - /* Until power9 tuning is available, use power8 tuning if -mcpu=power9. */ - if (processor_target_table[cpu_index].processor != PROCESSOR_POWER9) - rs6000_tune_index = tune_index = cpu_index; - else - { - size_t i; - tune_index = -1; - for (i = 0; i < ARRAY_SIZE (processor_target_table); i++) - if (processor_target_table[i].processor == PROCESSOR_POWER8) - { - rs6000_tune_index = tune_index = i; - break; - } - } - } + rs6000_tune_index = tune_index = cpu_index; else { size_t i; @@ -4636,8 +4621,7 @@ rs6000_option_override_internal (bool gl rs6000_sched_groups = (rs6000_cpu == PROCESSOR_POWER4 || rs6000_cpu == PROCESSOR_POWER5 || rs6000_cpu == PROCESSOR_POWER7 - || rs6000_cpu == PROCESSOR_POWER8 - || rs6000_cpu == PROCESSOR_POWER9); + || rs6000_cpu == PROCESSOR_POWER8); rs6000_align_branch_targets = (rs6000_cpu == PROCESSOR_POWER4 || rs6000_cpu == PROCESSOR_POWER5 || rs6000_cpu == PROCESSOR_POWER6 @@ -29825,13 +29809,19 @@ output_function_profiler (FILE *file, in /* The following variable value is the last issued insn. */ -static rtx last_scheduled_insn; +static rtx_insn * last_scheduled_insn; /* The following variable helps to balance issuing of load and store instructions */ static int load_store_pendulum; +/* The following variables are used to keep track of various scheduling + information. */ +static int divCnt; +static int vec_load_pendulum; + + /* Power4 load update and store update instructions are cracked into a load or store and an integer insn which are executed in the same cycle. Branches have their own dispatch slot which does not count against the @@ -29906,7 +29896,7 @@ rs6000_adjust_cost (rtx_insn *insn, rtx some cycles later. */ /* Separate a load from a narrower, dependent store. */ - if (rs6000_sched_groups + if ((rs6000_sched_groups || rs6000_cpu_attr == CPU_POWER9) && GET_CODE (PATTERN (insn)) == SET && GET_CODE (PATTERN (dep_insn)) == SET && GET_CODE (XEXP (PATTERN (insn), 1)) == MEM @@ -30144,6 +30134,8 @@ rs6000_adjust_cost (rtx_insn *insn, rtx break; } } + /* Fall through, no cost for output dependency. */ + case REG_DEP_ANTI: /* Anti dependency; DEP_INSN reads a register that INSN writes some cycles later. */ @@ -30516,8 +30508,9 @@ rs6000_issue_rate (void) case CPU_POWER7: return 5; case CPU_POWER8: - case CPU_POWER9: return 7; + case CPU_POWER9: + return 6; default: return 1; } @@ -30675,6 +30668,28 @@ is_store_insn (rtx insn, rtx *str_mem) return is_store_insn1 (PATTERN (insn), str_mem); } +/* Return whether TYPE is a Power9 pairable vector instruction type. */ + +static bool +is_power9_pairable_vec_type (enum attr_type type) +{ + switch (type) + { + case TYPE_VECSIMPLE: + case TYPE_VECCOMPLEX: + case TYPE_VECDIV: + case TYPE_VECCMP: + case TYPE_VECPERM: + case TYPE_VECFLOAT: + case TYPE_VECFDIV: + case TYPE_VECDOUBLE: + return true; + default: + break; + } + return false; +} + /* Returns whether the dependence between INSN and NEXT is considered costly by the given target. */ @@ -30786,6 +30801,10 @@ static int rs6000_sched_reorder2 (FILE *dump, int sched_verbose, rtx_insn **ready, int *pn_ready, int clock_var ATTRIBUTE_UNUSED) { + int pos; + int i; + rtx_insn *tmp; + if (sched_verbose) fprintf (dump, "// rs6000_sched_reorder2 :\n"); @@ -30831,9 +30850,6 @@ rs6000_sched_reorder2 (FILE *dump, int s */ if (rs6000_cpu == PROCESSOR_POWER6 && last_scheduled_insn) { - int pos; - int i; - rtx_insn *tmp; rtx load_mem, str_mem; if (is_store_insn (last_scheduled_insn, &str_mem)) @@ -30982,6 +30998,224 @@ rs6000_sched_reorder2 (FILE *dump, int s } } + /* Do Power9 dependent reordering if necessary. */ + if (rs6000_cpu == PROCESSOR_POWER9 && last_scheduled_insn + && recog_memoized (last_scheduled_insn) >= 0) + { + enum attr_type type; + + type = get_attr_type (last_scheduled_insn); + + /* Try to issue fixed point divides back-to-back in pairs so they will + be routed to separate execution units and execute in parallel. */ + if (type == TYPE_DIV && divCnt == 0) + { + /* First divide has been scheduled. */ + divCnt = 1; + + /* Scan the ready list looking for another divide, if found move it + to the end of the list so it is chosen next. */ + pos = *pn_ready-1; + while (pos >= 0) + { + if (recog_memoized (ready[pos]) >= 0 + && get_attr_type (ready[pos]) == TYPE_DIV) + { + tmp = ready[pos]; + for (i = pos; i < *pn_ready-1; i++) + ready[i] = ready[i + 1]; + ready[*pn_ready-1] = tmp; + break; + } + pos--; + } + } + else + { + /* Last insn was the 2nd divide or not a divide, reset the counter. */ + divCnt = 0; + + /* Power9 can execute 2 vector operations and 2 vector loads in a + single cycle. So try to pair up and alternate groups of vector and + vector load instructions. + + To aid this formation, a counter is maintained to keep track of + vec/vecload insns issued. The value of vec_load_pendulum maintains + the current state with the following values: + + 0 : Initial state, no vec/vecload group has been started. + + -1 : 1 vector load has been issued and another has been found on + the ready list and moved to the end. + + -2 : 2 vector loads have been issued and a vector operation has + been found and moved to the end of the ready list. + + -3 : 2 vector loads and a vector insn have been issued and a + vector operation has been found and moved to the end of the + ready list. + + 1 : 1 vector insn has been issued and another has been found and + moved to the end of the ready list. + + 2 : 2 vector insns have been issued and a vector load has been + found and moved to the end of the ready list. + + 3 : 2 vector insns and a vector load have been issued and another + vector load has been found and moved to the end of the ready + list. + */ + if (type == TYPE_VECLOAD) + { + /* Issued a vecload. */ + if (vec_load_pendulum == 0) + { + /* We issued a single vecload, look for another and move to + to the end of the ready list so it will be scheduled next. + Set pendulum if found. */ + pos = *pn_ready-1; + while (pos >= 0) + { + if (recog_memoized (ready[pos]) >= 0 + && get_attr_type (ready[pos]) == TYPE_VECLOAD) + { + tmp = ready[pos]; + for (i = pos; i < *pn_ready-1; i++) + ready[i] = ready[i + 1]; + ready[*pn_ready-1] = tmp; + vec_load_pendulum = -1; + return cached_can_issue_more; + } + pos--; + } + } + else if (vec_load_pendulum == -1) + { + /* This is the second vecload we've issued, search the ready + list for a vector operation so we can try to schedule a + pair of those next. If found move to the end of the ready + list so it is scheduled next and set the pendulum. */ + pos = *pn_ready-1; + while (pos >= 0) + { + if (recog_memoized (ready[pos]) >= 0 + && is_power9_pairable_vec_type ( + get_attr_type (ready[pos]))) + { + tmp = ready[pos]; + for (i = pos; i < *pn_ready-1; i++) + ready[i] = ready[i + 1]; + ready[*pn_ready-1] = tmp; + vec_load_pendulum = -2; + return cached_can_issue_more; + } + pos--; + } + } + else if (vec_load_pendulum == 2) + { + /* Two vector ops have been issued and we've just issued a + vecload, look for another vecload and move to end of ready + list if found. */ + pos = *pn_ready-1; + while (pos >= 0) + { + if (recog_memoized (ready[pos]) >= 0 + && get_attr_type (ready[pos]) == TYPE_VECLOAD) + { + tmp = ready[pos]; + for (i = pos; i < *pn_ready-1; i++) + ready[i] = ready[i + 1]; + ready[*pn_ready-1] = tmp; + /* Set pendulum so that next vecload will be seen as + finishing a group, not start of one. */ + vec_load_pendulum = 3; + return cached_can_issue_more; + } + pos--; + } + } + } + else if (is_power9_pairable_vec_type (type)) + { + /* Issued a vector operation. */ + if (vec_load_pendulum == 0) + /* We issued a single vec op, look for another and move to + to the end of the ready list so it will be scheduled next. + Set pendulum if found. */ + { + pos = *pn_ready-1; + while (pos >= 0) + { + if (recog_memoized (ready[pos]) >= 0 + && is_power9_pairable_vec_type ( + get_attr_type (ready[pos]))) + { + tmp = ready[pos]; + for (i = pos; i < *pn_ready-1; i++) + ready[i] = ready[i + 1]; + ready[*pn_ready-1] = tmp; + vec_load_pendulum = 1; + return cached_can_issue_more; + } + pos--; + } + } + else if (vec_load_pendulum == 1) + { + /* This is the second vec op we've issued, search the ready + list for a vecload operation so we can try to schedule a + pair of those next. If found move to the end of the ready + list so it is scheduled next and set the pendulum. */ + pos = *pn_ready-1; + while (pos >= 0) + { + if (recog_memoized (ready[pos]) >= 0 + && get_attr_type (ready[pos]) == TYPE_VECLOAD) + { + tmp = ready[pos]; + for (i = pos; i < *pn_ready-1; i++) + ready[i] = ready[i + 1]; + ready[*pn_ready-1] = tmp; + vec_load_pendulum = 2; + return cached_can_issue_more; + } + pos--; + } + } + else if (vec_load_pendulum == -2) + { + /* Two vecload ops have been issued and we've just issued a + vec op, look for another vec op and move to end of ready + list if found. */ + pos = *pn_ready-1; + while (pos >= 0) + { + if (recog_memoized (ready[pos]) >= 0 + && is_power9_pairable_vec_type ( + get_attr_type (ready[pos]))) + { + tmp = ready[pos]; + for (i = pos; i < *pn_ready-1; i++) + ready[i] = ready[i + 1]; + ready[*pn_ready-1] = tmp; + /* Set pendulum so that next vec op will be seen as + finishing a group, not start of one. */ + vec_load_pendulum = -3; + return cached_can_issue_more; + } + pos--; + } + } + } + } + + /* We've either finished a vec/vecload group, couldn't find an insn to + continue the current group, or the last insn had nothing to do with + with a group. In any case, reset the pendulum. */ + vec_load_pendulum = 0; + } + return cached_can_issue_more; } @@ -31150,7 +31384,6 @@ insn_must_be_first_in_group (rtx_insn *i } break; case PROCESSOR_POWER8: - case PROCESSOR_POWER9: type = get_attr_type (insn); switch (type) @@ -31281,7 +31514,6 @@ insn_must_be_last_in_group (rtx_insn *in } break; case PROCESSOR_POWER8: - case PROCESSOR_POWER9: type = get_attr_type (insn); switch (type) @@ -31400,7 +31632,7 @@ force_new_group (int sched_verbose, FILE /* Do we have a special group ending nop? */ if (rs6000_cpu_attr == CPU_POWER6 || rs6000_cpu_attr == CPU_POWER7 - || rs6000_cpu_attr == CPU_POWER8 || rs6000_cpu_attr == CPU_POWER9) + || rs6000_cpu_attr == CPU_POWER8) { nop = gen_group_ending_nop (); emit_insn_before (nop, next_insn); @@ -31654,8 +31886,10 @@ rs6000_sched_init (FILE *dump ATTRIBUTE_ int sched_verbose ATTRIBUTE_UNUSED, int max_ready ATTRIBUTE_UNUSED) { - last_scheduled_insn = NULL_RTX; + last_scheduled_insn = NULL; load_store_pendulum = 0; + divCnt = 0; + vec_load_pendulum = 0; } /* The following function is called at the end of scheduling BB. @@ -31699,8 +31933,10 @@ rs6000_sched_finish (FILE *dump, int sch struct _rs6000_sched_context { short cached_can_issue_more; - rtx last_scheduled_insn; + rtx_insn * last_scheduled_insn; int load_store_pendulum; + int divCnt; + int vec_load_pendulum; }; typedef struct _rs6000_sched_context rs6000_sched_context_def; @@ -31723,14 +31959,18 @@ rs6000_init_sched_context (void *_sc, bo if (clean_p) { sc->cached_can_issue_more = 0; - sc->last_scheduled_insn = NULL_RTX; + sc->last_scheduled_insn = NULL; sc->load_store_pendulum = 0; + sc->divCnt = 0; + sc->vec_load_pendulum = 0; } else { sc->cached_can_issue_more = cached_can_issue_more; sc->last_scheduled_insn = last_scheduled_insn; sc->load_store_pendulum = load_store_pendulum; + sc->divCnt = divCnt; + sc->vec_load_pendulum = vec_load_pendulum; } } @@ -31745,6 +31985,8 @@ rs6000_set_sched_context (void *_sc) cached_can_issue_more = sc->cached_can_issue_more; last_scheduled_insn = sc->last_scheduled_insn; load_store_pendulum = sc->load_store_pendulum; + divCnt = sc->divCnt; + vec_load_pendulum = sc->vec_load_pendulum; } /* Free _SC. */ Index: config/rs6000/vsx.md =================================================================== --- config/rs6000/vsx.md (revision 237621) +++ config/rs6000/vsx.md (working copy) @@ -1252,6 +1252,7 @@ (define_insn "vsx_smax3" "VECTOR_UNIT_VSX_P (mode)" "xvmax %x0,%x1,%x2" [(set_attr "type" "") + (set_attr "power9_alu2" "yes") (set_attr "fp_type" "")]) (define_insn "*vsx_smin3" @@ -1261,6 +1262,7 @@ (define_insn "*vsx_smin3" "VECTOR_UNIT_VSX_P (mode)" "xvmin %x0,%x1,%x2" [(set_attr "type" "") + (set_attr "power9_alu2" "yes") (set_attr "fp_type" "")]) (define_insn "*vsx_sqrt2" @@ -1421,6 +1423,7 @@ (define_insn "vsx_eq" "VECTOR_UNIT_VSX_P (mode)" "xvcmpeq %x0,%x1,%x2" [(set_attr "type" "") + (set_attr "power9_alu2" "yes") (set_attr "fp_type" "")]) (define_insn "vsx_gt" @@ -1430,6 +1433,7 @@ (define_insn "vsx_gt" "VECTOR_UNIT_VSX_P (mode)" "xvcmpgt %x0,%x1,%x2" [(set_attr "type" "") + (set_attr "power9_alu2" "yes") (set_attr "fp_type" "")]) (define_insn "*vsx_ge" @@ -1439,6 +1443,7 @@ (define_insn "*vsx_ge" "VECTOR_UNIT_VSX_P (mode)" "xvcmpge %x0,%x1,%x2" [(set_attr "type" "") + (set_attr "power9_alu2" "yes") (set_attr "fp_type" "")]) ;; Compare vectors producing a vector result and a predicate, setting CR6 to @@ -1454,7 +1459,8 @@ (define_insn "*vsx_eq__p" (match_dup 2)))] "VECTOR_UNIT_VSX_P (mode)" "xvcmpeq. %x0,%x1,%x2" - [(set_attr "type" "")]) + [(set_attr "type" "") + (set_attr "power9_alu2" "yes")]) (define_insn "*vsx_gt__p" [(set (reg:CC 74) @@ -1467,7 +1473,8 @@ (define_insn "*vsx_gt__p" (match_dup 2)))] "VECTOR_UNIT_VSX_P (mode)" "xvcmpgt. %x0,%x1,%x2" - [(set_attr "type" "")]) + [(set_attr "type" "") + (set_attr "power9_alu2" "yes")]) (define_insn "*vsx_ge__p" [(set (reg:CC 74) @@ -1480,7 +1487,8 @@ (define_insn "*vsx_ge__p" (match_dup 2)))] "VECTOR_UNIT_VSX_P (mode)" "xvcmpge. %x0,%x1,%x2" - [(set_attr "type" "")]) + [(set_attr "type" "") + (set_attr "power9_alu2" "yes")]) ;; Vector select (define_insn "*vsx_xxsel" @@ -1667,7 +1675,8 @@ (define_insn "vsx_xscvspdpn" UNSPEC_VSX_CVSPDPN))] "TARGET_XSCVSPDPN" "xscvspdpn %x0,%x1" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "power9_alu2" "yes")]) (define_insn "vsx_xscvdpspn_scalar" [(set (match_operand:V4SF 0 "vsx_register_operand" "=wf,?wa") @@ -1684,7 +1693,8 @@ (define_insn "vsx_xscvspdpn_directmove" UNSPEC_VSX_CVSPDPN))] "TARGET_XSCVSPDPN" "xscvspdpn %x0,%x1" - [(set_attr "type" "fp")]) + [(set_attr "type" "fp") + (set_attr "power9_alu2" "yes")]) ;; Convert and scale (used by vec_ctf, vec_cts, vec_ctu for double/long long) Index: config/rs6000/altivec.md =================================================================== --- config/rs6000/altivec.md (revision 237621) +++ config/rs6000/altivec.md (working copy) @@ -511,7 +511,8 @@ (define_insn "altivec_vaddus" (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] "" "vaddus %0,%1,%2" - [(set_attr "type" "vecsimple")]) + [(set_attr "type" "vecsimple") + (set_attr "power9_alu2" "yes")]) (define_insn "altivec_vaddss" [(set (match_operand:VI 0 "register_operand" "=v") @@ -521,7 +522,8 @@ (define_insn "altivec_vaddss" (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] "VECTOR_UNIT_ALTIVEC_P (mode)" "vaddss %0,%1,%2" - [(set_attr "type" "vecsimple")]) + [(set_attr "type" "vecsimple") + (set_attr "power9_alu2" "yes")]) ;; sub (define_insn "sub3" @@ -557,7 +559,8 @@ (define_insn "altivec_vsubus" (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] "VECTOR_UNIT_ALTIVEC_P (mode)" "vsubus %0,%1,%2" - [(set_attr "type" "vecsimple")]) + [(set_attr "type" "vecsimple") + (set_attr "power9_alu2" "yes")]) (define_insn "altivec_vsubss" [(set (match_operand:VI 0 "register_operand" "=v") @@ -567,7 +570,8 @@ (define_insn "altivec_vsubss" (set (reg:SI 110) (unspec:SI [(const_int 0)] UNSPEC_SET_VSCR))] "VECTOR_UNIT_ALTIVEC_P (mode)" "vsubss %0,%1,%2" - [(set_attr "type" "vecsimple")]) + [(set_attr "type" "vecsimple") + (set_attr "power9_alu2" "yes")]) ;; (define_insn "altivec_vavgu" @@ -577,7 +581,8 @@ (define_insn "altivec_vavgu" UNSPEC_VAVGU))] "TARGET_ALTIVEC" "vavgu %0,%1,%2" - [(set_attr "type" "vecsimple")]) + [(set_attr "type" "vecsimple") + (set_attr "power9_alu2" "yes")]) (define_insn "altivec_vavgs" [(set (match_operand:VI 0 "register_operand" "=v") @@ -586,7 +591,8 @@ (define_insn "altivec_vavgs" UNSPEC_VAVGS))] "VECTOR_UNIT_ALTIVEC_P (mode)" "vavgs %0,%1,%2" - [(set_attr "type" "vecsimple")]) + [(set_attr "type" "vecsimple") + (set_attr "power9_alu2" "yes")]) (define_insn "altivec_vcmpbfp" [(set (match_operand:V4SI 0 "register_operand" "=v") @@ -595,7 +601,8 @@ (define_insn "altivec_vcmpbfp" UNSPEC_VCMPBFP))] "VECTOR_UNIT_ALTIVEC_P (V4SImode)" "vcmpbfp %0,%1,%2" - [(set_attr "type" "veccmp")]) + [(set_attr "type" "veccmp") + (set_attr "power9_alu2" "yes")]) (define_insn "*altivec_eq" [(set (match_operand:VI2 0 "altivec_register_operand" "=v") @@ -627,7 +634,8 @@ (define_insn "*altivec_eqv4sf" (match_operand:V4SF 2 "altivec_register_operand" "v")))] "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" "vcmpeqfp %0,%1,%2" - [(set_attr "type" "veccmp")]) + [(set_attr "type" "veccmp") + (set_attr "power9_alu2" "yes")]) (define_insn "*altivec_gtv4sf" [(set (match_operand:V4SF 0 "altivec_register_operand" "=v") @@ -635,7 +643,8 @@ (define_insn "*altivec_gtv4sf" (match_operand:V4SF 2 "altivec_register_operand" "v")))] "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" "vcmpgtfp %0,%1,%2" - [(set_attr "type" "veccmp")]) + [(set_attr "type" "veccmp") + (set_attr "power9_alu2" "yes")]) (define_insn "*altivec_gev4sf" [(set (match_operand:V4SF 0 "altivec_register_operand" "=v") @@ -643,7 +652,8 @@ (define_insn "*altivec_gev4sf" (match_operand:V4SF 2 "altivec_register_operand" "v")))] "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" "vcmpgefp %0,%1,%2" - [(set_attr "type" "veccmp")]) + [(set_attr "type" "veccmp") + (set_attr "power9_alu2" "yes")]) (define_insn "*altivec_vsel" [(set (match_operand:VM 0 "altivec_register_operand" "=v") @@ -854,7 +864,8 @@ (define_insn "umax3" (match_operand:VI2 2 "register_operand" "v")))] "" "vmaxu %0,%1,%2" - [(set_attr "type" "vecsimple")]) + [(set_attr "type" "vecsimple") + (set_attr "power9_alu2" "yes")]) (define_insn "smax3" [(set (match_operand:VI2 0 "register_operand" "=v") @@ -862,7 +873,8 @@ (define_insn "smax3" (match_operand:VI2 2 "register_operand" "v")))] "" "vmaxs %0,%1,%2" - [(set_attr "type" "vecsimple")]) + [(set_attr "type" "vecsimple") + (set_attr "power9_alu2" "yes")]) (define_insn "*altivec_smaxv4sf3" [(set (match_operand:V4SF 0 "register_operand" "=v") @@ -870,7 +882,8 @@ (define_insn "*altivec_smaxv4sf3" (match_operand:V4SF 2 "register_operand" "v")))] "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" "vmaxfp %0,%1,%2" - [(set_attr "type" "veccmp")]) + [(set_attr "type" "veccmp") + (set_attr "power9_alu2" "yes")]) (define_insn "umin3" [(set (match_operand:VI2 0 "register_operand" "=v") @@ -878,7 +891,8 @@ (define_insn "umin3" (match_operand:VI2 2 "register_operand" "v")))] "" "vminu %0,%1,%2" - [(set_attr "type" "vecsimple")]) + [(set_attr "type" "vecsimple") + (set_attr "power9_alu2" "yes")]) (define_insn "smin3" [(set (match_operand:VI2 0 "register_operand" "=v") @@ -886,7 +900,8 @@ (define_insn "smin3" (match_operand:VI2 2 "register_operand" "v")))] "" "vmins %0,%1,%2" - [(set_attr "type" "vecsimple")]) + [(set_attr "type" "vecsimple") + (set_attr "power9_alu2" "yes")]) (define_insn "*altivec_sminv4sf3" [(set (match_operand:V4SF 0 "register_operand" "=v") @@ -894,7 +909,8 @@ (define_insn "*altivec_sminv4sf3" (match_operand:V4SF 2 "register_operand" "v")))] "VECTOR_UNIT_ALTIVEC_P (V4SFmode)" "vminfp %0,%1,%2" - [(set_attr "type" "veccmp")]) + [(set_attr "type" "veccmp") + (set_attr "power9_alu2" "yes")]) (define_insn "altivec_vmhaddshs" [(set (match_operand:V8HI 0 "register_operand" "=v") @@ -1614,7 +1630,8 @@ (define_insn "*altivec_vrl" (match_operand:VI2 2 "register_operand" "v")))] "" "vrl %0,%1,%2" - [(set_attr "type" "vecsimple")]) + [(set_attr "type" "vecsimple") + (set_attr "power9_alu2" "yes")]) (define_insn "altivec_vsl" [(set (match_operand:V4SI 0 "register_operand" "=v") @@ -1658,7 +1675,8 @@ (define_insn "*altivec_vsl" (match_operand:VI2 2 "register_operand" "v")))] "" "vsl %0,%1,%2" - [(set_attr "type" "vecsimple")]) + [(set_attr "type" "vecsimple") + (set_attr "power9_alu2" "yes")]) (define_insn "*altivec_vsr" [(set (match_operand:VI2 0 "register_operand" "=v") @@ -1666,7 +1684,8 @@ (define_insn "*altivec_vsr" (match_operand:VI2 2 "register_operand" "v")))] "" "vsr %0,%1,%2" - [(set_attr "type" "vecsimple")]) + [(set_attr "type" "vecsimple") + (set_attr "power9_alu2" "yes")]) (define_insn "*altivec_vsra" [(set (match_operand:VI2 0 "register_operand" "=v") @@ -1674,7 +1693,8 @@ (define_insn "*altivec_vsra" (match_operand:VI2 2 "register_operand" "v")))] "" "vsra %0,%1,%2" - [(set_attr "type" "vecsimple")]) + [(set_attr "type" "vecsimple") + (set_attr "power9_alu2" "yes")]) (define_insn "altivec_vsr" [(set (match_operand:V4SI 0 "register_operand" "=v") @@ -3463,6 +3483,7 @@ (define_insn "*p8v_clz2" "TARGET_P8_VECTOR" "vclz %0,%1" [(set_attr "length" "4") + (set_attr "power9_alu2" "yes") (set_attr "type" "vecsimple")]) ;; Vector absolute difference unsigned @@ -3490,6 +3511,7 @@ (define_insn "*p9v_ctz2" "TARGET_P9_VECTOR" "vctz %0,%1" [(set_attr "length" "4") + (set_attr "power9_alu2" "yes") (set_attr "type" "vecsimple")]) ;; Vector population count @@ -3499,6 +3521,7 @@ (define_insn "*p8v_popcount2" "TARGET_P8_VECTOR" "vpopcnt %0,%1" [(set_attr "length" "4") + (set_attr "power9_alu2" "yes") (set_attr "type" "vecsimple")]) ;; Vector parity @@ -3508,6 +3531,7 @@ (define_insn "*p9v_parity2" "TARGET_P9_VECTOR" "vprtyb %0,%1" [(set_attr "length" "4") + (set_attr "power9_alu2" "yes") (set_attr "type" "vecsimple")]) ;; Vector Gather Bits by Bytes by Doubleword Index: config/rs6000/dfp.md =================================================================== --- config/rs6000/dfp.md (revision 237621) +++ config/rs6000/dfp.md (working copy) @@ -58,7 +58,7 @@ (define_insn "extendsddd2" (float_extend:DD (match_operand:SD 1 "gpc_reg_operand" "f")))] "TARGET_DFP" "dctdp %0,%1" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) (define_expand "extendsdtd2" [(set (match_operand:TD 0 "gpc_reg_operand" "=d") @@ -76,7 +76,7 @@ (define_insn "truncddsd2" (float_truncate:SD (match_operand:DD 1 "gpc_reg_operand" "d")))] "TARGET_DFP" "drsp %0,%1" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) (define_expand "negdd2" [(set (match_operand:DD 0 "gpc_reg_operand" "") @@ -160,7 +160,7 @@ (define_insn "extendddtd2" (float_extend:TD (match_operand:DD 1 "gpc_reg_operand" "d")))] "TARGET_DFP" "dctqpq %0,%1" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) ;; The result of drdpq is an even/odd register pair with the converted ;; value in the even register and zero in the odd register. @@ -173,7 +173,7 @@ (define_insn "trunctddd2" (clobber (match_scratch:TD 2 "=d"))] "TARGET_DFP" "drdpq %2,%1\;fmr %0,%2" - [(set_attr "type" "fp") + [(set_attr "type" "dfp") (set_attr "length" "8")]) (define_insn "adddd3" @@ -182,7 +182,7 @@ (define_insn "adddd3" (match_operand:DD 2 "gpc_reg_operand" "d")))] "TARGET_DFP" "dadd %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) (define_insn "addtd3" [(set (match_operand:TD 0 "gpc_reg_operand" "=d") @@ -190,7 +190,7 @@ (define_insn "addtd3" (match_operand:TD 2 "gpc_reg_operand" "d")))] "TARGET_DFP" "daddq %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) (define_insn "subdd3" [(set (match_operand:DD 0 "gpc_reg_operand" "=d") @@ -198,7 +198,7 @@ (define_insn "subdd3" (match_operand:DD 2 "gpc_reg_operand" "d")))] "TARGET_DFP" "dsub %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) (define_insn "subtd3" [(set (match_operand:TD 0 "gpc_reg_operand" "=d") @@ -206,7 +206,7 @@ (define_insn "subtd3" (match_operand:TD 2 "gpc_reg_operand" "d")))] "TARGET_DFP" "dsubq %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) (define_insn "muldd3" [(set (match_operand:DD 0 "gpc_reg_operand" "=d") @@ -214,7 +214,7 @@ (define_insn "muldd3" (match_operand:DD 2 "gpc_reg_operand" "d")))] "TARGET_DFP" "dmul %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) (define_insn "multd3" [(set (match_operand:TD 0 "gpc_reg_operand" "=d") @@ -222,7 +222,7 @@ (define_insn "multd3" (match_operand:TD 2 "gpc_reg_operand" "d")))] "TARGET_DFP" "dmulq %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) (define_insn "divdd3" [(set (match_operand:DD 0 "gpc_reg_operand" "=d") @@ -230,7 +230,7 @@ (define_insn "divdd3" (match_operand:DD 2 "gpc_reg_operand" "d")))] "TARGET_DFP" "ddiv %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) (define_insn "divtd3" [(set (match_operand:TD 0 "gpc_reg_operand" "=d") @@ -238,7 +238,7 @@ (define_insn "divtd3" (match_operand:TD 2 "gpc_reg_operand" "d")))] "TARGET_DFP" "ddivq %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) (define_insn "*cmpdd_internal1" [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") @@ -246,7 +246,7 @@ (define_insn "*cmpdd_internal1" (match_operand:DD 2 "gpc_reg_operand" "d")))] "TARGET_DFP" "dcmpu %0,%1,%2" - [(set_attr "type" "fpcompare")]) + [(set_attr "type" "dfp")]) (define_insn "*cmptd_internal1" [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") @@ -254,21 +254,21 @@ (define_insn "*cmptd_internal1" (match_operand:TD 2 "gpc_reg_operand" "d")))] "TARGET_DFP" "dcmpuq %0,%1,%2" - [(set_attr "type" "fpcompare")]) + [(set_attr "type" "dfp")]) (define_insn "floatdidd2" [(set (match_operand:DD 0 "gpc_reg_operand" "=d") (float:DD (match_operand:DI 1 "gpc_reg_operand" "d")))] "TARGET_DFP && TARGET_POPCNTD" "dcffix %0,%1" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) (define_insn "floatditd2" [(set (match_operand:TD 0 "gpc_reg_operand" "=d") (float:TD (match_operand:DI 1 "gpc_reg_operand" "d")))] "TARGET_DFP" "dcffixq %0,%1" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) ;; Convert a decimal64 to a decimal64 whose value is an integer. ;; This is the first stage of converting it to an integer type. @@ -278,7 +278,7 @@ (define_insn "ftruncdd2" (fix:DD (match_operand:DD 1 "gpc_reg_operand" "d")))] "TARGET_DFP" "drintn. 0,%0,%1,1" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) ;; Convert a decimal64 whose value is an integer to an actual integer. ;; This is the second stage of converting decimal float to integer type. @@ -288,7 +288,7 @@ (define_insn "fixdddi2" (fix:DI (match_operand:DD 1 "gpc_reg_operand" "d")))] "TARGET_DFP" "dctfix %0,%1" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) ;; Convert a decimal128 to a decimal128 whose value is an integer. ;; This is the first stage of converting it to an integer type. @@ -298,7 +298,7 @@ (define_insn "ftrunctd2" (fix:TD (match_operand:TD 1 "gpc_reg_operand" "d")))] "TARGET_DFP" "drintnq. 0,%0,%1,1" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) ;; Convert a decimal128 whose value is an integer to an actual integer. ;; This is the second stage of converting decimal float to integer type. @@ -308,7 +308,7 @@ (define_insn "fixtddi2" (fix:DI (match_operand:TD 1 "gpc_reg_operand" "d")))] "TARGET_DFP" "dctfixq %0,%1" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) ;; Decimal builtin support @@ -333,7 +333,7 @@ (define_insn "dfp_ddedpd_" UNSPEC_DDEDPD))] "TARGET_DFP" "ddedpd %1,%0,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) (define_insn "dfp_denbcd_" [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d") @@ -342,7 +342,7 @@ (define_insn "dfp_denbcd_" UNSPEC_DENBCD))] "TARGET_DFP" "denbcd %1,%0,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) (define_insn "dfp_dxex_" [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d") @@ -350,7 +350,7 @@ (define_insn "dfp_dxex_" UNSPEC_DXEX))] "TARGET_DFP" "dxex %0,%1" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) (define_insn "dfp_diex_" [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d") @@ -359,7 +359,7 @@ (define_insn "dfp_diex_" UNSPEC_DXEX))] "TARGET_DFP" "diex %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) (define_insn "dfp_dscli_" [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d") @@ -368,7 +368,7 @@ (define_insn "dfp_dscli_" UNSPEC_DSCLI))] "TARGET_DFP" "dscli %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) (define_insn "dfp_dscri_" [(set (match_operand:D64_D128 0 "gpc_reg_operand" "=d") @@ -377,4 +377,4 @@ (define_insn "dfp_dscri_" UNSPEC_DSCRI))] "TARGET_DFP" "dscri %0,%1,%2" - [(set_attr "type" "fp")]) + [(set_attr "type" "dfp")]) Index: config/rs6000/crypto.md =================================================================== --- config/rs6000/crypto.md (revision 237621) +++ config/rs6000/crypto.md (working copy) @@ -107,4 +107,5 @@ (define_insn "crypto_vshasigma" UNSPEC_VSHASIGMA))] "TARGET_CRYPTO" "vshasigma %0,%1,%2,%3" - [(set_attr "type" "crypto")]) + [(set_attr "type" "vecsimple") + (set_attr "power9_alu2" "yes")]) Index: config/rs6000/rs6000.md =================================================================== --- config/rs6000/rs6000.md (revision 237621) +++ config/rs6000/rs6000.md (working copy) @@ -183,7 +183,7 @@ (define_attr "type" brinc, vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm, vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto, - htm" + htm,htmsimple,dfp" (const_string "integer")) ;; What data size does this instruction work on? @@ -275,6 +275,13 @@ (define_attr "cell_micro" "not,condition (const_string "always") (const_string "not"))) +;; Is this instruction a Power9 ALU2 insn? +(define_attr "power9_alu2" "no,yes" (const_string "no")) + +;; Define attribute for insn mnemonic +(define_attr "mnemonic" "unknown" (const_string "unknown")) + + (automata_option "ndfa") (include "rs64.md") @@ -298,6 +305,7 @@ (define_attr "cell_micro" "not,condition (include "power6.md") (include "power7.md") (include "power8.md") +(include "power9.md") (include "cell.md") (include "xfpu.md") (include "a2.md") @@ -4510,7 +4518,8 @@ (define_insn "*cmp_fpr" "@ fcmpu %0,%1,%2 xscmpudp %0,%x1,%x2" - [(set_attr "type" "fpcompare")]) + [(set_attr "type" "fpcompare") + (set_attr "power9_alu2" "yes")]) ;; Floating point conversions (define_expand "extendsfdf2" @@ -4830,7 +4839,8 @@ (define_insn "*fpmask" (match_operand:V2DI 5 "zero_constant" "")))] "TARGET_P9_MINMAX" "xscmp%V1dp %x0,%x2,%x3" - [(set_attr "type" "fpcompare")]) + [(set_attr "type" "fpcompare") + (set_attr "power9_alu2" "yes")]) (define_insn "*xxsel" [(set (match_operand:SFDF 0 "vsx_register_operand" "=") @@ -13658,7 +13668,7 @@ (define_insn "*cmp_hw" (match_operand:IEEE128 2 "altivec_register_operand" "v")))] "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (mode)" "xscmpuqp %0,%1,%2" - [(set_attr "type" "fpcompare")]) + [(set_attr "type" "veccmp")]) --------------040402040002000509040706--