Projects
openEuler:24.03:SP1:Everything
gcc
_service:tar_scm:0092-LoongArch-Added-TLS-Le-Re...
Sign Up
Log In
Username
Password
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File _service:tar_scm:0092-LoongArch-Added-TLS-Le-Relax-support.patch of Package gcc
From 58d41ffad306a359ecd2902ec19d582506f14b10 Mon Sep 17 00:00:00 2001 From: Lulu Cheng <chenglulu@loongson.cn> Date: Tue, 12 Dec 2023 16:32:31 +0800 Subject: [PATCH 092/188] LoongArch: Added TLS Le Relax support. Check whether the assembler supports tls le relax. If it supports it, the assembly instruction sequence of tls le relax will be generated by default. The original way to obtain the tls le symbol address: lu12i.w $rd, %le_hi20(sym) ori $rd, $rd, %le_lo12(sym) add.{w/d} $rd, $rd, $tp If the assembler supports tls le relax, the following sequence is generated: lu12i.w $rd, %le_hi20_r(sym) add.{w/d} $rd,$rd,$tp,%le_add_r(sym) addi.{w/d} $rd,$rd,%le_lo12_r(sym) gcc/ChangeLog: * config.in: Regenerate. * config/loongarch/loongarch-opts.h (HAVE_AS_TLS_LE_RELAXATION): Define. * config/loongarch/loongarch.cc (loongarch_legitimize_tls_address): Added TLS Le Relax support. (loongarch_print_operand_reloc): Add the output string of TLS Le Relax. * config/loongarch/loongarch.md (@add_tls_le_relax<mode>): New template. * configure: Regenerate. * configure.ac: Check if binutils supports TLS le relax. gcc/testsuite/ChangeLog: * lib/target-supports.exp: Add a function to check whether binutil supports TLS Le Relax. * gcc.target/loongarch/tls-le-relax.c: New test. --- gcc/config.in | 6 +++ gcc/config/loongarch/loongarch-opts.h | 4 ++ gcc/config/loongarch/loongarch.cc | 46 +++++++++++++++++-- gcc/config/loongarch/loongarch.md | 12 +++++ gcc/configure | 31 +++++++++++++ gcc/configure.ac | 5 ++ .../gcc.target/loongarch/tls-le-relax.c | 12 +++++ gcc/testsuite/lib/target-supports.exp | 12 +++++ 8 files changed, 125 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/gcc.target/loongarch/tls-le-relax.c diff --git a/gcc/config.in b/gcc/config.in index 033cfb98b..7220b2b2b 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -771,6 +771,12 @@ #endif +/* Define if your assembler supports tls le relocation. */ +#ifndef USED_FOR_TARGET +#undef HAVE_AS_TLS_LE_RELAXATION +#endif + + /* Define if your assembler supports vl/vst/vlm/vstm with an optional alignment hint argument. */ #ifndef USED_FOR_TARGET diff --git a/gcc/config/loongarch/loongarch-opts.h b/gcc/config/loongarch/loongarch-opts.h index 639ed50bd..8491bee0d 100644 --- a/gcc/config/loongarch/loongarch-opts.h +++ b/gcc/config/loongarch/loongarch-opts.h @@ -114,4 +114,8 @@ struct loongarch_flags { #define HAVE_AS_TLS 0 #endif +#ifndef HAVE_AS_TLS_LE_RELAXATION +#define HAVE_AS_TLS_LE_RELAXATION 0 +#endif + #endif /* LOONGARCH_OPTS_H */ diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index c6318bee9..d1b1950dc 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -2993,7 +2993,29 @@ loongarch_legitimize_tls_address (rtx loc) case TLS_MODEL_LOCAL_EXEC: { - /* la.tls.le; tp-relative add. */ + /* la.tls.le; tp-relative add. + + normal: + lu12i.w $rd, %le_hi20(sym) + ori $rd, $rd, %le_lo12(sym) + add.{w/d} $rd, $rd, $tp + (st.{w/d}/ld.{w/d} $rs, $rd, 0) + + tls le relax: + lu12i.w $rd, %le_hi20_r(sym) + add.{w/d} $rd,$rd,$tp + addi.{w/d} $rd,$rd,%le_lo12_r(sym) + (st.{w/d}/ld.{w/d} $rs, $rd, 0) + + extreme (When the code model is set to extreme, the TLS le Relax + instruction sequence is not generated): + lu12i.w $rd, %le_hi20(sym) + ori $rd, $rd, %le_lo12(sym) + lu32i.d $rd, %le64_lo20(sym) + lu52i.d $rd, $rd, %le64_hi12(sym) + add.d $rd, $rd, $tp + (st.{w/d}/ld.{w/d} $rs, $rd, 0) */ + tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM); tmp1 = gen_reg_rtx (Pmode); dest = gen_reg_rtx (Pmode); @@ -3004,7 +3026,20 @@ 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_ori_l_lo12 (Pmode, tmp1, high, tmp2)); + + /* The assembler does not implement tls le relax support when the + code model is extreme, so when the code model is extreme, the + old symbol address acquisition method is still used. */ + if (HAVE_AS_TLS_LE_RELAXATION && !TARGET_CMODEL_EXTREME) + { + emit_insn (gen_add_tls_le_relax (Pmode, dest, high, + tp, loc)); + loongarch_emit_move (dest, + gen_rtx_LO_SUM (Pmode, dest, tmp2)); + return dest; + } + else + emit_insn (gen_ori_l_lo12 (Pmode, tmp1, high, tmp2)); if (TARGET_CMODEL_EXTREME) { @@ -5936,7 +5971,12 @@ loongarch_print_operand_reloc (FILE *file, rtx op, bool hi64_part, gcc_unreachable (); } else - reloc = hi_reloc ? "%le_hi20" : "%le_lo12"; + { + if (HAVE_AS_TLS_LE_RELAXATION && !TARGET_CMODEL_EXTREME) + reloc = hi_reloc ? "%le_hi20_r" : "%le_lo12_r"; + else + reloc = hi_reloc ? "%le_hi20" : "%le_lo12"; + } break; case SYMBOL_TLSGD: diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md index 996df66e8..02c537d4c 100644 --- a/gcc/config/loongarch/loongarch.md +++ b/gcc/config/loongarch/loongarch.md @@ -73,6 +73,7 @@ UNSPEC_LOAD_FROM_GOT UNSPEC_PCALAU12I UNSPEC_PCALAU12I_GR + UNSPEC_ADD_TLS_LE_RELAX UNSPEC_ORI_L_LO12 UNSPEC_LUI_L_HI20 UNSPEC_LUI_H_LO20 @@ -2503,6 +2504,17 @@ "pcalau12i\t%0,%%pc_hi20(%1)" [(set_attr "type" "move")]) +(define_insn "@add_tls_le_relax<mode>" + [(set (match_operand:P 0 "register_operand" "=r") + (unspec:P [(match_operand:P 1 "register_operand" "r") + (match_operand:P 2 "register_operand" "r") + (match_operand:P 3 "symbolic_operand")] + UNSPEC_ADD_TLS_LE_RELAX))] + "HAVE_AS_TLS_LE_RELAXATION" + "add.<d>\t%0,%1,%2,%%le_add_r(%3)" + [(set_attr "type" "move")] +) + (define_insn "@ori_l_lo12<mode>" [(set (match_operand:P 0 "register_operand" "=r") (unspec:P [(match_operand:P 1 "register_operand" "r") diff --git a/gcc/configure b/gcc/configure index 5842e7a18..eecfe60d6 100755 --- a/gcc/configure +++ b/gcc/configure @@ -28968,6 +28968,37 @@ if test $gcc_cv_as_loongarch_cond_branch_relax = yes; then $as_echo "#define HAVE_AS_COND_BRANCH_RELAXATION 1" >>confdefs.h +fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for tls le relaxation support" >&5 +$as_echo_n "checking assembler for tls le relaxation support... " >&6; } +if ${gcc_cv_as_loongarch_tls_le_relaxation_support+:} false; then : + $as_echo_n "(cached) " >&6 +else + gcc_cv_as_loongarch_tls_le_relaxation_support=no + if test x$gcc_cv_as != x; then + $as_echo 'lu12i.w $t0,%le_hi20_r(a)' > conftest.s + if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5' + { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5 + (eval $ac_try) 2>&5 + ac_status=$? + $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 + test $ac_status = 0; }; } + then + gcc_cv_as_loongarch_tls_le_relaxation_support=yes + else + echo "configure: failed program was" >&5 + cat conftest.s >&5 + fi + rm -f conftest.o conftest.s + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_loongarch_tls_le_relaxation_support" >&5 +$as_echo "$gcc_cv_as_loongarch_tls_le_relaxation_support" >&6; } +if test $gcc_cv_as_loongarch_tls_le_relaxation_support = yes; then + +$as_echo "#define HAVE_AS_TLS_LE_RELAXATION 1" >>confdefs.h + fi ;; diff --git a/gcc/configure.ac b/gcc/configure.ac index 9c3fd3ad6..d1032440d 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -5357,6 +5357,11 @@ x: beq $a0,$a1,a],, [AC_DEFINE(HAVE_AS_COND_BRANCH_RELAXATION, 1, [Define if your assembler supports conditional branch relaxation.])]) + gcc_GAS_CHECK_FEATURE([tls le relaxation support], + gcc_cv_as_loongarch_tls_le_relaxation_support,, + [lu12i.w $t0,%le_hi20_r(a)],, + [AC_DEFINE(HAVE_AS_TLS_LE_RELAXATION, 1, + [Define if your assembler supports tls le relocation.])]) ;; s390*-*-*) gcc_GAS_CHECK_FEATURE([.gnu_attribute support], diff --git a/gcc/testsuite/gcc.target/loongarch/tls-le-relax.c b/gcc/testsuite/gcc.target/loongarch/tls-le-relax.c new file mode 100644 index 000000000..a9a404fc7 --- /dev/null +++ b/gcc/testsuite/gcc.target/loongarch/tls-le-relax.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mcmodel=normal -mexplicit-relocs" } */ +/* { dg-final { scan-assembler "%le_add_r" { target tls_le_relax } } } */ + +__attribute__ ((tls_model ("local-exec"))) __thread int a; + +void +test (void) +{ + a = 10; +} + diff --git a/gcc/testsuite/lib/target-supports.exp b/gcc/testsuite/lib/target-supports.exp index b8bff1a31..20fbd43ee 100644 --- a/gcc/testsuite/lib/target-supports.exp +++ b/gcc/testsuite/lib/target-supports.exp @@ -10582,6 +10582,18 @@ proc check_effective_target_loongarch_call36_support { } { } ""] } +# Returns 1 if binutils supports TLS le Relax, 0 otherwise. +proc check_effective_target_tls_le_relax { } { + if [check_effective_target_tls_native] { + return [check_no_compiler_messages loongarch_tls_le_relax object { + /* Assembly code */ + lu12i.w $r12, %le_hi20_r(a) + }] + } + + return 0; +} + # Return 1 if the target does *not* require strict alignment. proc check_effective_target_non_strict_align {} { -- 2.43.0
Locations
Projects
Search
Status Monitor
Help
Open Build Service
OBS Manuals
API Documentation
OBS Portal
Reporting a Bug
Contact
Mailing List
Forums
Chat (IRC)
Twitter
Open Build Service (OBS)
is an
openSUSE project
.
浙ICP备2022010568号-2