From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from loongson.cn (mail.loongson.cn [114.242.206.163]) by sourceware.org (Postfix) with ESMTP id 4FFDD3858D28 for ; Sat, 20 Aug 2022 09:04:14 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 4FFDD3858D28 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 [10.20.4.52] (unknown [10.20.4.52]) by localhost.localdomain (Coremail) with SMTP id AQAAf8CxkOCJowBjZegFAA--.27277S2; Sat, 20 Aug 2022 17:04:09 +0800 (CST) Subject: Re: [commited PATCH v4] LoongArch: Add support code model extreme. To: gcc-patches@gcc.gnu.org Cc: xry111@xry111.site, i@xen0n.name, xuchenghua@loongson.cn References: <20220820083927.51849-1-chenglulu@loongson.cn> From: Lulu Cheng Message-ID: <70050223-d20b-cbec-2523-8e26396264f2@loongson.cn> Date: Sat, 20 Aug 2022 17:04:09 +0800 User-Agent: Mozilla/5.0 (X11; Linux mips64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 MIME-Version: 1.0 In-Reply-To: <20220820083927.51849-1-chenglulu@loongson.cn> Content-Type: text/plain; charset=gbk; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US X-CM-TRANSID: AQAAf8CxkOCJowBjZegFAA--.27277S2 X-Coremail-Antispam: 1UD129KBjvAXoWfAw4xXr4kuF1fKr4kCr1DAwb_yoW5Aw1xAo Z5AF4DGa18Gr1akwsrKrnxW3W0yry0y3yrAayqvryrWF40yry5AryfKw45Cry3JryDJry5 CFy7Za9rAasrtF98n29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUY37AC8VAFwI0_Jr0_Gr1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2 x7M28EF7xvwVC0I7IYx2IY67AKxVW8JVW5JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVW8 JVWxJwA2z4x0Y4vEx4A2jsIE14v26r4UJVWxJr1l84ACjcxK6I8E87Iv6xkF7I0E14v26r 4UJVWxJr1le2I262IYc4CY6c8Ij28IcVAaY2xG8wAqx4xG64xvF2IEw4CE5I8CrVC2j2Wl Yx0E2Ix0cI8IcVAFwI0_Jr0_Jr4lYx0Ex4A2jsIE14v26r1j6r4UMcvjeVCFs4IE7xkEbV WUJVW8JwACjcxG0xvEwIxGrwACjI8F5VA0II8E6IAqYI8I648v4I1lc7I2V7IY0VAS07Al zVAYIcxG8wCY02Avz4vE-syl42xK82IYc2Ij64vIr41l4I8I3I0E4IkC6x0Yz7v_Jr0_Gr 1lx2IqxVAqx4xG67AKxVWUJVWUGwC20s026x8GjcxK67AKxVWUGVWUWwC2zVAF1VAY17CE 14v26r126r1DMIIYrxkI7VAKI48JMIIF0xvE2Ix0cI8IcVAFwI0_Jr0_JF4lIxAIcVC0I7 IYx2IY6xkF7I0E14v26r1j6r4UMIIF0xvE42xK8VAvwI8IcIk0rVWUJVWUCwCI42IY6I8E 87Iv67AKxVWUJVW8JwCI42IY6I8E87Iv6xkF7I0E14v26r4j6r4UJbIYCTnIWIevJa73Uj IFyTuYvjfU5WlkUUUUU X-CM-SenderInfo: xfkh0wpoxo3qxorr0wxvrqhubq/ X-Spam-Status: No, score=-9.3 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, KAM_SHORT, KAM_STOCKGEN, MIME_CHARSET_FARAWAY, NICE_REPLY_A, 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: , X-List-Received-Date: Sat, 20 Aug 2022 09:04:23 -0000 Pushd to r13-2128. ÔÚ 2022/8/20 ÏÂÎç4:39, Lulu Cheng дµÀ: > 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'. > > v3 -> v4: > - Fix the bug of loongarch_tls_symbol function loading in function > loongarch_call_tls_get_addr. > > ---------------------------------------------------------------------------- > 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 | 222 +++++++++++++++--- > 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, 318 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..207ac2762c6 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,44 @@ 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, loongarch_tls_symbol); > + } > insn = emit_call_insn (gen_call_value_internal (v0, dest, const0_rtx)); > } > > @@ -2508,7 +2550,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 +2588,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 +2668,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 +2679,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 +2688,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 +4672,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 +4777,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 +4836,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 +4851,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 +4867,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 +5007,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 +5981,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" } } */