From patchwork Sat Aug 20 02:29:19 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lulu Cheng X-Patchwork-Id: 56891 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B858C3858280 for ; Sat, 20 Aug 2022 02:31:00 +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 7E08C3858D39 for ; Sat, 20 Aug 2022 02:29:35 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 7E08C3858D39 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 AQAAf8Dx_2sHRwBjZIIFAA--.23403S2; Sat, 20 Aug 2022 10:29:31 +0800 (CST) From: Lulu Cheng To: gcc-patches@gcc.gnu.org Subject: [PATCH v3] LoongArch: Add support code model extreme. Date: Sat, 20 Aug 2022 10:29:19 +0800 Message-Id: <20220820022918.2855759-1-chenglulu@loongson.cn> X-Mailer: git-send-email 2.31.1 MIME-Version: 1.0 X-CM-TRANSID: AQAAf8Dx_2sHRwBjZIIFAA--.23403S2 X-Coremail-Antispam: 1UD129KBjvAXoWfWF13JF1UuF1xuw1fKrykZrb_yoW5Ww4rZo WrAF4DJw48Wr1akwsrKrnxWw18Ar10yrWrAa9Fvr1rGF4Iy345ZryfKa15ur9xJr9rX345 Cas7Za9rAasrJF98n29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUY07AC8VAFwI0_Jr0_Gr1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2 x7M28EF7xvwVC0I7IYx2IY67AKxVWUJVWUCwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW8 JVWxJwA2z4x0Y4vEx4A2jsIE14v26F4j6r4UJwA2z4x0Y4vEx4A2jsIEc7CjxVAFwI0_Gr 1j6F4UJwAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv 7VC0I7IYx2IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r 1j6r4UM4x0Y48IcxkI7VAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwCY02Avz4vE-syl 42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr1lx2IqxVAqx4xG67AKxVWUJV WUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE14v26r126r1DMIIYrxkI7VAK I48JMIIF0xvE2Ix0cI8IcVAFwI0_Jr0_JF4lIxAIcVC0I7IYx2IY6xkF7I0E14v26r1j6r 4UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E87Iv67AKxVWUJVW8JwCI42IY 6I8E87Iv6xkF7I0E14v26r1j6r4UYxBIdaVFxhVjvjDU0xZFpf9x0JUdEfOUUUUU= 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+patchwork=sourceware.org@gcc.gnu.org Sender: "Gcc-patches" v1 -> v2: - Modify some description information. - Add options -W[no]extreme-plt, warn about code model extreme not support plt mode, and then disable plt. v2 -> v3: - When -mcmodel=extreme, default set to -fno-plt mode, if the user forces to use '-mcmodel=extreme -fplt', an error will be reported. - Delete -Wextreme-plt. - Fix bug when compiling with '-mcmodel=normal -fno-plt -mno-explicit-relocs'. ---------------------------------------------------------------------------- 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=extreme' 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. Document -W[no-]extreme-plt. 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 | 223 +++++++++++++++--- gcc/config/loongarch/loongarch.md | 34 ++- gcc/config/loongarch/predicates.md | 9 +- gcc/doc/invoke.texi | 50 +--- .../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, 319 insertions(+), 82 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..c5667f5ae3c 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -2436,7 +2436,19 @@ 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) + { + gcc_assert (TARGET_EXPLICIT_RELOCS); + + 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 { @@ -2449,14 +2461,45 @@ loongarch_call_tls_get_addr (rtx sym, enum loongarch_symbol_type type, rtx v0) } if (flag_plt) - insn = emit_call_insn (gen_call_value_internal (v0, loongarch_tls_symbol, + insn = emit_call_insn (gen_call_value_internal (v0, + loongarch_tls_symbol, const0_rtx)); else { 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) + { + gcc_assert (TARGET_EXPLICIT_RELOCS); + + rtx tmp1 = gen_reg_rtx (Pmode); + rtx high = gen_reg_rtx (Pmode); + + 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), + 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 + { + if (TARGET_EXPLICIT_RELOCS) + { + 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)); + } + else + loongarch_emit_move (dest, + gen_rtx_MEM (Pmode, loongarch_tls_symbol)); + } insn = emit_call_insn (gen_call_value_internal (v0, dest, const0_rtx)); } @@ -2508,7 +2551,23 @@ 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) + { + gcc_assert (TARGET_EXPLICIT_RELOCS); + + 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 +2589,18 @@ 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) + { + gcc_assert (TARGET_EXPLICIT_RELOCS); + + 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 +2669,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 +2680,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 +2689,42 @@ 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 ()) + { + gcc_assert (TARGET_EXPLICIT_RELOCS); + + 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 +4673,86 @@ 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; + if (TARGET_CMODEL_EXTREME) + gcc_assert (TARGET_EXPLICIT_RELOCS); + 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 +4778,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 +4837,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 +4852,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 +4868,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 +5008,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,13 +5982,21 @@ 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 needs %s", + "extreme", "-mexplicit-relocs"); + if (opts->x_flag_plt) - error ("code model %qs and %qs not support %s mode", - "tiny-static", "extreme", "plt"); + { + if (global_options_set.x_flag_plt) + error ("code model %qs is not compatible with %s", + "extreme", "-fplt"); + opts->x_flag_plt = 0; + } break; + case CMODEL_TINY_STATIC: case CMODEL_NORMAL: case CMODEL_TINY: case CMODEL_LARGE: 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..8712bc25e3c 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -1020,6 +1020,7 @@ Objective-C and Objective-C++ Dialects}. -mcond-move-float -mno-cond-move-float @gol -memcpy -mno-memcpy -mstrict-align -mno-strict-align @gol -mmax-inline-memcpy-size=@var{n} @gol +-mexplicit-relocs -mno-explicit-relocs @gol -mcmodel=@var{code-model}} @emph{M32R/D Options} @@ -25076,50 +25077,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" } } */