diff mbox series

[v4] LoongArch: Add support for TLS descriptors

Message ID 20240312092002.1335661-1-mengqinggang@loongson.cn
State New
Headers show
Series [v4] LoongArch: Add support for TLS descriptors | expand

Commit Message

mengqinggang March 12, 2024, 9:20 a.m. UTC
Add support for TLS descriptors on normal code model and extreme code model.

Normal code model instruction sequence:
  -mno-explicit-relocs:
    la.tls.desc	$r4, s
    add.d	$r12, $r4, $r2
  -mexplicit-relocs:
    pcalau12i	$r4,%desc_pc_hi20(s)
    addi.d	$r4,$r4,%desc_pc_lo12(s)
    ld.d	$r1,$r4,%desc_ld(s)
    jirl	$r1,$r1,%desc_call(s)
    add.d	$r12, $r4, $r2

Extreme code model instruction sequence:
  -mno-explicit-relocs:
    la.tls.desc	$r4, $r12, s
    add.d	$r12, $r4, $r2
  -mexplicit-relocs:
    pcalau12i	$r4,%desc_pc_hi20(s)
    addi.d	$r12,$r0,%desc_pc_lo12(s)
    lu32i.d	$r12,%desc64_pc_lo20(s)
    lu52i.d	$r12,$r12,%desc64_pc_hi12(s)
    add.d	$r4,$r4,$r12
    ld.d	$r1,$r4,%desc_ld(s)
    jirl	$r1,$r1,%desc_call(s)
    add.d	$r12, $r4, $r2

The default is still traditional TLS model, but can be configured with
--with-tls={trad,desc}. The default can change to TLS descriptors once
libc and LLVM support this.

gcc/ChangeLog:

	* config.gcc: Add --with-tls option to change TLS flavor.
	* config/loongarch/genopts/loongarch.opt.in: Add -mtls-dialect to
	configure TLS flavor.
	* config/loongarch/loongarch-def.h (struct loongarch_target): Add
	tls_dialect.
	* config/loongarch/loongarch-driver.cc (la_driver_init): Add tls
	flavor.
	* config/loongarch/loongarch-opts.cc (loongarch_init_target): Add
	tls_dialect.
	(loongarch_config_target): Ditto.
	(loongarch_update_gcc_opt_status): Ditto.
	* config/loongarch/loongarch-opts.h (loongarch_init_target):Ditto.
	(TARGET_TLS_DESC): New define.
	* config/loongarch/loongarch.cc (loongarch_symbol_insns): Add TLS DESC
	instructions sequence length.
	(loongarch_legitimize_tls_address): New TLS DESC instruction sequence.
	(loongarch_option_override_internal): Add la_opt_tls_dialect.
	(loongarch_option_restore): Add la_target.tls_dialect.
	* config/loongarch/loongarch.md (@got_load_tls_desc<mode>): Normal
	code model for TLS DESC.
	(got_load_tls_desc_off64): Extreme code model for TLS DESC.
	* config/loongarch/loongarch.opt: Regenerated.

gcc/testsuite/ChangeLog:

	* gcc.target/loongarch/cmodel-extreme-1.c: Add -mtls-dialect=trad.
	* gcc.target/loongarch/cmodel-extreme-2.c: Ditto.
	* gcc.target/loongarch/explicit-relocs-auto-tls-ld-gd.c: Ditto.
	* gcc.target/loongarch/explicit-relocs-medium-call36-auto-tls-ld-gd.c:
	Ditto.
	* gcc.target/loongarch/func-call-medium-1.c: Ditto.
	* gcc.target/loongarch/func-call-medium-2.c: Ditto.
	* gcc.target/loongarch/func-call-medium-3.c: Ditto.
	* gcc.target/loongarch/func-call-medium-4.c: Ditto.
	* gcc.target/loongarch/tls-extreme-macro.c: Ditto.
	* gcc.target/loongarch/tls-gd-noplt.c: Ditto.
	* gcc.target/loongarch/explicit-relocs-auto-extreme-tls-desc.c: New test.
	* gcc.target/loongarch/explicit-relocs-auto-tls-desc.c: New test.
	* gcc.target/loongarch/explicit-relocs-extreme-tls-desc.c: New test.
	* gcc.target/loongarch/explicit-relocs-tls-desc.c: New test.
---
Changes v3 -> v4:
- Add TLS descriptors test cases.

Changes v2 -> v3:
- Set default to traditional TLS model.
- Add support for -mexplicit-relocs and extreme code model.

Changes v1 -> v2:
- Clobber fcc0-fcc7 registers in got_load_tls_desc template.
- Support --with-tls in configure.

v3 link: https://sourceware.org/pipermail/gcc-patches/2024-March/647578.html
v2 link: https://sourceware.org/pipermail/gcc-patches/2024-February/646817.html
v1 link: https://sourceware.org/pipermail/gcc-patches/2023-December/638907.html

 gcc/config.gcc                                | 19 +++++-
 gcc/config/loongarch/genopts/loongarch.opt.in | 14 ++++
 gcc/config/loongarch/loongarch-def.h          |  7 ++
 gcc/config/loongarch/loongarch-driver.cc      |  2 +-
 gcc/config/loongarch/loongarch-opts.cc        | 12 +++-
 gcc/config/loongarch/loongarch-opts.h         |  2 +
 gcc/config/loongarch/loongarch.cc             | 48 +++++++++----
 gcc/config/loongarch/loongarch.md             | 68 +++++++++++++++++++
 gcc/config/loongarch/loongarch.opt            | 14 ++++
 .../gcc.target/loongarch/cmodel-extreme-1.c   |  2 +-
 .../gcc.target/loongarch/cmodel-extreme-2.c   |  2 +-
 .../explicit-relocs-auto-extreme-tls-desc.c   | 10 +++
 .../loongarch/explicit-relocs-auto-tls-desc.c | 10 +++
 .../explicit-relocs-auto-tls-ld-gd.c          |  2 +-
 .../explicit-relocs-extreme-tls-desc.c        | 16 +++++
 ...icit-relocs-medium-call36-auto-tls-ld-gd.c |  2 +-
 .../loongarch/explicit-relocs-tls-desc.c      | 13 ++++
 .../gcc.target/loongarch/func-call-medium-1.c |  2 +-
 .../gcc.target/loongarch/func-call-medium-2.c |  2 +-
 .../gcc.target/loongarch/func-call-medium-3.c |  2 +-
 .../gcc.target/loongarch/func-call-medium-4.c |  2 +-
 .../gcc.target/loongarch/tls-extreme-macro.c  |  2 +-
 .../gcc.target/loongarch/tls-gd-noplt.c       |  2 +-
 23 files changed, 229 insertions(+), 26 deletions(-)
 create mode 100644 gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-extreme-tls-desc.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-tls-desc.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/explicit-relocs-extreme-tls-desc.c
 create mode 100644 gcc/testsuite/gcc.target/loongarch/explicit-relocs-tls-desc.c

Comments

Xi Ruoyao March 12, 2024, 10:15 p.m. UTC | #1
On Tue, 2024-03-12 at 17:20 +0800, mengqinggang wrote:
> +(define_insn "@got_load_tls_desc<mode>"
> +  [(set (match_operand:P 0 "register_operand" "=r")
> +	(unspec:P
> +	    [(match_operand:P 1 "symbolic_operand" "")]
> +	    UNSPEC_TLS_DESC))
> +    (clobber (reg:SI FCC0_REGNUM))
> +    (clobber (reg:SI FCC1_REGNUM))
> +    (clobber (reg:SI FCC2_REGNUM))
> +    (clobber (reg:SI FCC3_REGNUM))
> +    (clobber (reg:SI FCC4_REGNUM))
> +    (clobber (reg:SI FCC5_REGNUM))
> +    (clobber (reg:SI FCC6_REGNUM))
> +    (clobber (reg:SI FCC7_REGNUM))
> +    (clobber (reg:SI RETURN_ADDR_REGNUM))]
> +  "TARGET_TLS_DESC"
> +{
> +  return TARGET_EXPLICIT_RELOCS
> +    ? "pcalau12i\t$r4,%%desc_pc_hi20(%1)\n\
> +      \taddi.d\t$r4,$r4,%%desc_pc_lo12(%1)\n\
> +      \tld.d\t$r1,$r4,%%desc_ld(%1)\n\
> +      \tjirl\t$r1,$r1,%%desc_call(%1)"

Use something like

    ? "pcalau12i\t$r4,%%desc_pc_hi20(%1)\n\t"
      "addi.d\t$r4,$r4,%%desc_pc_lo12(%1)\n\t"
      "ld.d\t$r1,$r4,%%desc_ld(%1)\n\t"
      "jirl\t$r1,$r1,%%desc_call(%1)"
    : "la.tls.desc\t%0,%1";

to prevent additional white spaces in the output asm before tabs.

> +    : "la.tls.desc\t%0,%1";
> +}
> +  [(set_attr "got" "load")
> +   (set_attr "mode" "<MODE>")
> +   (set_attr "length" "16")])
> +
> +(define_insn "got_load_tls_desc_off64"
> +  [(set (match_operand:DI 0 "register_operand" "=r")
> +	(unspec:DI
> +	    [(match_operand:DI 1 "symbolic_operand" "")]
> +	    UNSPEC_TLS_DESC_OFF64))
> +    (clobber (reg:SI FCC0_REGNUM))
> +    (clobber (reg:SI FCC1_REGNUM))
> +    (clobber (reg:SI FCC2_REGNUM))
> +    (clobber (reg:SI FCC3_REGNUM))
> +    (clobber (reg:SI FCC4_REGNUM))
> +    (clobber (reg:SI FCC5_REGNUM))
> +    (clobber (reg:SI FCC6_REGNUM))
> +    (clobber (reg:SI FCC7_REGNUM))
> +    (clobber (reg:SI RETURN_ADDR_REGNUM))
> +    (clobber (match_operand:DI 2 "register_operand" "=&r"))]
> +  "TARGET_TLS_DESC && TARGET_CMODEL_EXTREME"
> +{
> +  return TARGET_EXPLICIT_RELOCS
> +    ? "pcalau12i\t$r4,%%desc_pc_hi20(%1)\n\
> +      \taddi.d\t%2,$r0,%%desc_pc_lo12(%1)\n\
> +      \tlu32i.d\t%2,%%desc64_pc_lo20(%1)\n\
> +      \tlu52i.d\t%2,%2,%%desc64_pc_hi12(%1)\n\
> +      \tadd.d\t$r4,$r4,%2\n\
> +      \tld.d\t$r1,$r4,%%desc_ld(%1)\n\
> +      \tjirl\t$r1,$r1,%%desc_call(%1)"
> +    : "la.tls.desc\t%0,%2,%1";

Likewise.

> +}
> +  [(set_attr "got" "load")
> +   (set_attr "length" "28")])

Otherwise OK.

It's better to allow splitting these two instructions but we can do it
in another patch.  And IMO it's better to enable TLS desc by default if
supported by both the assembler and the libc, but we'll have to defer it
until Glibc 2.40 release.
Xi Ruoyao March 12, 2024, 10:56 p.m. UTC | #2
On Wed, 2024-03-13 at 06:15 +0800, Xi Ruoyao wrote:
> > +(define_insn "@got_load_tls_desc<mode>"
> > +  [(set (match_operand:P 0 "register_operand" "=r")

Hmm, and it looks like we should use (reg:P 4) instead of match_operand
here, because the instruction does not work for a different register:
with TARGET_EXPLICIT_RELOCS we are hard coding r4, and without
TARGET_EXPLICIT_RELOCS the TLS desc function still only puts the return
value in r4.

> > +	(unspec:P
> > +	    [(match_operand:P 1 "symbolic_operand" "")]
> > +	    UNSPEC_TLS_DESC))
> > +    (clobber (reg:SI FCC0_REGNUM))
> > +    (clobber (reg:SI FCC1_REGNUM))
> > +    (clobber (reg:SI FCC2_REGNUM))
> > +    (clobber (reg:SI FCC3_REGNUM))
> > +    (clobber (reg:SI FCC4_REGNUM))
> > +    (clobber (reg:SI FCC5_REGNUM))
> > +    (clobber (reg:SI FCC6_REGNUM))
> > +    (clobber (reg:SI FCC7_REGNUM))
> > +    (clobber (reg:SI RETURN_ADDR_REGNUM))]
> > +  "TARGET_TLS_DESC"
> > +{
> > +  return TARGET_EXPLICIT_RELOCS
> > +    ? "pcalau12i\t$r4,%%desc_pc_hi20(%1)\n\
> > +      \taddi.d\t$r4,$r4,%%desc_pc_lo12(%1)\n\
> > +      \tld.d\t$r1,$r4,%%desc_ld(%1)\n\
> > +      \tjirl\t$r1,$r1,%%desc_call(%1)"
> 
> Use something like
> 
>     ? "pcalau12i\t$r4,%%desc_pc_hi20(%1)\n\t"
>       "addi.d\t$r4,$r4,%%desc_pc_lo12(%1)\n\t"
>       "ld.d\t$r1,$r4,%%desc_ld(%1)\n\t"
>       "jirl\t$r1,$r1,%%desc_call(%1)"
>     : "la.tls.desc\t%0,%1";
> 
> to prevent additional white spaces in the output asm before tabs.
Xi Ruoyao March 13, 2024, 2:24 a.m. UTC | #3
On Wed, 2024-03-13 at 06:56 +0800, Xi Ruoyao wrote:
> On Wed, 2024-03-13 at 06:15 +0800, Xi Ruoyao wrote:
> > > +(define_insn "@got_load_tls_desc<mode>"
> > > +  [(set (match_operand:P 0 "register_operand" "=r")
> 
> Hmm, and it looks like we should use (reg:P 4) instead of match_operand
> here, because the instruction does not work for a different register:
> with TARGET_EXPLICIT_RELOCS we are hard coding r4, and without
> TARGET_EXPLICIT_RELOCS the TLS desc function still only puts the return
> value in r4.

Suggested changes:

diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index 303666bf6d5..8f4d3f36c26 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -2954,10 +2954,10 @@ loongarch_legitimize_tls_address (rtx loc)
 	  tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
 
 	  if (TARGET_CMODEL_EXTREME)
-	    emit_insn (gen_got_load_tls_desc_off64 (a0, loc,
+	    emit_insn (gen_got_load_tls_desc_off64 (loc,
 						    gen_reg_rtx (DImode)));
 	  else
-	    emit_insn (gen_got_load_tls_desc (Pmode, a0, loc));
+	    emit_insn (gen_got_load_tls_desc (Pmode, loc));
 
 	  emit_insn (gen_add3_insn (dest, a0, tp));
 	}
diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md
index 0a1a6a24f61..8e8f1012344 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -2772,9 +2772,9 @@ (define_insn "store_word<mode>"
 ;; Thread-Local Storage
 
 (define_insn "@got_load_tls_desc<mode>"
-  [(set (match_operand:P 0 "register_operand" "=r")
+  [(set (reg:P 4)
 	(unspec:P
-	    [(match_operand:P 1 "symbolic_operand" "")]
+	    [(match_operand:P 0 "symbolic_operand" "")]
 	    UNSPEC_TLS_DESC))
     (clobber (reg:SI FCC0_REGNUM))
     (clobber (reg:SI FCC1_REGNUM))
@@ -2788,20 +2788,20 @@ (define_insn "@got_load_tls_desc<mode>"
   "TARGET_TLS_DESC"
 {
   return TARGET_EXPLICIT_RELOCS
-    ? "pcalau12i\t$r4,%%desc_pc_hi20(%1)\n\
-      \taddi.d\t$r4,$r4,%%desc_pc_lo12(%1)\n\
-      \tld.d\t$r1,$r4,%%desc_ld(%1)\n\
-      \tjirl\t$r1,$r1,%%desc_call(%1)"
-    : "la.tls.desc\t%0,%1";
+    ? "pcalau12i\t$r4,%%desc_pc_hi20(%0)\n\t"
+      "addi.d\t$r4,$r4,%%desc_pc_lo12(%0)\n\t"
+      "ld.d\t$r1,$r4,%%desc_ld(%0)\n\t"
+      "jirl\t$r1,$r1,%%desc_call(%0)"
+    : "la.tls.desc\t$r4,%0";
 }
   [(set_attr "got" "load")
    (set_attr "mode" "<MODE>")
    (set_attr "length" "16")])
 
 (define_insn "got_load_tls_desc_off64"
-  [(set (match_operand:DI 0 "register_operand" "=r")
+  [(set (reg:DI 4)
 	(unspec:DI
-	    [(match_operand:DI 1 "symbolic_operand" "")]
+	    [(match_operand:DI 0 "symbolic_operand" "")]
 	    UNSPEC_TLS_DESC_OFF64))
     (clobber (reg:SI FCC0_REGNUM))
     (clobber (reg:SI FCC1_REGNUM))
@@ -2812,18 +2812,18 @@ (define_insn "got_load_tls_desc_off64"
     (clobber (reg:SI FCC6_REGNUM))
     (clobber (reg:SI FCC7_REGNUM))
     (clobber (reg:SI RETURN_ADDR_REGNUM))
-    (clobber (match_operand:DI 2 "register_operand" "=&r"))]
+    (clobber (match_operand:DI 1 "register_operand" "=&r"))]
   "TARGET_TLS_DESC && TARGET_CMODEL_EXTREME"
 {
   return TARGET_EXPLICIT_RELOCS
-    ? "pcalau12i\t$r4,%%desc_pc_hi20(%1)\n\
-      \taddi.d\t%2,$r0,%%desc_pc_lo12(%1)\n\
-      \tlu32i.d\t%2,%%desc64_pc_lo20(%1)\n\
-      \tlu52i.d\t%2,%2,%%desc64_pc_hi12(%1)\n\
-      \tadd.d\t$r4,$r4,%2\n\
-      \tld.d\t$r1,$r4,%%desc_ld(%1)\n\
-      \tjirl\t$r1,$r1,%%desc_call(%1)"
-    : "la.tls.desc\t%0,%2,%1";
+    ? "pcalau12i\t$r4,%%desc_pc_hi20(%0)\n\t"
+      "addi.d\t%1,$r0,%%desc_pc_lo12(%0)\n\t"
+      "lu32i.d\t%1,%%desc64_pc_lo20(%0)\n\t"
+      "lu52i.d\t%1,%2,%%desc64_pc_hi12(%0)\n\t"
+      "add.d\t$r4,$r4,%1\n\t"
+      "ld.d\t$r1,$r4,%%desc_ld(%0)\n\t"
+      "jirl\t$r1,$r1,%%desc_call(%0)"
+    : "la.tls.desc\t$r4,%1,%0";
 }
   [(set_attr "got" "load")
    (set_attr "length" "28")])
mengqinggang March 13, 2024, 3:06 a.m. UTC | #4
在 2024/3/13 上午6:15, Xi Ruoyao 写道:
> On Tue, 2024-03-12 at 17:20 +0800, mengqinggang wrote:
>> +(define_insn "@got_load_tls_desc<mode>"
>> +  [(set (match_operand:P 0 "register_operand" "=r")
>> +	(unspec:P
>> +	    [(match_operand:P 1 "symbolic_operand" "")]
>> +	    UNSPEC_TLS_DESC))
>> +    (clobber (reg:SI FCC0_REGNUM))
>> +    (clobber (reg:SI FCC1_REGNUM))
>> +    (clobber (reg:SI FCC2_REGNUM))
>> +    (clobber (reg:SI FCC3_REGNUM))
>> +    (clobber (reg:SI FCC4_REGNUM))
>> +    (clobber (reg:SI FCC5_REGNUM))
>> +    (clobber (reg:SI FCC6_REGNUM))
>> +    (clobber (reg:SI FCC7_REGNUM))
>> +    (clobber (reg:SI RETURN_ADDR_REGNUM))]
>> +  "TARGET_TLS_DESC"
>> +{
>> +  return TARGET_EXPLICIT_RELOCS
>> +    ? "pcalau12i\t$r4,%%desc_pc_hi20(%1)\n\
>> +      \taddi.d\t$r4,$r4,%%desc_pc_lo12(%1)\n\
>> +      \tld.d\t$r1,$r4,%%desc_ld(%1)\n\
>> +      \tjirl\t$r1,$r1,%%desc_call(%1)"
> Use something like
>
>      ? "pcalau12i\t$r4,%%desc_pc_hi20(%1)\n\t"
>        "addi.d\t$r4,$r4,%%desc_pc_lo12(%1)\n\t"
>        "ld.d\t$r1,$r4,%%desc_ld(%1)\n\t"
>        "jirl\t$r1,$r1,%%desc_call(%1)"
>      : "la.tls.desc\t%0,%1";
>
> to prevent additional white spaces in the output asm before tabs.
>
>> +    : "la.tls.desc\t%0,%1";
>> +}
>> +  [(set_attr "got" "load")
>> +   (set_attr "mode" "<MODE>")
>> +   (set_attr "length" "16")])
>> +
>> +(define_insn "got_load_tls_desc_off64"
>> +  [(set (match_operand:DI 0 "register_operand" "=r")
>> +	(unspec:DI
>> +	    [(match_operand:DI 1 "symbolic_operand" "")]
>> +	    UNSPEC_TLS_DESC_OFF64))
>> +    (clobber (reg:SI FCC0_REGNUM))
>> +    (clobber (reg:SI FCC1_REGNUM))
>> +    (clobber (reg:SI FCC2_REGNUM))
>> +    (clobber (reg:SI FCC3_REGNUM))
>> +    (clobber (reg:SI FCC4_REGNUM))
>> +    (clobber (reg:SI FCC5_REGNUM))
>> +    (clobber (reg:SI FCC6_REGNUM))
>> +    (clobber (reg:SI FCC7_REGNUM))
>> +    (clobber (reg:SI RETURN_ADDR_REGNUM))
>> +    (clobber (match_operand:DI 2 "register_operand" "=&r"))]
>> +  "TARGET_TLS_DESC && TARGET_CMODEL_EXTREME"
>> +{
>> +  return TARGET_EXPLICIT_RELOCS
>> +    ? "pcalau12i\t$r4,%%desc_pc_hi20(%1)\n\
>> +      \taddi.d\t%2,$r0,%%desc_pc_lo12(%1)\n\
>> +      \tlu32i.d\t%2,%%desc64_pc_lo20(%1)\n\
>> +      \tlu52i.d\t%2,%2,%%desc64_pc_hi12(%1)\n\
>> +      \tadd.d\t$r4,$r4,%2\n\
>> +      \tld.d\t$r1,$r4,%%desc_ld(%1)\n\
>> +      \tjirl\t$r1,$r1,%%desc_call(%1)"
>> +    : "la.tls.desc\t%0,%2,%1";
> Likewise.
>
>> +}
>> +  [(set_attr "got" "load")
>> +   (set_attr "length" "28")])
> Otherwise OK.
>
> It's better to allow splitting these two instructions but we can do it
> in another patch.  And IMO it's better to enable TLS desc by default if
> supported by both the assembler and the libc, but we'll have to defer it
> until Glibc 2.40 release.


Do we need to wait until LLVM also supports TLS DESC  before setting it 
as default?


>
Xi Ruoyao March 13, 2024, 9:16 a.m. UTC | #5
On Wed, 2024-03-13 at 11:06 +0800, mengqinggang wrote:
> 
> 在 2024/3/13 上午6:15, Xi Ruoyao 写道:
> > On Tue, 2024-03-12 at 17:20 +0800, mengqinggang wrote:
> > > +(define_insn "@got_load_tls_desc<mode>"
> > > +  [(set (match_operand:P 0 "register_operand" "=r")
> > > +	(unspec:P
> > > +	    [(match_operand:P 1 "symbolic_operand" "")]
> > > +	    UNSPEC_TLS_DESC))
> > > +    (clobber (reg:SI FCC0_REGNUM))
> > > +    (clobber (reg:SI FCC1_REGNUM))
> > > +    (clobber (reg:SI FCC2_REGNUM))
> > > +    (clobber (reg:SI FCC3_REGNUM))
> > > +    (clobber (reg:SI FCC4_REGNUM))
> > > +    (clobber (reg:SI FCC5_REGNUM))
> > > +    (clobber (reg:SI FCC6_REGNUM))
> > > +    (clobber (reg:SI FCC7_REGNUM))
> > > +    (clobber (reg:SI RETURN_ADDR_REGNUM))]
> > > +  "TARGET_TLS_DESC"
> > > +{
> > > +  return TARGET_EXPLICIT_RELOCS
> > > +    ? "pcalau12i\t$r4,%%desc_pc_hi20(%1)\n\
> > > +      \taddi.d\t$r4,$r4,%%desc_pc_lo12(%1)\n\
> > > +      \tld.d\t$r1,$r4,%%desc_ld(%1)\n\
> > > +      \tjirl\t$r1,$r1,%%desc_call(%1)"
> > Use something like
> > 
> >      ? "pcalau12i\t$r4,%%desc_pc_hi20(%1)\n\t"
> >        "addi.d\t$r4,$r4,%%desc_pc_lo12(%1)\n\t"
> >        "ld.d\t$r1,$r4,%%desc_ld(%1)\n\t"
> >        "jirl\t$r1,$r1,%%desc_call(%1)"
> >      : "la.tls.desc\t%0,%1";
> > 
> > to prevent additional white spaces in the output asm before tabs.
> > 
> > > +    : "la.tls.desc\t%0,%1";
> > > +}
> > > +  [(set_attr "got" "load")
> > > +   (set_attr "mode" "<MODE>")
> > > +   (set_attr "length" "16")])
> > > +
> > > +(define_insn "got_load_tls_desc_off64"
> > > +  [(set (match_operand:DI 0 "register_operand" "=r")
> > > +	(unspec:DI
> > > +	    [(match_operand:DI 1 "symbolic_operand" "")]
> > > +	    UNSPEC_TLS_DESC_OFF64))
> > > +    (clobber (reg:SI FCC0_REGNUM))
> > > +    (clobber (reg:SI FCC1_REGNUM))
> > > +    (clobber (reg:SI FCC2_REGNUM))
> > > +    (clobber (reg:SI FCC3_REGNUM))
> > > +    (clobber (reg:SI FCC4_REGNUM))
> > > +    (clobber (reg:SI FCC5_REGNUM))
> > > +    (clobber (reg:SI FCC6_REGNUM))
> > > +    (clobber (reg:SI FCC7_REGNUM))
> > > +    (clobber (reg:SI RETURN_ADDR_REGNUM))
> > > +    (clobber (match_operand:DI 2 "register_operand" "=&r"))]
> > > +  "TARGET_TLS_DESC && TARGET_CMODEL_EXTREME"
> > > +{
> > > +  return TARGET_EXPLICIT_RELOCS
> > > +    ? "pcalau12i\t$r4,%%desc_pc_hi20(%1)\n\
> > > +      \taddi.d\t%2,$r0,%%desc_pc_lo12(%1)\n\
> > > +      \tlu32i.d\t%2,%%desc64_pc_lo20(%1)\n\
> > > +      \tlu52i.d\t%2,%2,%%desc64_pc_hi12(%1)\n\
> > > +      \tadd.d\t$r4,$r4,%2\n\
> > > +      \tld.d\t$r1,$r4,%%desc_ld(%1)\n\
> > > +      \tjirl\t$r1,$r1,%%desc_call(%1)"
> > > +    : "la.tls.desc\t%0,%2,%1";
> > Likewise.
> > 
> > > +}
> > > +  [(set_attr "got" "load")
> > > +   (set_attr "length" "28")])
> > Otherwise OK.
> > 
> > It's better to allow splitting these two instructions but we can do it
> > in another patch.  And IMO it's better to enable TLS desc by default if
> > supported by both the assembler and the libc, but we'll have to defer it
> > until Glibc 2.40 release.
> 
> 
> Do we need to wait until LLVM also supports TLS DESC  before setting it 
> as default?

Hmm, maybe...  I remember when we added R_LARCH_ALIGN lld was being
broken for a while.
Xi Ruoyao March 13, 2024, 9:19 a.m. UTC | #6
On Wed, 2024-03-13 at 10:24 +0800, Xi Ruoyao wrote:
>    return TARGET_EXPLICIT_RELOCS
> -    ? "pcalau12i\t$r4,%%desc_pc_hi20(%1)\n\
> -      \taddi.d\t%2,$r0,%%desc_pc_lo12(%1)\n\
> -      \tlu32i.d\t%2,%%desc64_pc_lo20(%1)\n\
> -      \tlu52i.d\t%2,%2,%%desc64_pc_hi12(%1)\n\
> -      \tadd.d\t$r4,$r4,%2\n\
> -      \tld.d\t$r1,$r4,%%desc_ld(%1)\n\
> -      \tjirl\t$r1,$r1,%%desc_call(%1)"
> -    : "la.tls.desc\t%0,%2,%1";
> +    ? "pcalau12i\t$r4,%%desc_pc_hi20(%0)\n\t"
> +      "addi.d\t%1,$r0,%%desc_pc_lo12(%0)\n\t"
> +      "lu32i.d\t%1,%%desc64_pc_lo20(%0)\n\t"
> +      "lu52i.d\t%1,%2,%%desc64_pc_hi12(%0)\n\t"

Oops, the "%2" in the above line should be "%1".

> +      "add.d\t$r4,$r4,%1\n\t"
> +      "ld.d\t$r1,$r4,%%desc_ld(%0)\n\t"
> +      "jirl\t$r1,$r1,%%desc_call(%0)"
> +    : "la.tls.desc\t$r4,%1,%0";
diff mbox series

Patch

diff --git a/gcc/config.gcc b/gcc/config.gcc
index 624e0dae191..baebafdbf5d 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -4991,7 +4991,7 @@  case "${target}" in
 		;;
 
 	loongarch*-*)
-		supported_defaults="abi arch tune fpu simd multilib-default strict-align-lib"
+		supported_defaults="abi arch tune fpu simd multilib-default strict-align-lib tls"
 
 		# Local variables
 		unset \
@@ -5249,6 +5249,18 @@  case "${target}" in
 			with_multilib_list="${abi_base}/${abi_ext}"
 		fi
 
+		# Handle --with-tls.
+		case "$with_tls" in
+		"" \
+		| trad | desc)
+		    # OK
+		    ;;
+		*)
+		    echo "Unknown TLS method used in --with-tls=$with_tls" 1>&2
+		    exit 1
+		    ;;
+		esac
+
 		# Check if the configured default ABI combination is included in
 		# ${with_multilib_list}.
 		loongarch_multilib_list_sane=no
@@ -5914,6 +5926,11 @@  case ${target} in
 		lasx)    tm_defines="$tm_defines DEFAULT_ISA_EXT_SIMD=ISA_EXT_SIMD_LASX" ;;
 		esac
 
+		case ${with_tls} in
+		"" | trad)	tm_defines="$tm_defines DEFAULT_TLS_TYPE=TLS_TRADITIONAL" ;;
+		desc)		tm_defines="$tm_defines DEFAULT_TLS_TYPE=TLS_DESCRIPTORS" ;;
+		esac
+
 		tmake_file="loongarch/t-loongarch $tmake_file"
 		;;
 
diff --git a/gcc/config/loongarch/genopts/loongarch.opt.in b/gcc/config/loongarch/genopts/loongarch.opt.in
index 02f918053f5..7de107c3e3d 100644
--- a/gcc/config/loongarch/genopts/loongarch.opt.in
+++ b/gcc/config/loongarch/genopts/loongarch.opt.in
@@ -262,3 +262,17 @@  default value is 4.
 ; CPUCFG independently, so we use bit flags to specify them.
 TargetVariable
 HOST_WIDE_INT la_isa_evolution = 0
+
+Enum
+Name(tls_type) Type(int)
+The possible TLS dialects:
+
+EnumValue
+Enum(tls_type) String(trad) Value(TLS_TRADITIONAL)
+
+EnumValue
+Enum(tls_type) String(desc) Value(TLS_DESCRIPTORS)
+
+mtls-dialect=
+Target RejectNegative Joined Enum(tls_type) Var(la_opt_tls_dialect) Init(M_OPT_UNSET) Save
+Specify TLS dialect.
diff --git a/gcc/config/loongarch/loongarch-def.h b/gcc/config/loongarch/loongarch-def.h
index 2dbf006d013..48d60e2b456 100644
--- a/gcc/config/loongarch/loongarch-def.h
+++ b/gcc/config/loongarch/loongarch-def.h
@@ -175,6 +175,7 @@  struct loongarch_target
   int cpu_arch;	    /* CPU_ */
   int cpu_tune;	    /* same */
   int cmodel;	    /* CMODEL_ */
+  int tls_dialect;  /* TLS_ */
 };
 
 /* CPU model */
@@ -188,6 +189,12 @@  enum {
   N_TUNE_TYPES	    = 5
 };
 
+/* TLS types.  */
+enum {
+  TLS_TRADITIONAL = 0,
+  TLS_DESCRIPTORS = 1
+};
+
 /* CPU model properties */
 extern loongarch_def_array<const char *, N_ARCH_TYPES>
   loongarch_cpu_strings;
diff --git a/gcc/config/loongarch/loongarch-driver.cc b/gcc/config/loongarch/loongarch-driver.cc
index 62658f531ad..8c4ed34698b 100644
--- a/gcc/config/loongarch/loongarch-driver.cc
+++ b/gcc/config/loongarch/loongarch-driver.cc
@@ -45,7 +45,7 @@  la_driver_init (int argc ATTRIBUTE_UNUSED, const char **argv ATTRIBUTE_UNUSED)
   /* Initialize all fields of la_target.  */
   loongarch_init_target (&la_target, M_OPT_UNSET, M_OPT_UNSET, M_OPT_UNSET,
 			 M_OPT_UNSET, M_OPT_UNSET, M_OPT_UNSET, M_OPT_UNSET,
-			 0, 0);
+			 M_OPT_UNSET, 0, 0);
   return "";
 }
 
diff --git a/gcc/config/loongarch/loongarch-opts.cc b/gcc/config/loongarch/loongarch-opts.cc
index 7eeac43ed2f..ec929aa7f29 100644
--- a/gcc/config/loongarch/loongarch-opts.cc
+++ b/gcc/config/loongarch/loongarch-opts.cc
@@ -139,6 +139,7 @@  void
 loongarch_init_target (struct loongarch_target *target,
 		       int cpu_arch, int cpu_tune, int fpu, int simd,
 		       int abi_base, int abi_ext, int cmodel,
+		       int tls_dialect,
 		       HOST_WIDE_INT isa_evolution,
 		       HOST_WIDE_INT isa_evolution_set)
 {
@@ -153,6 +154,7 @@  loongarch_init_target (struct loongarch_target *target,
   target->abi.base = abi_base;
   target->abi.ext = abi_ext;
   target->cmodel = cmodel;
+  target->tls_dialect = tls_dialect;
 }
 
 
@@ -174,7 +176,8 @@  loongarch_config_target (struct loongarch_target *target,
   obstack_init (&msg_obstack);
 
   struct {
-    int arch, tune, fpu, simd, abi_base, abi_ext, cmodel, abi_flt;
+    int arch, tune, fpu, simd, abi_base, abi_ext, cmodel,
+	tls_dialect, abi_flt;
   } constrained = {
       M_OPT_ABSENT (target->cpu_arch)	  ? 0 : 1,
       M_OPT_ABSENT (target->cpu_tune)	  ? 0 : 1,
@@ -183,6 +186,7 @@  loongarch_config_target (struct loongarch_target *target,
       M_OPT_ABSENT (target->abi.base)	  ? 0 : 1,
       M_OPT_ABSENT (target->abi.ext)	  ? 0 : 1,
       M_OPT_ABSENT (target->cmodel)	  ? 0 : 1,
+      M_OPT_ABSENT (target->tls_dialect)  ? 0 : 1,
       M_OPT_ABSENT (target->abi.base)	  ? 0 : 1,
   };
 
@@ -551,6 +555,9 @@  fallback:
       gcc_unreachable ();
     }
 
+  t.tls_dialect = constrained.tls_dialect ? target->tls_dialect
+	  : DEFAULT_TLS_TYPE;
+
   /* Cleanup and return.  */
   obstack_free (&msg_obstack, NULL);
   *target = t;
@@ -786,6 +793,9 @@  loongarch_update_gcc_opt_status (struct loongarch_target *target,
   /* status of -mcmodel */
   opts->x_la_opt_cmodel = target->cmodel;
 
+  /* status of -mtls-dialect */
+  opts->x_la_opt_tls_dialect = target->tls_dialect;
+
   /* status of -mfpu */
   opts->x_la_opt_fpu = target->isa.fpu;
 
diff --git a/gcc/config/loongarch/loongarch-opts.h b/gcc/config/loongarch/loongarch-opts.h
index 586e67e65ee..88e23fcee4b 100644
--- a/gcc/config/loongarch/loongarch-opts.h
+++ b/gcc/config/loongarch/loongarch-opts.h
@@ -35,6 +35,7 @@  void
 loongarch_init_target (struct loongarch_target *target,
 		       int cpu_arch, int cpu_tune, int fpu, int simd,
 		       int abi_base, int abi_ext, int cmodel,
+		       int tls_dialect,
 		       HOST_WIDE_INT isa_evolutions,
 		       HOST_WIDE_INT isa_evolutions_set);
 
@@ -83,6 +84,7 @@  struct loongarch_flags {
 #define TARGET_ABI_LP64		  (la_target.abi.base == ABI_BASE_LP64D	\
 				   || la_target.abi.base == ABI_BASE_LP64F \
 				   || la_target.abi.base == ABI_BASE_LP64S)
+#define TARGET_TLS_DESC		  (la_target.tls_dialect == TLS_DESCRIPTORS)
 
 #define ISA_HAS_LSX \
   (la_target.isa.simd == ISA_EXT_SIMD_LSX \
diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc
index 70e31bb831c..303666bf6d5 100644
--- a/gcc/config/loongarch/loongarch.cc
+++ b/gcc/config/loongarch/loongarch.cc
@@ -2028,7 +2028,7 @@  loongarch_symbol_insns (enum loongarch_symbol_type type, machine_mode mode)
 
     case SYMBOL_TLSGD:
     case SYMBOL_TLSLDM:
-      return 3;
+      return TARGET_TLS_DESC ? 4 : 3;
 
     case SYMBOL_PCREL64:
       return 5;
@@ -2930,24 +2930,44 @@  loongarch_call_tls_get_addr (rtx sym, enum loongarch_symbol_type type, rtx v0)
 static rtx
 loongarch_legitimize_tls_address (rtx loc)
 {
-  rtx dest, tp, tmp, tmp1, tmp2, tmp3;
+  rtx dest, tp, tmp, tmp1, tmp2, tmp3, a0;
   enum tls_model model = SYMBOL_REF_TLS_MODEL (loc);
   rtx_insn *insn;
 
   switch (model)
     {
     case TLS_MODEL_LOCAL_DYNAMIC:
-      tmp = gen_rtx_REG (Pmode, GP_RETURN);
-      dest = gen_reg_rtx (Pmode);
-      insn = loongarch_call_tls_get_addr (loc, SYMBOL_TLSLDM, tmp);
-      emit_libcall_block (insn, dest, tmp, loc);
-      break;
-
+      if (!TARGET_TLS_DESC)
+	{
+	  tmp = gen_rtx_REG (Pmode, GP_RETURN);
+	  dest = gen_reg_rtx (Pmode);
+	  insn = loongarch_call_tls_get_addr (loc, SYMBOL_TLSLDM, tmp);
+	  emit_libcall_block (insn, dest, tmp, loc);
+	  break;
+	}
+      /* Fall through.  */
     case TLS_MODEL_GLOBAL_DYNAMIC:
-      tmp = gen_rtx_REG (Pmode, GP_RETURN);
-      dest = gen_reg_rtx (Pmode);
-      insn = loongarch_call_tls_get_addr (loc, SYMBOL_TLSGD, tmp);
-      emit_libcall_block (insn, dest, tmp, loc);
+      if (TARGET_TLS_DESC)
+	{
+	  a0 = gen_rtx_REG (Pmode, GP_ARG_FIRST);
+	  dest = gen_reg_rtx (Pmode);
+	  tp = gen_rtx_REG (Pmode, THREAD_POINTER_REGNUM);
+
+	  if (TARGET_CMODEL_EXTREME)
+	    emit_insn (gen_got_load_tls_desc_off64 (a0, loc,
+						    gen_reg_rtx (DImode)));
+	  else
+	    emit_insn (gen_got_load_tls_desc (Pmode, a0, loc));
+
+	  emit_insn (gen_add3_insn (dest, a0, tp));
+	}
+      else
+	{
+	  tmp = gen_rtx_REG (Pmode, GP_RETURN);
+	  dest = gen_reg_rtx (Pmode);
+	  insn = loongarch_call_tls_get_addr (loc, SYMBOL_TLSGD, tmp);
+	  emit_libcall_block (insn, dest, tmp, loc);
+	}
       break;
 
     case TLS_MODEL_INITIAL_EXEC:
@@ -7660,7 +7680,8 @@  loongarch_option_override_internal (struct gcc_options *opts,
   loongarch_init_target (&la_target,
 			 la_opt_cpu_arch, la_opt_cpu_tune, la_opt_fpu,
 			 la_opt_simd, la_opt_abi_base, la_opt_abi_ext,
-			 la_opt_cmodel, opts->x_la_isa_evolution,
+			 la_opt_cmodel, la_opt_tls_dialect,
+			 opts->x_la_isa_evolution,
 			 opts_set->x_la_isa_evolution);
 
   /* Handle target-specific options: compute defaults/conflicts etc.  */
@@ -7873,6 +7894,7 @@  loongarch_option_restore (struct gcc_options *,
   la_target.isa.evolution = ptr->x_la_isa_evolution;
 
   la_target.cmodel = ptr->x_la_opt_cmodel;
+  la_target.tls_dialect = ptr->x_la_opt_tls_dialect;
 }
 
 /* Implement TARGET_CONDITIONAL_REGISTER_USAGE.  */
diff --git a/gcc/config/loongarch/loongarch.md b/gcc/config/loongarch/loongarch.md
index 525e1e82183..0a1a6a24f61 100644
--- a/gcc/config/loongarch/loongarch.md
+++ b/gcc/config/loongarch/loongarch.md
@@ -52,6 +52,8 @@  (define_c_enum "unspec" [
 
   ;; TLS
   UNSPEC_TLS
+  UNSPEC_TLS_DESC
+  UNSPEC_TLS_DESC_OFF64
 
   ;; Stack tie
   UNSPEC_TIE
@@ -127,6 +129,15 @@  (define_constants
    (T1_REGNUM			13)
    (S0_REGNUM			23)
 
+   (FCC0_REGNUM			64)
+   (FCC1_REGNUM			65)
+   (FCC2_REGNUM			66)
+   (FCC3_REGNUM			67)
+   (FCC4_REGNUM			68)
+   (FCC5_REGNUM			69)
+   (FCC6_REGNUM			70)
+   (FCC7_REGNUM			71)
+
    ;; Return path styles
    (NORMAL_RETURN		0)
    (SIBCALL_RETURN		1)
@@ -2760,6 +2771,63 @@  (define_insn "store_word<mode>"
 
 ;; Thread-Local Storage
 
+(define_insn "@got_load_tls_desc<mode>"
+  [(set (match_operand:P 0 "register_operand" "=r")
+	(unspec:P
+	    [(match_operand:P 1 "symbolic_operand" "")]
+	    UNSPEC_TLS_DESC))
+    (clobber (reg:SI FCC0_REGNUM))
+    (clobber (reg:SI FCC1_REGNUM))
+    (clobber (reg:SI FCC2_REGNUM))
+    (clobber (reg:SI FCC3_REGNUM))
+    (clobber (reg:SI FCC4_REGNUM))
+    (clobber (reg:SI FCC5_REGNUM))
+    (clobber (reg:SI FCC6_REGNUM))
+    (clobber (reg:SI FCC7_REGNUM))
+    (clobber (reg:SI RETURN_ADDR_REGNUM))]
+  "TARGET_TLS_DESC"
+{
+  return TARGET_EXPLICIT_RELOCS
+    ? "pcalau12i\t$r4,%%desc_pc_hi20(%1)\n\
+      \taddi.d\t$r4,$r4,%%desc_pc_lo12(%1)\n\
+      \tld.d\t$r1,$r4,%%desc_ld(%1)\n\
+      \tjirl\t$r1,$r1,%%desc_call(%1)"
+    : "la.tls.desc\t%0,%1";
+}
+  [(set_attr "got" "load")
+   (set_attr "mode" "<MODE>")
+   (set_attr "length" "16")])
+
+(define_insn "got_load_tls_desc_off64"
+  [(set (match_operand:DI 0 "register_operand" "=r")
+	(unspec:DI
+	    [(match_operand:DI 1 "symbolic_operand" "")]
+	    UNSPEC_TLS_DESC_OFF64))
+    (clobber (reg:SI FCC0_REGNUM))
+    (clobber (reg:SI FCC1_REGNUM))
+    (clobber (reg:SI FCC2_REGNUM))
+    (clobber (reg:SI FCC3_REGNUM))
+    (clobber (reg:SI FCC4_REGNUM))
+    (clobber (reg:SI FCC5_REGNUM))
+    (clobber (reg:SI FCC6_REGNUM))
+    (clobber (reg:SI FCC7_REGNUM))
+    (clobber (reg:SI RETURN_ADDR_REGNUM))
+    (clobber (match_operand:DI 2 "register_operand" "=&r"))]
+  "TARGET_TLS_DESC && TARGET_CMODEL_EXTREME"
+{
+  return TARGET_EXPLICIT_RELOCS
+    ? "pcalau12i\t$r4,%%desc_pc_hi20(%1)\n\
+      \taddi.d\t%2,$r0,%%desc_pc_lo12(%1)\n\
+      \tlu32i.d\t%2,%%desc64_pc_lo20(%1)\n\
+      \tlu52i.d\t%2,%2,%%desc64_pc_hi12(%1)\n\
+      \tadd.d\t$r4,$r4,%2\n\
+      \tld.d\t$r1,$r4,%%desc_ld(%1)\n\
+      \tjirl\t$r1,$r1,%%desc_call(%1)"
+    : "la.tls.desc\t%0,%2,%1";
+}
+  [(set_attr "got" "load")
+   (set_attr "length" "28")])
+
 (define_insn "@load_tls<mode>"
   [(set (match_operand:P 0 "register_operand" "=r")
 	(unspec:P
diff --git a/gcc/config/loongarch/loongarch.opt b/gcc/config/loongarch/loongarch.opt
index f10fcdd968c..1c54ab6ae43 100644
--- a/gcc/config/loongarch/loongarch.opt
+++ b/gcc/config/loongarch/loongarch.opt
@@ -271,6 +271,20 @@  default value is 4.
 TargetVariable
 HOST_WIDE_INT la_isa_evolution = 0
 
+Enum
+Name(tls_type) Type(int)
+The possible TLS dialects:
+
+EnumValue
+Enum(tls_type) String(trad) Value(TLS_TRADITIONAL)
+
+EnumValue
+Enum(tls_type) String(desc) Value(TLS_DESCRIPTORS)
+
+mtls-dialect=
+Target RejectNegative Joined Enum(tls_type) Var(la_opt_tls_dialect) Init(M_OPT_UNSET) Save
+Specify TLS dialect.
+
 mfrecipe
 Target Mask(ISA_FRECIPE) Var(la_isa_evolution)
 Support frecipe.{s/d} and frsqrte.{s/d} instructions.
diff --git a/gcc/testsuite/gcc.target/loongarch/cmodel-extreme-1.c b/gcc/testsuite/gcc.target/loongarch/cmodel-extreme-1.c
index 564ee4017f7..6269607e7df 100644
--- a/gcc/testsuite/gcc.target/loongarch/cmodel-extreme-1.c
+++ b/gcc/testsuite/gcc.target/loongarch/cmodel-extreme-1.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-march=loongarch64 -mabi=lp64d -O2 -mcmodel=extreme -fno-plt -mexplicit-relocs=always -fdump-rtl-final" } */
+/* { dg-options "-march=loongarch64 -mabi=lp64d -O2 -mcmodel=extreme -mtls-dialect=trad -fno-plt -mexplicit-relocs=always -fdump-rtl-final" } */
 
 int a;
 extern int b;
diff --git a/gcc/testsuite/gcc.target/loongarch/cmodel-extreme-2.c b/gcc/testsuite/gcc.target/loongarch/cmodel-extreme-2.c
index ce834805f38..35f6ee0bb30 100644
--- a/gcc/testsuite/gcc.target/loongarch/cmodel-extreme-2.c
+++ b/gcc/testsuite/gcc.target/loongarch/cmodel-extreme-2.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-march=loongarch64 -mabi=lp64d -O2 -mcmodel=extreme -fno-plt -mexplicit-relocs=auto -fdump-rtl-final" } */
+/* { dg-options "-march=loongarch64 -mabi=lp64d -O2 -mcmodel=extreme -mtls-dialect=trad -fno-plt -mexplicit-relocs=auto -fdump-rtl-final" } */
 
 #include "cmodel-extreme-1.c"
 
diff --git a/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-extreme-tls-desc.c b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-extreme-tls-desc.c
new file mode 100644
index 00000000000..0fc7a1a5117
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-extreme-tls-desc.c
@@ -0,0 +1,10 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fPIC -mcmodel=extreme -mexplicit-relocs=auto -mtls-dialect=desc" } */
+
+__thread int a __attribute__((visibility("hidden")));
+extern __thread int b __attribute__((visibility("default")));
+
+int test() { return a + b; }
+
+/* { dg-final { scan-assembler "la\\.tls\\.desc\t\\\$r4,\\\$r12,\\.LANCHOR0" { target tls_native } } } */
+/* { dg-final { scan-assembler "la\\.tls\\.desc\t\\\$r4,\\\$r12,\\.LANCHOR0" { target tls_native } } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-tls-desc.c b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-tls-desc.c
new file mode 100644
index 00000000000..37947ecfdc8
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-tls-desc.c
@@ -0,0 +1,10 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fPIC -mexplicit-relocs=auto -mtls-dialect=desc" } */
+
+__thread int a __attribute__((visibility("hidden")));
+extern __thread int b __attribute__((visibility("default")));
+
+int test() { return a + b; }
+
+/* { dg-final { scan-assembler "la\\.tls\\.desc\t\\\$r4,\\.LANCHOR0" { target tls_native } } } */
+/* { dg-final { scan-assembler "la\\.tls\\.desc\t\\\$r4,\\.LANCHOR0" { target tls_native } } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-tls-ld-gd.c b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-tls-ld-gd.c
index ca55fcfc53e..b47e37c822c 100644
--- a/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-tls-ld-gd.c
+++ b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-auto-tls-ld-gd.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-O2 -fPIC -mexplicit-relocs=auto" } */
+/* { dg-options "-O2 -fPIC -mexplicit-relocs=auto -mtls-dialect=trad" } */
 
 __thread int a __attribute__((visibility("hidden")));
 extern __thread int b __attribute__((visibility("default")));
diff --git a/gcc/testsuite/gcc.target/loongarch/explicit-relocs-extreme-tls-desc.c b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-extreme-tls-desc.c
new file mode 100644
index 00000000000..3797556e1e6
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-extreme-tls-desc.c
@@ -0,0 +1,16 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fPIC -mexplicit-relocs -mtls-dialect=desc -mcmodel=extreme" } */
+
+__thread int a __attribute__((visibility("hidden")));
+extern __thread int b __attribute__((visibility("default")));
+
+int test() { return a + b; }
+
+/* { dg-final { scan-assembler "pcalau12i\t\\\$r4,%desc_pc_hi20\\\(\\.LANCHOR0\\\)" { target tls_native } } } */
+/* { dg-final { scan-assembler "addi.d\t\\\$r12,\\\$r0,%desc_pc_lo12\\\(\\.LANCHOR0\\\)" { target tls_native } } } */
+/* { dg-final { scan-assembler "lu32i.d\t\\\$r12,%desc64_pc_lo20\\\(\\.LANCHOR0\\\)" { target tls_native } } } */
+/* { dg-final { scan-assembler "lu52i.d\t\\\$r12,\\\$r12,%desc64_pc_hi12\\\(\\.LANCHOR0\\\)" { target tls_native } } } */
+/* { dg-final { scan-assembler "add.d\t\\\$r4,\\\$r4,\\\$r12" { target tls_native } } } */
+/* { dg-final { scan-assembler "ld.d\t\\\$r1,\\\$r4,%desc_ld\\\(\\.LANCHOR0\\\)" { target tls_native } } } */
+/* { dg-final { scan-assembler "jirl\t\\\$r1,\\\$r1,%desc_call\\\(\\.LANCHOR0\\\)" { target tls_native } } } */
+/* { dg-final { scan-assembler "add.d\t\\\$r12,\\\$r4,\\\$r2" { target tls_native } } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/explicit-relocs-medium-call36-auto-tls-ld-gd.c b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-medium-call36-auto-tls-ld-gd.c
index d1a4820834c..cfb8553236a 100644
--- a/gcc/testsuite/gcc.target/loongarch/explicit-relocs-medium-call36-auto-tls-ld-gd.c
+++ b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-medium-call36-auto-tls-ld-gd.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-O2 -fPIC -mexplicit-relocs=auto -mcmodel=medium -fplt" } */
+/* { dg-options "-O2 -fPIC -mexplicit-relocs=auto -mtls-dialect=trad -mcmodel=medium -fplt" } */
 /* { dg-final { scan-assembler "pcaddu18i\t\\\$r1,%call36\\\(__tls_get_addr\\\)" { target { tls_native && loongarch_call36_support } } } } */
 
 #include "./explicit-relocs-auto-tls-ld-gd.c"
diff --git a/gcc/testsuite/gcc.target/loongarch/explicit-relocs-tls-desc.c b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-tls-desc.c
new file mode 100644
index 00000000000..f6690309156
--- /dev/null
+++ b/gcc/testsuite/gcc.target/loongarch/explicit-relocs-tls-desc.c
@@ -0,0 +1,13 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fPIC -mexplicit-relocs -mtls-dialect=desc" } */
+
+__thread int a __attribute__((visibility("hidden")));
+extern __thread int b __attribute__((visibility("default")));
+
+int test() { return a + b; }
+
+/* { dg-final { scan-assembler "pcalau12i\t\\\$r4,%desc_pc_hi20\\\(\\.LANCHOR0\\\)" { target tls_native } } } */
+/* { dg-final { scan-assembler "addi.d\t\\\$r4,\\\$r4,%desc_pc_lo12\\\(\\.LANCHOR0\\\)" { target tls_native } } } */
+/* { dg-final { scan-assembler "ld.d\t\\\$r1,\\\$r4,%desc_ld\\\(\\.LANCHOR0\\\)" { target tls_native } } } */
+/* { dg-final { scan-assembler "jirl\t\\\$r1,\\\$r1,%desc_call\\\(\\.LANCHOR0\\\)" { target tls_native } } } */
+/* { dg-final { scan-assembler "add.d\t\\\$r12,\\\$r4,\\\$r2" { target tls_native } } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-medium-1.c b/gcc/testsuite/gcc.target/loongarch/func-call-medium-1.c
index 6339e832fe5..5e81df55207 100644
--- a/gcc/testsuite/gcc.target/loongarch/func-call-medium-1.c
+++ b/gcc/testsuite/gcc.target/loongarch/func-call-medium-1.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-mabi=lp64d -O0 -fpic -fplt -mno-explicit-relocs -mcmodel=medium" } */
+/* { dg-options "-mabi=lp64d -O0 -fpic -fplt -mno-explicit-relocs -mtls-dialect=trad -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" } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-medium-2.c b/gcc/testsuite/gcc.target/loongarch/func-call-medium-2.c
index a53e75e0bf9..d73df2dd8c2 100644
--- a/gcc/testsuite/gcc.target/loongarch/func-call-medium-2.c
+++ b/gcc/testsuite/gcc.target/loongarch/func-call-medium-2.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-mabi=lp64d -O0 -fno-pic -fplt -mno-explicit-relocs -mcmodel=medium" } */
+/* { dg-options "-mabi=lp64d -O0 -fno-pic -fplt -mno-explicit-relocs -mtls-dialect=trad -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" } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-medium-3.c b/gcc/testsuite/gcc.target/loongarch/func-call-medium-3.c
index 0da7bf98e3c..88a66745070 100644
--- a/gcc/testsuite/gcc.target/loongarch/func-call-medium-3.c
+++ b/gcc/testsuite/gcc.target/loongarch/func-call-medium-3.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt -mno-explicit-relocs -mcmodel=medium" } */
+/* { dg-options "-mabi=lp64d -O0 -fpic -fno-plt -mno-explicit-relocs -mtls-dialect=trad -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" } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/func-call-medium-4.c b/gcc/testsuite/gcc.target/loongarch/func-call-medium-4.c
index 0219688ae80..f9dc12feaf5 100644
--- a/gcc/testsuite/gcc.target/loongarch/func-call-medium-4.c
+++ b/gcc/testsuite/gcc.target/loongarch/func-call-medium-4.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt -mno-explicit-relocs -mcmodel=medium" } */
+/* { dg-options "-mabi=lp64d -O0 -fno-pic -fno-plt -mno-explicit-relocs -mtls-dialect=trad -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" } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/tls-extreme-macro.c b/gcc/testsuite/gcc.target/loongarch/tls-extreme-macro.c
index 4341f82129c..4adda4202fd 100644
--- a/gcc/testsuite/gcc.target/loongarch/tls-extreme-macro.c
+++ b/gcc/testsuite/gcc.target/loongarch/tls-extreme-macro.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-march=loongarch64 -mabi=lp64d -O2 -mcmodel=extreme -fno-plt -mexplicit-relocs=none" } */
+/* { dg-options "-march=loongarch64 -mabi=lp64d -O2 -mcmodel=extreme -mtls-dialect=trad -fno-plt -mexplicit-relocs=none" } */
 /* { dg-final { scan-assembler "test_le:.*la.tls.le\t\\\$r\[0-9\]+,\\\.L" { target tls_native } } } */
 /* { dg-final { scan-assembler "test_ie:.*la.tls.ie\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,\\\.L" { target tls_native } } } */
 /* { dg-final { scan-assembler "test_ld:.*la.tls.ld\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,\\\.L.*la.global\t\\\$r\[0-9\]+,\\\$r\[0-9\]+,__tls_get_addr" { target tls_native } } } */
diff --git a/gcc/testsuite/gcc.target/loongarch/tls-gd-noplt.c b/gcc/testsuite/gcc.target/loongarch/tls-gd-noplt.c
index 9432c477e9d..dfa1bf53c92 100644
--- a/gcc/testsuite/gcc.target/loongarch/tls-gd-noplt.c
+++ b/gcc/testsuite/gcc.target/loongarch/tls-gd-noplt.c
@@ -1,5 +1,5 @@ 
 /* { dg-do compile } */
-/* { dg-options "-O0 -fno-plt -mcmodel=normal -mexplicit-relocs" } */
+/* { dg-options "-O0 -fno-plt -mcmodel=normal -mtls-dialect=trad -mexplicit-relocs" } */
 /* { dg-final { scan-assembler "pcalau12i\t.*%got_pc_hi20\\(__tls_get_addr\\)\n\tld\.d.*%got_pc_lo12\\(__tls_get_addr\\)" { target tls_native } } } */
 
 __attribute__ ((tls_model ("global-dynamic"))) __thread int a;