From patchwork Mon Jan 29 08:22:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: chenglulu X-Patchwork-Id: 193324 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:7301:2087:b0:106:209c:c626 with SMTP id gs7csp428216dyb; Mon, 29 Jan 2024 00:26:10 -0800 (PST) X-Google-Smtp-Source: AGHT+IEpKPB9J9MN7LBCnaiauXa/omc8I/VHvgBjK2UoP+yDfgX8iIlrXw6F80QbEpOl5Hgyal+Q X-Received: by 2002:a05:622a:1d4:b0:42a:a6c8:da39 with SMTP id t20-20020a05622a01d400b0042aa6c8da39mr1415859qtw.53.1706516769970; Mon, 29 Jan 2024 00:26:09 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706516769; cv=pass; d=google.com; s=arc-20160816; b=CubKDyaIIxU936NfTAVP0y4ejXd3yKIhylV23mEFxcYDO7k4gmkENzH0XYl32nNabH 2MJYgk4XE54rVQ9J9ZuWTCovC+ER/Zaa82S3uo69lbGBh3RjbUfWf60oBhp0R8wjNAYS kwnK+Sc++qyiZSp+bM5on/TMcDpxHqYlDW50H36wjeb5uDxQJzUhltdloDtc948mCz4Y FazixQQzu+m/y03wE/px1fhwZrYqHfK8Y8C7dvA7wiFjevU4QSEG5Ktta/CDSnQzkH9Y 70wfazfFSLxFB9i7U9ofSWcCVcDMbfAr9y+p+cNkPEfTfcrNde1imOT3A6xkvkFO6dyL 10gA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:arc-filter:dmarc-filter:delivered-to; bh=1pdXXDodX0TDkgYoNR64RSnk7G6x4QQthML9ntydT8Y=; fh=OB4wyvXNh6jiRENO2dRbI/vi0qsrYTu6/l5X8j6p8dY=; b=l485K8CKxQ/aU2KaXLtBdlQUH3eE/Dddx/fCifSJQFj8dVaWL1FXOxsD3PzYdv/guE 7I+1D8AAzdBIycUJlSFt/uuDy3Cbc6yAjMqbSJ9NClXouHeEPpz+7qQaZu5KBWqspzGA lL0BrjvdSSAssIPW+vhhTrZP/ausVz00sKgc6c7XLe8KzEg0oUvBGDtS3xaT6hWaixG7 AK1JrgsfA5BZPJCDbhGwkwGF927w7jY/FHl1lCefJa1Q7dDtIwZSihNb0P0M0a2Ey2Cg Q75FzlCyWhTn0dMwXxPEgTm4uDAx2HkMWOFFYPVN+pObsVHa60CrYk8HK1SXRTXV+D4p 2YoA== ARC-Authentication-Results: i=2; mx.google.com; arc=pass (i=1); 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" Received: from server2.sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id k4-20020a05620a0b8400b007819e1e4697si3504378qkh.646.2024.01.29.00.26.09 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 29 Jan 2024 00:26:09 -0800 (PST) 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; arc=pass (i=1); 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" Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id A684638582A6 for ; Mon, 29 Jan 2024 08:26:09 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail.loongson.cn (mail.loongson.cn [114.242.206.163]) by sourceware.org (Postfix) with ESMTP id A7A94385840B for ; Mon, 29 Jan 2024 08:22:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org A7A94385840B Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=loongson.cn ARC-Filter: OpenARC Filter v1.0.0 sourceware.org A7A94385840B Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=114.242.206.163 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1706516557; cv=none; b=cG49bo45IB3LwG5JNl+eJgMKkI4ETprgeTl8np1nbGjE8GdVh0lpwSPxd3Hxr8TD4dnaB+i4L/Os7KCc1WPya5ihNplabYpK5As4cpt6y8kR3mZTeA1HH7lArDIfNgVU4r4PgpDFNumgIsIER89FpEg1zSJlPD742AIcN0rrgLg= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1706516557; c=relaxed/simple; bh=rmMLezwVy5Wb8TrCKKSnen/dZIcMNQ2E7nQm4Ppm4Bs=; h=From:To:Subject:Date:Message-Id:MIME-Version; b=Z/r4cGokm2Aeb6P9zLxr6/WwqYcfTcQc5K/fvC2C3XhFwf3fXgKKiUw9Dg0m/Gn+ukFLo49CqGJFZTUB59xqtVULhvg0uqYZeCoiPipVPnvQjT+D0If1fzy99UxhTY7BZwnFzc1NFHjGifTiPwjBQGWmGQyC4KXca7TjJdQXX9U= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from loongson.cn (unknown [10.20.4.107]) by gateway (Coremail) with SMTP id _____8AxPOlBYLdlm7EHAA--.14009S3; Mon, 29 Jan 2024 16:22:25 +0800 (CST) Received: from loongson-pc.loongson.cn (unknown [10.20.4.107]) by localhost.localdomain (Coremail) with SMTP id AQAAf8BxnhMrYLdlKxklAA--.26775S7; Mon, 29 Jan 2024 16:22:23 +0800 (CST) From: Lulu Cheng To: gcc-patches@gcc.gnu.org Cc: xry111@xry111.site, i@xen0n.name, xuchenghua@loongson.cn Subject: [PATCH v5 5/5] LoongArch: Don't split the instructions containing relocs for extreme code model. Date: Mon, 29 Jan 2024 16:22:01 +0800 Message-Id: <20240129082201.26087-6-chenglulu@loongson.cn> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20240129082201.26087-1-chenglulu@loongson.cn> References: <20240129082201.26087-1-chenglulu@loongson.cn> MIME-Version: 1.0 X-CM-TRANSID: AQAAf8BxnhMrYLdlKxklAA--.26775S7 X-CM-SenderInfo: xfkh0wpoxo3qxorr0wxvrqhubq/ X-Coremail-Antispam: 1Uk129KBj9fXoWftr4xGw1ktrW3Zw1xGF17Jwc_yoW8uryrAo Z3CF4UJw48Wr1SkwsrKrnxJr10yFyIyw4rZa9Fvr1rGF40yryYv3s3KanYv34fZrsrJry5 uFW7WF9rC3y7Xr98l-sFpf9Il3svdjkaLaAFLSUrUUUUjb8apTn2vfkv8UJUUUU8wcxFpf 9Il3svdxBIdaVrn0xqx4xG64xvF2IEw4CE5I8CrVC2j2Jv73VFW2AGmfu7bjvjm3AaLaJ3 UjIYCTnIWjp_UUUY87kC6x804xWl14x267AKxVWUJVW8JwAFc2x0x2IEx4CE42xK8VAvwI 8IcIk0rVWrJVCq3wAFIxvE14AKwVWUXVWUAwA2ocxC64kIII0Yj41l84x0c7CEw4AK67xG Y2AK021l84ACjcxK6xIIjxv20xvE14v26r4j6ryUM28EF7xvwVC0I7IYx2IY6xkF7I0E14 v26r4j6F4UM28EF7xvwVC2z280aVAFwI0_Gr1j6F4UJwA2z4x0Y4vEx4A2jsIEc7CjxVAF wI0_Gr1j6F4UJwAS0I0E0xvYzxvE52x082IY62kv0487Mc804VCY07AIYIkI8VC2zVCFFI 0UMc02F40EFcxC0VAKzVAqx4xG6I80ewAv7VC0I7IYx2IY67AKxVWUtVWrXwAv7VC2z280 aVAFwI0_Gr0_Cr1lOx8S6xCaFVCjc4AY6r1j6r4UM4x0Y48IcxkI7VAKI48JMxAIw28Icx kI7VAKI48JMxC20s026xCaFVCjc4AY6r1j6r4UMI8I3I0E5I8CrVAFwI0_Jr0_Jr4lx2Iq xVCjr7xvwVAFwI0_JrI_JrWlx4CE17CEb7AF67AKxVWUAVWUtwCIc40Y0x0EwIxGrwCI42 IY6xIIjxv20xvE14v26r4j6ryUMIIF0xvE2Ix0cI8IcVCY1x0267AKxVW8JVWxJwCI42IY 6xAIw20EY4v20xvaj40_Jr0_JF4lIxAIcVC2z280aVAFwI0_Gr0_Cr1lIxAIcVC2z280aV CY1x0267AKxVW8JVW8JrUvcSsGvfC2KfnxnUUI43ZEXa7IU8l38UUUUUU== X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, KAM_STOCKGEN, 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+ouuuleilei=gmail.com@gcc.gnu.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789412528934086276 X-GMAIL-MSGID: 1789412528934086276 From: Xi Ruoyao The ABI mandates the pcalau12i/addi.d/lu32i.d/lu52i.d instructions for addressing a symbol to be adjacent. So model them as "one large instruction", i.e. define_insn, with two output registers. The real address is the sum of these two registers. The advantage of this approach is the RTL passes can still use ldx/stx instructions to skip an addi.d instruction. gcc/ChangeLog: * config/loongarch/loongarch.md (unspec): Add UNSPEC_LA_PCREL_64_PART1 and UNSPEC_LA_PCREL_64_PART2. (la_pcrel64_two_parts): New define_insn. * config/loongarch/loongarch.cc (loongarch_tls_symbol): Fix a typo in the comment. (loongarch_call_tls_get_addr): If -mcmodel=extreme -mexplicit-relocs={always,auto}, use la_pcrel64_two_parts for addressing the TLS symbol and __tls_get_addr. Emit an REG_EQUAL note to allow CSE addressing __tls_get_addr. (loongarch_legitimize_tls_address): If -mcmodel=extreme -mexplicit-relocs={always,auto}, address TLS IE symbols with la_pcrel64_two_parts. (loongarch_split_symbol): If -mcmodel=extreme -mexplicit-relocs={always,auto}, address symbols with la_pcrel64_two_parts. (loongarch_output_mi_thunk): Clean up unreachable code. If -mcmodel=extreme -mexplicit-relocs={always,auto}, address the MI thunks with la_pcrel64_two_parts. gcc/testsuite/ChangeLog: * gcc.target/loongarch/func-call-extreme-1.c (dg-options): Use -O2 instead of -O0 to ensure the pcalau12i/addi/lu32i/lu52i instruction sequences are not reordered by the compiler. (NOIPA): Disallow interprocedural optimizations. * gcc.target/loongarch/func-call-extreme-2.c: Remove the content duplicated from func-call-extreme-1.c, include it instead. (dg-options): Likewise. * gcc.target/loongarch/func-call-extreme-3.c (dg-options): Likewise. * gcc.target/loongarch/func-call-extreme-4.c (dg-options): Likewise. * gcc.target/loongarch/cmodel-extreme-1.c: New test. * gcc.target/loongarch/cmodel-extreme-2.c: New test. * g++.target/loongarch/cmodel-extreme-mi-thunk-1.C: New test. * g++.target/loongarch/cmodel-extreme-mi-thunk-2.C: New test. * g++.target/loongarch/cmodel-extreme-mi-thunk-3.C: New test. --- gcc/config/loongarch/loongarch.cc | 131 ++++++++++-------- gcc/config/loongarch/loongarch.md | 20 +++ .../loongarch/cmodel-extreme-mi-thunk-1.C | 11 ++ .../loongarch/cmodel-extreme-mi-thunk-2.C | 6 + .../loongarch/cmodel-extreme-mi-thunk-3.C | 6 + .../gcc.target/loongarch/cmodel-extreme-1.c | 18 +++ .../gcc.target/loongarch/cmodel-extreme-2.c | 7 + .../loongarch/func-call-extreme-1.c | 14 +- .../loongarch/func-call-extreme-2.c | 29 +--- .../loongarch/func-call-extreme-3.c | 2 +- .../loongarch/func-call-extreme-4.c | 2 +- 11 files changed, 154 insertions(+), 92 deletions(-) create mode 100644 gcc/testsuite/g++.target/loongarch/cmodel-extreme-mi-thunk-1.C create mode 100644 gcc/testsuite/g++.target/loongarch/cmodel-extreme-mi-thunk-2.C create mode 100644 gcc/testsuite/g++.target/loongarch/cmodel-extreme-mi-thunk-3.C create mode 100644 gcc/testsuite/gcc.target/loongarch/cmodel-extreme-1.c create mode 100644 gcc/testsuite/gcc.target/loongarch/cmodel-extreme-2.c diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index 564de9c2642..89dd33553da 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -2737,7 +2737,7 @@ loongarch_add_offset (rtx temp, rtx reg, HOST_WIDE_INT offset) return plus_constant (Pmode, reg, offset); } -/* The __tls_get_attr symbol. */ +/* The __tls_get_addr symbol. */ static GTY (()) rtx loongarch_tls_symbol; /* Load an entry for a TLS access. */ @@ -2777,20 +2777,22 @@ loongarch_call_tls_get_addr (rtx sym, enum loongarch_symbol_type type, rtx v0) if (loongarch_explicit_relocs_p (type)) { - /* Split tls symbol to high and low. */ - rtx high = gen_rtx_HIGH (Pmode, copy_rtx (loc)); - high = loongarch_force_temporary (tmp, high); - if (TARGET_CMODEL_EXTREME) { - rtx tmp1 = gen_reg_rtx (Pmode); - emit_insn (gen_tls_low (Pmode, tmp1, gen_rtx_REG (Pmode, 0), loc)); - emit_insn (gen_lui_h_lo20 (tmp1, tmp1, loc)); - emit_insn (gen_lui_h_hi12 (tmp1, tmp1, loc)); - emit_move_insn (a0, gen_rtx_PLUS (Pmode, high, tmp1)); + rtx part1 = gen_reg_rtx (Pmode); + rtx part2 = gen_reg_rtx (Pmode); + + emit_insn (gen_la_pcrel64_two_parts (part1, part2, loc)); + emit_move_insn (a0, gen_rtx_PLUS (Pmode, part1, part2)); } else - emit_insn (gen_tls_low (Pmode, a0, high, loc)); + { + /* Split tls symbol to high and low. */ + rtx high = gen_rtx_HIGH (Pmode, copy_rtx (loc)); + + high = loongarch_force_temporary (tmp, high); + emit_insn (gen_tls_low (Pmode, a0, high, loc)); + } } else emit_insn (loongarch_load_tls (a0, loc, type)); @@ -2872,22 +2874,28 @@ loongarch_call_tls_get_addr (rtx sym, enum loongarch_symbol_type type, rtx v0) { if (loongarch_explicit_relocs_p (SYMBOL_GOT_DISP)) { - rtx tmp1 = gen_reg_rtx (Pmode); - rtx high = gen_reg_rtx (Pmode); + gcc_assert (la_opt_explicit_relocs != EXPLICIT_RELOCS_NONE); - loongarch_emit_move (high, - gen_rtx_HIGH (Pmode, - loongarch_tls_symbol)); - loongarch_emit_move (tmp1, - gen_rtx_LO_SUM (Pmode, - gen_rtx_REG (Pmode, 0), + rtx part1 = gen_reg_rtx (Pmode); + rtx part2 = gen_reg_rtx (Pmode); + + emit_insn (gen_la_pcrel64_two_parts (part1, part2, loongarch_tls_symbol)); - emit_insn (gen_lui_h_lo20 (tmp1, tmp1, loongarch_tls_symbol)); - emit_insn (gen_lui_h_hi12 (tmp1, tmp1, loongarch_tls_symbol)); - loongarch_emit_move (dest, - gen_rtx_MEM (Pmode, - gen_rtx_PLUS (Pmode, - high, tmp1))); + loongarch_emit_move ( + dest, + gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, + part1, + part2))); + + /* Put an REG_EQUAL note here to allow CSE (storing + part1 + part2, i.e. the address of tls_get_addr into + a saved register and use it for multiple TLS + accesses). */ + rtx sum = gen_rtx_UNSPEC ( + Pmode, gen_rtvec (1, loongarch_tls_symbol), + UNSPEC_ADDRESS_FIRST + + loongarch_classify_symbol (loongarch_tls_symbol)); + set_unique_reg_note (get_last_insn (), REG_EQUAL, sum); } else emit_insn (gen_movdi_symbolic_off64 (dest, loongarch_tls_symbol, @@ -2950,24 +2958,30 @@ loongarch_legitimize_tls_address (rtx loc) dest = gen_reg_rtx (Pmode); if (loongarch_explicit_relocs_p (SYMBOL_TLS_IE)) { - tmp3 = gen_reg_rtx (Pmode); - rtx high = gen_rtx_HIGH (Pmode, copy_rtx (tmp2)); - high = loongarch_force_temporary (tmp3, high); - if (TARGET_CMODEL_EXTREME) { - rtx tmp3 = gen_reg_rtx (Pmode); - emit_insn (gen_tls_low (Pmode, tmp3, - gen_rtx_REG (Pmode, 0), tmp2)); - emit_insn (gen_lui_h_lo20 (tmp3, tmp3, tmp2)); - emit_insn (gen_lui_h_hi12 (tmp3, tmp3, tmp2)); + gcc_assert (la_opt_explicit_relocs + != EXPLICIT_RELOCS_NONE); + + rtx part1 = gen_reg_rtx (Pmode); + rtx part2 = gen_reg_rtx (Pmode); + + emit_insn (gen_la_pcrel64_two_parts (part1, part2, + tmp2)); emit_move_insn (tmp1, gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, - high, tmp3))); + part1, + part2))); } else - emit_insn (gen_ld_from_got (Pmode, tmp1, high, tmp2)); + { + tmp3 = gen_reg_rtx (Pmode); + rtx high = gen_rtx_HIGH (Pmode, copy_rtx (tmp2)); + + high = loongarch_force_temporary (tmp3, high); + emit_insn (gen_ld_from_got (Pmode, tmp1, high, tmp2)); + } } else emit_insn (loongarch_load_tls (tmp1, tmp2, SYMBOL_TLS_IE)); @@ -3146,24 +3160,23 @@ loongarch_split_symbol (rtx temp, rtx addr, machine_mode mode, rtx *low_out) || !loongarch_split_symbol_type (symbol_type)) return false; - rtx high, temp1 = NULL; + rtx high; if (temp == NULL) temp = gen_reg_rtx (Pmode); - /* Get the 12-31 bits of the address. */ - high = gen_rtx_HIGH (Pmode, copy_rtx (addr)); - high = loongarch_force_temporary (temp, high); - if (loongarch_symbol_extreme_p (symbol_type) && can_create_pseudo_p ()) { gcc_assert (la_opt_explicit_relocs != EXPLICIT_RELOCS_NONE); - temp1 = gen_reg_rtx (Pmode); - emit_move_insn (temp1, gen_rtx_LO_SUM (Pmode, gen_rtx_REG (Pmode, 0), - addr)); - emit_insn (gen_lui_h_lo20 (temp1, temp1, addr)); - emit_insn (gen_lui_h_hi12 (temp1, temp1, addr)); + high = gen_reg_rtx (Pmode); + emit_insn (gen_la_pcrel64_two_parts (high, temp, addr)); + } + else + { + /* Get the 12-31 bits of the address. */ + high = gen_rtx_HIGH (Pmode, copy_rtx (addr)); + high = loongarch_force_temporary (temp, high); } if (low_out) @@ -3172,7 +3185,7 @@ loongarch_split_symbol (rtx temp, rtx addr, machine_mode mode, rtx *low_out) case SYMBOL_PCREL64: if (can_create_pseudo_p ()) { - *low_out = gen_rtx_PLUS (Pmode, high, temp1); + *low_out = gen_rtx_PLUS (Pmode, high, temp); break; } /* fall through */ @@ -3184,7 +3197,8 @@ loongarch_split_symbol (rtx temp, rtx addr, machine_mode mode, rtx *low_out) /* SYMBOL_GOT_DISP symbols are loaded from the GOT. */ { if (TARGET_CMODEL_EXTREME && can_create_pseudo_p ()) - *low_out = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, high, temp1)); + *low_out = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, high, + temp)); else { rtx low = gen_rtx_LO_SUM (Pmode, high, addr); @@ -7454,21 +7468,24 @@ loongarch_output_mi_thunk (FILE *file, tree thunk_fndecl ATTRIBUTE_UNUSED, allowed, otherwise load the address into a register first. */ if (use_sibcall_p) { - if (TARGET_CMODEL_EXTREME) - { - emit_insn (gen_movdi_symbolic_off64 (temp1, fnaddr, temp2)); - insn = emit_call_insn (gen_sibcall_internal (temp1, const0_rtx)); - } - else - insn = emit_call_insn (gen_sibcall_internal (fnaddr, const0_rtx)); + /* If TARGET_CMODEL_EXTREME, we cannot do a direct jump at all + and const_call_insn_operand should have returned false. */ + gcc_assert (!TARGET_CMODEL_EXTREME); + + insn = emit_call_insn (gen_sibcall_internal (fnaddr, const0_rtx)); SIBLING_CALL_P (insn) = 1; } else { - if (TARGET_CMODEL_EXTREME) + if (!TARGET_CMODEL_EXTREME) + loongarch_emit_move (temp1, fnaddr); + else if (la_opt_explicit_relocs == EXPLICIT_RELOCS_NONE) emit_insn (gen_movdi_symbolic_off64 (temp1, fnaddr, temp2)); else - loongarch_emit_move (temp1, fnaddr); + { + emit_insn (gen_la_pcrel64_two_parts (temp1, temp2, fnaddr)); + emit_move_insn (temp1, gen_rtx_PLUS (Pmode, temp1, temp2)); + } emit_jump_insn (gen_indirect_jump (temp1)); } diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md index 5ec1d5a46d5..dffa41b0bf5 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -84,6 +84,8 @@ (define_c_enum "unspec" [ UNSPEC_CALL_VALUE_MULTIPLE_INTERNAL_1 UNSPEC_LOAD_SYMBOL_OFFSET64 + UNSPEC_LA_PCREL_64_PART1 + UNSPEC_LA_PCREL_64_PART2 ]) (define_c_enum "unspecv" [ @@ -2224,6 +2226,24 @@ (define_insn_and_split "movdi_symbolic_off64" [(set_attr "mode" "DI") (set_attr "insn_count" "5")]) +;; The 64-bit PC-relative part of address loading. +;; Note that the psABI does not allow splitting it. +(define_insn "la_pcrel64_two_parts" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand:DI 2 "") (pc)] UNSPEC_LA_PCREL_64_PART1)) + (set (match_operand:DI 1 "register_operand" "=r") + (unspec:DI [(match_dup 2) (pc)] UNSPEC_LA_PCREL_64_PART2))] + "TARGET_ABI_LP64 && la_opt_explicit_relocs != EXPLICIT_RELOCS_NONE" + { + return "pcalau12i\t%0,%r2\n\t" + "addi.d\t%1,$r0,%L2\n\t" + "lu32i.d\t%1,%R2\n\t" + "lu52i.d\t%1,%1,%H2"; + } + [(set_attr "move_type" "move") + (set_attr "mode" "DI") + (set_attr "length" "16")]) + ;; 32-bit Integer moves (define_expand "movsi" diff --git a/gcc/testsuite/g++.target/loongarch/cmodel-extreme-mi-thunk-1.C b/gcc/testsuite/g++.target/loongarch/cmodel-extreme-mi-thunk-1.C new file mode 100644 index 00000000000..ff1f7c165e2 --- /dev/null +++ b/gcc/testsuite/g++.target/loongarch/cmodel-extreme-mi-thunk-1.C @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-inline -march=loongarch64 -mabi=lp64d -O2 -mcmodel=extreme -fno-plt -mexplicit-relocs=always -mdirect-extern-access" } */ + +struct A { + virtual ~A(); +}; + +struct B : virtual A {}; +void var() { B(); } + +/* { dg-final { scan-assembler "pcalau12i\t\[^\n\]*%pc_hi20\\(\\.LTHUNK0\\)\n\taddi\\.d\t\[^\n\]*%pc_lo12\\(\\\.LTHUNK0\\)\n\tlu32i\\.d\t\[^\n\]*%pc64_lo20\\(\\.LTHUNK0\\)\n\tlu52i\\.d\t\[^\n\]*%pc64_hi12\\(\\.LTHUNK0\\)" } } */ diff --git a/gcc/testsuite/g++.target/loongarch/cmodel-extreme-mi-thunk-2.C b/gcc/testsuite/g++.target/loongarch/cmodel-extreme-mi-thunk-2.C new file mode 100644 index 00000000000..c9aa16b410d --- /dev/null +++ b/gcc/testsuite/g++.target/loongarch/cmodel-extreme-mi-thunk-2.C @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-inline -march=loongarch64 -mabi=lp64d -O2 -mcmodel=extreme -fno-plt -mexplicit-relocs=auto -mdirect-extern-access" } */ + +#include "cmodel-extreme-mi-thunk-1.C" + +/* { dg-final { scan-assembler "pcalau12i\t\[^\n\]*%pc_hi20\\(\\.LTHUNK0\\)\n\taddi\\.d\t\[^\n\]*%pc_lo12\\(\\\.LTHUNK0\\)\n\tlu32i\\.d\t\[^\n\]*%pc64_lo20\\(\\.LTHUNK0\\)\n\tlu52i\\.d\t\[^\n\]*%pc64_hi12\\(\\.LTHUNK0\\)" } } */ diff --git a/gcc/testsuite/g++.target/loongarch/cmodel-extreme-mi-thunk-3.C b/gcc/testsuite/g++.target/loongarch/cmodel-extreme-mi-thunk-3.C new file mode 100644 index 00000000000..afb86c8bdee --- /dev/null +++ b/gcc/testsuite/g++.target/loongarch/cmodel-extreme-mi-thunk-3.C @@ -0,0 +1,6 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fno-inline -march=loongarch64 -mabi=lp64d -O2 -mcmodel=extreme -fno-plt -mexplicit-relocs=none -mdirect-extern-access" } */ + +#include "cmodel-extreme-mi-thunk-1.C" + +/* { dg-final { scan-assembler "la.local\t\[^\n\]*\\.LTHUNK0" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/cmodel-extreme-1.c b/gcc/testsuite/gcc.target/loongarch/cmodel-extreme-1.c new file mode 100644 index 00000000000..564ee4017f7 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/cmodel-extreme-1.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-options "-march=loongarch64 -mabi=lp64d -O2 -mcmodel=extreme -fno-plt -mexplicit-relocs=always -fdump-rtl-final" } */ + +int a; +extern int b; +__thread int c __attribute__ ((tls_model ("local-exec"))); +__thread int d __attribute__ ((tls_model ("initial-exec"))); +__thread int e __attribute__ ((tls_model ("local-dynamic"))); +__thread int f __attribute__ ((tls_model ("global-dynamic"))); + +void +test (void) +{ + a = b + c + d + e + f; +} + +/* a, b, d, e, f, and __tls_get_addr. */ +/* { dg-final { scan-rtl-dump-times "la_pcrel64_two_parts" 6 "final" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/cmodel-extreme-2.c b/gcc/testsuite/gcc.target/loongarch/cmodel-extreme-2.c new file mode 100644 index 00000000000..ce834805f38 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/cmodel-extreme-2.c @@ -0,0 +1,7 @@ +/* { dg-do compile } */ +/* { dg-options "-march=loongarch64 -mabi=lp64d -O2 -mcmodel=extreme -fno-plt -mexplicit-relocs=auto -fdump-rtl-final" } */ + +#include "cmodel-extreme-1.c" + +/* a, b, d, e, f, and __tls_get_addr. */ +/* { dg-final { scan-rtl-dump-times "la_pcrel64_two_parts" 6 "final" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-extreme-1.c b/gcc/testsuite/gcc.target/loongarch/func-call-extreme-1.c index db1e0f85396..fdb4cf1ff7f 100644 --- a/gcc/testsuite/gcc.target/loongarch/func-call-extreme-1.c +++ b/gcc/testsuite/gcc.target/loongarch/func-call-extreme-1.c @@ -1,31 +1,33 @@ /* { dg-do compile } */ -/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt -mexplicit-relocs -mcmodel=extreme" } */ +/* { dg-options "-mabi=lp64d -O2 -fno-pic -fno-plt -mexplicit-relocs -mcmodel=extreme" } */ /* { dg-final { scan-assembler "test:.*pcalau12i.*%got_pc_hi20.*\n\taddi\.d.*%got_pc_lo12.*\n\tlu32i\.d.*%got64_pc_lo20.*\n\tlu52i\.d.*%got64_pc_hi12.*\n\tldx\.d" } } */ /* { dg-final { scan-assembler "test1:.*pcalau12i.*%pc_hi20.*\n\taddi\.d.*%pc_lo12.*\n\tlu32i\.d.*%pc64_lo20.*\n\tlu52i\.d.*pc64_hi12.*\n\tadd\.d" } } */ /* { dg-final { scan-assembler "test2:.*pcalau12i.*%pc_hi20.*\n\taddi\.d.*%pc_lo12.*\n\tlu32i\.d.*%pc64_lo20.*\n\tlu52i\.d.*pc64_hi12.*\n\tadd\.d" } } */ +#define NOIPA __attribute__ ((noipa)) + extern void g (void); -void +NOIPA void f (void) {} -static void +NOIPA static void l (void) {} -void +NOIPA void test (void) { g (); } -void +NOIPA void test1 (void) { f (); } -void +NOIPA void test2 (void) { l (); diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-extreme-2.c b/gcc/testsuite/gcc.target/loongarch/func-call-extreme-2.c index 21bf81ae837..dfba3882b97 100644 --- a/gcc/testsuite/gcc.target/loongarch/func-call-extreme-2.c +++ b/gcc/testsuite/gcc.target/loongarch/func-call-extreme-2.c @@ -1,32 +1,7 @@ /* { dg-do compile } */ -/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt -mexplicit-relocs -mcmodel=extreme" } */ +/* { dg-options "-mabi=lp64d -O2 -fpic -fno-plt -mexplicit-relocs -mcmodel=extreme" } */ /* { dg-final { scan-assembler "test:.*pcalau12i.*%got_pc_hi20.*\n\taddi\.d.*%got_pc_lo12.*\n\tlu32i\.d.*%got64_pc_lo20.*\n\tlu52i\.d.*%got64_pc_hi12.*\n\tldx\.d" } } */ /* { dg-final { scan-assembler "test1:.*pcalau12i.*%got_pc_hi20.*\n\taddi\.d.*%got_pc_lo12.*\n\tlu32i\.d.*%got64_pc_lo20.*\n\tlu52i\.d.*%got64_pc_hi12.*\n\tldx\.d" } } */ /* { dg-final { scan-assembler "test2:.*pcalau12i.*%pc_hi20.*\n\taddi\.d.*%pc_lo12.*\n\tlu32i\.d.*%pc64_lo20.*\n\tlu52i\.d.*pc64_hi12.*\n\tadd\.d" } } */ -extern void g (void); -void -f (void) -{} - -static void -l (void) -{} - -void -test (void) -{ - g (); -} - -void -test1 (void) -{ - f (); -} - -void -test2 (void) -{ - l (); -} +#include "func-call-extreme-1.c" diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-extreme-3.c b/gcc/testsuite/gcc.target/loongarch/func-call-extreme-3.c index a4da44b4a3d..1f5234f83d1 100644 --- a/gcc/testsuite/gcc.target/loongarch/func-call-extreme-3.c +++ b/gcc/testsuite/gcc.target/loongarch/func-call-extreme-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt -mexplicit-relocs=auto -mcmodel=extreme" } */ +/* { dg-options "-mabi=lp64d -O2 -fno-pic -fno-plt -mexplicit-relocs=auto -mcmodel=extreme" } */ /* { dg-final { scan-assembler "test:.*pcalau12i.*%got_pc_hi20.*\n\taddi\.d.*%got_pc_lo12.*\n\tlu32i\.d.*%got64_pc_lo20.*\n\tlu52i\.d.*%got64_pc_hi12.*\n\tldx\.d" } } */ /* { dg-final { scan-assembler "test1:.*pcalau12i.*%pc_hi20.*\n\taddi\.d.*%pc_lo12.*\n\tlu32i\.d.*%pc64_lo20.*\n\tlu52i\.d.*pc64_hi12.*\n\tadd\.d" } } */ /* { dg-final { scan-assembler "test2:.*pcalau12i.*%pc_hi20.*\n\taddi\.d.*%pc_lo12.*\n\tlu32i\.d.*%pc64_lo20.*\n\tlu52i\.d.*pc64_hi12.*\n\tadd\.d" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-extreme-4.c b/gcc/testsuite/gcc.target/loongarch/func-call-extreme-4.c index 16b00f4c5f2..c4228500635 100644 --- a/gcc/testsuite/gcc.target/loongarch/func-call-extreme-4.c +++ b/gcc/testsuite/gcc.target/loongarch/func-call-extreme-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt -mexplicit-relocs=auto -mcmodel=extreme" } */ +/* { dg-options "-mabi=lp64d -O2 -fpic -fno-plt -mexplicit-relocs=auto -mcmodel=extreme" } */ /* { dg-final { scan-assembler "test:.*pcalau12i.*%got_pc_hi20.*\n\taddi\.d.*%got_pc_lo12.*\n\tlu32i\.d.*%got64_pc_lo20.*\n\tlu52i\.d.*%got64_pc_hi12.*\n\tldx\.d" } } */ /* { dg-final { scan-assembler "test1:.*pcalau12i.*%got_pc_hi20.*\n\taddi\.d.*%got_pc_lo12.*\n\tlu32i\.d.*%got64_pc_lo20.*\n\tlu52i\.d.*%got64_pc_hi12.*\n\tldx\.d" } } */ /* { dg-final { scan-assembler "test2:.*pcalau12i.*%pc_hi20.*\n\taddi\.d.*%pc_lo12.*\n\tlu32i\.d.*%pc64_lo20.*\n\tlu52i\.d.*pc64_hi12.*\n\tadd\.d" } } */