From patchwork Mon Jun 19 18:54:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Carl Love X-Patchwork-Id: 110139 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp3193194vqr; Mon, 19 Jun 2023 11:54:58 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5mF2PHjJF5qizRXoGNKbp6IwC80WtMeiOqLVU5Eyvw0lgLfaz0rLObLd9tfQbc/4dBpcfo X-Received: by 2002:aa7:d419:0:b0:51a:2fa4:2d46 with SMTP id z25-20020aa7d419000000b0051a2fa42d46mr6661045edq.23.1687200898079; Mon, 19 Jun 2023 11:54:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1687200898; cv=none; d=google.com; s=arc-20160816; b=EDa7JPf90deVEQ17YzCvZ8a+hgMbXmdEdU7X9Ohmgunmfgt/Td61M9aGRww3L6Id3O gYjU5rJPO5TIaYgNPKeF6YH0/tCol0Q7Z7XkYv7I8gV23cwD3XHN6IaLPipGUR1RzYyS 7Tqd6C98+vCO+/vqmbqW+lklZLhUtGOQdee15g7Y5yxaeejKQ9/qOABDOSLIiUpAWZpW PJIQy9nqn3VFxQ/VRCLNWVdc5qcf3W5pbCtbR1caYBIGou4qKjJNuqsvM+YY5WnLg4y0 hb97SiVzsCe76viZgkYNJ78hlj82vUrVqkTpUs9I7JeETIo/8JAZf/XROsK7ylV08Q8W SB0g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-transfer-encoding:mime-version:date:cc:to:subject :message-id:dmarc-filter:delivered-to:dkim-signature:dkim-filter; bh=fKWPjjPA3qxDnzEHSeWoukKkweMHj9JMdKxLLRp6bXQ=; b=fBNb6HtgRD86L5ghY2q78KCw5YvUh4eoMMwOGYX2q6gQHaW9EEVlyetu32osTEjP1K HLEi7PyZ9dMQTvogAjdHsVs5wH3PA7ziUzfEkf2hWj6oTW/64SApBRq5KTd6MC7HA6RH SykjqZlxCKcmHFe8zEi8+acswPBw3URECB1nZbSK3bc8/Yh5hdrinNJFEgC9NKIAdJUz L2Ffrg3JSeyG6iEseR0siJFF846XYVS7JEt223BmOu0KuPrT409AcGIWhvxsoyOfeUYe RivWXmLNjMWVhdJyyGpYNIuDcx90pk929MsDmxiV5cbMTgpR3aKIFfjPbxUDwlCmT8xP LmlQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=vGD43CIn; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id h25-20020aa7c619000000b0051a1f1748a2si72672edq.148.2023.06.19.11.54.57 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 19 Jun 2023 11:54:58 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) client-ip=2620:52:3:1:0:246e:9693:128c; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=vGD43CIn; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 2620:52:3:1:0:246e:9693:128c as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 9B5723858025 for ; Mon, 19 Jun 2023 18:54:56 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 9B5723858025 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1687200896; bh=fKWPjjPA3qxDnzEHSeWoukKkweMHj9JMdKxLLRp6bXQ=; h=Subject:To:Cc:Date:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:List-Subscribe:From:Reply-To:From; b=vGD43CInsCl57/yrY7P0iWSBvPScAXDKYHFqPCwY8RHQubC+AFYWDTp3xwZvkVu6m iE8HNaCJDWYFFXu7KzGFflWUjal16FNqK6X6b+tpG1xbg2VTkn2Vj0Zc3SItMA9JXf GwURMwqLubWyMNUybosEAmwFyf21yj+VIG+VANyA= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by sourceware.org (Postfix) with ESMTPS id 8B70A3858035 for ; Mon, 19 Jun 2023 18:54:09 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 8B70A3858035 Received: from pps.filterd (m0356517.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 35JIlU6c030565; Mon, 19 Jun 2023 18:54:08 GMT Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3ravksg385-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 19 Jun 2023 18:54:07 +0000 Received: from m0356517.ppops.net (m0356517.ppops.net [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 35JImMbY000321; Mon, 19 Jun 2023 18:54:07 GMT Received: from ppma03dal.us.ibm.com (b.bd.3ea9.ip4.static.sl-reverse.com [169.62.189.11]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3ravksg37x-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 19 Jun 2023 18:54:07 +0000 Received: from pps.filterd (ppma03dal.us.ibm.com [127.0.0.1]) by ppma03dal.us.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 35J7YkoH006007; Mon, 19 Jun 2023 18:54:06 GMT Received: from smtprelay01.wdc07v.mail.ibm.com ([9.208.129.119]) by ppma03dal.us.ibm.com (PPS) with ESMTPS id 3r94f5bmaw-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 19 Jun 2023 18:54:06 +0000 Received: from smtpav01.wdc07v.mail.ibm.com (smtpav01.wdc07v.mail.ibm.com [10.39.53.228]) by smtprelay01.wdc07v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 35JIs4du11010386 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Mon, 19 Jun 2023 18:54:04 GMT Received: from smtpav01.wdc07v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 61F8858059; Mon, 19 Jun 2023 18:54:04 +0000 (GMT) Received: from smtpav01.wdc07v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 97A2E58065; Mon, 19 Jun 2023 18:54:03 +0000 (GMT) Received: from li-e362e14c-2378-11b2-a85c-87d605f3c641.ibm.com (unknown [9.61.18.149]) by smtpav01.wdc07v.mail.ibm.com (Postfix) with ESMTP; Mon, 19 Jun 2023 18:54:03 +0000 (GMT) Message-ID: <35552b6539d3469d7f74dbd9ec75061515a1d61c.camel@us.ibm.com> Subject: [PATCH ver 6] rs6000: Add builtins for IEEE 128-bit floating point values To: "Kewen.Lin" , dje.gcc@gmail.com, gcc-patches@gcc.gnu.org, Segher Boessenkool Cc: Peter Bergner , cel@us.ibm.com Date: Mon, 19 Jun 2023 11:54:03 -0700 X-Mailer: Evolution 3.28.5 (3.28.5-18.el8) Mime-Version: 1.0 X-TM-AS-GCONF: 00 X-Proofpoint-GUID: VxvsPVFRskN_2n6Kdv17urEWBOyF_Zs6 X-Proofpoint-ORIG-GUID: cdI2IPQ0_ezQx1npvu7RuEAQ30HK-n__ X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.254,Aquarius:18.0.957,Hydra:6.0.591,FMLib:17.11.176.26 definitions=2023-06-19_11,2023-06-16_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 mlxscore=0 clxscore=1015 suspectscore=0 malwarescore=0 spamscore=0 impostorscore=0 adultscore=0 lowpriorityscore=0 mlxlogscore=999 priorityscore=1501 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2305260000 definitions=main-2306190171 X-Spam-Status: No, score=-11.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_MSPIKE_H5, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Carl Love via Gcc-patches From: Carl Love Reply-To: Carl Love Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1764798328799831686?= X-GMAIL-MSGID: =?utf-8?q?1769158369367017522?= Kewen, GCC maintainers: Version 6, Fixed missing change log entry. Changed builtin id names as requested. Missed making the change on the last version. Fixed comment in the three test cases. Reran regression suite on Power 10, no regressions. Version 5, Tested the patch on P9 BE per request. Fixed up test case to get the correct expected values for BE and LE. Fixed typos. Updated the doc/extend.texi to clarify the vector arguments. Changed test file names per request. Moved builtin defs next to related definitions. Renamed new mode_attr. Removed new mode_iterator, used existing iterator instead. Renamed mode_iterator VSEEQP_DI to V2DI_DI. Fixed up overloaded definitions per request. Version 4, added missing cases for new xxexpqp, xsxexpdp and xsxsigqp cases to rs6000_expand_builtin. Merged the new define_insn definitions with the existing definitions. Renamed the builtins by removing the __builtin_ prefix from the names. Fixed the documentation for the builtins. Updated the test files to check the desired instructions were generated. Retested patch on Power 10 with no regressions. Version 3, was able to get the overloaded version of scalar_insert_exp to work and the change to xsxexpqp_f128_ define instruction to work with the suggestions from Kewen. Version 2, I have addressed the various comments from Kewen. I had issues with adding an additional overloaded version of scalar_insert_exp with vector arguments. The overload infrastructure didn't work with a mix of scalar and vector arguments. I did rename the __builtin_insertf128_exp to __builtin_vsx_scalar_insert_exp_qp make it similar to the existing builtin. I also wasn't able to get the suggested merge of xsxexpqp_f128_ with xsxexpqp_ to work so I left the two simpler definitiions. The patch add three new builtins to extract the significand and exponent of an IEEE float 128-bit value where the builtin argument is a vector. Additionally, a builtin to insert the exponent into an IEEE float 128-bit vector argument is added. These builtins were requested since there is no clean and optimal way to transfer between a vector and a scalar IEEE 128 bit value. The patch has been tested on Power 9 BE and Power 10 LE with no regressions. Please let me know if the patch is acceptable or not. Thanks. Carl -------------------------------------------- rs6000: Add builtins for IEEE 128-bit floating point values Add support for the following builtins: __vector unsigned long long int scalar_extract_exp_to_vec (__ieee128); __vector unsigned __int128 scalar_extract_sig_to_vec (__ieee128); __ieee128 scalar_insert_exp (__vector unsigned __int128, __vector unsigned long long); The instructions used in the builtins operate on vector registers. Thus the result must be moved to a scalar type. There is no clean, performant way to do this. The user code typically needs the result as a vector anyway. gcc/ * config/rs6000/rs6000-builtin.cc (rs6000_expand_builtin): Rename CCDE_FOR_xsxexpqp_tf to CODE_FOR_xsxexpqp_tf_di. Rename CODE_FOR_xsxexpqp_kf to CODE_FOR_xsxexpqp_kf_di. (CODE_FOR_xsxexpqp_kf_v2di, CODE_FOR_xsxsigqp_kf_v1ti, CODE_FOR_xsiexpqp_kf_v2di): Add case statements. * config/rs6000/rs6000-buildin.def (__builtin_extractf128_exp, __builtin_extractf128_sig, __builtin_insertf128_exp): Add new builtin definitions. Rename xsxexpqp_kf, xsxsigqp_kf, xsiexpqp_kf to xsexpqp_kf_di, xsxsigqp_kf_ti, xsiexpqp_kf_di respectively. * config/rs6000/rs6000-c.cc (altivec_resolve_overloaded_builtin): Update case RS6000_OVLD_VEC_VSIE to handle MODE_VECTOR_INT for new overloaded instance. Update comments. * config/rs6000/rs6000-overload.def (__builtin_vec_scalar_insert_exp): Add new overload definition with vector arguments. (scalar_extract_exp_to_vec, scalar_extract_sig_to_vec): New overloaded definitions. * config/vsx.md (V2DI_DI): New mode iterator. (DI_to_TI): New mode attribute. Rename xsxexpqp_ to sxexpqp__. Rename xsxsigqp_ to xsxsigqp__. Rename xsiexpqp_ to xsiexpqp__. * doc/extend.texi (__builtin_extractf128_exp, __builtin_extractf128_sig): Add documentation for new builtins. (scalar_insert_exp): Add new overloaded builtin definition. gcc/testsuite/ * gcc.target/powerpc/bfp/extract-exp-8.c: New test case. * gcc.target/powerpc/bfp/extract-sig-8.c: New test case. * gcc.target/powerpc/bfp/insert-exp-16.c: New test case. --- gcc/config/rs6000/rs6000-builtin.cc | 21 +++- gcc/config/rs6000/rs6000-builtins.def | 15 ++- gcc/config/rs6000/rs6000-c.cc | 10 +- gcc/config/rs6000/rs6000-overload.def | 12 ++ gcc/config/rs6000/vsx.md | 25 +++-- gcc/doc/extend.texi | 24 +++- .../powerpc/bfp/scalar-extract-exp-8.c | 58 ++++++++++ .../powerpc/bfp/scalar-extract-sig-8.c | 65 +++++++++++ .../powerpc/bfp/scalar-insert-exp-16.c | 103 ++++++++++++++++++ 9 files changed, 307 insertions(+), 26 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-8.c create mode 100644 gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-8.c create mode 100644 gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-16.c diff --git a/gcc/config/rs6000/rs6000-builtin.cc b/gcc/config/rs6000/rs6000-builtin.cc index 534698e7d3e..a8f291c6a72 100644 --- a/gcc/config/rs6000/rs6000-builtin.cc +++ b/gcc/config/rs6000/rs6000-builtin.cc @@ -3326,17 +3326,26 @@ rs6000_expand_builtin (tree exp, rtx target, rtx /* subtarget */, case CODE_FOR_fmakf4_odd: icode = CODE_FOR_fmatf4_odd; break; - case CODE_FOR_xsxexpqp_kf: - icode = CODE_FOR_xsxexpqp_tf; + case CODE_FOR_xsxexpqp_kf_di: + icode = CODE_FOR_xsxexpqp_tf_di; break; - case CODE_FOR_xsxsigqp_kf: - icode = CODE_FOR_xsxsigqp_tf; + case CODE_FOR_xsxexpqp_kf_v2di: + icode = CODE_FOR_xsxexpqp_tf_v2di; + break; + case CODE_FOR_xsxsigqp_kf_ti: + icode = CODE_FOR_xsxsigqp_tf_ti; + break; + case CODE_FOR_xsxsigqp_kf_v1ti: + icode = CODE_FOR_xsxsigqp_tf_v1ti; break; case CODE_FOR_xststdcnegqp_kf: icode = CODE_FOR_xststdcnegqp_tf; break; - case CODE_FOR_xsiexpqp_kf: - icode = CODE_FOR_xsiexpqp_tf; + case CODE_FOR_xsiexpqp_kf_di: + icode = CODE_FOR_xsiexpqp_tf_di; + break; + case CODE_FOR_xsiexpqp_kf_v2di: + icode = CODE_FOR_xsiexpqp_tf_v2di; break; case CODE_FOR_xsiexpqpf_kf: icode = CODE_FOR_xsiexpqpf_tf; diff --git a/gcc/config/rs6000/rs6000-builtins.def b/gcc/config/rs6000/rs6000-builtins.def index 638d0bc72ca..da0ddfa127c 100644 --- a/gcc/config/rs6000/rs6000-builtins.def +++ b/gcc/config/rs6000/rs6000-builtins.def @@ -2902,19 +2902,28 @@ TRUNCF128_ODD trunckfdf2_odd {} const signed long long __builtin_vsx_scalar_extract_expq (_Float128); - VSEEQP xsxexpqp_kf {} + VSEEQP xsxexpqp_kf_di {} + + vull __builtin_vsx_scalar_extract_exp_to_vec (_Float128); + VSEEQPV xsxexpqp_kf_v2di {} const signed __int128 __builtin_vsx_scalar_extract_sigq (_Float128); - VSESQP xsxsigqp_kf {} + VSESQP xsxsigqp_kf_ti {} + + vuq __builtin_vsx_scalar_extract_sig_to_vec (_Float128); + VSESQPV xsxsigqp_kf_v1ti {} const _Float128 __builtin_vsx_scalar_insert_exp_q (unsigned __int128, \ unsigned long long); - VSIEQP xsiexpqp_kf {} + VSIEQP xsiexpqp_kf_di {} const _Float128 __builtin_vsx_scalar_insert_exp_qp (_Float128, \ unsigned long long); VSIEQPF xsiexpqpf_kf {} + const _Float128 __builtin_vsx_scalar_insert_exp_vqp (vuq, vull); + VSIEQPV xsiexpqp_kf_v2di {} + const signed int __builtin_vsx_scalar_test_data_class_qp (_Float128, \ const int<7>); VSTDCQP xststdcqp_kf {} diff --git a/gcc/config/rs6000/rs6000-c.cc b/gcc/config/rs6000/rs6000-c.cc index 8555174d36e..11060f697db 100644 --- a/gcc/config/rs6000/rs6000-c.cc +++ b/gcc/config/rs6000/rs6000-c.cc @@ -1929,11 +1929,15 @@ altivec_resolve_overloaded_builtin (location_t loc, tree fndecl, 128-bit variant of built-in function. */ if (GET_MODE_PRECISION (arg1_mode) > 64) { - /* If first argument is of float variety, choose variant - that expects __ieee128 argument. Otherwise, expect - __int128 argument. */ + /* If first argument is of float variety, choose the variant that + expects __ieee128 argument. If the first argument is vector + int, choose the variant that expects vector unsigned + __int128 argument. Otherwise, expect scalar __int128 argument. + */ if (GET_MODE_CLASS (arg1_mode) == MODE_FLOAT) instance_code = RS6000_BIF_VSIEQPF; + else if (GET_MODE_CLASS (arg1_mode) == MODE_VECTOR_INT) + instance_code = RS6000_BIF_VSIEQPV; else instance_code = RS6000_BIF_VSIEQP; } diff --git a/gcc/config/rs6000/rs6000-overload.def b/gcc/config/rs6000/rs6000-overload.def index c582490c084..470d718efde 100644 --- a/gcc/config/rs6000/rs6000-overload.def +++ b/gcc/config/rs6000/rs6000-overload.def @@ -4515,6 +4515,18 @@ VSIEQP _Float128 __builtin_vec_scalar_insert_exp (_Float128, unsigned long long); VSIEQPF + _Float128 __builtin_vec_scalar_insert_exp (vuq, vull); + VSIEQPV + +[VEC_VSEEV, scalar_extract_exp_to_vec, \ + __builtin_vec_scalar_extract_exp_to_vector] + vull __builtin_vec_scalar_extract_exp_to_vector (_Float128); + VSEEQPV + +[VEC_VSESV, scalar_extract_sig_to_vec, \ + __builtin_vec_scalar_extract_sig_to_vector] + vuq __builtin_vec_scalar_extract_sig_to_vector (_Float128); + VSESQPV [VEC_VSTDC, scalar_test_data_class, __builtin_vec_scalar_test_data_class] unsigned int __builtin_vec_scalar_test_data_class (float, const int); diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index 7d845df5c2d..86cb98a2c61 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -396,6 +396,9 @@ V4SF V2DF V2DI]) +(define_mode_iterator V2DI_DI [V2DI DI]) +(define_mode_attr DI_to_TI [(V2DI "V1TI") + (DI "TI")]) (define_mode_attr VM3_char [(V2DI "d") (V4SI "w") @@ -5008,9 +5011,10 @@ ;; ISA 3.0 Binary Floating-Point Support ;; VSX Scalar Extract Exponent Quad-Precision -(define_insn "xsxexpqp_" - [(set (match_operand:DI 0 "altivec_register_operand" "=v") - (unspec:DI [(match_operand:IEEE128 1 "altivec_register_operand" "v")] +(define_insn "xsxexpqp__" + [(set (match_operand:V2DI_DI 0 "altivec_register_operand" "=v") + (unspec:V2DI_DI + [(match_operand:IEEE128 1 "altivec_register_operand" "v")] UNSPEC_VSX_SXEXPDP))] "TARGET_P9_VECTOR" "xsxexpqp %0,%1" @@ -5026,9 +5030,10 @@ [(set_attr "type" "integer")]) ;; VSX Scalar Extract Significand Quad-Precision -(define_insn "xsxsigqp_" - [(set (match_operand:TI 0 "altivec_register_operand" "=v") - (unspec:TI [(match_operand:IEEE128 1 "altivec_register_operand" "v")] +(define_insn "xsxsigqp__" + [(set (match_operand:VEC_TI 0 "altivec_register_operand" "=v") + (unspec:VEC_TI [(match_operand:IEEE128 1 + "altivec_register_operand" "v")] UNSPEC_VSX_SXSIG))] "TARGET_P9_VECTOR" "xsxsigqp %0,%1" @@ -5055,10 +5060,12 @@ [(set_attr "type" "vecmove")]) ;; VSX Scalar Insert Exponent Quad-Precision -(define_insn "xsiexpqp_" +(define_insn "xsiexpqp__" [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") - (unspec:IEEE128 [(match_operand:TI 1 "altivec_register_operand" "v") - (match_operand:DI 2 "altivec_register_operand" "v")] + (unspec:IEEE128 [(match_operand: 1 + "altivec_register_operand" "v") + (match_operand:V2DI_DI 2 + "altivec_register_operand" "v")] UNSPEC_VSX_SIEXPQP))] "TARGET_P9_VECTOR" "xsiexpqp %0,%1,%2" diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index e426a2eb7d8..e90fdbd098b 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -19724,6 +19724,10 @@ double scalar_insert_exp (double significand, unsigned long long int exponent); ieee_128 scalar_insert_exp (unsigned __int128 significand, unsigned long long int exponent); ieee_128 scalar_insert_exp (ieee_128 significand, unsigned long long int exponent); +vector ieee_128 scalar_insert_exp (vector unsigned __int128 significand, + vector unsigned long long exponent); +vector unsigned long long scalar_extract_exp_to_vec (ieee_128); +vector unsigned __int128 scalar_extract_sig_to_vec (ieee_128); int scalar_cmp_exp_gt (double arg1, double arg2); int scalar_cmp_exp_lt (double arg1, double arg2); @@ -19771,11 +19775,21 @@ of the result are composed of the least significant 11 bits of the When supplied with a 128-bit first argument, the @code{scalar_insert_exp} built-in function returns a quad-precision -ieee floating point value. The sign bit of the result is copied from -the most significant bit of the @code{significand} argument. -The significand and exponent components of the result are composed of -the least significant 15 bits of the @code{exponent} argument and the -least significant 112 bits of the @code{significand} argument respectively. +IEEE floating point value if the two arguments were scalar. If the two +arguments are vectors, the return value is a vector IEEE floating point value. +The sign bit of the result is copied from the most significant bit of the +@code{significand} argument. The significand and exponent components of the +result are composed of the least significant 15 bits of the @code{exponent} +argument (element 0 on big-endian and element 1 on little-endian) and the +least significant 112 bits of the @code{significand} argument +respectively. Note, the @code{significand} is the scalar argument or in the +case of vector arguments, @code{significand} is element 0 for big-endian and +element 1 for little-endian. + +The @code{scalar_extract_exp_to_vec}, +and @code{scalar_extract_sig_to_vec} are similar to +@code{scalar_extract_exp}, @code{scalar_extract_sig} except they return +a vector result of type unsigned long long and unsigned __int128 respectively. The @code{scalar_cmp_exp_gt}, @code{scalar_cmp_exp_lt}, @code{scalar_cmp_exp_eq}, and @code{scalar_cmp_exp_unordered} built-in diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-8.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-8.c new file mode 100644 index 00000000000..eedcfcdac96 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-exp-8.c @@ -0,0 +1,58 @@ +/* { dg-do run { target { powerpc*-*-* } } } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p9vector_hw } */ +/* { dg-options "-mdejagnu-cpu=power9 -save-temps" } */ + +#include +#include + +#if DEBUG +#include +#endif + +vector unsigned long long int +get_exponents (__ieee128 *p) +{ + __ieee128 source = *p; + + return scalar_extract_exp_to_vec (source); +} + +int +main () +{ + vector unsigned long long int result, exp_result; + union conv128_t + { + __ieee128 val_ieee128; + __int128 val_int128; + } source; + +#ifdef _BIG_ENDIAN + exp_result[1] = 0x0ULL; + exp_result[0] = 0x1234ULL; +#else + exp_result[0] = 0x0ULL; + exp_result[1] = 0x1234ULL; +#endif + source.val_int128 = 0x923456789ABCDEF0ULL; + source.val_int128 = (source.val_int128 << 64) | 0x123456789ABCDEFULL; + + result = get_exponents (&source.val_ieee128); + + if ((result[0] != exp_result[0]) || (result[1] != exp_result[1])) +#if DEBUG + { + printf("result[0] = 0x%llx; exp_result[0] = 0x%llx\n", + result[0], exp_result[0]); + printf("result[1] = 0x%llx; exp_result[1] = 0x%llx\n", + result[1], exp_result[1]); + } +#else + abort(); +#endif + return 0; +} + +/* Check that the expected extract exponent instruction is generated. */ +/* { dg-final { scan-assembler-times {\mxsxexpqp\M} 1 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-8.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-8.c new file mode 100644 index 00000000000..69a908a53c2 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-extract-sig-8.c @@ -0,0 +1,65 @@ +/* { dg-do run { target { powerpc*-*-* } } } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p9vector_hw } */ +/* { dg-options "-mdejagnu-cpu=power9 -save-temps" } */ + +#include +#include + +#if DEBUG +#include +#endif + +vector unsigned __int128 +get_significand (__ieee128 *p) +{ + __ieee128 source = *p; + + return scalar_extract_sig_to_vec(source); +} + +int +main () +{ + #define NOT_ZERO_OR_DENORMAL 0x1000000000000 + + union conv128_t + { + __ieee128 val_ieee128; + unsigned long long int val_ull[2]; + unsigned __int128 val_uint128; + vector unsigned __int128 val_vuint128; + } source, result, exp_result; + + /* Result is not zero or denormal. */ +#ifdef _BIG_ENDIAN + exp_result.val_ull[0] = 0x00056789ABCDEF0ULL | NOT_ZERO_OR_DENORMAL; + exp_result.val_ull[1] = 0x123456789ABCDEFULL; +#else + exp_result.val_ull[1] = 0x00056789ABCDEF0ULL | NOT_ZERO_OR_DENORMAL; + exp_result.val_ull[0] = 0x123456789ABCDEFULL; +#endif + source.val_uint128 = 0x923456789ABCDEF0ULL; + source.val_uint128 = (source.val_uint128 << 64) | 0x123456789ABCDEFULL; + + /* Note, bits[0:14] are set to 0, bit[15] is 0 if the input was zero or + Denormal, 1 otherwise. */ + result.val_vuint128 = get_significand (&source.val_ieee128); + + if ((result.val_ull[0] != exp_result.val_ull[0]) + || (result.val_ull[1] != exp_result.val_ull[1])) +#if DEBUG + { + printf("result[0] = 0x%llx; exp_result[0] = 0x%llx\n", + result.val_ull[0], exp_result.val_ull[0]); + printf("result[1] = 0x%llx; exp_result[1] = 0x%llx\n", + result.val_ull[1], exp_result.val_ull[1]); + } +#else + abort(); +#endif + return 0; +} + +/* Check that the expected extract significand instruction is generated. */ +/* { dg-final { scan-assembler-times {\mxsxsigqp\M} 1 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-16.c b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-16.c new file mode 100644 index 00000000000..f0e03c5173d --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/bfp/scalar-insert-exp-16.c @@ -0,0 +1,103 @@ +/* { dg-do run { target { powerpc*-*-* } } } */ +/* { dg-require-effective-target lp64 } */ +/* { dg-require-effective-target p9vector_hw } */ +/* { dg-options "-mdejagnu-cpu=power9 -save-temps" } */ + +#include +#include + +#ifdef DEBUG +#include +#endif + +__ieee128 +insert_exponent (vector unsigned __int128 *significand_p, + vector unsigned long long int *exponent_p) +{ + vector unsigned __int128 significand = *significand_p; + vector unsigned long long int exponent = *exponent_p; + + return scalar_insert_exp (significand, exponent); +} + +__ieee128 +insert_exponent2 (unsigned __int128 significand, + unsigned long long int exponent) +{ + return scalar_insert_exp (significand, exponent); +} + +int +main () +{ + __ieee128 val_ieee128, result_ieee128, exp_result_ieee128; + unsigned __int128 val_int128; + unsigned long long int val_ull; + union conv128_t + { + __ieee128 val_ieee128; + vector unsigned __int128 val_vint128; + vector unsigned long long int val_vull; + } result, exp_result, significand; + + vector unsigned long long int exponent; + + /* Scalar argument test */ + val_ieee128 = 0xFEDCBA9876543210ULL; + val_ull = 0x5678; +#ifdef _BIG_ENDIAN + exp_result.val_vull[1] = 0xfedcba9876543210; + exp_result.val_vull[0] = 0x5678000000000000ULL; +#else + exp_result.val_vull[0] = 0xfedcba9876543210; + exp_result.val_vull[1] = 0x5678000000000000ULL; +#endif + result_ieee128 = insert_exponent2 (val_ieee128, val_ull); + + if (result_ieee128 != exp_result.val_ieee128) +#ifdef DEBUG + { + result.val_ieee128 = result_ieee128; + printf("Scalar argument ERROR:\n"); + printf(" val_ieee128 = 0x%llx %llx\n", + result.val_vull[1], result.val_vull[0]); + printf(" exp_val_ieee128 = 0x%llx %llx\n", + exp_result.val_vull[1], exp_result.val_vull[0]); + } +#else + abort (); +#endif + + /* Vector argument test */ + significand.val_vull[0] = 0xFEDCBA9876543210ULL; + significand.val_vull[1] = 0x7FFF12345678ABCDULL; /* positive value */ + + exponent[0] = 0x5678; + exponent[1] = 0x1234; + +#ifdef _BIG_ENDIAN + exp_result.val_vull[0] = 0xD678BA9876543210ULL; + exp_result.val_vull[1] = 0x7FFF12345678ABCDULL; +#else + exp_result.val_vull[0] = 0xFEDCBA9876543210ULL; + exp_result.val_vull[1] = 0x123412345678ABCDULL; +#endif + result.val_ieee128 = insert_exponent(&significand.val_vint128, &exponent); + + if (result.val_ieee128 != exp_result.val_ieee128) +#ifdef DEBUG + { + printf("Vector argument ERROR:\n"); + printf(" result = 0x%llx %llx\n", + result.val_vull[1], result.val_vull[0]); + printf(" exp_result = 0x%llx %llx\n", + exp_result.val_vull[1], exp_result.val_vull[0]); + } +#else + abort (); +#endif + +} + +/* Check that the expected insert exponent instruction is generated. */ +/* { dg-final { scan-assembler-times {\mxsiexpqp\M} 2 } } */