From patchwork Thu Aug 18 10:01:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: chenglulu X-Patchwork-Id: 596 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:6a10:38f:b0:2d5:3c95:9e21 with SMTP id 15csp170753pxh; Thu, 18 Aug 2022 03:02:03 -0700 (PDT) X-Google-Smtp-Source: AA6agR7k+WTypLEzCix02J9ne175vbCq+va43BO/TflLFF70HO/Cb0Kt1rxSufJ2mtr92H2nnZWn X-Received: by 2002:a17:907:868f:b0:730:bc1f:a8d8 with SMTP id qa15-20020a170907868f00b00730bc1fa8d8mr1498806ejc.106.1660816923634; Thu, 18 Aug 2022 03:02:03 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1660816923; cv=none; d=google.com; s=arc-20160816; b=ghR3tAB6d052VdQ9gQkCIlAMJfx2ctaYPGcZjGsGEDY+xtg5G9BnHqGUPn9wCkX7cK R3cwLs+AWNmSt3uB6m+ZhzRhARTiClsmU9BvnRDmiPuBWNHk6w+QY/ItYMtSsMQWjg1k ZRDwLxTKHOdB26VZDHsUAF8BPYoY3O+Icrw17B3d7zmkcCbJ7l3kN7VX+eiQG7Qyo5ea G7T8MnzBzrR4FpwFeMg+7gKSUp6J7V7ekSUdE+v/9z0Kyp3DzoAoahkwG6LplZ2T/owo YAqd6ShwpeAlOJ1qH5wA8INaq9u9qfhVVn08h1nQyjShGzYl9vR6dBYwvmjHFJ7cbV1y 9pkw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:cc:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:message-id:date:subject:to:from:dmarc-filter :delivered-to; bh=Zhosf6gv7qjTV06KEmm3HjphYmA++y5KgeJCwJkSwkM=; b=nBJt+MTPpt03l+StfhzEGgg5pSRDIWTbOiMC0bIHs9ivWT7y1u+1DD8+DK3QTYGP2B gx4zYvT3N5/F4u1h7MtDUkjiSsqePApzZRTFFgUhOoct/E2y3VRTMqwzopV5JanvUwMf DlgOp9x+s6tq9cb5/pZg71trqc28CTawkfo8RzSmWlVl9RKShOG8YqrzmVEH2hfidvkr xuSF5Kw1fM6LOk+z60VYF576g3tRy2X3umcd/mI0BrDFHE8xOU49AvnAVPvl2n0TM4iE 1hdMRQO4xqkLzIJHqDpjo4l0xytEkFF3gF+wSLZcVB3tEgJiuN7r+iDSq4Oug4Z83zUF L+hw== ARC-Authentication-Results: i=1; mx.google.com; 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 sourceware.org (server2.sourceware.org. [2620:52:3:1:0:246e:9693:128c]) by mx.google.com with ESMTPS id he38-20020a1709073da600b0073be6050f61si808258ejc.625.2022.08.18.03.02.03 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Aug 2022 03:02:03 -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; 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 A1FED38582BF for ; Thu, 18 Aug 2022 10:01:56 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by sourceware.org (Postfix) with ESMTP id 9946F3858437 for ; Thu, 18 Aug 2022 10:01:22 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 9946F3858437 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=loongson.cn Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=loongson.cn Received: from 5.5.5 (unknown [10.2.5.5]) by localhost.localdomain (Coremail) with SMTP id AQAAf8Bx32vqDf5icMUDAA--.14744S2; Thu, 18 Aug 2022 18:01:18 +0800 (CST) From: Lulu Cheng To: gcc-patches@gcc.gnu.org Subject: [PATCH v1] LoongArch: Add support code model extreme. Date: Thu, 18 Aug 2022 18:01:12 +0800 Message-Id: <20220818100112.142343-1-chenglulu@loongson.cn> X-Mailer: git-send-email 2.31.1 MIME-Version: 1.0 X-CM-TRANSID: AQAAf8Bx32vqDf5icMUDAA--.14744S2 X-Coremail-Antispam: 1UD129KBjvAXoWfWF1xGryDGFy7Ww4UtFW3GFg_yoW5XF15to Z5AF4DJw48Gr1akwsrKrnxW3W8Zr10yrWrAa9Fvr1rGF4Iy345Zr93Ka15ur9xJrnrX345 uas7Za9rAasrJF98n29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUY07AC8VAFwI0_Jr0_Gr1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2 x7M28EF7xvwVC0I7IYx2IY67AKxVW8JVW5JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVWx JVW8Jr1l84ACjcxK6I8E87Iv67AKxVWxJr0_GcWl84ACjcxK6I8E87Iv6xkF7I0E14v26r xl6s0DM2AIxVAIcxkEcVAq07x20xvEncxIr21l5I8CrVACY4xI64kE6c02F40Ex7xfMcIj 6xIIjxv20xvE14v26r1Y6r17McIj6I8E87Iv67AKxVWUJVW8JwAm72CE4IkC6x0Yz7v_Jr 0_Gr1lF7xvr2IYc2Ij64vIr41lF7I21c0EjII2zVCS5cI20VAGYxC7MxkIecxEwVCm-wCF 04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8JwC20s026c02F40E14v26r1j6r 18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAFwI0_JF0_Jw1lIxkGc2Ij64vI r41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjxv20xvEc7CjxVAFwI0_Jr0_Gr 1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2jsIE14v26r1j6r4UMIIF0xvE x4A2jsIEc7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0xZFpf9x0JU9189UUUUU= X-CM-SenderInfo: xfkh0wpoxo3qxorr0wxvrqhubq/ X-Spam-Status: No, score=-11.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, KAM_STOCKGEN, SPF_HELO_PASS, 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.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: xuchenghua@loongson.cn, Lulu Cheng , i@xen0n.name 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?1741492766255321378?= X-GMAIL-MSGID: =?utf-8?q?1741492766255321378?= Use five instructions to calculate a signed 64-bit offset relative to the pc. gcc/ChangeLog: * config/loongarch/loongarch-opts.cc: Allow cmodel to be extreme. * config/loongarch/loongarch.cc (loongarch_call_tls_get_addr): Add extreme support for TLS GD and LD types. (loongarch_legitimize_tls_address): Add extreme support for TLS LE and IE. (loongarch_split_symbol): When compiling with -mcmodel=extreme, the symbol address will be obtained through five instructions. (loongarch_print_operand_reloc): Add support. (loongarch_print_operand): Add support. (loongarch_print_operand_address): Add support. (loongarch_option_override_internal): Set '-mcmodel=large' option incompatible with '-mno-explicit-relocs'. * config/loongarch/loongarch.md (@lui_l_hi20): Loads bits 12-31 of data into registers. (lui_h_lo20): Load bits 32-51 of the data and spell bits 0-31 of the source register. (lui_h_hi12): Load bits 52-63 of the data and spell bits 0-51 of the source register. * config/loongarch/predicates.md: Symbols need to be decomposed when defining the macro TARGET_CMODEL_EXTREME * doc/invoke.texi: Modify the description information of cmodel in the document. gcc/testsuite/ChangeLog: * gcc.target/loongarch/func-call-1.c: Add option '-mcmodel=normal'. * gcc.target/loongarch/func-call-2.c: Likewise. * gcc.target/loongarch/func-call-3.c: Likewise. * gcc.target/loongarch/func-call-4.c: Likewise. * gcc.target/loongarch/func-call-5.c: Likewise. * gcc.target/loongarch/func-call-6.c: Likewise. * gcc.target/loongarch/func-call-7.c: Likewise. * gcc.target/loongarch/func-call-8.c: Likewise. * gcc.target/loongarch/relocs-symbol-noaddend.c: Likewise. * gcc.target/loongarch/func-call-extreme-1.c: New test. * gcc.target/loongarch/func-call-extreme-2.c: New test. --- gcc/config/loongarch/loongarch-opts.cc | 3 +- gcc/config/loongarch/loongarch.cc | 185 +++++++++++++++--- gcc/config/loongarch/loongarch.md | 34 +++- gcc/config/loongarch/predicates.md | 9 +- gcc/doc/invoke.texi | 49 +---- .../gcc.target/loongarch/func-call-1.c | 2 +- .../gcc.target/loongarch/func-call-2.c | 2 +- .../gcc.target/loongarch/func-call-3.c | 2 +- .../gcc.target/loongarch/func-call-4.c | 2 +- .../gcc.target/loongarch/func-call-5.c | 2 +- .../gcc.target/loongarch/func-call-6.c | 2 +- .../gcc.target/loongarch/func-call-7.c | 2 +- .../gcc.target/loongarch/func-call-8.c | 2 +- .../loongarch/func-call-extreme-1.c | 32 +++ .../loongarch/func-call-extreme-2.c | 32 +++ .../loongarch/relocs-symbol-noaddend.c | 2 +- 16 files changed, 285 insertions(+), 77 deletions(-) create mode 100644 gcc/testsuite/gcc.target/loongarch/func-call-extreme-1.c create mode 100644 gcc/testsuite/gcc.target/loongarch/func-call-extreme-2.c diff --git a/gcc/config/loongarch/loongarch-opts.cc b/gcc/config/loongarch/loongarch-opts.cc index 3f70943ded6..2ae89f23443 100644 --- a/gcc/config/loongarch/loongarch-opts.cc +++ b/gcc/config/loongarch/loongarch-opts.cc @@ -376,14 +376,13 @@ fallback: /* 5. Target code model */ t.cmodel = constrained.cmodel ? opt_cmodel : CMODEL_NORMAL; - if (t.cmodel != CMODEL_NORMAL) + if (t.cmodel != CMODEL_NORMAL && t.cmodel != CMODEL_EXTREME) { warning (0, "%qs is not supported, now cmodel is set to %qs", loongarch_cmodel_strings[t.cmodel], "normal"); t.cmodel = CMODEL_NORMAL; } - /* Cleanup and return. */ obstack_free (&msg_obstack, NULL); *target = t; diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index 24378143641..ad1ec12a8c4 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -2436,7 +2436,17 @@ loongarch_call_tls_get_addr (rtx sym, enum loongarch_symbol_type type, rtx v0) /* 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)); + + 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)); + } + else + emit_insn (gen_tls_low (Pmode, a0, high, loc)); } else { @@ -2456,7 +2466,21 @@ loongarch_call_tls_get_addr (rtx sym, enum loongarch_symbol_type type, rtx v0) rtx dest = gen_reg_rtx (Pmode); rtx high = gen_reg_rtx (Pmode); loongarch_emit_move (high, gen_rtx_HIGH (Pmode, loongarch_tls_symbol)); - emit_insn (gen_ld_from_got (Pmode, dest, high, loongarch_tls_symbol)); + + if (TARGET_CMODEL_EXTREME) + { + rtx tmp1 = gen_reg_rtx (Pmode); + loongarch_emit_move (tmp1, gen_rtx_LO_SUM (Pmode, + gen_rtx_REG (Pmode, 0), + 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))); + } + else + emit_insn (gen_ld_from_got (Pmode, dest, high, loongarch_tls_symbol)); insn = emit_call_insn (gen_call_value_internal (v0, dest, const0_rtx)); } @@ -2508,7 +2532,21 @@ loongarch_legitimize_tls_address (rtx loc) 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)); + + 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)); + emit_move_insn (tmp1, + gen_rtx_MEM (Pmode, + gen_rtx_PLUS (Pmode, + high, tmp3))); + } + else + emit_insn (gen_ld_from_got (Pmode, tmp1, high, tmp2)); } else emit_insn (loongarch_got_load_tls_ie (tmp1, loc)); @@ -2530,11 +2568,16 @@ loongarch_legitimize_tls_address (rtx loc) rtx high = gen_rtx_HIGH (Pmode, copy_rtx (tmp2)); high = loongarch_force_temporary (tmp3, high); emit_insn (gen_ori_l_lo12 (Pmode, tmp1, high, tmp2)); + + if (TARGET_CMODEL_EXTREME) + { + emit_insn (gen_lui_h_lo20 (tmp1, tmp1, tmp2)); + emit_insn (gen_lui_h_hi12 (tmp1, tmp1, tmp2)); + } } else emit_insn (loongarch_got_load_tls_le (tmp1, loc)); emit_insn (gen_add3_insn (dest, tmp1, tp)); - } break; @@ -2603,7 +2646,6 @@ bool loongarch_split_symbol (rtx temp, rtx addr, machine_mode mode, rtx *low_out) { enum loongarch_symbol_type symbol_type; - rtx high; /* If build with '-mno-explicit-relocs', don't split symbol. */ if (!TARGET_EXPLICIT_RELOCS) @@ -2615,6 +2657,8 @@ 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; + if (temp == NULL) temp = gen_reg_rtx (Pmode); @@ -2622,20 +2666,40 @@ loongarch_split_symbol (rtx temp, rtx addr, machine_mode mode, rtx *low_out) high = gen_rtx_HIGH (Pmode, copy_rtx (addr)); high = loongarch_force_temporary (temp, high); + if (TARGET_CMODEL_EXTREME && can_create_pseudo_p ()) + { + 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)); + } + if (low_out) switch (symbol_type) { case SYMBOL_PCREL: - *low_out = gen_rtx_LO_SUM (Pmode, high, addr); - break; + { + if (TARGET_CMODEL_EXTREME && can_create_pseudo_p ()) + *low_out = gen_rtx_PLUS (Pmode, high, temp1); + else + *low_out = gen_rtx_LO_SUM (Pmode, high, addr); + break; + } case SYMBOL_GOT_DISP: /* SYMBOL_GOT_DISP symbols are loaded from the GOT. */ { - rtx low = gen_rtx_LO_SUM (Pmode, high, addr); - rtx mem = gen_rtx_MEM (Pmode, low); - *low_out = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, mem), - UNSPEC_LOAD_FROM_GOT); + if (TARGET_CMODEL_EXTREME && can_create_pseudo_p ()) + *low_out = gen_rtx_MEM (Pmode, gen_rtx_PLUS (Pmode, high, temp1)); + else + { + rtx low = gen_rtx_LO_SUM (Pmode, high, addr); + rtx mem = gen_rtx_MEM (Pmode, low); + *low_out = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, mem), + UNSPEC_LOAD_FROM_GOT); + } + break; } @@ -4584,34 +4648,83 @@ loongarch_memmodel_needs_release_fence (enum memmodel model) in context CONTEXT. HI_RELOC indicates a high-part reloc. */ static void -loongarch_print_operand_reloc (FILE *file, rtx op, bool hi_reloc) +loongarch_print_operand_reloc (FILE *file, rtx op, bool hi64_part, + bool hi_reloc) { const char *reloc; switch (loongarch_classify_symbolic_expression (op)) { case SYMBOL_PCREL: - reloc = hi_reloc ? "%pc_hi20" : "%pc_lo12"; + if (hi64_part) + { + if (TARGET_CMODEL_EXTREME) + reloc = hi_reloc ? "%pc64_hi12" : "%pc64_lo20"; + else + gcc_unreachable (); + } + else + reloc = hi_reloc ? "%pc_hi20" : "%pc_lo12"; break; case SYMBOL_GOT_DISP: - reloc = hi_reloc ? "%got_pc_hi20" : "%got_pc_lo12"; + if (hi64_part) + { + if (TARGET_CMODEL_EXTREME) + reloc = hi_reloc ? "%got64_pc_hi12" : "%got64_pc_lo20"; + else + gcc_unreachable (); + } + else + reloc = hi_reloc ? "%got_pc_hi20" : "%got_pc_lo12"; break; case SYMBOL_TLS_IE: - reloc = hi_reloc ? "%ie_pc_hi20" : "%ie_pc_lo12"; + if (hi64_part) + { + if (TARGET_CMODEL_EXTREME) + reloc = hi_reloc ? "%ie64_pc_hi12" : "%ie64_pc_lo20"; + else + gcc_unreachable (); + } + else + reloc = hi_reloc ? "%ie_pc_hi20" : "%ie_pc_lo12"; break; case SYMBOL_TLS_LE: - reloc = hi_reloc ? "%le_hi20" : "%le_lo12"; + if (hi64_part) + { + if (TARGET_CMODEL_EXTREME) + reloc = hi_reloc ? "%le64_hi12" : "%le64_lo20"; + else + gcc_unreachable (); + } + else + reloc = hi_reloc ? "%le_hi20" : "%le_lo12"; break; case SYMBOL_TLSGD: - reloc = hi_reloc ? "%gd_pc_hi20" : "%got_pc_lo12"; + if (hi64_part) + { + if (TARGET_CMODEL_EXTREME) + reloc = hi_reloc ? "%got64_pc_hi12" : "%got64_pc_lo20"; + else + gcc_unreachable (); + } + else + reloc = hi_reloc ? "%gd_pc_hi20" : "%got_pc_lo12"; break; case SYMBOL_TLSLDM: - reloc = hi_reloc ? "%ld_pc_hi20" : "%got_pc_lo12"; + if (hi64_part) + { + if (TARGET_CMODEL_EXTREME) + reloc = hi_reloc ? "%got64_pc_hi12" : "%got64_pc_lo20"; + else + gcc_unreachable (); + } + else + reloc = hi_reloc ? "%ld_pc_hi20" : "%got_pc_lo12"; break; default: @@ -4637,6 +4750,8 @@ loongarch_print_operand_reloc (FILE *file, rtx op, bool hi_reloc) 'L' Print the low-part relocation associated with OP. 'm' Print one less than CONST_INT OP in decimal. 'N' Print the inverse of the integer branch condition for comparison OP. + 'r' Print address 12-31bit relocation associated with OP. + 'R' Print address 32-51bit relocation associated with OP. 'T' Print 'f' for (eq:CC ...), 't' for (ne:CC ...), 'z' for (eq:?I ...), 'n' for (ne:?I ...). 't' Like 'T', but with the EQ/NE cases reversed @@ -4694,7 +4809,13 @@ loongarch_print_operand (FILE *file, rtx op, int letter) case 'h': if (code == HIGH) op = XEXP (op, 0); - loongarch_print_operand_reloc (file, op, true /* hi_reloc */); + loongarch_print_operand_reloc (file, op, false /* hi64_part */, + true /* hi_reloc */); + break; + + case 'H': + loongarch_print_operand_reloc (file, op, true /* hi64_part */, + true /* hi_reloc */); break; case 'i': @@ -4703,7 +4824,8 @@ loongarch_print_operand (FILE *file, rtx op, int letter) break; case 'L': - loongarch_print_operand_reloc (file, op, false /* lo_reloc */); + loongarch_print_operand_reloc (file, op, false /* hi64_part*/, + false /* lo_reloc */); break; case 'm': @@ -4718,6 +4840,16 @@ loongarch_print_operand (FILE *file, rtx op, int letter) letter); break; + case 'r': + loongarch_print_operand_reloc (file, op, false /* hi64_part */, + true /* lo_reloc */); + break; + + case 'R': + loongarch_print_operand_reloc (file, op, true /* hi64_part */, + false /* lo_reloc */); + break; + case 't': case 'T': { @@ -4848,7 +4980,8 @@ loongarch_print_operand_address (FILE *file, machine_mode /* mode */, rtx x) case ADDRESS_LO_SUM: fprintf (file, "%s,", reg_names[REGNO (addr.reg)]); - loongarch_print_operand_reloc (file, addr.offset, false /* hi_reloc */); + loongarch_print_operand_reloc (file, addr.offset, false /* hi64_part */, + false /* hi_reloc */); return; case ADDRESS_CONST_INT: @@ -5821,8 +5954,16 @@ loongarch_option_override_internal (struct gcc_options *opts) switch (la_target.cmodel) { - case CMODEL_TINY_STATIC: case CMODEL_EXTREME: + if (!TARGET_EXPLICIT_RELOCS) + error ("code model %qs not support %s mode", + "extreme", "-mno-explicit-relocs"); + if (opts->x_flag_plt) + error ("code model %qs and %qs not support %s mode", + "tiny-static", "extreme", "plt"); + break; + + case CMODEL_TINY_STATIC: if (opts->x_flag_plt) error ("code model %qs and %qs not support %s mode", "tiny-static", "extreme", "plt"); diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md index 8e8868de9f5..8fc10444c2a 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -60,6 +60,9 @@ (define_c_enum "unspec" [ UNSPEC_LOAD_FROM_GOT UNSPEC_ORI_L_LO12 + UNSPEC_LUI_L_HI20 + UNSPEC_LUI_H_LO20 + UNSPEC_LUI_H_HI12 UNSPEC_TLS_LOW ]) @@ -1934,16 +1937,45 @@ (define_insn "@ld_from_got" [(set_attr "type" "move")] ) +(define_insn "@lui_l_hi20" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand:P 1 "symbolic_operand")] + UNSPEC_LUI_L_HI20))] + "" + "lu12i.w\t%0,%r1" + [(set_attr "type" "move")] +) + (define_insn "@ori_l_lo12" [(set (match_operand:P 0 "register_operand" "=r") (unspec:P [(match_operand:P 1 "register_operand" "r") - (match_operand:P 2 "symbolic_operand")] + (match_operand:P 2 "symbolic_operand")] UNSPEC_ORI_L_LO12))] "" "ori\t%0,%1,%L2" [(set_attr "type" "move")] ) +(define_insn "lui_h_lo20" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "register_operand" "0") + (match_operand:DI 2 "symbolic_operand")] + UNSPEC_LUI_H_LO20))] + "TARGET_64BIT" + "lu32i.d\t%0,%R2" + [(set_attr "type" "move")] +) + +(define_insn "lui_h_hi12" + [(set (match_operand:DI 0 "register_operand" "=r") + (unspec:DI [(match_operand:DI 1 "register_operand" "r") + (match_operand:DI 2 "symbolic_operand")] + UNSPEC_LUI_H_HI12))] + "TARGET_64BIT" + "lu52i.d\t%0,%1,%H2" + [(set_attr "type" "move")] +) + ;; Convert floating-point numbers to integers (define_insn "frint_" [(set (match_operand:ANYF 0 "register_operand" "=f") diff --git a/gcc/config/loongarch/predicates.md b/gcc/config/loongarch/predicates.md index cd3528c7c97..e38c6fbdd5f 100644 --- a/gcc/config/loongarch/predicates.md +++ b/gcc/config/loongarch/predicates.md @@ -111,7 +111,7 @@ (define_predicate "const_call_insn_operand" (match_code "const,symbol_ref,label_ref") { /* Split symbol to high and low if return false. - If defined TARGET_CMODEL_LARGE, all symbol would be splited, + If defined TARGET_CMODEL_EXTREME, all symbol would be splited, else if offset is not zero, the symbol would be splited. */ enum loongarch_symbol_type symbol_type; @@ -126,10 +126,13 @@ (define_predicate "const_call_insn_operand" switch (symbol_type) { case SYMBOL_PCREL: - return 1; + if (TARGET_CMODEL_EXTREME) + return false; + else + return 1; case SYMBOL_GOT_DISP: - if (TARGET_CMODEL_LARGE || !flag_plt) + if (TARGET_CMODEL_EXTREME || !flag_plt) return false; else return 1; diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 1ac81ad0bb4..f5076a407c3 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -25076,50 +25076,19 @@ less than or equal to @var{n} bytes. The default value of @var{n} is 1024. @item -mcmodel=@var{code-model} Set the code model to one of: @table @samp -@item tiny-static -@itemize @bullet -@item -local symbol and global strong symbol: The data section must be within +/-2MiB addressing space. -The text section must be within +/-128MiB addressing space. -@item -global weak symbol: The got table must be within +/-2GiB addressing space. -@end itemize - -@item tiny -@itemize @bullet -@item -local symbol: The data section must be within +/-2MiB addressing space. -The text section must be within +/-128MiB -addressing space. -@item -global symbol: The got table must be within +/-2GiB addressing space. -@end itemize +@item tiny-static (Not implemented yet) +@item tiny (Not implemented yet) @item normal -@itemize @bullet -@item -local symbol: The data section must be within +/-2GiB addressing space. -The text section must be within +/-128MiB addressing space. -@item -global symbol: The got table must be within +/-2GiB addressing space. -@end itemize +The text segment must be within 128MB addressing space. The data segment must +be within 2GB addressing space. -@item large -@itemize @bullet -@item -local symbol: The data section must be within +/-2GiB addressing space. -The text section must be within +/-128GiB addressing space. -@item -global symbol: The got table must be within +/-2GiB addressing space. -@end itemize +@item large (Not implemented yet) -@item extreme(Not implemented yet) -@itemize @bullet -@item -local symbol: The data and text section must be within +/-8EiB addressing space. -@item -global symbol: The data got table must be within +/-8EiB addressing space. -@end itemize +@item extreme +This mode does not limit the size of the code segment and data segment. +The @option{-mcmodel=extreme} option is incompatible with @option{-fplt} and +@option{-mno-explicit-relocs}. @end table The default code model is @code{normal}. diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-1.c b/gcc/testsuite/gcc.target/loongarch/func-call-1.c index 01b8ea23fb9..76bf11b0c03 100644 --- a/gcc/testsuite/gcc.target/loongarch/func-call-1.c +++ b/gcc/testsuite/gcc.target/loongarch/func-call-1.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mabi=lp64d -O0 -fpic -fplt -mno-explicit-relocs" } */ +/* { dg-options "-mabi=lp64d -O0 -fpic -fplt -mno-explicit-relocs -mcmodel=normal" } */ /* { dg-final { scan-assembler "test:.*bl\t%plt\\(g\\)\n" } } */ /* { dg-final { scan-assembler "test1:.*bl\t%plt\\(f\\)\n" } } */ /* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-2.c b/gcc/testsuite/gcc.target/loongarch/func-call-2.c index 4565baaec9e..4b468fef8b4 100644 --- a/gcc/testsuite/gcc.target/loongarch/func-call-2.c +++ b/gcc/testsuite/gcc.target/loongarch/func-call-2.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mabi=lp64d -O0 -fno-pic -fplt -mno-explicit-relocs" } */ +/* { dg-options "-mabi=lp64d -O0 -fno-pic -fplt -mno-explicit-relocs -mcmodel=normal" } */ /* { dg-final { scan-assembler "test:.*bl\t%plt\\(g\\)\n" } } */ /* { dg-final { scan-assembler "test1:.*bl\tf\n" } } */ /* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-3.c b/gcc/testsuite/gcc.target/loongarch/func-call-3.c index 4f669a029e7..dd3a4882d60 100644 --- a/gcc/testsuite/gcc.target/loongarch/func-call-3.c +++ b/gcc/testsuite/gcc.target/loongarch/func-call-3.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt -mno-explicit-relocs" } */ +/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt -mno-explicit-relocs -mcmodel=normal" } */ /* { dg-final { scan-assembler "test:.*la\.global\t.*g\n\tjirl" } } */ /* { dg-final { scan-assembler "test1:.*la\.global\t.*f\n\tjirl" } } */ /* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-4.c b/gcc/testsuite/gcc.target/loongarch/func-call-4.c index 943adb6403f..f8158ec349f 100644 --- a/gcc/testsuite/gcc.target/loongarch/func-call-4.c +++ b/gcc/testsuite/gcc.target/loongarch/func-call-4.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt -mno-explicit-relocs" } */ +/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt -mno-explicit-relocs -mcmodel=normal" } */ /* { dg-final { scan-assembler "test:.*la\.global\t.*g\n\tjirl" } } */ /* { dg-final { scan-assembler "test1:.*bl\tf\n" } } */ /* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-5.c b/gcc/testsuite/gcc.target/loongarch/func-call-5.c index 2c2a1c8a1b6..37994af430d 100644 --- a/gcc/testsuite/gcc.target/loongarch/func-call-5.c +++ b/gcc/testsuite/gcc.target/loongarch/func-call-5.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mabi=lp64d -O0 -fpic -fplt -mexplicit-relocs" } */ +/* { dg-options "-mabi=lp64d -O0 -fpic -fplt -mexplicit-relocs -mcmodel=normal" } */ /* { dg-final { scan-assembler "test:.*bl\t%plt\\(g\\)\n" } } */ /* { dg-final { scan-assembler "test1:.*bl\t%plt\\(f\\)\n" } } */ /* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-6.c b/gcc/testsuite/gcc.target/loongarch/func-call-6.c index 4b0e4266ec8..8e366e376e7 100644 --- a/gcc/testsuite/gcc.target/loongarch/func-call-6.c +++ b/gcc/testsuite/gcc.target/loongarch/func-call-6.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mabi=lp64d -O0 -fno-pic -fplt -mexplicit-relocs" } */ +/* { dg-options "-mabi=lp64d -O0 -fno-pic -fplt -mexplicit-relocs -mcmodel=normal" } */ /* { dg-final { scan-assembler "test:.*bl\t%plt\\(g\\)\n" } } */ /* { dg-final { scan-assembler "test1:.*bl\tf\n" } } */ /* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-7.c b/gcc/testsuite/gcc.target/loongarch/func-call-7.c index 51792711f72..4177c3d962e 100644 --- a/gcc/testsuite/gcc.target/loongarch/func-call-7.c +++ b/gcc/testsuite/gcc.target/loongarch/func-call-7.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt -mexplicit-relocs" } */ +/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt -mexplicit-relocs -mcmodel=normal" } */ /* { dg-final { scan-assembler "test:.*pcalau12i\t.*%got_pc_hi20\\(g\\)\n\tld\.d\t.*%got_pc_lo12\\(g\\)\n\tjirl" } } */ /* { dg-final { scan-assembler "test1:.*pcalau12i\t.*%got_pc_hi20\\(f\\)\n\tld\.d\t.*%got_pc_lo12\\(f\\)\n\tjirl" } } */ /* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-8.c b/gcc/testsuite/gcc.target/loongarch/func-call-8.c index 330140d883d..4254eaa16d4 100644 --- a/gcc/testsuite/gcc.target/loongarch/func-call-8.c +++ b/gcc/testsuite/gcc.target/loongarch/func-call-8.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt -mexplicit-relocs" } */ +/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt -mexplicit-relocs -mcmodel=normal" } */ /* { dg-final { scan-assembler "test:.*pcalau12i\t.*%got_pc_hi20\\(g\\)\n\tld\.d\t.*%got_pc_lo12\\(g\\)\n\tjirl" } } */ /* { dg-final { scan-assembler "test1:.*bl\tf\n" } } */ /* { dg-final { scan-assembler "test2:.*bl\tl\n" } } */ diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-extreme-1.c b/gcc/testsuite/gcc.target/loongarch/func-call-extreme-1.c new file mode 100644 index 00000000000..db1e0f85396 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/func-call-extreme-1.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O0 -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" } } */ + +extern void g (void); +void +f (void) +{} + +static void +l (void) +{} + +void +test (void) +{ + g (); +} + +void +test1 (void) +{ + f (); +} + +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 new file mode 100644 index 00000000000..21bf81ae837 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/func-call-extreme-2.c @@ -0,0 +1,32 @@ +/* { dg-do compile } */ +/* { dg-options "-mabi=lp64d -O0 -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 (); +} diff --git a/gcc/testsuite/gcc.target/loongarch/relocs-symbol-noaddend.c b/gcc/testsuite/gcc.target/loongarch/relocs-symbol-noaddend.c index bfcc9bc338f..3ec8bd229fd 100644 --- a/gcc/testsuite/gcc.target/loongarch/relocs-symbol-noaddend.c +++ b/gcc/testsuite/gcc.target/loongarch/relocs-symbol-noaddend.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-mabi=lp64d -mexplicit-relocs -fno-pic -O2" } */ +/* { dg-options "-mabi=lp64d -mexplicit-relocs -fno-pic -O2 -mcmodel=normal" } */ /* { dg-final { scan-assembler "pcalau12i.*%pc_hi20\\(\.LANCHOR0\\)\n" } } */ /* { dg-final { scan-assembler "addi\.d.*%pc_lo12\\(\.LANCHOR0\\)\n" } } */ /* { dg-final { scan-assembler "ldptr.d\t\\\$r4,.*,0\n" } } */