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 AF3C93857034 for ; Wed, 24 Aug 2022 06:58:11 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org AF3C93857034 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 AQAAf8Cx9OH+ywVjm4QIAA--.37907S2; Wed, 24 Aug 2022 14:58:07 +0800 (CST) Subject: Re: [commited PATCH v1] LoongArch: Add new code model 'medium'. To: Huacai Chen Cc: gcc-patches@gcc.gnu.org, Xu Chenghua , Wang Xuerui References: <20220820090425.525292-1-chenglulu@loongson.cn> From: Lulu Cheng Message-ID: <629d2dbd-6d3e-ce5a-483c-be67b4f40954@loongson.cn> Date: Wed, 24 Aug 2022 14:58:06 +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: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US X-CM-TRANSID:AQAAf8Cx9OH+ywVjm4QIAA--.37907S2 X-Coremail-Antispam: 1UD129KBjvAXoWfWF4fuFWDGw4ktF17Zr4xZwb_yoW5KF4rJo WFyF17Xw48Gryak3WDK3sIqryjyry8Ar4xAa9Fvw1fuF4kta45Ary7Ka15ZrW3JFZ7J3yU Cas7Ja97Aas7Gws8n29KB7ZKAUJUUUUU529EdanIXcx71UUUUU7v73VFW2AGmfu7bjvjm3 AaLaJ3UjIYCTnIWjp_UUUYV7AC8VAFwI0_Jr0_Gr1l1xkIjI8I6I8E6xAIw20EY4v20xva j40_Wr0E3s1l1IIY67AEw4v_Jr0_Jr4l8cAvFVAK0II2c7xJM28CjxkF64kEwVA0rcxSw2 x7M28EF7xvwVC0I7IYx2IY67AKxVW5JVW7JwA2z4x0Y4vE2Ix0cI8IcVCY1x0267AKxVWx JVW8Jr1l84ACjcxK6I8E87Iv67AKxVW8Jr0_Cr1UM28EF7xvwVC2z280aVCY1x0267AKxV W0oVCq3wAS0I0E0xvYzxvE52x082IY62kv0487Mc02F40EFcxC0VAKzVAqx4xG6I80ewAv 7VC0I7IYx2IY67AKxVWUGVWUXwAv7VC2z280aVAFwI0_Jr0_Gr1lOx8S6xCaFVCjc4AY6r 1j6r4UM4x0Y48IcVAKI48JM4x0x7Aq67IIx4CEVc8vx2IErcIFxwCYjI0SjxkI62AI1cAE 67vIY487MxkIecxEwVCm-wCF04k20xvY0x0EwIxGrwCFx2IqxVCFs4IE7xkEbVWUJVW8Jw C20s026c02F40E14v26r1j6r18MI8I3I0E7480Y4vE14v26r106r1rMI8E67AF67kF1VAF wI0_JF0_Jw1lIxkGc2Ij64vIr41lIxAIcVC0I7IYx2IY67AKxVWUJVWUCwCI42IY6xIIjx v20xvEc7CjxVAFwI0_Gr0_Cr1lIxAIcVCF04k26cxKx2IYs7xG6r1j6r1xMIIF0xvEx4A2 jsIE14v26r1j6r4UMIIF0xvEx4A2jsIEc7CjxVAFwI0_Gr0_Gr1UYxBIdaVFxhVjvjDU0x ZFpf9x0JUdEfOUUUUU= X-CM-SenderInfo: xfkh0wpoxo3qxorr0wxvrqhubq/ X-Spam-Status: No, score=-11.8 required=5.0 tests=BAYES_00,GIT_PATCH_0,KAM_DMARC_STATUS,KAM_SHORT,KAM_STOCKGEN,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 List-Id: Pushed to r13-2165. 在 2022/8/20 下午5:18, Huacai Chen 写道: > Hi, Lulu, > > I think there is a typo in your subject line. > > Huacai > > On Sat, Aug 20, 2022 at 5:05 PM Lulu Cheng wrote: >> The function jump instruction in normal mode is 'bl', >> so the scope of the function jump is +-128MB. >> >> Now we've added support for 'medium' mode, this mode is >> to complete the function jump through two instructions: >> pcalau12i + jirl >> So in this mode the function jump range is increased to +-2GB. >> >> Compared with 'normal' mode, 'medium' mode only affects the >> jump range of functions. >> >> gcc/ChangeLog: >> >> * config/loongarch/genopts/loongarch-strings: Support code model medium. >> * config/loongarch/genopts/loongarch.opt.in: Likewise. >> * config/loongarch/loongarch-def.c: Likewise. >> * config/loongarch/loongarch-def.h (CMODEL_LARGE): Likewise. >> (CMODEL_EXTREME): Likewise. >> (N_CMODEL_TYPES): Likewise. >> (CMODEL_MEDIUM): Likewise. >> * config/loongarch/loongarch-opts.cc: Likewise. >> * config/loongarch/loongarch-opts.h (TARGET_CMODEL_MEDIUM): Likewise. >> * config/loongarch/loongarch-str.h (STR_CMODEL_MEDIUM): Likewise. >> * config/loongarch/loongarch.cc (loongarch_call_tls_get_addr): >> Tls symbol Loading support medium mode. >> (loongarch_legitimize_call_address): When medium mode, make a symbolic >> jump with two instructions. >> (loongarch_option_override_internal): Support medium. >> * config/loongarch/loongarch.md (@pcalau12i): New template. >> (@sibcall_internal_1): New function call templates added to support >> medium mode. >> (@sibcall_value_internal_1): Likewise. >> (@sibcall_value_multiple_internal_1): Likewise. >> (@call_internal_1): Likewise. >> (@call_value_internal_1): Likewise. >> (@call_value_multiple_internal_1): Likewise. >> * config/loongarch/loongarch.opt: Support medium. >> * config/loongarch/predicates.md: Add processing about medium mode. >> * doc/invoke.texi: Document for '-mcmodel=medium'. >> >> gcc/testsuite/ChangeLog: >> >> * gcc.target/loongarch/func-call-medium-1.c: New test. >> * gcc.target/loongarch/func-call-medium-2.c: New test. >> * gcc.target/loongarch/func-call-medium-3.c: New test. >> * gcc.target/loongarch/func-call-medium-4.c: New test. >> * gcc.target/loongarch/func-call-medium-5.c: New test. >> * gcc.target/loongarch/func-call-medium-6.c: New test. >> * gcc.target/loongarch/func-call-medium-7.c: New test. >> * gcc.target/loongarch/func-call-medium-8.c: New test. >> * gcc.target/loongarch/tls-gd-noplt.c: Add compile parameter '-mexplicit-relocs'. >> --- >> .../loongarch/genopts/loongarch-strings | 1 + >> gcc/config/loongarch/genopts/loongarch.opt.in | 3 + >> gcc/config/loongarch/loongarch-def.c | 1 + >> gcc/config/loongarch/loongarch-def.h | 7 +- >> gcc/config/loongarch/loongarch-opts.cc | 15 ++- >> gcc/config/loongarch/loongarch-opts.h | 1 + >> gcc/config/loongarch/loongarch-str.h | 1 + >> gcc/config/loongarch/loongarch.cc | 123 +++++++++++++---- >> gcc/config/loongarch/loongarch.md | 125 +++++++++++++++++- >> gcc/config/loongarch/loongarch.opt | 3 + >> gcc/config/loongarch/predicates.md | 15 ++- >> gcc/doc/invoke.texi | 3 + >> .../gcc.target/loongarch/func-call-medium-1.c | 41 ++++++ >> .../gcc.target/loongarch/func-call-medium-2.c | 41 ++++++ >> .../gcc.target/loongarch/func-call-medium-3.c | 41 ++++++ >> .../gcc.target/loongarch/func-call-medium-4.c | 41 ++++++ >> .../gcc.target/loongarch/func-call-medium-5.c | 42 ++++++ >> .../gcc.target/loongarch/func-call-medium-6.c | 42 ++++++ >> .../gcc.target/loongarch/func-call-medium-7.c | 43 ++++++ >> .../gcc.target/loongarch/func-call-medium-8.c | 42 ++++++ >> .../gcc.target/loongarch/tls-gd-noplt.c | 4 +- >> 21 files changed, 595 insertions(+), 40 deletions(-) >> create mode 100644 gcc/testsuite/gcc.target/loongarch/func-call-medium-1.c >> create mode 100644 gcc/testsuite/gcc.target/loongarch/func-call-medium-2.c >> create mode 100644 gcc/testsuite/gcc.target/loongarch/func-call-medium-3.c >> create mode 100644 gcc/testsuite/gcc.target/loongarch/func-call-medium-4.c >> create mode 100644 gcc/testsuite/gcc.target/loongarch/func-call-medium-5.c >> create mode 100644 gcc/testsuite/gcc.target/loongarch/func-call-medium-6.c >> create mode 100644 gcc/testsuite/gcc.target/loongarch/func-call-medium-7.c >> create mode 100644 gcc/testsuite/gcc.target/loongarch/func-call-medium-8.c >> >> diff --git a/gcc/config/loongarch/genopts/loongarch-strings b/gcc/config/loongarch/genopts/loongarch-strings >> index cb88ed56b68..44ebb7ab10b 100644 >> --- a/gcc/config/loongarch/genopts/loongarch-strings >> +++ b/gcc/config/loongarch/genopts/loongarch-strings >> @@ -54,5 +54,6 @@ OPTSTR_CMODEL cmodel >> STR_CMODEL_NORMAL normal >> STR_CMODEL_TINY tiny >> STR_CMODEL_TS tiny-static >> +STR_CMODEL_MEDIUM medium >> STR_CMODEL_LARGE large >> STR_CMODEL_EXTREME extreme >> diff --git a/gcc/config/loongarch/genopts/loongarch.opt.in b/gcc/config/loongarch/genopts/loongarch.opt.in >> index a571b6b7524..ebdd9538d48 100644 >> --- a/gcc/config/loongarch/genopts/loongarch.opt.in >> +++ b/gcc/config/loongarch/genopts/loongarch.opt.in >> @@ -172,6 +172,9 @@ Enum(cmodel) String(@@STR_CMODEL_TINY@@) Value(CMODEL_TINY) >> EnumValue >> Enum(cmodel) String(@@STR_CMODEL_TS@@) Value(CMODEL_TINY_STATIC) >> >> +EnumValue >> +Enum(cmodel) String(@@STR_CMODEL_MEDIUM@@) Value(CMODEL_MEDIUM) >> + >> EnumValue >> Enum(cmodel) String(@@STR_CMODEL_LARGE@@) Value(CMODEL_LARGE) >> >> diff --git a/gcc/config/loongarch/loongarch-def.c b/gcc/config/loongarch/loongarch-def.c >> index c8769b7d65e..cbf995d81b5 100644 >> --- a/gcc/config/loongarch/loongarch-def.c >> +++ b/gcc/config/loongarch/loongarch-def.c >> @@ -152,6 +152,7 @@ loongarch_cmodel_strings[] = { >> [CMODEL_NORMAL] = STR_CMODEL_NORMAL, >> [CMODEL_TINY] = STR_CMODEL_TINY, >> [CMODEL_TINY_STATIC] = STR_CMODEL_TS, >> + [CMODEL_MEDIUM] = STR_CMODEL_MEDIUM, >> [CMODEL_LARGE] = STR_CMODEL_LARGE, >> [CMODEL_EXTREME] = STR_CMODEL_EXTREME, >> }; >> diff --git a/gcc/config/loongarch/loongarch-def.h b/gcc/config/loongarch/loongarch-def.h >> index c2c35b6ba5c..b5985f07052 100644 >> --- a/gcc/config/loongarch/loongarch-def.h >> +++ b/gcc/config/loongarch/loongarch-def.h >> @@ -82,9 +82,10 @@ extern const char* loongarch_cmodel_strings[]; >> #define CMODEL_NORMAL 0 >> #define CMODEL_TINY 1 >> #define CMODEL_TINY_STATIC 2 >> -#define CMODEL_LARGE 3 >> -#define CMODEL_EXTREME 4 >> -#define N_CMODEL_TYPES 5 >> +#define CMODEL_MEDIUM 3 >> +#define CMODEL_LARGE 4 >> +#define CMODEL_EXTREME 5 >> +#define N_CMODEL_TYPES 6 >> >> /* enum switches */ >> /* The "SW_" codes represent command-line switches (options that >> diff --git a/gcc/config/loongarch/loongarch-opts.cc b/gcc/config/loongarch/loongarch-opts.cc >> index 2ae89f23443..e13eafb5882 100644 >> --- a/gcc/config/loongarch/loongarch-opts.cc >> +++ b/gcc/config/loongarch/loongarch-opts.cc >> @@ -376,11 +376,24 @@ fallback: >> >> /* 5. Target code model */ >> t.cmodel = constrained.cmodel ? opt_cmodel : CMODEL_NORMAL; >> - if (t.cmodel != CMODEL_NORMAL && t.cmodel != CMODEL_EXTREME) >> + >> + switch (t.cmodel) >> { >> + case CMODEL_TINY: >> + case CMODEL_TINY_STATIC: >> + case CMODEL_LARGE: >> warning (0, "%qs is not supported, now cmodel is set to %qs", >> loongarch_cmodel_strings[t.cmodel], "normal"); >> t.cmodel = CMODEL_NORMAL; >> + break; >> + >> + case CMODEL_NORMAL: >> + case CMODEL_MEDIUM: >> + case CMODEL_EXTREME: >> + break; >> + >> + default: >> + gcc_unreachable (); >> } >> >> /* Cleanup and return. */ >> diff --git a/gcc/config/loongarch/loongarch-opts.h b/gcc/config/loongarch/loongarch-opts.h >> index da24ecd2b50..3523a4cf78d 100644 >> --- a/gcc/config/loongarch/loongarch-opts.h >> +++ b/gcc/config/loongarch/loongarch-opts.h >> @@ -46,6 +46,7 @@ loongarch_config_target (struct loongarch_target *target, >> #define TARGET_CMODEL_NORMAL (la_target.cmodel == CMODEL_NORMAL) >> #define TARGET_CMODEL_TINY (la_target.cmodel == CMODEL_TINY) >> #define TARGET_CMODEL_TINY_STATIC (la_target.cmodel == CMODEL_TINY_STATIC) >> +#define TARGET_CMODEL_MEDIUM (la_target.cmodel == CMODEL_MEDIUM) >> #define TARGET_CMODEL_LARGE (la_target.cmodel == CMODEL_LARGE) >> #define TARGET_CMODEL_EXTREME (la_target.cmodel == CMODEL_EXTREME) >> >> diff --git a/gcc/config/loongarch/loongarch-str.h b/gcc/config/loongarch/loongarch-str.h >> index 0e8889b8c96..9f1b0989c82 100644 >> --- a/gcc/config/loongarch/loongarch-str.h >> +++ b/gcc/config/loongarch/loongarch-str.h >> @@ -53,6 +53,7 @@ along with GCC; see the file COPYING3. If not see >> #define STR_CMODEL_NORMAL "normal" >> #define STR_CMODEL_TINY "tiny" >> #define STR_CMODEL_TS "tiny-static" >> +#define STR_CMODEL_MEDIUM "medium" >> #define STR_CMODEL_LARGE "large" >> #define STR_CMODEL_EXTREME "extreme" >> >> diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc >> index 207ac2762c6..16fd4acc970 100644 >> --- a/gcc/config/loongarch/loongarch.cc >> +++ b/gcc/config/loongarch/loongarch.cc >> @@ -2461,44 +2461,96 @@ 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, >> - const0_rtx)); >> - else >> { >> - rtx dest = gen_reg_rtx (Pmode); >> - >> - if (TARGET_CMODEL_EXTREME) >> + switch (la_opt_cmodel) >> { >> - gcc_assert (TARGET_EXPLICIT_RELOCS); >> + case CMODEL_NORMAL: >> + insn = emit_call_insn (gen_call_value_internal (v0, >> + loongarch_tls_symbol, >> + const0_rtx)); >> + break; >> >> - rtx tmp1 = gen_reg_rtx (Pmode); >> - rtx high = gen_reg_rtx (Pmode); >> + case CMODEL_MEDIUM: >> + { >> + rtx reg = gen_reg_rtx (Pmode); >> + if (TARGET_EXPLICIT_RELOCS) >> + { >> + emit_insn (gen_pcalau12i (Pmode, reg, loongarch_tls_symbol)); >> + rtx call = gen_call_value_internal_1 (Pmode, v0, reg, >> + loongarch_tls_symbol, >> + const0_rtx); >> + insn = emit_call_insn (call); >> + } >> + else >> + { >> + emit_move_insn (reg, loongarch_tls_symbol); >> + insn = emit_call_insn (gen_call_value_internal (v0, >> + reg, >> + const0_rtx)); >> + } >> + break; >> + } >> >> - 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))); >> + /* code model extreme not support plt. */ >> + case CMODEL_EXTREME: >> + case CMODEL_LARGE: >> + case CMODEL_TINY: >> + case CMODEL_TINY_STATIC: >> + default: >> + gcc_unreachable (); >> } >> - else >> + } >> + else >> + { >> + rtx dest = gen_reg_rtx (Pmode); >> + >> + switch (la_opt_cmodel) >> { >> - if (TARGET_EXPLICIT_RELOCS) >> + case CMODEL_NORMAL: >> + case CMODEL_MEDIUM: >> + { >> + 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); >> + break; >> + } >> + >> + case 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)); >> - emit_insn (gen_ld_from_got (Pmode, dest, high, >> - 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 >> - loongarch_emit_move (dest, loongarch_tls_symbol); >> + break; >> + >> + case CMODEL_LARGE: >> + case CMODEL_TINY: >> + case CMODEL_TINY_STATIC: >> + default: >> + gcc_unreachable (); >> } >> + >> insn = emit_call_insn (gen_call_value_internal (v0, dest, const0_rtx)); >> } >> >> @@ -2618,6 +2670,24 @@ loongarch_legitimize_call_address (rtx addr) >> loongarch_emit_move (reg, addr); >> return reg; >> } >> + >> + enum loongarch_symbol_type symbol_type = loongarch_classify_symbol (addr); >> + >> + /* Split function call insn 'bl sym' or 'bl %plt(sym)' to : >> + pcalau12i $rd, %pc_hi20(sym) >> + jr $rd, %pc_lo12(sym). */ >> + >> + if (TARGET_CMODEL_MEDIUM >> + && TARGET_EXPLICIT_RELOCS >> + && (SYMBOL_REF_P (addr) || LABEL_REF_P (addr)) >> + && (symbol_type == SYMBOL_PCREL >> + || (symbol_type == SYMBOL_GOT_DISP && flag_plt))) >> + { >> + rtx reg = gen_reg_rtx (Pmode); >> + emit_insn (gen_pcalau12i (Pmode, reg, addr)); >> + return gen_rtx_LO_SUM (Pmode, reg, addr); >> + } >> + >> return addr; >> } >> >> @@ -5996,6 +6066,7 @@ loongarch_option_override_internal (struct gcc_options *opts) >> break; >> >> case CMODEL_TINY_STATIC: >> + case CMODEL_MEDIUM: >> case CMODEL_NORMAL: >> case CMODEL_TINY: >> case CMODEL_LARGE: >> diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md >> index 8fc10444c2a..3787fd8230f 100644 >> --- a/gcc/config/loongarch/loongarch.md >> +++ b/gcc/config/loongarch/loongarch.md >> @@ -59,11 +59,15 @@ (define_c_enum "unspec" [ >> UNSPEC_CRCC >> >> UNSPEC_LOAD_FROM_GOT >> + UNSPEC_PCALAU12I >> UNSPEC_ORI_L_LO12 >> UNSPEC_LUI_L_HI20 >> UNSPEC_LUI_H_LO20 >> UNSPEC_LUI_H_HI12 >> UNSPEC_TLS_LOW >> + >> + UNSPEC_SIBCALL_VALUE_MULTIPLE_INTERNAL_1 >> + UNSPEC_CALL_VALUE_MULTIPLE_INTERNAL_1 >> ]) >> >> (define_c_enum "unspecv" [ >> @@ -1946,6 +1950,14 @@ (define_insn "@lui_l_hi20" >> [(set_attr "type" "move")] >> ) >> >> +(define_insn "@pcalau12i" >> + [(set (match_operand:P 0 "register_operand" "=j") >> + (unspec:P [(match_operand:P 1 "symbolic_operand" "")] >> + UNSPEC_PCALAU12I))] >> + "" >> + "pcalau12i\t%0,%%pc_hi20(%1)" >> + [(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") >> @@ -2877,7 +2889,12 @@ (define_expand "sibcall" >> { >> rtx target = loongarch_legitimize_call_address (XEXP (operands[0], 0)); >> >> - emit_call_insn (gen_sibcall_internal (target, operands[1])); >> + if (GET_CODE (target) == LO_SUM) >> + emit_call_insn (gen_sibcall_internal_1 (Pmode, XEXP (target, 0), >> + XEXP (target, 1), >> + operands[1])); >> + else >> + emit_call_insn (gen_sibcall_internal (target, operands[1])); >> DONE; >> }) >> >> @@ -2891,6 +2908,14 @@ (define_insn "sibcall_internal" >> b\t%%plt(%0)" >> [(set_attr "jirl" "indirect,direct,direct")]) >> >> +(define_insn "@sibcall_internal_1" >> + [(call (mem:P (lo_sum:P (match_operand:P 0 "register_operand" "j") >> + (match_operand:P 1 "symbolic_operand" ""))) >> + (match_operand 2 "" ""))] >> + "SIBLING_CALL_P (insn) && TARGET_CMODEL_MEDIUM" >> + "jirl\t$r0,%0,%%pc_lo12(%1)" >> + [(set_attr "jirl" "indirect")]) >> + >> (define_expand "sibcall_value" >> [(parallel [(set (match_operand 0 "") >> (call (match_operand 1 "") >> @@ -2906,7 +2931,14 @@ (define_expand "sibcall_value" >> rtx arg1 = XEXP (XVECEXP (operands[0],0, 0), 0); >> rtx arg2 = XEXP (XVECEXP (operands[0],0, 1), 0); >> >> - emit_call_insn (gen_sibcall_value_multiple_internal (arg1, target, >> + if (GET_CODE (target) == LO_SUM) >> + emit_call_insn (gen_sibcall_value_multiple_internal_1 (Pmode, arg1, >> + XEXP (target, 0), >> + XEXP (target, 1), >> + operands[2], >> + arg2)); >> + else >> + emit_call_insn (gen_sibcall_value_multiple_internal (arg1, target, >> operands[2], >> arg2)); >> } >> @@ -2916,7 +2948,13 @@ (define_expand "sibcall_value" >> if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) == 1) >> operands[0] = XEXP (XVECEXP (operands[0], 0, 0), 0); >> >> - emit_call_insn (gen_sibcall_value_internal (operands[0], target, >> + if (GET_CODE (target) == LO_SUM) >> + emit_call_insn (gen_sibcall_value_internal_1 (Pmode, operands[0], >> + XEXP (target, 0), >> + XEXP (target, 1), >> + operands[2])); >> + else >> + emit_call_insn (gen_sibcall_value_internal (operands[0], target, >> operands[2])); >> } >> DONE; >> @@ -2933,6 +2971,15 @@ (define_insn "sibcall_value_internal" >> b\t%%plt(%1)" >> [(set_attr "jirl" "indirect,direct,direct")]) >> >> +(define_insn "@sibcall_value_internal_1" >> + [(set (match_operand 0 "register_operand" "") >> + (call (mem:P (lo_sum:P (match_operand:P 1 "register_operand" "j") >> + (match_operand:P 2 "symbolic_operand" ""))) >> + (match_operand 3 "" "")))] >> + "SIBLING_CALL_P (insn) && TARGET_CMODEL_MEDIUM" >> + "jirl\t$r0,%1,%%pc_lo12(%2)" >> + [(set_attr "jirl" "indirect")]) >> + >> (define_insn "sibcall_value_multiple_internal" >> [(set (match_operand 0 "register_operand" "") >> (call (mem:SI (match_operand 1 "call_insn_operand" "j,c,b")) >> @@ -2947,6 +2994,21 @@ (define_insn "sibcall_value_multiple_internal" >> b\t%%plt(%1)" >> [(set_attr "jirl" "indirect,direct,direct")]) >> >> +(define_insn "@sibcall_value_multiple_internal_1" >> + [(set (match_operand 0 "register_operand" "") >> + (call (mem:P (unspec:P [(match_operand:P 1 "register_operand" "j") >> + (match_operand:P 2 "symbolic_operand" "")] >> + UNSPEC_SIBCALL_VALUE_MULTIPLE_INTERNAL_1)) >> + (match_operand 3 "" ""))) >> + (set (match_operand 4 "register_operand" "") >> + (call (mem:P (unspec:P [(match_dup 1) >> + (match_dup 2)] >> + UNSPEC_SIBCALL_VALUE_MULTIPLE_INTERNAL_1)) >> + (match_dup 3)))] >> + "SIBLING_CALL_P (insn) && TARGET_CMODEL_MEDIUM" >> + "jirl\t$r0,%1,%%pc_lo12(%2)" >> + [(set_attr "jirl" "indirect")]) >> + >> (define_expand "call" >> [(parallel [(call (match_operand 0 "") >> (match_operand 1 "")) >> @@ -2956,7 +3018,11 @@ (define_expand "call" >> { >> rtx target = loongarch_legitimize_call_address (XEXP (operands[0], 0)); >> >> - emit_call_insn (gen_call_internal (target, operands[1])); >> + if (GET_CODE (target) == LO_SUM) >> + emit_call_insn (gen_call_internal_1 (Pmode, XEXP (target, 0), >> + XEXP (target, 1), operands[1])); >> + else >> + emit_call_insn (gen_call_internal (target, operands[1])); >> DONE; >> }) >> >> @@ -2971,6 +3037,15 @@ (define_insn "call_internal" >> bl\t%%plt(%0)" >> [(set_attr "jirl" "indirect,direct,direct")]) >> >> +(define_insn "@call_internal_1" >> + [(call (mem:P (lo_sum:P (match_operand:P 0 "register_operand" "j") >> + (match_operand:P 1 "symbolic_operand" ""))) >> + (match_operand 2 "" "")) >> + (clobber (reg:SI RETURN_ADDR_REGNUM))] >> + "TARGET_CMODEL_MEDIUM" >> + "jirl\t$r1,%0,%%pc_lo12(%1)" >> + [(set_attr "jirl" "indirect")]) >> + >> (define_expand "call_value" >> [(parallel [(set (match_operand 0 "") >> (call (match_operand 1 "") >> @@ -2985,7 +3060,13 @@ (define_expand "call_value" >> rtx arg1 = XEXP (XVECEXP (operands[0], 0, 0), 0); >> rtx arg2 = XEXP (XVECEXP (operands[0], 0, 1), 0); >> >> - emit_call_insn (gen_call_value_multiple_internal (arg1, target, >> + if (GET_CODE (target) == LO_SUM) >> + emit_call_insn (gen_call_value_multiple_internal_1 (Pmode, arg1, >> + XEXP (target, 0), >> + XEXP (target, 1), >> + operands[2], arg2)); >> + else >> + emit_call_insn (gen_call_value_multiple_internal (arg1, target, >> operands[2], arg2)); >> } >> else >> @@ -2994,7 +3075,13 @@ (define_expand "call_value" >> if (GET_CODE (operands[0]) == PARALLEL && XVECLEN (operands[0], 0) == 1) >> operands[0] = XEXP (XVECEXP (operands[0], 0, 0), 0); >> >> - emit_call_insn (gen_call_value_internal (operands[0], target, >> + if (GET_CODE (target) == LO_SUM) >> + emit_call_insn (gen_call_value_internal_1 (Pmode, operands[0], >> + XEXP (target, 0), >> + XEXP (target, 1), >> + operands[2])); >> + else >> + emit_call_insn (gen_call_value_internal (operands[0], target, >> operands[2])); >> } >> DONE; >> @@ -3012,6 +3099,16 @@ (define_insn "call_value_internal" >> bl\t%%plt(%1)" >> [(set_attr "jirl" "indirect,direct,direct")]) >> >> +(define_insn "@call_value_internal_1" >> + [(set (match_operand 0 "register_operand" "") >> + (call (mem:P (lo_sum:P (match_operand:P 1 "register_operand" "j") >> + (match_operand:P 2 "symbolic_operand" ""))) >> + (match_operand 3 "" ""))) >> + (clobber (reg:SI RETURN_ADDR_REGNUM))] >> + "TARGET_CMODEL_MEDIUM" >> + "jirl\t$r1,%1,%%pc_lo12(%2)" >> + [(set_attr "jirl" "indirect")]) >> + >> (define_insn "call_value_multiple_internal" >> [(set (match_operand 0 "register_operand" "") >> (call (mem:SI (match_operand 1 "call_insn_operand" "e,c,b")) >> @@ -3027,6 +3124,22 @@ (define_insn "call_value_multiple_internal" >> bl\t%%plt(%1)" >> [(set_attr "jirl" "indirect,direct,direct")]) >> >> +(define_insn "@call_value_multiple_internal_1" >> + [(set (match_operand 0 "register_operand" "") >> + (call (mem:P (unspec:P [(match_operand:P 1 "register_operand" "j") >> + (match_operand:P 2 "symbolic_operand" "")] >> + UNSPEC_CALL_VALUE_MULTIPLE_INTERNAL_1)) >> + (match_operand 3 "" ""))) >> + (set (match_operand 4 "register_operand" "") >> + (call (mem:P (unspec:P [(match_dup 1) >> + (match_dup 2)] >> + UNSPEC_CALL_VALUE_MULTIPLE_INTERNAL_1)) >> + (match_dup 3))) >> + (clobber (reg:SI RETURN_ADDR_REGNUM))] >> + "TARGET_CMODEL_MEDIUM" >> + "jirl\t$r1,%1,%%pc_lo12(%2)" >> + [(set_attr "jirl" "indirect")]) >> + >> >> ;; Call subroutine returning any type. >> (define_expand "untyped_call" >> diff --git a/gcc/config/loongarch/loongarch.opt b/gcc/config/loongarch/loongarch.opt >> index 9df7e187283..6395234218b 100644 >> --- a/gcc/config/loongarch/loongarch.opt >> +++ b/gcc/config/loongarch/loongarch.opt >> @@ -179,6 +179,9 @@ Enum(cmodel) String(tiny) Value(CMODEL_TINY) >> EnumValue >> Enum(cmodel) String(tiny-static) Value(CMODEL_TINY_STATIC) >> >> +EnumValue >> +Enum(cmodel) String(medium) Value(CMODEL_MEDIUM) >> + >> EnumValue >> Enum(cmodel) String(large) Value(CMODEL_LARGE) >> >> diff --git a/gcc/config/loongarch/predicates.md b/gcc/config/loongarch/predicates.md >> index e38c6fbdd5f..8bd0c1376c9 100644 >> --- a/gcc/config/loongarch/predicates.md >> +++ b/gcc/config/loongarch/predicates.md >> @@ -123,16 +123,27 @@ (define_predicate "const_call_insn_operand" >> if (offset != const0_rtx) >> return false; >> >> + /* When compiling with '-mcmodel=medium -mexplicit-relocs' >> + symbols are splited in loongarch_legitimize_call_address. >> + >> + When compiling with '-mcmodel=medium -mno-explicit-relocs', >> + first obtain the symbolic address or the address of the >> + plt entry, and then perform an indirect jump, so return false. */ >> + >> switch (symbol_type) >> { >> case SYMBOL_PCREL: >> - if (TARGET_CMODEL_EXTREME) >> + if (TARGET_CMODEL_EXTREME >> + || (TARGET_CMODEL_MEDIUM && !TARGET_EXPLICIT_RELOCS)) >> return false; >> else >> return 1; >> >> case SYMBOL_GOT_DISP: >> - if (TARGET_CMODEL_EXTREME || !flag_plt) >> + if (TARGET_CMODEL_EXTREME >> + || !flag_plt >> + || (flag_plt && TARGET_CMODEL_MEDIUM >> + && !TARGET_EXPLICIT_RELOCS)) >> return false; >> else >> return 1; >> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi >> index 8712bc25e3c..60702a52c8f 100644 >> --- a/gcc/doc/invoke.texi >> +++ b/gcc/doc/invoke.texi >> @@ -25084,6 +25084,9 @@ Set the code model to one of: >> The text segment must be within 128MB addressing space. The data segment must >> be within 2GB addressing space. >> >> +@item medium >> +The text segment and data segment must be within 2GB addressing space. >> + >> @item large (Not implemented yet) >> >> @item extreme >> diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-medium-1.c b/gcc/testsuite/gcc.target/loongarch/func-call-medium-1.c >> new file mode 100644 >> index 00000000000..276d73e5ee8 >> --- /dev/null >> +++ b/gcc/testsuite/gcc.target/loongarch/func-call-medium-1.c >> @@ -0,0 +1,41 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-mabi=lp64d -O0 -fpic -fplt -mno-explicit-relocs -mcmodel=medium" } */ >> +/* { 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:.*la\.local\t.*l\n\tjirl" } } */ >> +/* { dg-final { scan-assembler "test3:.*la\.global\t.*\_\_tls\_get\_addr" } } */ >> + >> +extern void g (void); >> +void >> +f (void) >> +{} >> + >> +static void >> +l (void) >> +{} >> + >> +void >> +test (void) >> +{ >> + g (); >> +} >> + >> +void >> +test1 (void) >> +{ >> + f (); >> +} >> + >> +void >> +test2 (void) >> +{ >> + l (); >> +} >> + >> +__attribute__ ((tls_model ("global-dynamic"))) __thread int a; >> + >> +void >> +test3 (void) >> +{ >> + a = 10; >> +} >> diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-medium-2.c b/gcc/testsuite/gcc.target/loongarch/func-call-medium-2.c >> new file mode 100644 >> index 00000000000..237821c066b >> --- /dev/null >> +++ b/gcc/testsuite/gcc.target/loongarch/func-call-medium-2.c >> @@ -0,0 +1,41 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-mabi=lp64d -O0 -fno-pic -fplt -mno-explicit-relocs -mcmodel=medium" } */ >> +/* { dg-final { scan-assembler "test:.*la\.global\t.*g\n\tjirl" } } */ >> +/* { dg-final { scan-assembler "test1:.*la\.local\t.*f\n\tjirl" } } */ >> +/* { dg-final { scan-assembler "test2:.*la\.local\t.*l\n\tjirl" } } */ >> +/* { dg-final { scan-assembler "test3:.*la\.global\t.*\_\_tls\_get\_addr" } } */ >> + >> +extern void g (void); >> +void >> +f (void) >> +{} >> + >> +static void >> +l (void) >> +{} >> + >> +void >> +test (void) >> +{ >> + g (); >> +} >> + >> +void >> +test1 (void) >> +{ >> + f (); >> +} >> + >> +void >> +test2 (void) >> +{ >> + l (); >> +} >> + >> +__attribute__ ((tls_model ("global-dynamic"))) __thread int a; >> + >> +void >> +test3 (void) >> +{ >> + a = 10; >> +} >> diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-medium-3.c b/gcc/testsuite/gcc.target/loongarch/func-call-medium-3.c >> new file mode 100644 >> index 00000000000..9a6e16103bc >> --- /dev/null >> +++ b/gcc/testsuite/gcc.target/loongarch/func-call-medium-3.c >> @@ -0,0 +1,41 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt -mno-explicit-relocs -mcmodel=medium" } */ >> +/* { 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:.*la\.local\t.*l\n\tjirl" } } */ >> +/* { dg-final { scan-assembler "test3:.*la\.global\t.*\_\_tls\_get\_addr" } } */ >> + >> +extern void g (void); >> +void >> +f (void) >> +{} >> + >> +static void >> +l (void) >> +{} >> + >> +void >> +test (void) >> +{ >> + g (); >> +} >> + >> +void >> +test1 (void) >> +{ >> + f (); >> +} >> + >> +void >> +test2 (void) >> +{ >> + l (); >> +} >> + >> +__attribute__ ((tls_model ("global-dynamic"))) __thread int a; >> + >> +void >> +test3 (void) >> +{ >> + a = 10; >> +} >> diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-medium-4.c b/gcc/testsuite/gcc.target/loongarch/func-call-medium-4.c >> new file mode 100644 >> index 00000000000..2577e345239 >> --- /dev/null >> +++ b/gcc/testsuite/gcc.target/loongarch/func-call-medium-4.c >> @@ -0,0 +1,41 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt -mno-explicit-relocs -mcmodel=medium" } */ >> +/* { dg-final { scan-assembler "test:.*la\.global\t.*g\n\tjirl" } } */ >> +/* { dg-final { scan-assembler "test1:.*la\.local\t.*f\n\tjirl" } } */ >> +/* { dg-final { scan-assembler "test2:.*la\.local\t.*l\n\tjirl" } } */ >> +/* { dg-final { scan-assembler "test3:.*la\.global\t.*\_\_tls\_get\_addr" } } */ >> + >> +extern void g (void); >> +void >> +f (void) >> +{} >> + >> +static void >> +l (void) >> +{} >> + >> +void >> +test (void) >> +{ >> + g (); >> +} >> + >> +void >> +test1 (void) >> +{ >> + f (); >> +} >> + >> +void >> +test2 (void) >> +{ >> + l (); >> +} >> + >> +__attribute__ ((tls_model ("global-dynamic"))) __thread int a; >> + >> +void >> +test3 (void) >> +{ >> + a = 10; >> +} >> diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-medium-5.c b/gcc/testsuite/gcc.target/loongarch/func-call-medium-5.c >> new file mode 100644 >> index 00000000000..d70b6ea4663 >> --- /dev/null >> +++ b/gcc/testsuite/gcc.target/loongarch/func-call-medium-5.c >> @@ -0,0 +1,42 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-mabi=lp64d -O0 -fpic -fplt -mexplicit-relocs -mcmodel=medium" } */ >> +/* { dg-final { scan-assembler "test:.*pcalau12i.*%pc_hi20\\(g\\)\n\tjirl.*pc_lo12\\(g\\)" } } */ >> +/* { dg-final { scan-assembler "test1:.*pcalau12i.*%pc_hi20\\(f\\)\n\tjirl.*%pc_lo12\\(f\\)" } } */ >> +/* { dg-final { scan-assembler "test2:.*pcalau12i.*%pc_hi20\\(l\\)\n\tjirl.*%pc_lo12\\(l\\)" } } */ >> +/* { dg-final { scan-assembler "test3:.*pcalau12i.*%pc_hi20\\(__tls_get_addr\\)\n\t.*\n\tjirl.*%pc_lo12\\(__tls_get_addr\\)" } } */ >> + >> +extern void g (void); >> + >> +void >> +f (void) >> +{} >> + >> +static void >> +l (void) >> +{} >> + >> +void >> +test (void) >> +{ >> + g (); >> +} >> + >> +void >> +test1 (void) >> +{ >> + f (); >> +} >> + >> +void >> +test2 (void) >> +{ >> + l (); >> +} >> + >> +__attribute__ ((tls_model ("global-dynamic"))) __thread int a; >> + >> +void >> +test3 (void) >> +{ >> + a = 10; >> +} >> diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-medium-6.c b/gcc/testsuite/gcc.target/loongarch/func-call-medium-6.c >> new file mode 100644 >> index 00000000000..f963a99441a >> --- /dev/null >> +++ b/gcc/testsuite/gcc.target/loongarch/func-call-medium-6.c >> @@ -0,0 +1,42 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-mabi=lp64d -O0 -fno-pic -fplt -mexplicit-relocs -mcmodel=medium" } */ >> +/* { dg-final { scan-assembler "test:.*pcalau12i.*%pc_hi20\\(g\\)\n\tjirl.*pc_lo12\\(g\\)" } } */ >> +/* { dg-final { scan-assembler "test1:.*pcalau12i.*%pc_hi20\\(f\\)\n\tjirl.*%pc_lo12\\(f\\)" } } */ >> +/* { dg-final { scan-assembler "test2:.*pcalau12i.*%pc_hi20\\(l\\)\n\tjirl.*%pc_lo12\\(l\\)" } } */ >> +/* { dg-final { scan-assembler "test3:.*pcalau12i.*%pc_hi20\\(__tls_get_addr\\)\n\t.*\n\tjirl.*%pc_lo12\\(__tls_get_addr\\)" } } */ >> + >> +extern void g (void); >> + >> +void >> +f (void) >> +{} >> + >> +static void >> +l (void) >> +{} >> + >> +void >> +test (void) >> +{ >> + g (); >> +} >> + >> +void >> +test1 (void) >> +{ >> + f (); >> +} >> + >> +void >> +test2 (void) >> +{ >> + l (); >> +} >> + >> +__attribute__ ((tls_model ("global-dynamic"))) __thread int a; >> + >> +void >> +test3 (void) >> +{ >> + a = 10; >> +} >> diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-medium-7.c b/gcc/testsuite/gcc.target/loongarch/func-call-medium-7.c >> new file mode 100644 >> index 00000000000..f2818b2da76 >> --- /dev/null >> +++ b/gcc/testsuite/gcc.target/loongarch/func-call-medium-7.c >> @@ -0,0 +1,43 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt -mexplicit-relocs -mcmodel=medium" } */ >> +/* { 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:.*pcalau12i\t.*%pc_hi20\\(l\\)\n\tjirl.*%pc_lo12\\(l\\)" } } */ >> +/* { dg-final { scan-assembler "test3:.*pcalau12i.*%got_pc_hi20\\(__tls_get_addr\\)\n\tld\.d.*%got_pc_lo12\\(__tls_get_addr\\)" } } */ >> + >> + >> +extern void g (void); >> + >> +void >> +f (void) >> +{} >> + >> +static void >> +l (void) >> +{} >> + >> +void >> +test (void) >> +{ >> + g (); >> +} >> + >> +void >> +test1 (void) >> +{ >> + f (); >> +} >> + >> +void >> +test2 (void) >> +{ >> + l (); >> +} >> + >> +__attribute__ ((tls_model ("global-dynamic"))) __thread int a; >> + >> +void >> +test3 (void) >> +{ >> + a = 10; >> +} >> diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-medium-8.c b/gcc/testsuite/gcc.target/loongarch/func-call-medium-8.c >> new file mode 100644 >> index 00000000000..7fa873d84bb >> --- /dev/null >> +++ b/gcc/testsuite/gcc.target/loongarch/func-call-medium-8.c >> @@ -0,0 +1,42 @@ >> +/* { dg-do compile } */ >> +/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt -mexplicit-relocs -mcmodel=medium" } */ >> +/* { 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.*%pc_hi20\\(f\\)\n\tjirl.*%pc_lo12\\(f\\)" } } */ >> +/* { dg-final { scan-assembler "test2:.*pcalau12i\t.*%pc_hi20\\(l\\)\n\tjirl.*%pc_lo12\\(l\\)" } } */ >> +/* { dg-final { scan-assembler "test3:.*pcalau12i.*%got_pc_hi20\\(__tls_get_addr\\)\n\tld\.d.*%got_pc_lo12\\(__tls_get_addr\\)" } } */ >> + >> +extern void g (void); >> + >> +void >> +f (void) >> +{} >> + >> +static void >> +l (void) >> +{} >> + >> +void >> +test (void) >> +{ >> + g (); >> +} >> + >> +void >> +test1 (void) >> +{ >> + f (); >> +} >> + >> +void >> +test2 (void) >> +{ >> + l (); >> +} >> + >> +__attribute__ ((tls_model ("global-dynamic"))) __thread int a; >> + >> +void >> +test3 (void) >> +{ >> + a = 10; >> +} >> diff --git a/gcc/testsuite/gcc.target/loongarch/tls-gd-noplt.c b/gcc/testsuite/gcc.target/loongarch/tls-gd-noplt.c >> index 32a0acf9b18..375663286f0 100644 >> --- a/gcc/testsuite/gcc.target/loongarch/tls-gd-noplt.c >> +++ b/gcc/testsuite/gcc.target/loongarch/tls-gd-noplt.c >> @@ -1,6 +1,6 @@ >> /* { dg-do compile } */ >> -/* { dg-options "-O2 -fno-plt -mcmodel=normal" } */ >> -/* { dg-final { scan-assembler "pcalau12i\t.*%got_pc_hi20\\(__tls_get_addr\\)" } } */ >> +/* { dg-options "-O0 -fno-plt -mcmodel=normal -mexplicit-relocs" } */ >> +/* { dg-final { scan-assembler "pcalau12i\t.*%got_pc_hi20\\(__tls_get_addr\\)\n\tld\.d.*%got_pc_lo12\\(__tls_get_addr\\)" } } */ >> >> __attribute__ ((tls_model ("global-dynamic"))) __thread int a; >> >> -- >> 2.31.1 >>