From patchwork Wed Dec 6 05:24:25 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiufu Guo X-Patchwork-Id: 1872431 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=ibm.com header.i=@ibm.com header.a=rsa-sha256 header.s=pp1 header.b=PyURGbly; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4SlQnv2LNVz1ySd for ; Wed, 6 Dec 2023 16:24:51 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 1B1D73861894 for ; Wed, 6 Dec 2023 05:24:49 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx0b-001b2d01.pphosted.com (mx0b-001b2d01.pphosted.com [148.163.158.5]) by sourceware.org (Postfix) with ESMTPS id 68E913858429; Wed, 6 Dec 2023 05:24:34 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 68E913858429 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=linux.ibm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linux.ibm.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 68E913858429 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=148.163.158.5 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701840278; cv=none; b=ip196rwlOZmQ28E7rUv3Pev84SEu9nCbOLKSPEVgaDHFgyHdlN8lzNeCvZFc3JxB0onwwmVkFHBpD9xpVCpMIGuMYUpc9yqFr8PCnBIKmta5FWC2FuabGN6KdSC8eJDY38DJcO9sr5XnouqkNn6MLY+rKXQoUKJhufjAytJA8HI= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1701840278; c=relaxed/simple; bh=rjdVvZ+6xPP3j0nXfvXN91W79HXbmmTLfF1UVN7MPbY=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=B78VS6v2f6qJ45AOpLB7F6cwOOkVjeZQVB/JyR2Tyd/B62fupFs1DPUMHMi7FYReF9ObCnP939pIPtnOEfp08rGrAnBKi1nEySkPdycATCZKmYve76P3dzFAT+vLr/Xv01q3627T4jHEt22jAbBYogjmkSoXth0t4K8X9zst220= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from pps.filterd (m0353725.ppops.net [127.0.0.1]) by mx0a-001b2d01.pphosted.com (8.17.1.19/8.17.1.19) with ESMTP id 3B64h3xF026303; Wed, 6 Dec 2023 05:24:34 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ibm.com; h=from : to : cc : subject : date : message-id : content-transfer-encoding : mime-version; s=pp1; bh=ZbXxgcsbB7jwXsGLYPSAIxtKSD51+GKgZdJ/GCw5ePc=; b=PyURGblyaofCRH519Mc+/qnDx98IiO9hWUIYVDgO7oWenqOTqdff2iuIT/YdxmZePfuY mLUntqJ4B8xx42vOrQzvYElHM9Ier8PjNCCxnNo1VRofwEGiTVSJj3sSKcopy6k3jK8T 9IX9+apqsyc/mfoA5v4oibIaV6MdBLPhb7+1Dkhx9UxxdoE34LDMUkhlLQCyQYvpkQRg j2sUEce18/spjpCrEELhkMqiUsccR1ejX1Cp9CnMlSx3ezaYow+lTRDql8bfZ6oajopJ rJ9ZyjHHhQL78tnQsEjTaMLkZ06RMbwWMg+1Nblj7+jJdvSSaEMSUiKV7f1az7YORB+j 5Q== Received: from pps.reinject (localhost [127.0.0.1]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3utj5vh0ht-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 06 Dec 2023 05:24:33 +0000 Received: from m0353725.ppops.net (m0353725.ppops.net [127.0.0.1]) by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 3B6568vt005076; Wed, 6 Dec 2023 05:24:32 GMT Received: from ppma11.dal12v.mail.ibm.com (db.9e.1632.ip4.static.sl-reverse.com [50.22.158.219]) by mx0a-001b2d01.pphosted.com (PPS) with ESMTPS id 3utj5vh0hd-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 06 Dec 2023 05:24:32 +0000 Received: from pps.filterd (ppma11.dal12v.mail.ibm.com [127.0.0.1]) by ppma11.dal12v.mail.ibm.com (8.17.1.19/8.17.1.19) with ESMTP id 3B65JwO2010965; Wed, 6 Dec 2023 05:24:32 GMT Received: from smtprelay07.fra02v.mail.ibm.com ([9.218.2.229]) by ppma11.dal12v.mail.ibm.com (PPS) with ESMTPS id 3utav2taym-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 06 Dec 2023 05:24:32 +0000 Received: from smtpav04.fra02v.mail.ibm.com (smtpav04.fra02v.mail.ibm.com [10.20.54.103]) by smtprelay07.fra02v.mail.ibm.com (8.14.9/8.14.9/NCO v10.0) with ESMTP id 3B65OTVu1180168 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 6 Dec 2023 05:24:29 GMT Received: from smtpav04.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 3FAF42004F; Wed, 6 Dec 2023 05:24:29 +0000 (GMT) Received: from smtpav04.fra02v.mail.ibm.com (unknown [127.0.0.1]) by IMSVA (Postfix) with ESMTP id 262722004B; Wed, 6 Dec 2023 05:24:28 +0000 (GMT) Received: from genoa.aus.stglabs.ibm.com (unknown [9.40.192.157]) by smtpav04.fra02v.mail.ibm.com (Postfix) with ESMTP; Wed, 6 Dec 2023 05:24:27 +0000 (GMT) From: Jiufu Guo To: gcc-patches@gcc.gnu.org Cc: segher@kernel.crashing.org, dje.gcc@gmail.com, linkw@gcc.gnu.org, bergner@linux.ibm.com, guojiufu@linux.ibm.com Subject: [PATCH V3 1/3]rs6000: update num_insns_constant for 2 insns Date: Wed, 6 Dec 2023 13:24:25 +0800 Message-Id: <20231206052427.143889-1-guojiufu@linux.ibm.com> X-Mailer: git-send-email 2.25.1 X-TM-AS-GCONF: 00 X-Proofpoint-ORIG-GUID: ebu0vBsmAvP7t7IUeD849Vl7pUSdYhr1 X-Proofpoint-GUID: e3icb8ypbekwuc8QwTpi2GUBCKbMBYc5 X-Proofpoint-UnRewURL: 0 URL was un-rewritten MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.997,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2023-12-06_03,2023-12-05_01,2023-05-22_02 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 mlxscore=0 suspectscore=0 impostorscore=0 spamscore=0 mlxlogscore=999 clxscore=1015 phishscore=0 lowpriorityscore=0 adultscore=0 bulkscore=0 malwarescore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2311290000 definitions=main-2312060042 X-Spam-Status: No, score=-10.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, GIT_PATCH_0, KAM_SHORT, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, 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.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Hi, Trunk gcc supports more constants to be built via two instructions: e.g. "li/lis; xori/xoris/rldicl/rldicr/rldic". And then num_insns_constant should also be updated. Function "rs6000_emit_set_long_const" is used to build complicated constants; and "num_insns_constant_gpr" is used to compute 'how many instructions are needed" to build the constant. So, these two functions should be aligned. The idea of this patch is: to reuse "rs6000_emit_set_long_const" to compute/record the instruction number(when computing the insn_num, then do not emit instructions). Compare with the previous version: https://gcc.gnu.org/pipermail/gcc-patches/2023-November/636565.html This version updates "rs6000_emit_set_long_const" to use a condition if to select either "computing insn number" or "emitting the insn". And put them together to avoid misalign in the future. Bootstrap & regtest pass ppc64{,le}. Is this ok for trunk? BR, Jeff (Jiufu Guo) gcc/ChangeLog: * config/rs6000/rs6000.cc (rs6000_emit_set_long_const): Add new parameter to record number of instructions to build the constant. (num_insns_constant_gpr): Call rs6000_emit_set_long_const to compute num_insn. --- gcc/config/rs6000/rs6000.cc | 272 ++++++++++++++++++------------------ 1 file changed, 137 insertions(+), 135 deletions(-) diff --git a/gcc/config/rs6000/rs6000.cc b/gcc/config/rs6000/rs6000.cc index 3dfd79c4c43..dbdc72dce5d 100644 --- a/gcc/config/rs6000/rs6000.cc +++ b/gcc/config/rs6000/rs6000.cc @@ -1115,7 +1115,7 @@ static tree rs6000_handle_longcall_attribute (tree *, tree, tree, int, bool *); static tree rs6000_handle_altivec_attribute (tree *, tree, tree, int, bool *); static tree rs6000_handle_struct_attribute (tree *, tree, tree, int, bool *); static tree rs6000_builtin_vectorized_libmass (combined_fn, tree, tree); -static void rs6000_emit_set_long_const (rtx, HOST_WIDE_INT); +static void rs6000_emit_set_long_const (rtx, HOST_WIDE_INT, int * = nullptr); static int rs6000_memory_move_cost (machine_mode, reg_class_t, bool); static bool rs6000_debug_rtx_costs (rtx, machine_mode, int, int, int *, bool); static int rs6000_debug_address_cost (rtx, machine_mode, addr_space_t, @@ -6054,21 +6054,9 @@ num_insns_constant_gpr (HOST_WIDE_INT value) else if (TARGET_POWERPC64) { - HOST_WIDE_INT low = sext_hwi (value, 32); - HOST_WIDE_INT high = value >> 31; - - if (high == 0 || high == -1) - return 2; - - high >>= 1; - - if (low == 0 || low == high) - return num_insns_constant_gpr (high) + 1; - else if (high == 0) - return num_insns_constant_gpr (low) + 1; - else - return (num_insns_constant_gpr (high) - + num_insns_constant_gpr (low) + 1); + int num_insns = 0; + rs6000_emit_set_long_const (NULL, value, &num_insns); + return num_insns; } else @@ -10494,14 +10482,13 @@ can_be_built_by_li_and_rldic (HOST_WIDE_INT c, int *shift, HOST_WIDE_INT *mask) /* Subroutine of rs6000_emit_set_const, handling PowerPC64 DImode. Output insns to set DEST equal to the constant C as a series of - lis, ori and shl instructions. */ + lis, ori and shl instructions. If NUM_INSNS is not NULL, then + only increase *NUM_INSNS as the number of insns, and do not output + real insns. */ static void -rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c) +rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c, int *num_insns) { - rtx temp; - int shift; - HOST_WIDE_INT mask; HOST_WIDE_INT ud1, ud2, ud3, ud4; ud1 = c & 0xffff; @@ -10509,168 +10496,183 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c) ud3 = (c >> 32) & 0xffff; ud4 = (c >> 48) & 0xffff; - if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000)) - || (ud4 == 0 && ud3 == 0 && ud2 == 0 && ! (ud1 & 0x8000))) - emit_move_insn (dest, GEN_INT (sext_hwi (ud1, 16))); + /* This lambda is used to emit one insn or just increase the insn count. + When counting the insn number, no need to emit the insn. Here, two + kinds of insns are needed: move and rldimi. */ + auto count_or_emit_insn = [&num_insns] (rtx dest, rtx op1, rtx op2 = NULL) { + if (num_insns) + (*num_insns)++; + else if (!op2) + emit_move_insn (dest, op1); + else + emit_insn (gen_rotldi3_insert_3 (dest, op1, GEN_INT (32), op2, + GEN_INT (0xffffffff))); + }; - else if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000)) - || (ud4 == 0 && ud3 == 0 && ! (ud2 & 0x8000))) + if ((ud4 == 0xffff && ud3 == 0xffff && ud2 == 0xffff && (ud1 & 0x8000)) + || (ud4 == 0 && ud3 == 0 && ud2 == 0 && !(ud1 & 0x8000))) { - temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode); + /* li */ + count_or_emit_insn (dest, GEN_INT (sext_hwi (ud1, 16))); + return; + } + + rtx temp = num_insns ? nullptr + : can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest; - emit_move_insn (ud1 != 0 ? temp : dest, - GEN_INT (sext_hwi (ud2 << 16, 32))); + if ((ud4 == 0xffff && ud3 == 0xffff && (ud2 & 0x8000)) + || (ud4 == 0 && ud3 == 0 && !(ud2 & 0x8000))) + { + /* lis[; ori] */ + count_or_emit_insn (ud1 != 0 ? temp : dest, + GEN_INT (sext_hwi (ud2 << 16, 32))); if (ud1 != 0) - emit_move_insn (dest, gen_rtx_IOR (DImode, temp, GEN_INT (ud1))); + count_or_emit_insn (dest, gen_rtx_IOR (DImode, temp, GEN_INT (ud1))); + return; } - else if (ud4 == 0xffff && ud3 == 0xffff && !(ud2 & 0x8000) && ud1 == 0) + + if (ud4 == 0xffff && ud3 == 0xffff && !(ud2 & 0x8000) && ud1 == 0) { /* lis; xoris */ - temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode); - emit_move_insn (temp, GEN_INT (sext_hwi ((ud2 | 0x8000) << 16, 32))); - emit_move_insn (dest, gen_rtx_XOR (DImode, temp, GEN_INT (0x80000000))); + count_or_emit_insn (temp, GEN_INT (sext_hwi ((ud2 | 0x8000) << 16, 32))); + count_or_emit_insn (dest, + gen_rtx_XOR (DImode, temp, GEN_INT (0x80000000))); + return; } - else if (ud4 == 0xffff && ud3 == 0xffff && (ud1 & 0x8000)) + + if (ud4 == 0xffff && ud3 == 0xffff && (ud1 & 0x8000)) { /* li; xoris */ - temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode); - emit_move_insn (temp, GEN_INT (sext_hwi (ud1, 16))); - emit_move_insn (dest, gen_rtx_XOR (DImode, temp, - GEN_INT ((ud2 ^ 0xffff) << 16))); + count_or_emit_insn (temp, GEN_INT (sext_hwi (ud1, 16))); + count_or_emit_insn (dest, gen_rtx_XOR (DImode, temp, + GEN_INT ((ud2 ^ 0xffff) << 16))); + return; } - else if (can_be_built_by_li_lis_and_rotldi (c, &shift, &mask) - || can_be_built_by_li_lis_and_rldicl (c, &shift, &mask) - || can_be_built_by_li_lis_and_rldicr (c, &shift, &mask) - || can_be_built_by_li_and_rldic (c, &shift, &mask)) + + int shift; + HOST_WIDE_INT mask; + if (can_be_built_by_li_lis_and_rotldi (c, &shift, &mask) + || can_be_built_by_li_lis_and_rldicl (c, &shift, &mask) + || can_be_built_by_li_lis_and_rldicr (c, &shift, &mask) + || can_be_built_by_li_and_rldic (c, &shift, &mask)) { - temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode); + /* li/lis; rldicX */ unsigned HOST_WIDE_INT imm = (c | ~mask); imm = (imm >> shift) | (imm << (HOST_BITS_PER_WIDE_INT - shift)); - emit_move_insn (temp, GEN_INT (imm)); + count_or_emit_insn (temp, GEN_INT (imm)); if (shift != 0) temp = gen_rtx_ROTATE (DImode, temp, GEN_INT (shift)); if (mask != HOST_WIDE_INT_M1) temp = gen_rtx_AND (DImode, temp, GEN_INT (mask)); - emit_move_insn (dest, temp); - } - else if (ud3 == 0 && ud4 == 0) - { - temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode); + count_or_emit_insn (dest, temp); - gcc_assert (ud2 & 0x8000); + return; + } - if (ud1 == 0) - { - /* lis; rldicl */ - emit_move_insn (temp, GEN_INT (sext_hwi (ud2 << 16, 32))); - emit_move_insn (dest, - gen_rtx_AND (DImode, temp, GEN_INT (0xffffffff))); - } - else if (!(ud1 & 0x8000)) + if (ud3 == 0 && ud4 == 0) + { + gcc_assert ((ud2 & 0x8000) && ud1 != 0); + if (!(ud1 & 0x8000)) { /* li; oris */ - emit_move_insn (temp, GEN_INT (ud1)); - emit_move_insn (dest, - gen_rtx_IOR (DImode, temp, GEN_INT (ud2 << 16))); + count_or_emit_insn (temp, GEN_INT (ud1)); + count_or_emit_insn (dest, + gen_rtx_IOR (DImode, temp, GEN_INT (ud2 << 16))); + return; } - else - { - /* lis; ori; rldicl */ - emit_move_insn (temp, GEN_INT (sext_hwi (ud2 << 16, 32))); - emit_move_insn (temp, gen_rtx_IOR (DImode, temp, GEN_INT (ud1))); - emit_move_insn (dest, + + /* lis; ori; rldicl */ + count_or_emit_insn (temp, GEN_INT (sext_hwi (ud2 << 16, 32))); + count_or_emit_insn (temp, gen_rtx_IOR (DImode, temp, GEN_INT (ud1))); + count_or_emit_insn (dest, gen_rtx_AND (DImode, temp, GEN_INT (0xffffffff))); - } + return; } - else if (ud1 == ud3 && ud2 == ud4) + + if (ud1 == ud3 && ud2 == ud4) { - temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode); HOST_WIDE_INT num = (ud2 << 16) | ud1; - rs6000_emit_set_long_const (temp, sext_hwi (num, 32)); + rs6000_emit_set_long_const (temp, sext_hwi (num, 32), num_insns); + rtx one = gen_rtx_AND (DImode, temp, GEN_INT (0xffffffff)); rtx two = gen_rtx_ASHIFT (DImode, temp, GEN_INT (32)); - emit_move_insn (dest, gen_rtx_IOR (DImode, one, two)); + count_or_emit_insn (dest, gen_rtx_IOR (DImode, one, two)); + return; } - else if ((ud4 == 0xffff && (ud3 & 0x8000)) - || (ud4 == 0 && ! (ud3 & 0x8000))) - { - temp = !can_create_pseudo_p () ? dest : gen_reg_rtx (DImode); - emit_move_insn (temp, GEN_INT (sext_hwi (ud3 << 16, 32))); + if ((ud4 == 0xffff && (ud3 & 0x8000)) || (ud4 == 0 && !(ud3 & 0x8000))) + { + count_or_emit_insn (temp, GEN_INT (sext_hwi (ud3 << 16, 32))); if (ud2 != 0) - emit_move_insn (temp, gen_rtx_IOR (DImode, temp, GEN_INT (ud2))); - emit_move_insn (ud1 != 0 ? temp : dest, - gen_rtx_ASHIFT (DImode, temp, GEN_INT (16))); + count_or_emit_insn (temp, gen_rtx_IOR (DImode, temp, GEN_INT (ud2))); + count_or_emit_insn (ud1 != 0 ? temp : dest, + gen_rtx_ASHIFT (DImode, temp, GEN_INT (16))); if (ud1 != 0) - emit_move_insn (dest, gen_rtx_IOR (DImode, temp, GEN_INT (ud1))); + count_or_emit_insn (dest, gen_rtx_IOR (DImode, temp, GEN_INT (ud1))); + return; } - else if (TARGET_PREFIXED) + + if (TARGET_PREFIXED) { if (can_create_pseudo_p ()) { - /* pli A,L + pli B,H + rldimi A,B,32,0. */ - temp = gen_reg_rtx (DImode); - rtx temp1 = gen_reg_rtx (DImode); - emit_move_insn (temp, GEN_INT ((ud4 << 16) | ud3)); - emit_move_insn (temp1, GEN_INT ((ud2 << 16) | ud1)); - - emit_insn (gen_rotldi3_insert_3 (dest, temp, GEN_INT (32), temp1, - GEN_INT (0xffffffff))); + /* pli A,L; pli B,H; rldimi A,B,32,0. */ + rtx temp1 = num_insns ? nullptr : gen_reg_rtx (DImode); + count_or_emit_insn (temp, GEN_INT ((ud4 << 16) | ud3)); + count_or_emit_insn (temp1, GEN_INT ((ud2 << 16) | ud1)); + count_or_emit_insn (dest, temp, temp1); + return; } - else - { - /* pli A,H + sldi A,32 + paddi A,A,L. */ - emit_move_insn (dest, GEN_INT ((ud4 << 16) | ud3)); - emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32))); + /* There may be 1 insn inaccurate because of no info about dest. */ + bool can_use_paddi = dest ? REGNO (dest) != FIRST_GPR_REGNO : false; - bool can_use_paddi = REGNO (dest) != FIRST_GPR_REGNO; + /* pli A,H; sldi A,32; paddi A,A,L. */ + count_or_emit_insn (dest, GEN_INT ((ud4 << 16) | ud3)); + count_or_emit_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32))); - /* Use paddi for the low 32 bits. */ - if (ud2 != 0 && ud1 != 0 && can_use_paddi) - emit_move_insn (dest, gen_rtx_PLUS (DImode, dest, + /* Use paddi for the low 32 bits. */ + if (ud2 != 0 && ud1 != 0 && can_use_paddi) + count_or_emit_insn (dest, gen_rtx_PLUS (DImode, dest, GEN_INT ((ud2 << 16) | ud1))); - - /* Use oris, ori for low 32 bits. */ - if (ud2 != 0 && (ud1 == 0 || !can_use_paddi)) - emit_move_insn (dest, + /* Use oris, ori for low 32 bits. */ + if (ud2 != 0 && (ud1 == 0 || !can_use_paddi)) + count_or_emit_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud2 << 16))); - if (ud1 != 0 && (ud2 == 0 || !can_use_paddi)) - emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1))); - } + if (ud1 != 0 && (ud2 == 0 || !can_use_paddi)) + count_or_emit_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1))); + return; } - else + + if (can_create_pseudo_p ()) { - if (can_create_pseudo_p ()) - { - /* lis HIGH,UD4 ; ori HIGH,UD3 ; - lis LOW,UD2 ; ori LOW,UD1 ; rldimi LOW,HIGH,32,0. */ - rtx high = gen_reg_rtx (DImode); - rtx low = gen_reg_rtx (DImode); - HOST_WIDE_INT num = (ud2 << 16) | ud1; - rs6000_emit_set_long_const (low, sext_hwi (num, 32)); - num = (ud4 << 16) | ud3; - rs6000_emit_set_long_const (high, sext_hwi (num, 32)); - emit_insn (gen_rotldi3_insert_3 (dest, high, GEN_INT (32), low, - GEN_INT (0xffffffff))); - } - else - { - /* lis DEST,UD4 ; ori DEST,UD3 ; rotl DEST,32 ; - oris DEST,UD2 ; ori DEST,UD1. */ - emit_move_insn (dest, GEN_INT (sext_hwi (ud4 << 16, 32))); - if (ud3 != 0) - emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud3))); + /* lis HIGH,UD4 ; ori HIGH,UD3 ; + lis LOW,UD2 ; ori LOW,UD1 ; rldimi LOW,HIGH,32,0. */ + rtx high = num_insns ? nullptr : gen_reg_rtx (DImode); + rtx low = num_insns ? nullptr : gen_reg_rtx (DImode); + HOST_WIDE_INT num = (ud2 << 16) | ud1; + rs6000_emit_set_long_const (low, sext_hwi (num, 32), num_insns); + num = (ud4 << 16) | ud3; + rs6000_emit_set_long_const (high, sext_hwi (num, 32), num_insns); - emit_move_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32))); - if (ud2 != 0) - emit_move_insn (dest, - gen_rtx_IOR (DImode, dest, GEN_INT (ud2 << 16))); - if (ud1 != 0) - emit_move_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1))); - } + count_or_emit_insn (dest, high, low); + return; } + + /* lis DEST,UD4 ; ori DEST,UD3 ; rotl DEST,32 ; + oris DEST,UD2 ; ori DEST,UD1. */ + count_or_emit_insn (dest, GEN_INT (sext_hwi (ud4 << 16, 32))); + if (ud3 != 0) + count_or_emit_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud3))); + + count_or_emit_insn (dest, gen_rtx_ASHIFT (DImode, dest, GEN_INT (32))); + if (ud2 != 0) + count_or_emit_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud2 << 16))); + if (ud1 != 0) + count_or_emit_insn (dest, gen_rtx_IOR (DImode, dest, GEN_INT (ud1))); + + return; } /* Helper for the following. Get rid of [r+r] memory refs