From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx0a-001b2d01.pphosted.com (mx0a-001b2d01.pphosted.com [148.163.156.1]) by sourceware.org (Postfix) with ESMTPS id 08AA3384003E for ; Tue, 27 Jul 2021 21:06:28 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 08AA3384003E Received: from pps.filterd (m0187473.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.16.0.43/8.16.0.43) with SMTP id 16RL3hRk066394; Tue, 27 Jul 2021 17:06:27 -0400 Received: from ppma03wdc.us.ibm.com (ba.79.3fa9.ip4.static.sl-reverse.com [169.63.121.186]) by mx0a-001b2d01.pphosted.com with ESMTP id 3a2qpd3yf9-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 27 Jul 2021 17:06:27 -0400 Received: from pps.filterd (ppma03wdc.us.ibm.com [127.0.0.1]) by ppma03wdc.us.ibm.com (8.16.1.2/8.16.1.2) with SMTP id 16RL4Xtn016190; Tue, 27 Jul 2021 21:06:25 GMT Received: from b01cxnp23032.gho.pok.ibm.com (b01cxnp23032.gho.pok.ibm.com [9.57.198.27]) by ppma03wdc.us.ibm.com with ESMTP id 3a235mufm1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Tue, 27 Jul 2021 21:06:25 +0000 Received: from b01ledav004.gho.pok.ibm.com (b01ledav004.gho.pok.ibm.com [9.57.199.109]) by b01cxnp23032.gho.pok.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 16RL6OcE27263254 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 27 Jul 2021 21:06:24 GMT Received: from b01ledav004.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id C230111206D; Tue, 27 Jul 2021 21:06:24 +0000 (GMT) Received: from b01ledav004.gho.pok.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id ACD7B11206B; Tue, 27 Jul 2021 21:06:23 +0000 (GMT) Received: from lexx (unknown [9.171.17.235]) by b01ledav004.gho.pok.ibm.com (Postfix) with ESMTP; Tue, 27 Jul 2021 21:06:23 +0000 (GMT) Message-ID: <40a4cb9c7713135e064a3536bf6e02973a21f7a1.camel@vnet.ibm.com> Subject: Re: [PATCH 44/55] rs6000: Builtin expansion, part 1 From: will schmidt To: Bill Schmidt , gcc-patches@gcc.gnu.org Cc: segher@kernel.crashing.org Date: Tue, 27 Jul 2021 16:06:22 -0500 In-Reply-To: <33050d979b1daea306340b19a0cc8c17b54c6622.1623941442.git.wschmidt@linux.ibm.com> References: <33050d979b1daea306340b19a0cc8c17b54c6622.1623941442.git.wschmidt@linux.ibm.com> Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.28.5 (3.28.5-10.el7) Mime-Version: 1.0 Content-Transfer-Encoding: 7bit X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: mwHNLyXl4-_G9USGyvoccb_RogBxN0oN X-Proofpoint-GUID: mwHNLyXl4-_G9USGyvoccb_RogBxN0oN X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.391, 18.0.790 definitions=2021-07-27_14:2021-07-27, 2021-07-27 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 mlxscore=0 lowpriorityscore=0 bulkscore=0 spamscore=0 malwarescore=0 adultscore=0 impostorscore=0 clxscore=1015 phishscore=0 mlxlogscore=999 suspectscore=0 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2107140000 definitions=main-2107270123 X-Spam-Status: No, score=-12.1 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, GIT_PATCH_0, KAM_NUMSUBJECT, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) 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-List-Received-Date: Tue, 27 Jul 2021 21:06:31 -0000 On Thu, 2021-06-17 at 10:19 -0500, Bill Schmidt via Gcc-patches wrote: > 2021-06-17 Bill Schmidt > Hi, > gcc/ > * config/rs6000/rs6000-call.c (rs6000_expand_new_builtin): New > forward decl. > (rs6000_invalid_new_builtin): New stub function. > (rs6000_expand_builtin): Call rs6000_expand_new_builtin. > (rs6000_expand_ldst_mask): New stub function. > (new_cpu_expand_builtin): Likewise. > (elemrev_icode): Likewise. > (ldv_expand_builtin): Likewise. > (lxvrse_expand_builtin): Likewise. > (lxvrze_expand_builtin): Likewise. > (stv_expand_builtin): Likewise. > (new_mma_expand_builtin): Likewise. > (new_htm_expand_builtin): Likewise. > (rs6000_expand_new_builtin): New function. > --- > gcc/config/rs6000/rs6000-call.c | 526 ++++++++++++++++++++++++++++++++ > 1 file changed, 526 insertions(+) > > diff --git a/gcc/config/rs6000/rs6000-call.c b/gcc/config/rs6000/rs6000-call.c > index 52df3d165e1..8693836cd5a 100644 > --- a/gcc/config/rs6000/rs6000-call.c > +++ b/gcc/config/rs6000/rs6000-call.c > @@ -190,6 +190,7 @@ static tree builtin_function_type (machine_mode, machine_mode, > static void rs6000_common_init_builtins (void); > static void htm_init_builtins (void); > static void mma_init_builtins (void); > +static rtx rs6000_expand_new_builtin (tree, rtx, rtx, machine_mode, int); > static bool rs6000_gimple_fold_new_builtin (gimple_stmt_iterator *gsi); Ok if the forward declaration is necessary. I think we still have a todo to rearrange and eliminate some of those, IMO not worth holding up this patch series for that. > > > @@ -11664,6 +11665,14 @@ rs6000_invalid_builtin (enum rs6000_builtins fncode) > error ("%qs is not supported with the current options", name); > } > > +/* Raise an error message for a builtin function that is called without the > + appropriate target options being set. */ > + > +static void > +rs6000_invalid_new_builtin (enum rs6000_gen_builtins fncode) > +{ > +} > + > /* Target hook for early folding of built-ins, shamelessly stolen > from ia64.c. */ > > @@ -14193,6 +14202,9 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, > machine_mode mode ATTRIBUTE_UNUSED, > int ignore ATTRIBUTE_UNUSED) > { > + if (new_builtins_are_live) > + return rs6000_expand_new_builtin (exp, target, subtarget, mode, ignore); > + > tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); > enum rs6000_builtins fcode > = (enum rs6000_builtins) DECL_MD_FUNCTION_CODE (fndecl); > @@ -14485,6 +14497,520 @@ rs6000_expand_builtin (tree exp, rtx target, rtx subtarget ATTRIBUTE_UNUSED, > gcc_unreachable (); > } > > +/* Expand ALTIVEC_BUILTIN_MASK_FOR_LOAD. */ > +rtx > +rs6000_expand_ldst_mask (rtx target, tree arg0) > + { > + return target; > + } > + > +/* Expand the CPU builtin in FCODE and store the result in TARGET. */ > +static rtx > +new_cpu_expand_builtin (enum rs6000_gen_builtins fcode, > + tree exp ATTRIBUTE_UNUSED, rtx target) > +{ > + return target; > +} > + > +static insn_code > +elemrev_icode (rs6000_gen_builtins fcode) > +{ > + return (insn_code) 0; > +} > + > +static rtx > +ldv_expand_builtin (rtx target, insn_code icode, rtx *op, machine_mode tmode) > +{ > + return target; > +} > + > +static rtx > +lxvrse_expand_builtin (rtx target, insn_code icode, rtx *op, > + machine_mode tmode, machine_mode smode) > +{ > + return target; > +} > + > +static rtx > +lxvrze_expand_builtin (rtx target, insn_code icode, rtx *op, > + machine_mode tmode, machine_mode smode) > +{ > + return target; > +} > + > +static rtx > +stv_expand_builtin (insn_code icode, rtx *op, > + machine_mode tmode, machine_mode smode) > +{ > + return NULL_RTX; > +} > + > +/* Expand the MMA built-in in EXP. */ > +static rtx > +new_mma_expand_builtin (tree exp, rtx target, insn_code icode, > + rs6000_gen_builtins fcode) > +{ > + return target; > +} > + > +/* Expand the HTM builtin in EXP and store the result in TARGET. */ > +static rtx > +new_htm_expand_builtin (bifdata *bifaddr, rs6000_gen_builtins fcode, > + tree exp, rtx target) > +{ > + return const0_rtx; > +} > + > +/* Expand an expression EXP that calls a built-in function, > + with result going to TARGET if that's convenient > + (and in mode MODE if that's convenient). > + SUBTARGET may be used as the target for computing one of EXP's operands. > + IGNORE is nonzero if the value is to be ignored. > + Use the new builtin infrastructure. */ > +static rtx > +rs6000_expand_new_builtin (tree exp, rtx target, > + rtx subtarget ATTRIBUTE_UNUSED, > + machine_mode ignore_mode ATTRIBUTE_UNUSED, > + int ignore ATTRIBUTE_UNUSED) > +{ > + tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0); > + enum rs6000_gen_builtins fcode > + = (enum rs6000_gen_builtins) DECL_MD_FUNCTION_CODE (fndecl); > + size_t uns_fcode = (size_t)fcode; > + enum insn_code icode = rs6000_builtin_info_x[uns_fcode].icode; > + > + /* We have two different modes (KFmode, TFmode) that are the IEEE 128-bit > + floating point type, depending on whether long double is the IBM extended > + double (KFmode) or long double is IEEE 128-bit (TFmode). It is simpler if > + we only define one variant of the built-in function, and switch the code > + when defining it, rather than defining two built-ins and using the > + overload table in rs6000-c.c to switch between the two. If we don't have > + the proper assembler, don't do this switch because CODE_FOR_*kf* and > + CODE_FOR_*tf* will be CODE_FOR_nothing. */ ok > + if (FLOAT128_IEEE_P (TFmode)) > + switch (icode) > + { > + default: > + break; > + > + case CODE_FOR_sqrtkf2_odd: icode = CODE_FOR_sqrttf2_odd; break; > + case CODE_FOR_trunckfdf2_odd: icode = CODE_FOR_trunctfdf2_odd; break; > + case CODE_FOR_addkf3_odd: icode = CODE_FOR_addtf3_odd; break; > + case CODE_FOR_subkf3_odd: icode = CODE_FOR_subtf3_odd; break; > + case CODE_FOR_mulkf3_odd: icode = CODE_FOR_multf3_odd; break; > + case CODE_FOR_divkf3_odd: icode = CODE_FOR_divtf3_odd; break; > + case CODE_FOR_fmakf4_odd: icode = CODE_FOR_fmatf4_odd; break; > + case CODE_FOR_xsxexpqp_kf: icode = CODE_FOR_xsxexpqp_tf; break; > + case CODE_FOR_xsxsigqp_kf: icode = CODE_FOR_xsxsigqp_tf; break; > + case CODE_FOR_xststdcnegqp_kf: icode = CODE_FOR_xststdcnegqp_tf; break; > + case CODE_FOR_xsiexpqp_kf: icode = CODE_FOR_xsiexpqp_tf; break; > + case CODE_FOR_xsiexpqpf_kf: icode = CODE_FOR_xsiexpqpf_tf; break; > + case CODE_FOR_xststdcqp_kf: icode = CODE_FOR_xststdcqp_tf; break; > + > + case CODE_FOR_xscmpexpqp_eq_kf: > + icode = CODE_FOR_xscmpexpqp_eq_tf; > + break; > + > + case CODE_FOR_xscmpexpqp_lt_kf: > + icode = CODE_FOR_xscmpexpqp_lt_tf; > + break; > + > + case CODE_FOR_xscmpexpqp_gt_kf: > + icode = CODE_FOR_xscmpexpqp_gt_tf; > + break; > + > + case CODE_FOR_xscmpexpqp_unordered_kf: > + icode = CODE_FOR_xscmpexpqp_unordered_tf; > + break; > + } > + > + bifdata *bifaddr = &rs6000_builtin_info_x[uns_fcode]; > + > + /* In case of "#pragma target" changes, we initialize all builtins > + but check for actual availability during expand time. For > + invalid builtins, generate a normal call. */ > + switch (bifaddr->enable) > + { > + default: > + gcc_unreachable (); > + case ENB_ALWAYS: > + break; > + case ENB_P5: > + if (!TARGET_POPCNTB) > + { > + rs6000_invalid_new_builtin (fcode); > + return expand_call (exp, target, ignore); > + } > + break; > + case ENB_P6: > + if (!TARGET_CMPB) > + { > + rs6000_invalid_new_builtin (fcode); > + return expand_call (exp, target, ignore); > + } > + break; > + case ENB_ALTIVEC: > + if (!TARGET_ALTIVEC) > + { > + rs6000_invalid_new_builtin (fcode); > + return expand_call (exp, target, ignore); > + } > + break; > + case ENB_CELL: > + if (!TARGET_ALTIVEC || rs6000_cpu != PROCESSOR_CELL) > + { > + rs6000_invalid_new_builtin (fcode); > + return expand_call (exp, target, ignore); > + } > + break; > + case ENB_VSX: > + if (!TARGET_VSX) > + { > + rs6000_invalid_new_builtin (fcode); > + return expand_call (exp, target, ignore); > + } > + break; > + case ENB_P7: > + if (!TARGET_POPCNTD) > + { > + rs6000_invalid_new_builtin (fcode); > + return expand_call (exp, target, ignore); > + } > + break; > + case ENB_P7_64: > + if (!TARGET_POPCNTD || !TARGET_POWERPC64) > + { > + rs6000_invalid_new_builtin (fcode); > + return expand_call (exp, target, ignore); > + } > + break; > + case ENB_P8: > + if (!TARGET_DIRECT_MOVE) > + { > + rs6000_invalid_new_builtin (fcode); > + return expand_call (exp, target, ignore); > + } > + break; > + case ENB_P8V: > + if (!TARGET_P8_VECTOR) > + { > + rs6000_invalid_new_builtin (fcode); > + return expand_call (exp, target, ignore); > + } > + break; > + case ENB_P9: > + if (!TARGET_MODULO) > + { > + rs6000_invalid_new_builtin (fcode); > + return expand_call (exp, target, ignore); > + } > + break; > + case ENB_P9_64: > + if (!TARGET_MODULO || !TARGET_POWERPC64) > + { > + rs6000_invalid_new_builtin (fcode); > + return expand_call (exp, target, ignore); > + } > + break; > + case ENB_P9V: > + if (!TARGET_P9_VECTOR) > + { > + rs6000_invalid_new_builtin (fcode); > + return expand_call (exp, target, ignore); > + } > + break; > + case ENB_IEEE128_HW: > + if (!TARGET_FLOAT128_HW) > + { > + rs6000_invalid_new_builtin (fcode); > + return expand_call (exp, target, ignore); > + } > + break; > + case ENB_DFP: > + if (!TARGET_DFP) > + { > + rs6000_invalid_new_builtin (fcode); > + return expand_call (exp, target, ignore); > + } > + break; > + case ENB_CRYPTO: > + if (!TARGET_CRYPTO) > + { > + rs6000_invalid_new_builtin (fcode); > + return expand_call (exp, target, ignore); > + } > + break; > + case ENB_HTM: > + if (!TARGET_HTM) > + { > + rs6000_invalid_new_builtin (fcode); > + return expand_call (exp, target, ignore); > + } > + break; > + case ENB_P10: > + if (!TARGET_POWER10) > + { > + rs6000_invalid_new_builtin (fcode); > + return expand_call (exp, target, ignore); > + } > + break; > + case ENB_P10_64: > + if (!TARGET_POWER10 || !TARGET_POWERPC64) > + { > + rs6000_invalid_new_builtin (fcode); > + return expand_call (exp, target, ignore); > + } > + break; > + case ENB_MMA: > + if (!TARGET_MMA) > + { > + rs6000_invalid_new_builtin (fcode); > + return expand_call (exp, target, ignore); > + } > + break; > + }; > + > + if (bif_is_nosoft (*bifaddr) > + && rs6000_isa_flags & OPTION_MASK_SOFT_FLOAT) > + { > + error ("%<%s%> not supported with %<-msoft-float%>", > + bifaddr->bifname); > + return const0_rtx; > + } > + > + if (bif_is_no32bit (*bifaddr) && TARGET_32BIT) > + fatal_error (input_location, > + "%<%s%> is not supported in 32-bit mode", > + bifaddr->bifname); ok > + > + if (bif_is_cpu (*bifaddr)) > + return new_cpu_expand_builtin (fcode, exp, target); > + > + if (bif_is_init (*bifaddr)) > + return altivec_expand_vec_init_builtin (TREE_TYPE (exp), exp, target); > + > + if (bif_is_set (*bifaddr)) > + return altivec_expand_vec_set_builtin (exp); > + > + if (bif_is_extract (*bifaddr)) > + return altivec_expand_vec_ext_builtin (exp, target); > + > + if (bif_is_predicate (*bifaddr)) > + return altivec_expand_predicate_builtin (icode, exp, target); > + > + if (bif_is_htm (*bifaddr)) > + return new_htm_expand_builtin (bifaddr, fcode, exp, target); > + > + rtx pat; > + const int MAX_BUILTIN_ARGS = 6; > + tree arg[MAX_BUILTIN_ARGS]; > + rtx op[MAX_BUILTIN_ARGS]; > + machine_mode mode[MAX_BUILTIN_ARGS + 1]; > + bool void_func = TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node; > + int k; > + > + int nargs = bifaddr->nargs; > + gcc_assert (nargs <= MAX_BUILTIN_ARGS); > + > + if (void_func) > + k = 0; > + else > + { > + k = 1; > + mode[0] = insn_data[icode].operand[0].mode; > + } > + > + for (int i = 0; i < nargs; i++) > + { > + arg[i] = CALL_EXPR_ARG (exp, i); > + if (arg[i] == error_mark_node) > + return const0_rtx; > + STRIP_NOPS (arg[i]); > + op[i] = expand_normal (arg[i]); > + /* We have a couple of pesky patterns that don't specify the mode... */ > + if (!insn_data[icode].operand[i+k].mode) > + mode[i+k] = TARGET_64BIT ? Pmode : SImode; > + else > + mode[i+k] = insn_data[icode].operand[i+k].mode; > + } > + > + /* Check for restricted constant arguments. */ > + for (int i = 0; i < 2; i++) > + { > + switch (bifaddr->restr[i]) > + { > + default: > + case RES_NONE: > + break; > + case RES_BITS: > + { > + size_t mask = (1 << bifaddr->restr_val1[i]) - 1; > + tree restr_arg = arg[bifaddr->restr_opnd[i] - 1]; > + STRIP_NOPS (restr_arg); > + if (TREE_CODE (restr_arg) != INTEGER_CST > + || TREE_INT_CST_LOW (restr_arg) & ~mask) > + { > + error ("argument %d must be a %d-bit unsigned literal", > + bifaddr->restr_opnd[i], bifaddr->restr_val1[i]); > + return CONST0_RTX (mode[0]); > + } > + break; > + } ok > + case RES_RANGE: > + { > + tree restr_arg = arg[bifaddr->restr_opnd[i] - 1]; > + STRIP_NOPS (restr_arg); > + if (TREE_CODE (restr_arg) != INTEGER_CST > + || !IN_RANGE (tree_to_shwi (restr_arg), > + bifaddr->restr_val1[i], > + bifaddr->restr_val2[i])) > + { > + error ("argument %d must be a literal between %d and %d," > + " inclusive", > + bifaddr->restr_opnd[i], bifaddr->restr_val1[i], > + bifaddr->restr_val2[i]); > + return CONST0_RTX (mode[0]); > + } > + break; > + } ok > + case RES_VAR_RANGE: > + { > + tree restr_arg = arg[bifaddr->restr_opnd[i] - 1]; > + STRIP_NOPS (restr_arg); > + if (TREE_CODE (restr_arg) == INTEGER_CST > + && !IN_RANGE (tree_to_shwi (restr_arg), > + bifaddr->restr_val1[i], > + bifaddr->restr_val2[i])) > + { > + error ("argument %d must be a variable or a literal " > + "between %d and %d, inclusive", > + bifaddr->restr_opnd[i], bifaddr->restr_val1[i], > + bifaddr->restr_val2[i]); > + return CONST0_RTX (mode[0]); > + } > + break; > + } ok > + case RES_VALUES: > + { > + tree restr_arg = arg[bifaddr->restr_opnd[i] - 1]; > + STRIP_NOPS (restr_arg); > + if (TREE_CODE (restr_arg) != INTEGER_CST > + || (tree_to_shwi (restr_arg) != bifaddr->restr_val1[i] > + && tree_to_shwi (restr_arg) != bifaddr->restr_val2[i])) > + { > + error ("argument %d must be either a literal %d or a " > + "literal %d", > + bifaddr->restr_opnd[i], bifaddr->restr_val1[i], > + bifaddr->restr_val2[i]); > + return CONST0_RTX (mode[0]); > + } > + break; > + } ok > + } > + } > + > + if (bif_is_ldstmask (*bifaddr)) > + return rs6000_expand_ldst_mask (target, arg[0]); > + > + if (bif_is_stvec (*bifaddr)) > + { > + if (bif_is_reve (*bifaddr)) > + icode = elemrev_icode (fcode); > + return stv_expand_builtin (icode, op, mode[0], mode[1]); > + } > + > + if (bif_is_ldvec (*bifaddr)) > + { > + if (bif_is_reve (*bifaddr)) > + icode = elemrev_icode (fcode); > + return ldv_expand_builtin (target, icode, op, mode[0]); > + } > + > + if (bif_is_lxvrse (*bifaddr)) > + return lxvrse_expand_builtin (target, icode, op, mode[0], mode[1]); > + > + if (bif_is_lxvrze (*bifaddr)) > + return lxvrze_expand_builtin (target, icode, op, mode[0], mode[1]); > + > + if (bif_is_mma (*bifaddr)) > + return new_mma_expand_builtin (exp, target, icode, fcode); > + > + if (fcode == RS6000_BIF_PACK_IF > + && TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD) > + { > + icode = CODE_FOR_packtf; > + fcode = RS6000_BIF_PACK_TF; > + uns_fcode = (size_t)fcode; > + } > + else if (fcode == RS6000_BIF_UNPACK_IF > + && TARGET_LONG_DOUBLE_128 && !TARGET_IEEEQUAD) > + { > + icode = CODE_FOR_unpacktf; > + fcode = RS6000_BIF_UNPACK_TF; > + uns_fcode = (size_t)fcode; > + } > + > + if (TREE_TYPE (TREE_TYPE (fndecl)) == void_type_node) > + target = NULL_RTX; > + else if (target == 0 > + || GET_MODE (target) != mode[0] > + || !(*insn_data[icode].operand[0].predicate) (target, mode[0])) > + target = gen_reg_rtx (mode[0]); > + > + for (int i = 0; i < nargs; i++) > + if (! (*insn_data[icode].operand[i+k].predicate) (op[i], mode[i+k])) > + op[i] = copy_to_mode_reg (mode[i+k], op[i]); > + > + switch (nargs) > + { > + default: > + gcc_assert (MAX_BUILTIN_ARGS == 6); > + gcc_unreachable (); > + case 0: > + pat = (void_func > + ? GEN_FCN (icode) () > + : GEN_FCN (icode) (target)); > + break; > + case 1: > + pat = (void_func > + ? GEN_FCN (icode) (op[0]) > + : GEN_FCN (icode) (target, op[0])); > + break; > + case 2: > + pat = (void_func > + ? GEN_FCN (icode) (op[0], op[1]) > + : GEN_FCN (icode) (target, op[0], op[1])); > + break; > + case 3: > + pat = (void_func > + ? GEN_FCN (icode) (op[0], op[1], op[2]) > + : GEN_FCN (icode) (target, op[0], op[1], op[2])); > + break; > + case 4: > + pat = (void_func > + ? GEN_FCN (icode) (op[0], op[1], op[2], op[3]) > + : GEN_FCN (icode) (target, op[0], op[1], op[2], op[3])); > + break; > + case 5: > + pat = (void_func > + ? GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4]) > + : GEN_FCN (icode) (target, op[0], op[1], op[2], op[3], op[4])); > + break; > + case 6: > + pat = (void_func > + ? GEN_FCN (icode) (op[0], op[1], op[2], op[3], op[4], op[5]) > + : GEN_FCN (icode) (target, op[0], op[1], > + op[2], op[3], op[4], op[5])); > + break; > + } > + > + if (!pat) > + return 0; > + emit_insn (pat); > + > + return target; > +} ok, lgtm thanks -Will > + > /* Create a builtin vector type with a name. Taking care not to give > the canonical type a name. */ >