public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v4 0/5] Add support for TLS Descriptors (TLSDESC)
@ 2023-12-15 10:11 Lulu Cai
  2023-12-15 10:11 ` [PATCH v4 1/5] LoongArch: Add new relocs and macro for TLSDESC Lulu Cai
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Lulu Cai @ 2023-12-15 10:11 UTC (permalink / raw)
  To: binutils
  Cc: xuchenghua, chenglulu, liuzhensong, mengqinggang, xry111,
	i.swmail, maskray, luweining, wanglei, hejinyang, Lulu Cai

v4 mainly adjusted the relaxation conditions of GD/LD/DESC:
1. It is possible to relax for undefined symbols.
2. Modified the pcaddi calculation method to calculate the
   got address of the symbol instead of the actual address of the symbol.

Lulu Cai (4):
  LoongArch: Add new relocs and macro for TLSDESC.
  LoongArch: Add support for TLSDESC in ld.
  LoongArch: Add tls transition support. Transitions between DESC->IE/LE
    and IE->LE are supported now.
  LoongArch: Add testsuit for DESC and tls transition and tls
    relaxation.

mengqinggang (1):
  LoongArch: TLS LD/GD/DESC relaxation

 bfd/bfd-in2.h                                 |  15 +
 bfd/elfnn-loongarch.c                         | 555 ++++++++++++++++--
 bfd/elfxx-loongarch.c                         | 265 ++++++++-
 bfd/libbfd.h                                  |  15 +
 bfd/reloc.c                                   |  36 ++
 gas/config/tc-loongarch.c                     |  20 +-
 gas/testsuite/gas/loongarch/macro_op.d        | 128 ++--
 gas/testsuite/gas/loongarch/macro_op_32.d     | 120 ++--
 .../gas/loongarch/macro_op_large_abs.d        | 160 ++---
 .../gas/loongarch/macro_op_large_pc.d         | 160 ++---
 gas/testsuite/gas/loongarch/tlsdesc_32.d      |  28 +
 gas/testsuite/gas/loongarch/tlsdesc_32.s      |  12 +
 gas/testsuite/gas/loongarch/tlsdesc_64.d      |  28 +
 gas/testsuite/gas/loongarch/tlsdesc_64.s      |  12 +
 .../gas/loongarch/tlsdesc_large_abs.d         |  21 +
 .../gas/loongarch/tlsdesc_large_abs.s         |   9 +
 .../gas/loongarch/tlsdesc_large_pc.d          |  22 +
 .../gas/loongarch/tlsdesc_large_pc.s          |  13 +
 include/elf/loongarch.h                       |  26 +-
 include/opcode/loongarch.h                    |   6 +
 ld/testsuite/ld-loongarch-elf/desc-ie.d       |  16 +
 ld/testsuite/ld-loongarch-elf/desc-ie.s       |  18 +
 ld/testsuite/ld-loongarch-elf/desc-le.d       |  15 +
 ld/testsuite/ld-loongarch-elf/desc-le.s       |  14 +
 ld/testsuite/ld-loongarch-elf/desc-norelax.d  |  16 +
 ld/testsuite/ld-loongarch-elf/desc-norelax.s  |   5 +
 ld/testsuite/ld-loongarch-elf/desc-relax.d    |  15 +
 ld/testsuite/ld-loongarch-elf/desc-relax.s    |   5 +
 ld/testsuite/ld-loongarch-elf/ie-le.d         |  13 +
 ld/testsuite/ld-loongarch-elf/ie-le.s         |  11 +
 .../ld-loongarch-elf/ld-loongarch-elf.exp     |   9 +
 ld/testsuite/ld-loongarch-elf/macro_op.d      | 391 ++++++------
 ld/testsuite/ld-loongarch-elf/macro_op_32.d   | 120 ++--
 ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d   |  56 ++
 ld/testsuite/ld-loongarch-elf/tlsdesc-dso.s   |  66 +++
 opcodes/loongarch-opc.c                       |  54 ++
 36 files changed, 1907 insertions(+), 568 deletions(-)
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_32.d
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_32.s
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_64.d
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_64.s
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_large_abs.d
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_large_abs.s
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_large_pc.d
 create mode 100644 gas/testsuite/gas/loongarch/tlsdesc_large_pc.s
 create mode 100644 ld/testsuite/ld-loongarch-elf/desc-ie.d
 create mode 100644 ld/testsuite/ld-loongarch-elf/desc-ie.s
 create mode 100644 ld/testsuite/ld-loongarch-elf/desc-le.d
 create mode 100644 ld/testsuite/ld-loongarch-elf/desc-le.s
 create mode 100644 ld/testsuite/ld-loongarch-elf/desc-norelax.d
 create mode 100644 ld/testsuite/ld-loongarch-elf/desc-norelax.s
 create mode 100644 ld/testsuite/ld-loongarch-elf/desc-relax.d
 create mode 100644 ld/testsuite/ld-loongarch-elf/desc-relax.s
 create mode 100644 ld/testsuite/ld-loongarch-elf/ie-le.d
 create mode 100644 ld/testsuite/ld-loongarch-elf/ie-le.s
 create mode 100644 ld/testsuite/ld-loongarch-elf/tlsdesc-dso.d
 create mode 100644 ld/testsuite/ld-loongarch-elf/tlsdesc-dso.s

-- 
2.36.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v4 1/5] LoongArch: Add new relocs and macro for TLSDESC.
  2023-12-15 10:11 [PATCH v4 0/5] Add support for TLS Descriptors (TLSDESC) Lulu Cai
@ 2023-12-15 10:11 ` Lulu Cai
  2023-12-15 10:11 ` [PATCH v4 2/5] LoongArch: Add support for TLSDESC in ld Lulu Cai
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Lulu Cai @ 2023-12-15 10:11 UTC (permalink / raw)
  To: binutils
  Cc: xuchenghua, chenglulu, liuzhensong, mengqinggang, xry111,
	i.swmail, maskray, luweining, wanglei, hejinyang, Lulu Cai

---
 bfd/bfd-in2.h             |  12 +++
 bfd/elfxx-loongarch.c     | 211 +++++++++++++++++++++++++++++++++++++-
 bfd/libbfd.h              |  12 +++
 bfd/reloc.c               |  29 ++++++
 gas/config/tc-loongarch.c |  14 ++-
 include/elf/loongarch.h   |  22 +++-
 opcodes/loongarch-opc.c   |  54 ++++++++++
 7 files changed, 350 insertions(+), 4 deletions(-)

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 040d5560cdf..d3557a4fd74 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -7377,6 +7377,8 @@ enum bfd_reloc_code_real
   BFD_RELOC_LARCH_TLS_DTPREL64,
   BFD_RELOC_LARCH_TLS_TPREL32,
   BFD_RELOC_LARCH_TLS_TPREL64,
+  BFD_RELOC_LARCH_TLS_DESC32,
+  BFD_RELOC_LARCH_TLS_DESC64,
   BFD_RELOC_LARCH_MARK_LA,
   BFD_RELOC_LARCH_MARK_PCREL,
   BFD_RELOC_LARCH_SOP_PUSH_PCREL,
@@ -7460,6 +7462,16 @@ enum bfd_reloc_code_real
   BFD_RELOC_LARCH_ADD_ULEB128,
   BFD_RELOC_LARCH_SUB_ULEB128,
   BFD_RELOC_LARCH_64_PCREL,
+  BFD_RELOC_LARCH_TLS_DESC_PC_HI20,
+  BFD_RELOC_LARCH_TLS_DESC_ADD_PC_LO12,
+  BFD_RELOC_LARCH_TLS_DESC_LD,
+  BFD_RELOC_LARCH_TLS_DESC64_PC_LO20,
+  BFD_RELOC_LARCH_TLS_DESC64_PC_HI12,
+  BFD_RELOC_LARCH_TLS_DESC_HI20,
+  BFD_RELOC_LARCH_TLS_DESC_LO12,
+  BFD_RELOC_LARCH_TLS_DESC64_LO20,
+  BFD_RELOC_LARCH_TLS_DESC64_HI12,
+  BFD_RELOC_LARCH_TLS_DESC_CALL,
   BFD_RELOC_UNUSED
 };
 typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c
index 7f298c08fd3..819c4849ef5 100644
--- a/bfd/elfxx-loongarch.c
+++ b/bfd/elfxx-loongarch.c
@@ -293,8 +293,40 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
 	 NULL,				  /* adjust_reloc_bits */
 	 NULL),				  /* larch_reloc_type_name */
 
-  LOONGARCH_EMPTY_HOWTO (13),
-  LOONGARCH_EMPTY_HOWTO (14),
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC32,	  /* type (13).  */
+	 0,				  /* rightshift.  */
+	 4,				  /* size.  */
+	 32,				  /* bitsize.  */
+	 false,				  /* pc_relative.  */
+	 0,				  /* bitpos.  */
+	 complain_overflow_dont,	  /* complain_on_overflow.  */
+	 bfd_elf_generic_reloc,		  /* special_function.  */
+	 "R_LARCH_TLS_DESC32",		  /* name.  */
+	 false,				  /* partial_inplace.  */
+	 0,				  /* src_mask.  */
+	 ALL_ONES,		  	  /* dst_mask.  */
+	 false,				  /* pcrel_offset.  */
+	 BFD_RELOC_LARCH_TLS_DESC32,	  /* bfd_reloc_code_real_type.  */
+	 NULL,				  /* adjust_reloc_bits.  */
+	 NULL),				  /* larch_reloc_type_name.  */
+
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC64,	  /* type (14).  */
+	 0,				  /* rightshift.  */
+	 4,				  /* size.  */
+	 64,				  /* bitsize.  */
+	 false,				  /* pc_relative.  */
+	 0,				  /* bitpos.  */
+	 complain_overflow_dont,	  /* complain_on_overflow.  */
+	 bfd_elf_generic_reloc,		  /* special_function.  */
+	 "R_LARCH_TLS_DESC64",		  /* name.  */
+	 false,				  /* partial_inplace.  */
+	 0,				  /* src_mask.  */
+	 ALL_ONES,			  /* dst_mask.  */
+	 false,				  /* pcrel_offset.  */
+	 BFD_RELOC_LARCH_TLS_DESC64,	  /* bfd_reloc_code_real_type.  */
+	 NULL,				  /* adjust_reloc_bits.  */
+	 NULL),				  /* larch_reloc_type_name.  */
+
   LOONGARCH_EMPTY_HOWTO (15),
   LOONGARCH_EMPTY_HOWTO (16),
   LOONGARCH_EMPTY_HOWTO (17),
@@ -1547,6 +1579,181 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
 	 NULL,					/* adjust_reloc_bits */
 	 NULL),					/* larch_reloc_type_name */
 
+  LOONGARCH_EMPTY_HOWTO (110),
+
+  /* TLS_DESC PCREL.  */
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC_PC_HI20,	/* type (111).  */
+	 12,					/* rightshift.  */
+	 4,					/* size.  */
+	 20,					/* bitsize.  */
+	 true,					/* pc_relative.  */
+	 5,					/* bitpos.  */
+	 complain_overflow_signed,		/* complain_on_overflow.  */
+	 bfd_elf_generic_reloc,			/* special_function.  */
+	 "R_LARCH_TLS_DESC_PC_HI20",		/* name.  */
+	 false,					/* partial_inplace.  */
+	 0,					/* src_mask.  */
+	 0x1ffffe0,				/* dst_mask.  */
+	 false,					/* pcrel_offset.  */
+	 BFD_RELOC_LARCH_TLS_DESC_PC_HI20,	/* bfd_reloc_code_real_type.  */
+	 reloc_bits,				/* adjust_reloc_bits.  */
+	 "desc_pc_hi20"),			/* larch_reloc_type_name.  */
+
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC_ADD_PC_LO12,/* type (112).  */
+	 0,					/* rightshift.  */
+	 4,					/* size.  */
+	 12,					/* bitsize.  */
+	 true,					/* pc_relative.  */
+	 10,					/* bitpos.  */
+	 complain_overflow_signed,		/* complain_on_overflow.  */
+	 bfd_elf_generic_reloc,			/* special_function.  */
+	 "R_LARCH_TLS_DESC_ADD_PC_LO12",	/* name.  */
+	 false,					/* partial_inplace.  */
+	 0,					/* src_mask.  */
+	 0x3ffc00,				/* dst_mask.  */
+	 false,					/* pcrel_offset.  */
+	 BFD_RELOC_LARCH_TLS_DESC_ADD_PC_LO12,	/* bfd_reloc_code_real_type.  */
+	 reloc_bits,				/* adjust_reloc_bits.  */
+	 "desc_add_pc_lo12"),			/* larch_reloc_type_name.  */
+
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC_LD,		/* type (113).  */
+	 0,					/* rightshift.  */
+	 4,					/* size.  */
+	 0,					/* bitsize.  */
+	 true,					/* pc_relative.  */
+	 0,					/* bitpos.  */
+	 complain_overflow_signed,		/* complain_on_overflow.  */
+	 bfd_elf_generic_reloc,			/* special_function.  */
+	 "R_LARCH_TLS_DESC_LD",			/* name.  */
+	 false,					/* partial_inplace.  */
+	 0,					/* src_mask.  */
+	 0,					/* dst_mask.  */
+	 false,					/* pcrel_offset.  */
+	 BFD_RELOC_LARCH_TLS_DESC_LD,		/* bfd_reloc_code_real_type.  */
+	 NULL,					/* adjust_reloc_bits.  */
+	 "desc_ld"),				/* larch_reloc_type_name.  */
+
+  /* TLS_DESC64 LARGE PCREL.  */
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC64_PC_LO20, /* type (114).  */
+	32,				       /* rightshift.  */
+	4,				       /* size.  */
+	20,				       /* bitsize.  */
+	true,				       /* pc_relative.  */
+	5,				       /* bitpos.  */
+	complain_overflow_signed,	       /* complain_on_overflow.  */
+	bfd_elf_generic_reloc,		       /* special_function.  */
+	"R_LARCH_TLS_DESC64_PC_LO20",	       /* name.  */
+	false,				       /* partial_inplace.  */
+	0,				       /* src_mask.  */
+	0x1ffffe0,			       /* dst_mask.  */
+	false,				       /* pcrel_offset.  */
+	BFD_RELOC_LARCH_TLS_DESC64_PC_LO20,    /* bfd_reloc_code_real_type.  */
+	reloc_bits,			       /* adjust_reloc_bits.  */
+	"desc64_pc_lo20"),		       /* larch_reloc_type_name.  */
+
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC64_PC_HI12, /* type (115).  */
+	52,				       /* rightshift.  */
+	4,				       /* size.  */
+	12,				       /* bitsize.  */
+	true,				       /* pc_relative.  */
+	10,				       /* bitpos.  */
+	complain_overflow_signed,	       /* complain_on_overflow.  */
+	bfd_elf_generic_reloc,		       /* special_function.  */
+	"R_LARCH_TLS_DESC64_PC_HI12",	       /* name.  */
+	false,				       /* partial_inplace.  */
+	0,				       /* src_mask.  */
+	0x3ffc00,			       /* dst_mask.  */
+	false,				       /* pcrel_offset.  */
+	BFD_RELOC_LARCH_TLS_DESC64_PC_HI12,    /* bfd_reloc_code_real_type.  */
+	reloc_bits,			       /* adjust_reloc_bits.  */
+	"desc64_pc_hi12"),		       /* larch_reloc_type_name.  */
+
+  /* TLS_DESC ABS.  */
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC_HI20,	/* type (116).  */
+	 12,					/* rightshift.  */
+	 4,					/* size.  */
+	 20,					/* bitsize.  */
+	 false,					/* pc_relative.  */
+	 5,					/* bitpos.  */
+	 complain_overflow_signed,		/* complain_on_overflow.  */
+	 bfd_elf_generic_reloc,			/* special_function.  */
+	 "R_LARCH_TLS_DESC_HI20",		/* name.  */
+	 false,					/* partial_inplace.  */
+	 0,					/* src_mask.  */
+	 0x1ffffe0,				/* dst_mask.  */
+	 false,					/* pcrel_offset.  */
+	 BFD_RELOC_LARCH_TLS_DESC_HI20,		/* bfd_reloc_code_real_type.  */
+	 reloc_bits,				/* adjust_reloc_bits.  */
+	 "desc_hi20"),				/* larch_reloc_type_name.  */
+
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC_LO12,	/* type (117).  */
+	 0,					/* rightshift.  */
+	 4,					/* size.  */
+	 12,					/* bitsize.  */
+	 false,					/* pc_relative.  */
+	 10,					/* bitpos.  */
+	 complain_overflow_signed,		/* complain_on_overflow.  */
+	 bfd_elf_generic_reloc,			/* special_function.  */
+	 "R_LARCH_TLS_DESC_LO12",		/* name.  */
+	 false,					/* partial_inplace.  */
+	 0,					/* src_mask.  */
+	 0x3ffc00,				/* dst_mask.  */
+	 false,					/* pcrel_offset.  */
+	 BFD_RELOC_LARCH_TLS_DESC_LO12,		/* bfd_reloc_code_real_type.  */
+	 reloc_bits,				/* adjust_reloc_bits.  */
+	 "desc_lo12"),				/* larch_reloc_type_name.  */
+
+  /* TLS_DESC64 LARGE ABS.  */
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC64_LO20,    /* type (118).  */
+	32,				       /* rightshift.  */
+	4,				       /* size.  */
+	20,				       /* bitsize.  */
+	false,				       /* pc_relative.  */
+	5,				       /* bitpos.  */
+	complain_overflow_signed,	       /* complain_on_overflow.  */
+	bfd_elf_generic_reloc,		       /* special_function.  */
+	"R_LARCH_TLS_DESC64_LO20",	       /* name.  */
+	false,				       /* partial_inplace.  */
+	0,				       /* src_mask.  */
+	0x1ffffe0,			       /* dst_mask.  */
+	false,				       /* pcrel_offset.  */
+	BFD_RELOC_LARCH_TLS_DESC64_LO20,       /* bfd_reloc_code_real_type.  */
+	reloc_bits,			       /* adjust_reloc_bits.  */
+	"desc64_lo20"),			       /* larch_reloc_type_name.  */
+
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC64_HI12,    /* type (119).  */
+	52,				       /* rightshift.  */
+	4,				       /* size.  */
+	12,				       /* bitsize.  */
+	false,				       /* pc_relative.  */
+	10,				       /* bitpos.  */
+	complain_overflow_signed,	       /* complain_on_overflow.  */
+	bfd_elf_generic_reloc,		       /* special_function.  */
+	"R_LARCH_TLS_DESC64_HI12",	       /* name.  */
+	false,				       /* partial_inplace.  */
+	0,				       /* src_mask.  */
+	0x3ffc00,			       /* dst_mask.  */
+	false,				       /* pcrel_offset.  */
+	BFD_RELOC_LARCH_TLS_DESC64_HI12,       /* bfd_reloc_code_real_type.  */
+	reloc_bits,			       /* adjust_reloc_bits.  */
+	"desc64_hi12"),			       /* larch_reloc_type_name.  */
+
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC_CALL,	/* type (120).  */
+	 0,					/* rightshift.  */
+	 4,					/* size.  */
+	 0,					/* bitsize.  */
+	 false,					/* pc_relative.  */
+	 0,					/* bitpos.  */
+	 complain_overflow_dont,		/* complain_on_overflow.  */
+	 bfd_elf_generic_reloc,			/* special_function.  */
+	 "R_LARCH_TLS_DESC_CALL",		/* name.  */
+	 false,					/* partial_inplace.  */
+	 0,					/* src_mask.  */
+	 0,					/* dst_mask.  */
+	 false,					/* pcrel_offset.  */
+	 BFD_RELOC_LARCH_TLS_DESC_CALL,		/* bfd_reloc_code_real_type.  */
+	 NULL,					/* adjust_reloc_bits.  */
+	 "desc_call"),				/* larch_reloc_type_name.  */
 };
 
 reloc_howto_type *
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index cc432677a81..6ee021e84b5 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -3516,6 +3516,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_LARCH_TLS_DTPREL64",
   "BFD_RELOC_LARCH_TLS_TPREL32",
   "BFD_RELOC_LARCH_TLS_TPREL64",
+  "BFD_RELOC_LARCH_TLS_DESC32",
+  "BFD_RELOC_LARCH_TLS_DESC64",
   "BFD_RELOC_LARCH_MARK_LA",
   "BFD_RELOC_LARCH_MARK_PCREL",
   "BFD_RELOC_LARCH_SOP_PUSH_PCREL",
@@ -3599,6 +3601,16 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_LARCH_ADD_ULEB128",
   "BFD_RELOC_LARCH_SUB_ULEB128",
   "BFD_RELOC_LARCH_64_PCREL",
+  "BFD_RELOC_LARCH_TLS_DESC_PC_HI20",
+  "BFD_RELOC_LARCH_TLS_DESC_ADD_PC_LO12",
+  "BFD_RELOC_LARCH_TLS_DESC_LD",
+  "BFD_RELOC_LARCH_TLS_DESC64_PC_LO20",
+  "BFD_RELOC_LARCH_TLS_DESC64_PC_HI12",
+  "BFD_RELOC_LARCH_TLS_DESC_HI20",
+  "BFD_RELOC_LARCH_TLS_DESC_LO12",
+  "BFD_RELOC_LARCH_TLS_DESC64_LO20",
+  "BFD_RELOC_LARCH_TLS_DESC64_HI12",
+  "BFD_RELOC_LARCH_TLS_DESC_CALL",
  "@@overflow: BFD_RELOC_UNUSED@@",
 };
 #endif
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 93ebad879e0..0e354ef4b80 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -8111,6 +8111,10 @@ ENUMX
   BFD_RELOC_LARCH_TLS_TPREL32
 ENUMX
   BFD_RELOC_LARCH_TLS_TPREL64
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC32
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC64
 ENUMX
   BFD_RELOC_LARCH_MARK_LA
 ENUMX
@@ -8292,6 +8296,31 @@ ENUMX
 ENUMX
   BFD_RELOC_LARCH_64_PCREL
 
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC_PC_HI20
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC_ADD_PC_LO12
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC_LD
+
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC64_PC_LO20
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC64_PC_HI12
+
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC_HI20
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC_LO12
+
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC64_LO20
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC64_HI12
+
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC_CALL
+
 ENUMDOC
   LARCH relocations.
 
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index 59232832cf7..e1d5453b14f 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -682,7 +682,7 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2,
 		      esc_ch1, esc_ch2, bit_field, arg);
 
 	  if (ip->reloc_info[0].type >= BFD_RELOC_LARCH_B16
-	      && ip->reloc_info[0].type < BFD_RELOC_LARCH_64_PCREL)
+	      && ip->reloc_info[0].type <= BFD_RELOC_LARCH_TLS_DESC_CALL)
 	    {
 	      /* As we compact stack-relocs, it is no need for pop operation.
 		 But break out until here in order to check the imm field.
@@ -1270,6 +1270,14 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_LARCH_TLS_LD_HI20:
     case BFD_RELOC_LARCH_TLS_GD_PC_HI20:
     case BFD_RELOC_LARCH_TLS_GD_HI20:
+    case BFD_RELOC_LARCH_TLS_DESC_PC_HI20:
+    case BFD_RELOC_LARCH_TLS_DESC_ADD_PC_LO12:
+    case BFD_RELOC_LARCH_TLS_DESC64_PC_LO20:
+    case BFD_RELOC_LARCH_TLS_DESC64_PC_HI12:
+    case BFD_RELOC_LARCH_TLS_DESC_HI20:
+    case BFD_RELOC_LARCH_TLS_DESC_LO12:
+    case BFD_RELOC_LARCH_TLS_DESC64_LO20:
+    case BFD_RELOC_LARCH_TLS_DESC64_HI12:
       /* Add tls lo (got_lo reloc type).  */
       if (fixP->fx_addsy == NULL)
 	as_bad_where (fixP->fx_file, fixP->fx_line,
@@ -1290,6 +1298,10 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 	stack_top = 0;
       break;
 
+    case BFD_RELOC_LARCH_TLS_DESC_LD:
+    case BFD_RELOC_LARCH_TLS_DESC_CALL:
+      break;
+
     case BFD_RELOC_LARCH_SOP_POP_32_S_10_5:
     case BFD_RELOC_LARCH_SOP_POP_32_S_10_12:
     case BFD_RELOC_LARCH_SOP_POP_32_U_10_12:
diff --git a/include/elf/loongarch.h b/include/elf/loongarch.h
index e31395e13d5..da2fd119181 100644
--- a/include/elf/loongarch.h
+++ b/include/elf/loongarch.h
@@ -38,7 +38,8 @@ RELOC_NUMBER (R_LARCH_TLS_DTPREL64, 9)
 RELOC_NUMBER (R_LARCH_TLS_TPREL32, 10)
 RELOC_NUMBER (R_LARCH_TLS_TPREL64, 11)
 RELOC_NUMBER (R_LARCH_IRELATIVE, 12)
-
+RELOC_NUMBER (R_LARCH_TLS_DESC32, 13)
+RELOC_NUMBER (R_LARCH_TLS_DESC64, 14)
 /* Reserved for future relocs that the dynamic linker must understand.  */
 
 /* Used by the static linker for relocating .text.  */
@@ -251,6 +252,25 @@ RELOC_NUMBER (R_LARCH_SUB_ULEB128, 108)
 
 RELOC_NUMBER (R_LARCH_64_PCREL, 109)
 
+/* TLS_DESC PCREL.  */
+RELOC_NUMBER (R_LARCH_TLS_DESC_PC_HI20, 111)
+RELOC_NUMBER (R_LARCH_TLS_DESC_ADD_PC_LO12, 112)
+RELOC_NUMBER (R_LARCH_TLS_DESC_LD, 113)
+
+/* TLS_DESC LARGE PCREL.  */
+RELOC_NUMBER (R_LARCH_TLS_DESC64_PC_LO20, 114)
+RELOC_NUMBER (R_LARCH_TLS_DESC64_PC_HI12, 115)
+
+/* TLS_DESC ABS.  */
+RELOC_NUMBER (R_LARCH_TLS_DESC_HI20, 116)
+RELOC_NUMBER (R_LARCH_TLS_DESC_LO12, 117)
+
+/* TLSDESC LARGE ABS.  */
+RELOC_NUMBER (R_LARCH_TLS_DESC64_LO20, 118)
+RELOC_NUMBER (R_LARCH_TLS_DESC64_HI12, 119)
+
+RELOC_NUMBER (R_LARCH_TLS_DESC_CALL, 120)
+
 END_RELOC_NUMBERS (R_LARCH_count)
 
 /* Processor specific flags for the ELF header e_flags field.  */
diff --git a/opcodes/loongarch-opc.c b/opcodes/loongarch-opc.c
index 15c7da6340c..3adcb380e0e 100644
--- a/opcodes/loongarch-opc.c
+++ b/opcodes/loongarch-opc.c
@@ -293,6 +293,55 @@ const char *const loongarch_x_normal_name[32] =
   &LARCH_opts.ase_lp64,		      \
   &LARCH_opts.ase_gpcr
 
+/* For TLS_DESC32 pcrel.  */
+#define INSN_LA_TLS_DESC32		  \
+  "pcalau12i $r4,%%desc_pc_hi20(%2);"	  \
+  "addi.w $r4,$r4,%%desc_add_pc_lo12(%2);"\
+  "ld.w $r1,$r4,%%desc_ld(%2);"		  \
+  "jirl $r1,$r1,%%desc_call(%2);",	  \
+  &LARCH_opts.ase_ilp32,		  \
+  &LARCH_opts.ase_lp64
+
+/* For TLS_DESC32 abs.  */
+#define INSN_LA_TLS_DESC32_ABS		\
+  "lu12i.w $r4,%%desc_hi20(%2);"	\
+  "ori $r4,$r4,%%desc_lo12(%2);"	\
+  "ld.w $r1,$r4,0;"			\
+  "jirl $r1,$r1,%%desc_call(%2);",	\
+  &LARCH_opts.ase_gabs,			\
+  &LARCH_opts.ase_lp64
+
+/* For TLS_DESC64 pcrel.  */
+#define INSN_LA_TLS_DESC64		  \
+  "pcalau12i $r4,%%desc_pc_hi20(%2);"	  \
+  "addi.d $r4,$r4,%%desc_add_pc_lo12(%2);"\
+  "ld.d $r1,$r4,%%desc_ld(%2);"		  \
+  "jirl $r1,$r1,%%desc_call(%2);",	  \
+  &LARCH_opts.ase_lp64, 0
+
+/* For TLS_DESC64 large pcrel.  */
+#define INSN_LA_TLS_DESC64_LARGE_PCREL	 \
+  "pcalau12i $r4,%%desc_pc_hi20(%3);"	 \
+  "addi.d %2,$r0,%%desc_add_pc_lo12(%3);"\
+  "lu32i.d %2,%%desc64_pc_lo20(%3);"	 \
+  "lu52i.d %2,%2,%%desc64_pc_hi12(%3);"	 \
+  "add.d $r4,$r4,%2;"			 \
+  "ld.d $r1,$r4,0;"			 \
+  "jirl $r1,$r1,%%desc_call(%3);",	 \
+  &LARCH_opts.ase_lp64,			 \
+  &LARCH_opts.ase_gabs
+
+/* For TLS_DESC64 large abs.  */
+#define INSN_LA_TLS_DESC64_LARGE_ABS  \
+  "lu12i.w $r4,%%desc_hi20(%2);"      \
+  "ori $r4,$r4,%%desc_lo12(%2);"      \
+  "lu32i.d $r4,%%desc64_lo20(%2);"    \
+  "lu52i.d $r4,$r4,%%desc64_hi12(%2);"\
+  "ld.d $r1,$r4,0;"		      \
+  "jirl $r1,$r1,%%desc_call(%2);",    \
+  &LARCH_opts.ase_lp64,		      \
+  &LARCH_opts.ase_gpcr
+
 
 static struct loongarch_opcode loongarch_macro_opcodes[] =
 {
@@ -341,6 +390,11 @@ static struct loongarch_opcode loongarch_macro_opcodes[] =
   { 0, 0, "la.tls.gd",	"r,l",	  INSN_LA_TLS_GD64_LARGE_ABS,	0 },
   { 0, 0, "la.tls.gd",	"r,r,l",  INSN_LA_TLS_GD64_LARGE_PCREL,	0 },
   { 0, 0, "pcaddi",	"r,la",	  "pcaddi %1, %%pcrel_20(%2)",	&LARCH_opts.ase_ilp32, 0, 0 },
+  { 0, 0, "la.tls.desc", "r,l",   INSN_LA_TLS_DESC32, 0 },
+  { 0, 0, "la.tls.desc", "r,l",   INSN_LA_TLS_DESC32_ABS, 0 },
+  { 0, 0, "la.tls.desc", "r,l",	  INSN_LA_TLS_DESC64, 0 },
+  { 0, 0, "la.tls.desc", "r,l",   INSN_LA_TLS_DESC64_LARGE_ABS, 0 },
+  { 0, 0, "la.tls.desc", "r,r,l", INSN_LA_TLS_DESC64_LARGE_PCREL, 0 },
   { 0, 0, 0, 0, 0, 0, 0, 0 } /* Terminate the list.  */
 };
 
-- 
2.36.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v4 2/5] LoongArch: Add support for TLSDESC in ld.
  2023-12-15 10:11 [PATCH v4 0/5] Add support for TLS Descriptors (TLSDESC) Lulu Cai
  2023-12-15 10:11 ` [PATCH v4 1/5] LoongArch: Add new relocs and macro for TLSDESC Lulu Cai
@ 2023-12-15 10:11 ` Lulu Cai
  2023-12-15 10:11 ` [PATCH v4 3/5] LoongArch: Add tls transition support. Transitions between DESC->IE/LE and IE->LE are supported now Lulu Cai
  2023-12-15 10:11 ` [PATCH v4 4/5] LoongArch: TLS LD/GD/DESC relaxation Lulu Cai
  3 siblings, 0 replies; 5+ messages in thread
From: Lulu Cai @ 2023-12-15 10:11 UTC (permalink / raw)
  To: binutils
  Cc: xuchenghua, chenglulu, liuzhensong, mengqinggang, xry111,
	i.swmail, maskray, luweining, wanglei, hejinyang, Lulu Cai

---
 bfd/elfnn-loongarch.c | 168 ++++++++++++++++++++++++++++++++++++------
 1 file changed, 146 insertions(+), 22 deletions(-)

diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index 024c5d4cd96..b63f42bb6a7 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -48,6 +48,12 @@ struct loongarch_elf_link_hash_entry
 #define GOT_TLS_GD  2
 #define GOT_TLS_IE  4
 #define GOT_TLS_LE  8
+#define GOT_TLS_GDESC 16
+
+#define GOT_TLS_GD_BOTH_P(tls_type) \
+  ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_GDESC))
+#define GOT_TLS_GD_ANY_P(tls_type) \
+  ((tls_type & GOT_TLS_GD) || (tls_type & GOT_TLS_GDESC))
   char tls_type;
 };
 
@@ -563,6 +569,7 @@ loongarch_elf_record_tls_and_got_reference (bfd *abfd,
     case GOT_NORMAL:
     case GOT_TLS_GD:
     case GOT_TLS_IE:
+    case GOT_TLS_GDESC:
       /* Need GOT.  */
       if (htab->elf.sgot == NULL
 	  && !loongarch_elf_create_got_section (htab->elf.dynobj, info))
@@ -750,6 +757,14 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
 	    return false;
 	  break;
 
+	case R_LARCH_TLS_DESC_PC_HI20:
+	case R_LARCH_TLS_DESC_HI20:
+	  if (!loongarch_elf_record_tls_and_got_reference (abfd, info, h,
+							   r_symndx,
+							   GOT_TLS_GDESC))
+	    return false;
+	  break;
+
 	case R_LARCH_ABS_HI20:
 	case R_LARCH_SOP_PUSH_ABSOLUTE:
 	  if (h != NULL)
@@ -1129,7 +1144,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 
       s = htab->elf.sgot;
       h->got.offset = s->size;
-      if (tls_type & (GOT_TLS_GD | GOT_TLS_IE))
+      if (tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
 	{
 	  /* TLS_GD needs two dynamic relocs and two GOT slots.  */
 	  if (tls_type & GOT_TLS_GD)
@@ -1166,7 +1181,15 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 		  htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
 		}
 	    }
+
+	  /* TLS_DESC needs one dynamic reloc and two GOT slot.  */
+	  if (tls_type & GOT_TLS_GDESC)
+	    {
+	      s->size += GOT_ENTRY_SIZE * 2;
+	      htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
+	    }
 	}
+
       else
 	{
 	  s->size += GOT_ENTRY_SIZE;
@@ -1669,19 +1692,34 @@ loongarch_elf_size_dynamic_sections (bfd *output_bfd,
 	  if (0 < *local_got)
 	    {
 	      *local_got = s->size;
+	      if (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
+		{
+		  /* TLS gd use two got.  */
+		  if (*local_tls_type & GOT_TLS_GD)
+		    {
+		      s->size += 2 * GOT_ENTRY_SIZE;
+		      if (!bfd_link_executable (info))
+			srel->size += sizeof (ElfNN_External_Rela);
+		    }
 
-	      /* TLS gd use two got.  */
-	      if (*local_tls_type & GOT_TLS_GD)
-		s->size += GOT_ENTRY_SIZE * 2;
-	      else
-		/* Normal got, tls ie/ld use one got.  */
-		s->size += GOT_ENTRY_SIZE;
+		  /* TLS_DESC use two got.  */
+		  if (*local_tls_type & GOT_TLS_GDESC)
+		    {
+		      s->size += 2 * GOT_ENTRY_SIZE;
+		      srel->size += sizeof (ElfNN_External_Rela);
+		    }
 
-	      if (bfd_link_executable (info)
-		  && (*local_tls_type & (GOT_TLS_GD| GOT_TLS_IE)))
-		;/* Do nothing.  */
+		  /* TLS ie and use one got.  */
+		  if (*local_tls_type & GOT_TLS_IE)
+		    {
+		      s->size += GOT_ENTRY_SIZE;
+		      if (!bfd_link_executable (info))
+			srel->size += sizeof (ElfNN_External_Rela);
+		    }
+		}
 	      else
 		{
+		  s->size += GOT_ENTRY_SIZE;
 		  srel->size += sizeof (ElfNN_External_Rela);
 		}
 	    }
@@ -2120,6 +2158,15 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
     case R_LARCH_TLS_GD_PC_HI20:
     case R_LARCH_TLS_GD_HI20:
     case R_LARCH_PCREL20_S2:
+    case R_LARCH_TLS_DESC_PC_HI20:
+    case R_LARCH_TLS_DESC_ADD_PC_LO12:
+    case R_LARCH_TLS_DESC64_PC_LO20:
+    case R_LARCH_TLS_DESC64_PC_HI12:
+    case R_LARCH_TLS_DESC_HI20:
+    case R_LARCH_TLS_DESC_LO12:
+    case R_LARCH_TLS_DESC64_LO20:
+    case R_LARCH_TLS_DESC64_HI12:
+
       r = loongarch_check_offset (rel, input_section);
       if (r != bfd_reloc_ok)
 	break;
@@ -2129,6 +2176,11 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
 					    contents, value);
       break;
 
+    case R_LARCH_TLS_DESC_LD:
+    case R_LARCH_TLS_DESC_CALL:
+      r = bfd_reloc_ok;
+      break;
+
     case R_LARCH_RELAX:
       break;
 
@@ -2377,10 +2429,10 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
       struct elf_link_hash_entry *h = NULL;
       const char *name;
       bfd_reloc_status_type r = bfd_reloc_ok;
-      bool is_ie, is_undefweak, unresolved_reloc, defined_local;
+      bool is_ie, is_desc, is_undefweak, unresolved_reloc, defined_local;
       bool resolved_local, resolved_dynly, resolved_to_const;
       char tls_type;
-      bfd_vma relocation, off, ie_off;
+      bfd_vma relocation, off, ie_off, desc_off;
       int i, j;
 
       howto = loongarch_elf_rtype_to_howto (input_bfd, r_type);
@@ -2509,6 +2561,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 
       BFD_ASSERT (!resolved_local || defined_local);
 
+      is_desc = false;
       is_ie = false;
       switch (r_type)
 	{
@@ -3398,6 +3451,8 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 	case R_LARCH_TLS_LD_HI20:
 	case R_LARCH_TLS_GD_PC_HI20:
 	case R_LARCH_TLS_GD_HI20:
+	case R_LARCH_TLS_DESC_PC_HI20:
+	case R_LARCH_TLS_DESC_HI20:
 	  BFD_ASSERT (rel->r_addend == 0);
 	  unresolved_reloc = false;
 
@@ -3405,6 +3460,10 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 	      || r_type == R_LARCH_TLS_IE_HI20)
 	    is_ie = true;
 
+	  if (r_type == R_LARCH_TLS_DESC_PC_HI20
+	      || r_type == R_LARCH_TLS_DESC_HI20)
+	    is_desc = true;
+
 	  bfd_vma got_off = 0;
 	  if (h != NULL)
 	    {
@@ -3419,9 +3478,19 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 
 	  BFD_ASSERT (got_off != MINUS_ONE);
 
-	  ie_off = 0;
 	  tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
-	  if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
+
+	  /* If a tls variable is accessed in multiple ways, GD uses
+	     the first two slots of GOT, desc follows with two slots,
+	     and IE uses one slot at the end.  */
+	  desc_off = 0;
+	  if (GOT_TLS_GD_BOTH_P (tls_type))
+	    desc_off = 2 * GOT_ENTRY_SIZE;
+
+	  ie_off = 0;
+	  if (GOT_TLS_GD_BOTH_P (tls_type) && (tls_type & GOT_TLS_IE))
+	    ie_off = 4 * GOT_ENTRY_SIZE;
+	  else if (GOT_TLS_GD_ANY_P (tls_type) && (tls_type & GOT_TLS_IE))
 	    ie_off = 2 * GOT_ENTRY_SIZE;
 
 	  if ((got_off & 1) == 0)
@@ -3470,6 +3539,21 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 		      loongarch_elf_append_rela (output_bfd, relgot, &rela);
 		    }
 		}
+	      if (tls_type & GOT_TLS_GDESC)
+		{
+		  /* Unless it is a static link, DESC always emits a
+		     dynamic relocation.  */
+		  int indx = h && h->dynindx != -1 ? h->dynindx : 0;
+		  rela.r_offset = sec_addr (got) + got_off + desc_off;
+		  rela.r_addend = 0;
+		  if (indx == 0)
+		    rela.r_addend = relocation - elf_hash_table (info)->tls_sec->vma;
+
+		  rela.r_info = ELFNN_R_INFO (indx, R_LARCH_TLS_DESCNN);
+		  loongarch_elf_append_rela (output_bfd, relgot, &rela);
+		  bfd_put_NN (output_bfd, 0,
+			      got->contents + got_off + desc_off);
+		}
 	      if (tls_type & GOT_TLS_IE)
 		{
 		  rela.r_offset = sec_addr (got) + got_off + ie_off;
@@ -3497,16 +3581,52 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 		    }
 		}
 	    }
-	  relocation = (got_off & (~(bfd_vma)1)) + sec_addr (got)
-			+ (is_ie ? ie_off : 0);
+	  relocation = (got_off & (~(bfd_vma)1)) + sec_addr (got);
+	  if (is_desc)
+	    relocation += desc_off;
+	  else if (is_ie)
+	    relocation += ie_off;
 
 	  if (r_type == R_LARCH_TLS_LD_PC_HI20
 	      || r_type == R_LARCH_TLS_GD_PC_HI20
-	      || r_type == R_LARCH_TLS_IE_PC_HI20)
+	      || r_type == R_LARCH_TLS_IE_PC_HI20
+	      || r_type == R_LARCH_TLS_DESC_PC_HI20)
 	    RELOCATE_CALC_PC32_HI20 (relocation, pc);
 
 	  break;
 
+	case R_LARCH_TLS_DESC_ADD_PC_LO12:
+	case R_LARCH_TLS_DESC64_PC_LO20:
+	case R_LARCH_TLS_DESC64_PC_HI12:
+	case R_LARCH_TLS_DESC_LO12:
+	case R_LARCH_TLS_DESC64_LO20:
+	case R_LARCH_TLS_DESC64_HI12:
+	  {
+	    unresolved_reloc = false;
+
+	    if (h)
+	      relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)1));
+	    else
+	      relocation = sec_addr (got)
+			   + (local_got_offsets[r_symndx] & (~(bfd_vma)1));
+
+	    tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
+	    /* Use both TLS_GD and TLS_DESC.  */
+	    if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_GDESC))
+	      relocation += 2 * GOT_ENTRY_SIZE;
+	  }
+
+	    if (r_type == R_LARCH_TLS_DESC64_PC_LO20
+		|| r_type == R_LARCH_TLS_DESC64_PC_HI12)
+	      RELOCATE_CALC_PC64_HI32 (relocation, pc);
+
+	    break;
+
+	case R_LARCH_TLS_DESC_LD:
+	case R_LARCH_TLS_DESC_CALL:
+	  unresolved_reloc = false;
+	  break;
+
 	case R_LARCH_TLS_IE_PC_LO12:
 	case R_LARCH_TLS_IE64_PC_LO20:
 	case R_LARCH_TLS_IE64_PC_HI12:
@@ -3516,14 +3636,17 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 	  unresolved_reloc = false;
 
 	  if (h)
-	    relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)3));
+	    relocation = sec_addr (got) + (h->got.offset & (~(bfd_vma)1));
 	  else
 	    relocation = sec_addr (got)
-	      + (local_got_offsets[r_symndx] & (~(bfd_vma)3));
+	      + (local_got_offsets[r_symndx] & (~(bfd_vma)1));
 
 	  tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
-	  /* Use both TLS_GD and TLS_IE.  */
-	  if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
+	  /* Use TLS_GD TLS_DESC and TLS_IE.  */
+	  if (GOT_TLS_GD_BOTH_P (tls_type) && (tls_type & GOT_TLS_IE))
+	    relocation += 4 * GOT_ENTRY_SIZE;
+	  /* Use GOT_TLS_GD_ANY_P (tls_type) and TLS_IE.  */
+	  else if (GOT_TLS_GD_ANY_P (tls_type) && (tls_type & GOT_TLS_IE))
 	    relocation += 2 * GOT_ENTRY_SIZE;
 
 	  if (r_type == R_LARCH_TLS_IE64_PC_LO20
@@ -4149,7 +4272,8 @@ loongarch_elf_finish_dynamic_symbol (bfd *output_bfd,
 
   if (h->got.offset != MINUS_ONE
       /* TLS got entry have been handled in elf_relocate_section.  */
-      && !(loongarch_elf_hash_entry (h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE))
+      && !(loongarch_elf_hash_entry (h)->tls_type
+	   & (GOT_TLS_GD | GOT_TLS_IE | GOT_TLS_GDESC))
       /* Have allocated got entry but not allocated rela before.  */
       && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
     {
-- 
2.36.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v4 3/5] LoongArch: Add tls transition support. Transitions between DESC->IE/LE and IE->LE are supported now.
  2023-12-15 10:11 [PATCH v4 0/5] Add support for TLS Descriptors (TLSDESC) Lulu Cai
  2023-12-15 10:11 ` [PATCH v4 1/5] LoongArch: Add new relocs and macro for TLSDESC Lulu Cai
  2023-12-15 10:11 ` [PATCH v4 2/5] LoongArch: Add support for TLSDESC in ld Lulu Cai
@ 2023-12-15 10:11 ` Lulu Cai
  2023-12-15 10:11 ` [PATCH v4 4/5] LoongArch: TLS LD/GD/DESC relaxation Lulu Cai
  3 siblings, 0 replies; 5+ messages in thread
From: Lulu Cai @ 2023-12-15 10:11 UTC (permalink / raw)
  To: binutils
  Cc: xuchenghua, chenglulu, liuzhensong, mengqinggang, xry111,
	i.swmail, maskray, luweining, wanglei, hejinyang, Lulu Cai

---
 bfd/elfnn-loongarch.c      | 216 ++++++++++++++++++++++++++++++++++++-
 include/opcode/loongarch.h |   6 ++
 2 files changed, 221 insertions(+), 1 deletion(-)

diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index b63f42bb6a7..ad94a2a7835 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -145,6 +145,16 @@ struct loongarch_elf_link_hash_table
 #define elf_backend_rela_normal 1
 #define elf_backend_default_execstack 0
 
+#define IS_LOONGARCH_TLS_DESC_RELOC(R_TYPE)    \
+  ((R_TYPE) == R_LARCH_TLS_DESC_PC_HI20	\
+   || (R_TYPE) == R_LARCH_TLS_DESC_ADD_PC_LO12  \
+   || (R_TYPE) == R_LARCH_TLS_DESC_LD \
+   || (R_TYPE) == R_LARCH_TLS_DESC_CALL)
+
+#define IS_LOONGARCH_TLS_IE_RELOC(R_TYPE) \
+  ((R_TYPE) == R_LARCH_TLS_IE_PC_HI20 \
+   || (R_TYPE) == R_LARCH_TLS_IE_PC_LO12)
+
 /* Generate a PLT header.  */
 
 static bool
@@ -593,6 +603,10 @@ loongarch_elf_record_tls_and_got_reference (bfd *abfd,
 
   char *new_tls_type = &_bfd_loongarch_elf_tls_type (abfd, h, symndx);
   *new_tls_type |= tls_type;
+
+  /* If a symbol is accessed by both IE and DESC, relax DESC to IE.  */
+  if ((*new_tls_type & GOT_TLS_IE) && (*new_tls_type & GOT_TLS_GDESC))
+    *new_tls_type &= ~ (GOT_TLS_GDESC);
   if ((*new_tls_type & GOT_NORMAL) && (*new_tls_type & ~GOT_NORMAL))
     {
       _bfd_error_handler (_("%pB: `%s' accessed both as normal and "
@@ -605,6 +619,104 @@ loongarch_elf_record_tls_and_got_reference (bfd *abfd,
   return true;
 }
 
+static unsigned int
+loongarch_reloc_got_type (unsigned int r_type)
+{
+  switch (r_type)
+    {
+      case R_LARCH_TLS_DESC_PC_HI20:
+      case R_LARCH_TLS_DESC_ADD_PC_LO12:
+      case R_LARCH_TLS_DESC_LD:
+      case R_LARCH_TLS_DESC_CALL:
+	return GOT_TLS_GDESC;
+
+      case R_LARCH_TLS_IE_PC_HI20:
+      case R_LARCH_TLS_IE_PC_LO12:
+	return GOT_TLS_IE;
+
+      default:
+	break;
+    }
+  return GOT_UNKNOWN;
+}
+
+/* Return true if tls type transition can be performed.  */
+static bool
+loongarch_can_relax_tls (struct bfd_link_info *info, unsigned int r_type,
+			 struct elf_link_hash_entry *h, bfd *input_bfd,
+			 unsigned long r_symndx)
+{
+  char symbol_tls_type;
+  unsigned int reloc_got_type;
+
+  if (! (IS_LOONGARCH_TLS_DESC_RELOC (r_type)
+	 || IS_LOONGARCH_TLS_IE_RELOC (r_type)))
+    return false;
+
+  symbol_tls_type = _bfd_loongarch_elf_tls_type (input_bfd, h, r_symndx);
+  reloc_got_type = loongarch_reloc_got_type (r_type);
+
+  if (symbol_tls_type == GOT_TLS_IE && GOT_TLS_GD_ANY_P (reloc_got_type))
+    return true;
+
+  if (! bfd_link_executable (info))
+      return false;
+
+  if (h && h->root.type == bfd_link_hash_undefweak)
+    return false;
+
+  return true;
+}
+
+/* The type of relocation that can be transitioned.  */
+static unsigned int
+loongarch_tls_transition_without_check (struct bfd_link_info *info,
+					unsigned int r_type,
+					struct elf_link_hash_entry *h)
+{
+  bool local_exec = bfd_link_executable (info)
+		    && SYMBOL_REFERENCES_LOCAL (info, h);
+
+  switch (r_type)
+    {
+      case R_LARCH_TLS_DESC_PC_HI20:
+	return (local_exec
+		? R_LARCH_TLS_LE_HI20
+		: R_LARCH_TLS_IE_PC_HI20);
+
+      case R_LARCH_TLS_DESC_ADD_PC_LO12:
+	return (local_exec
+		? R_LARCH_TLS_LE_LO12
+		: R_LARCH_TLS_IE_PC_LO12);
+
+      case R_LARCH_TLS_DESC_LD:
+      case R_LARCH_TLS_DESC_CALL:
+	return R_LARCH_NONE;
+
+      case R_LARCH_TLS_IE_PC_HI20:
+	return local_exec ? R_LARCH_TLS_LE_HI20 : r_type;
+
+      case R_LARCH_TLS_IE_PC_LO12:
+	return local_exec ? R_LARCH_TLS_LE_LO12 : r_type;
+
+      default:
+	break;
+    }
+
+  return r_type;
+}
+
+static unsigned int
+loongarch_tls_transition (struct bfd_link_info *info, unsigned int r_type,
+			  struct elf_link_hash_entry *h, bfd *input_bfd,
+			  unsigned long r_symndx)
+{
+  if (! loongarch_can_relax_tls (info, r_type, h, input_bfd,r_symndx))
+    return r_type;
+
+  return loongarch_tls_transition_without_check (info, r_type, h);
+}
+
 /* Look through the relocs for a section during the first phase, and
    allocate space in the global offset table or procedure linkage
    table.  */
@@ -706,6 +818,7 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
       int need_dynreloc = 0;
       int only_need_pcrel = 0;
 
+      r_type = loongarch_tls_transition (info, r_type, h, abfd, r_symndx);
       switch (r_type)
 	{
 	case R_LARCH_GOT_PC_HI20:
@@ -2397,6 +2510,96 @@ loongarch_reloc_is_fatal (struct bfd_link_info *info,
       relocation += 0x100000000;			\
   })
 
+/* Transition instruction sequence to relax instruction sequence.  */
+static bool
+loongarch_tls_relax (bfd *abfd, asection *sec, Elf_Internal_Rela *rel,
+		    int r_type, struct elf_link_hash_entry *h,
+		    struct bfd_link_info *info)
+{
+  bool local_exec = bfd_link_executable (info)
+		    && SYMBOL_REFERENCES_LOCAL (info, h);
+  bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
+  unsigned long insn;
+
+  switch (r_type)
+    {
+      case R_LARCH_TLS_DESC_PC_HI20:
+	if (local_exec)
+	    /* DESC -> LE relaxation:
+	       pcalalau12i $a0,%desc_pc_hi20(var) =>
+	       lu12i.w $a0,%le_hi20(var)
+	    */
+	    bfd_put (32, abfd, LARCH_LU12I_W | LARCH_RD_A0,
+		     contents + rel->r_offset);
+
+	/* DESC -> IE relaxation:
+	   pcalalau12i $a0,%desc_pc_hi20(var) =>
+	   pcalalau12i $a0,%ie_pc_hi20(var)
+	*/
+	return true;
+
+      case R_LARCH_TLS_DESC_ADD_PC_LO12:
+	if (local_exec)
+	  {
+	    /* DESC -> LE relaxation:
+	       addi.d $a0,$a0,%desc_add_pc_lo12(var) =>
+	       ori  $a0,$a0,le_lo12(var)
+	    */
+	    insn = LARCH_ORI | LARCH_RD_RJ_A0;
+	    bfd_put (32, abfd, LARCH_ORI | LARCH_RD_RJ_A0,
+		     contents + rel->r_offset);
+	  }
+	else
+	  {
+	    /* DESC -> IE relaxation:
+	       addi.d $a0,$a0,%desc_add_pc_lo12(var) =>
+	       ld.d $a0,$a0,%%ie_pc_lo12
+	    */
+	    bfd_put (32, abfd, LARCH_LD_D | LARCH_RD_RJ_A0,
+		     contents + rel->r_offset);
+	  }
+	return true;
+
+      case R_LARCH_TLS_DESC_LD:
+      case R_LARCH_TLS_DESC_CALL:
+	/* DESC -> LE/IE relaxation:
+	   ld.d $ra,$a0,%desc_ld_pc_lo12(var) => NOP
+	   jirl $ra,$ra,%desc_call(var) => NOP
+	*/
+	bfd_put (32, abfd, LARCH_NOP, contents + rel->r_offset);
+	return true;
+
+      case R_LARCH_TLS_IE_PC_HI20:
+	if (local_exec)
+	  {
+	    /* IE -> LE relaxation:
+	       pcalalau12i $rd,%ie_pc_hi20(var) =>
+	       lu12i.w $rd,%le_hi20(var)
+	    */
+	    insn = bfd_getl32 (contents + rel->r_offset);
+	    bfd_put (32, abfd, LARCH_LU12I_W | (insn & 0x1f),
+		     contents + rel->r_offset);
+	  }
+	return true;
+
+      case R_LARCH_TLS_IE_PC_LO12:
+	if (local_exec)
+	  {
+	    /* IE -> LE relaxation:
+	       ld.d $rd,$rj,%%ie_pc_lo12 =>
+	       ori  $rd,$rj,le_lo12(var)
+	    */
+	    insn = bfd_getl32 (contents + rel->r_offset);
+	    bfd_put (32, abfd, LARCH_ORI | (insn & 0x3ff),
+		     contents + rel->r_offset);
+	  }
+	return true;
+    }
+
+  return false;
+}
+
+
 static int
 loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 				bfd *input_bfd, asection *input_section,
@@ -2420,7 +2623,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
   relend = relocs + input_section->reloc_count;
   for (rel = relocs; rel < relend; rel++)
     {
-      int r_type = ELFNN_R_TYPE (rel->r_info);
+      unsigned int r_type = ELFNN_R_TYPE (rel->r_info);
       unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
       bfd_vma pc = sec_addr (input_section) + rel->r_offset;
       reloc_howto_type *howto = NULL;
@@ -2430,6 +2633,7 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
       const char *name;
       bfd_reloc_status_type r = bfd_reloc_ok;
       bool is_ie, is_desc, is_undefweak, unresolved_reloc, defined_local;
+      unsigned int relaxed_r_type;
       bool resolved_local, resolved_dynly, resolved_to_const;
       char tls_type;
       bfd_vma relocation, off, ie_off, desc_off;
@@ -2561,6 +2765,16 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 
       BFD_ASSERT (!resolved_local || defined_local);
 
+      relaxed_r_type = loongarch_tls_transition (info, r_type, h, input_bfd, r_symndx);
+      if (relaxed_r_type != r_type)
+      {
+	howto = loongarch_elf_rtype_to_howto (input_bfd, relaxed_r_type);
+	BFD_ASSERT (howto != NULL);
+
+	if (loongarch_tls_relax (input_bfd, input_section, rel, r_type, h, info))
+	  r_type = relaxed_r_type;
+      }
+
       is_desc = false;
       is_ie = false;
       switch (r_type)
diff --git a/include/opcode/loongarch.h b/include/opcode/loongarch.h
index da936f7945a..32ff4d8a0f1 100644
--- a/include/opcode/loongarch.h
+++ b/include/opcode/loongarch.h
@@ -42,6 +42,12 @@ extern "C"
     ((value) < (-(1 << ((bits) - 1) << align)) 	\
       || (value) > ((((1 << ((bits) - 1)) - 1) << align)))
 
+  #define LARCH_LU12I_W 0x14000000
+  #define LARCH_ORI 0x03800000
+  #define LARCH_LD_D 0x28c00000
+  #define LARCH_RD_A0 0x04
+  #define LARCH_RD_RJ_A0 0x084
+
   typedef uint32_t insn_t;
 
   struct loongarch_opcode
-- 
2.36.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH v4 4/5] LoongArch: TLS LD/GD/DESC relaxation
  2023-12-15 10:11 [PATCH v4 0/5] Add support for TLS Descriptors (TLSDESC) Lulu Cai
                   ` (2 preceding siblings ...)
  2023-12-15 10:11 ` [PATCH v4 3/5] LoongArch: Add tls transition support. Transitions between DESC->IE/LE and IE->LE are supported now Lulu Cai
@ 2023-12-15 10:11 ` Lulu Cai
  3 siblings, 0 replies; 5+ messages in thread
From: Lulu Cai @ 2023-12-15 10:11 UTC (permalink / raw)
  To: binutils
  Cc: xuchenghua, chenglulu, liuzhensong, mengqinggang, xry111,
	i.swmail, maskray, luweining, wanglei, hejinyang

From: mengqinggang <mengqinggang@loongson.cn>

---
 bfd/bfd-in2.h                                 |   3 +
 bfd/elfnn-loongarch.c                         | 177 +++++++-
 bfd/elfxx-loongarch.c                         |  54 +++
 bfd/libbfd.h                                  |   3 +
 bfd/reloc.c                                   |   7 +
 gas/config/tc-loongarch.c                     |   6 +-
 gas/testsuite/gas/loongarch/macro_op.d        | 128 +++---
 gas/testsuite/gas/loongarch/macro_op_32.d     | 120 +++---
 .../gas/loongarch/macro_op_large_abs.d        | 160 +++----
 .../gas/loongarch/macro_op_large_pc.d         | 160 +++----
 include/elf/loongarch.h                       |   4 +
 ld/testsuite/ld-loongarch-elf/macro_op.d      | 391 +++++++++---------
 ld/testsuite/ld-loongarch-elf/macro_op_32.d   | 120 +++---
 13 files changed, 789 insertions(+), 544 deletions(-)

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index d3557a4fd74..6d666ac2b1c 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -7472,6 +7472,9 @@ enum bfd_reloc_code_real
   BFD_RELOC_LARCH_TLS_DESC64_LO20,
   BFD_RELOC_LARCH_TLS_DESC64_HI12,
   BFD_RELOC_LARCH_TLS_DESC_CALL,
+  BFD_RELOC_LARCH_TLS_LD_PCREL20_S2,
+  BFD_RELOC_LARCH_TLS_GD_PCREL20_S2,
+  BFD_RELOC_LARCH_TLS_DESC_PCREL20_S2,
   BFD_RELOC_UNUSED
 };
 typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index ad94a2a7835..5317c5e140d 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -2279,7 +2279,9 @@ perform_relocation (const Elf_Internal_Rela *rel, asection *input_section,
     case R_LARCH_TLS_DESC_LO12:
     case R_LARCH_TLS_DESC64_LO20:
     case R_LARCH_TLS_DESC64_HI12:
-
+    case R_LARCH_TLS_LD_PCREL20_S2:
+    case R_LARCH_TLS_GD_PCREL20_S2:
+    case R_LARCH_TLS_DESC_PCREL20_S2:
       r = loongarch_check_offset (rel, input_section);
       if (r != bfd_reloc_ok)
 	break;
@@ -3667,6 +3669,9 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 	case R_LARCH_TLS_GD_HI20:
 	case R_LARCH_TLS_DESC_PC_HI20:
 	case R_LARCH_TLS_DESC_HI20:
+	case R_LARCH_TLS_LD_PCREL20_S2:
+	case R_LARCH_TLS_GD_PCREL20_S2:
+	case R_LARCH_TLS_DESC_PCREL20_S2:
 	  BFD_ASSERT (rel->r_addend == 0);
 	  unresolved_reloc = false;
 
@@ -3675,7 +3680,8 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 	    is_ie = true;
 
 	  if (r_type == R_LARCH_TLS_DESC_PC_HI20
-	      || r_type == R_LARCH_TLS_DESC_HI20)
+	      || r_type == R_LARCH_TLS_DESC_HI20
+	      || r_type == R_LARCH_TLS_DESC_PCREL20_S2)
 	    is_desc = true;
 
 	  bfd_vma got_off = 0;
@@ -3806,7 +3812,11 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 	      || r_type == R_LARCH_TLS_IE_PC_HI20
 	      || r_type == R_LARCH_TLS_DESC_PC_HI20)
 	    RELOCATE_CALC_PC32_HI20 (relocation, pc);
-
+	  else if (r_type == R_LARCH_TLS_LD_PCREL20_S2
+	      || r_type == R_LARCH_TLS_GD_PCREL20_S2
+	      || r_type == R_LARCH_TLS_DESC_PCREL20_S2)
+	    relocation -= pc;
+	  /*else {} ABS relocations.  */
 	  break;
 
 	case R_LARCH_TLS_DESC_ADD_PC_LO12:
@@ -4228,6 +4238,84 @@ loongarch_relax_align (bfd *abfd, asection *sec,
 				   rel->r_addend - nop_bytes, link_info);
 }
 
+static bool
+loongarch_relax_tls_ld_gd_desc (bfd *abfd, asection *sec, asection *sym_sec,
+		       Elf_Internal_Rela *rel_hi, bfd_vma symval,
+		       struct bfd_link_info *info, bool *again)
+{
+  bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
+  Elf_Internal_Rela *rel_lo = rel_hi + 2;
+  uint32_t pca = bfd_get (32, abfd, contents + rel_hi->r_offset);
+  uint32_t add = bfd_get (32, abfd, contents + rel_lo->r_offset);
+  uint32_t rd = pca & 0x1f;
+
+  /* This section's output_offset need to subtract the bytes of instructions
+     relaxed by the previous sections, so it needs to be updated beforehand.
+     size_input_section already took care of updating it after relaxation,
+     so we additionally update once here.  */
+  sec->output_offset = sec->output_section->size;
+  bfd_vma pc = sec_addr (sec) + rel_hi->r_offset;
+
+  /* If pc and symbol not in the same segment, add/sub segment alignment.
+     FIXME: if there are multiple readonly segments?  */
+  if (!(sym_sec->flags & SEC_READONLY))
+    {
+      if (symval > pc)
+	pc -= info->maxpagesize;
+      else if (symval < pc)
+	pc += info->maxpagesize;
+    }
+
+  const uint32_t addi_d = 0x02c00000;
+  const uint32_t pcaddi = 0x18000000;
+
+  /* Is pcalau12i + addi.d insns?  */
+  if ((ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_GOT_PC_LO12
+	&& ELFNN_R_TYPE (rel_lo->r_info) != R_LARCH_TLS_DESC_ADD_PC_LO12)
+      || (ELFNN_R_TYPE ((rel_lo + 1)->r_info) != R_LARCH_RELAX)
+      || (ELFNN_R_TYPE ((rel_hi + 1)->r_info) != R_LARCH_RELAX)
+      || (rel_hi->r_offset + 4 != rel_lo->r_offset)
+      || ((add & addi_d) != addi_d)
+      /* Is pcalau12i $rd + addi.d $rd,$rd?  */
+      || ((add & 0x1f) != rd)
+      || (((add >> 5) & 0x1f) != rd)
+      /* Can be relaxed to pcaddi?  */
+      || (symval & 0x3) /* 4 bytes align.  */
+      || ((bfd_signed_vma)(symval - pc) < (bfd_signed_vma)(int32_t)0xffe00000)
+      || ((bfd_signed_vma)(symval - pc) > (bfd_signed_vma)(int32_t)0x1ffffc))
+    return false;
+
+  /* Continue next relax trip.  */
+  *again = true;
+
+  pca = pcaddi | rd;
+  bfd_put (32, abfd, pca, contents + rel_hi->r_offset);
+
+  /* Adjust relocations.  */
+  switch (ELFNN_R_TYPE (rel_hi->r_info))
+    {
+    case R_LARCH_TLS_LD_PC_HI20:
+      rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
+				      R_LARCH_TLS_LD_PCREL20_S2);
+      break;
+    case R_LARCH_TLS_GD_PC_HI20:
+      rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
+				      R_LARCH_TLS_GD_PCREL20_S2);
+      break;
+    case R_LARCH_TLS_DESC_PC_HI20:
+      rel_hi->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel_hi->r_info),
+				      R_LARCH_TLS_DESC_PCREL20_S2);
+      break;
+    default:
+      break;
+    }
+  rel_lo->r_info = ELFNN_R_INFO (0, R_LARCH_NONE);
+
+  loongarch_relax_delete_bytes (abfd, sec, rel_lo->r_offset, 4, info);
+
+  return true;
+}
+
 static bool
 loongarch_elf_relax_section (bfd *abfd, asection *sec,
 			       struct bfd_link_info *info,
@@ -4268,18 +4356,27 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
 						   0, NULL, NULL, NULL)))
     return true;
 
-      data->relocs = relocs;
+  data->relocs = relocs;
 
   for (unsigned int i = 0; i < sec->reloc_count; i++)
     {
-      Elf_Internal_Rela *rel = relocs + i;
-      asection *sym_sec;
+      char symtype;
       bfd_vma symval;
-      unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
+      asection *sym_sec;
       bool local_got = false;
-      char symtype;
+      Elf_Internal_Rela *rel = relocs + i;
       struct elf_link_hash_entry *h = NULL;
+      unsigned long r_type = ELFNN_R_TYPE (rel->r_info);
+      unsigned long r_symndx = ELFNN_R_SYM (rel->r_info);
 
+      /* Three kind of relocations:
+	 Normal: symval is the symbol address.
+	 R_LARCH_ALIGN: symval is the address of the last NOP instruction
+	 added by this relocation, and then adds 4 more.
+	 R_LARCH_CALL36: symval is the symbol address for local symbols,
+	 or the PLT entry address of the symbol. (Todo)
+	 R_LARCHL_TLS_LD/GD/DESC_PC_HI20: symval is the GOT entry address
+	 of the symbol.  */
       if (r_symndx < symtab_hdr->sh_info)
 	{
 	  Elf_Internal_Sym *sym = (Elf_Internal_Sym *)symtab_hdr->contents
@@ -4287,6 +4384,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
 	  if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC)
 	    continue;
 
+	  /* For R_LARCH_ALIGN?  */
 	  if (sym->st_shndx == SHN_UNDEF)
 	    {
 	      sym_sec = sec;
@@ -4312,10 +4410,21 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
 	  if (h != NULL && h->type == STT_GNU_IFUNC)
 	    continue;
 
-	  if ((h->root.type == bfd_link_hash_defined
-		    || h->root.type == bfd_link_hash_defweak)
-		   && h->root.u.def.section != NULL
-		   && h->root.u.def.section->output_section != NULL)
+	  /* For TLS LD/GD/DESC relocations, the got entry of the symbol
+	     is in current module. */
+	  if (R_LARCH_TLS_LD_PC_HI20 == r_type
+	      || R_LARCH_TLS_GD_PC_HI20 == r_type
+	      || R_LARCH_TLS_DESC_PC_HI20 == r_type)
+	    {
+	      if (loongarch_can_relax_tls (info, r_type, h, abfd, r_symndx))
+		continue;
+	      else
+		goto tls_got_relax;
+	    }
+	  else if ((h->root.type == bfd_link_hash_defined
+		  || h->root.type == bfd_link_hash_defweak)
+		&& h->root.u.def.section != NULL
+		&& h->root.u.def.section->output_section != NULL)
 	    {
 	      symval = h->root.u.def.value;
 	      sym_sec = h->root.u.def.section;
@@ -4347,7 +4456,28 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
 
       symval += sec_addr (sym_sec);
 
-      switch (ELFNN_R_TYPE (rel->r_info))
+      /* For TLS LD/GD/DESC relocations, symval is the got entry
+	 address of the symbol.  */
+tls_got_relax:
+      if (R_LARCH_TLS_LD_PC_HI20 == r_type
+	  || R_LARCH_TLS_GD_PC_HI20 == r_type
+	  || R_LARCH_TLS_DESC_PC_HI20 == r_type)
+	{
+	  bfd_vma got_off = 0;
+	  if (h != NULL)
+	    got_off = h->got.offset;
+	  else
+	    got_off = elf_local_got_offsets (abfd)[r_symndx];
+	  symval = sec_addr (htab->elf.sgot) + got_off;
+	  sym_sec = htab->elf.sgot;
+
+	  char tls_type = _bfd_loongarch_elf_tls_type (abfd, h, r_symndx);
+	  if (R_LARCH_TLS_DESC_PC_HI20 == r_type
+	      && GOT_TLS_GD_BOTH_P (tls_type))
+	    symval += 2 * GOT_ENTRY_SIZE;
+	}
+
+      switch (r_type)
 	{
 	case R_LARCH_ALIGN:
 	  if (1 == info->relax_pass)
@@ -4374,6 +4504,27 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec,
 					    info, again);
 	    }
 	  break;
+
+	case R_LARCH_TLS_LD_PC_HI20:
+	  if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
+	    loongarch_relax_tls_ld_gd_desc (abfd, sec, sym_sec, rel, symval,
+					    info, again);
+	  break;
+
+	case R_LARCH_TLS_GD_PC_HI20:
+	  if (0 == info->relax_pass && (i + 4) <= sec->reloc_count)
+	    loongarch_relax_tls_ld_gd_desc (abfd, sec, sym_sec, rel, symval,
+					    info, again);
+	  break;
+
+	case R_LARCH_TLS_DESC_PC_HI20:
+	  if (0 == info->relax_pass
+	      && (i + 4) <= sec->reloc_count
+	      && !loongarch_can_relax_tls (info, r_type, h, abfd, r_symndx))
+	    loongarch_relax_tls_ld_gd_desc (abfd, sec, sym_sec, rel, symval,
+					    info, again);
+	  break;
+
 	default:
 	  break;
 	}
diff --git a/bfd/elfxx-loongarch.c b/bfd/elfxx-loongarch.c
index 819c4849ef5..ab930e58aec 100644
--- a/bfd/elfxx-loongarch.c
+++ b/bfd/elfxx-loongarch.c
@@ -1754,6 +1754,60 @@ static loongarch_reloc_howto_type loongarch_howto_table[] =
 	 BFD_RELOC_LARCH_TLS_DESC_CALL,		/* bfd_reloc_code_real_type.  */
 	 NULL,					/* adjust_reloc_bits.  */
 	 "desc_call"),				/* larch_reloc_type_name.  */
+
+  /* For pcaddi, ld_pc_hi20 + ld_pc_lo12 can relax to ld_pcrel20_s2.  */
+  LOONGARCH_HOWTO (R_LARCH_TLS_LD_PCREL20_S2,	/* type (121).  */
+	 2,					/* rightshift.  */
+	 4,					/* size.  */
+	 20,					/* bitsize.  */
+	 false,					/* pc_relative.  */
+	 5,					/* bitpos.  */
+	 complain_overflow_signed,		/* complain_on_overflow.  */
+	 bfd_elf_generic_reloc,			/* special_function.  */
+	 "R_LARCH_TLS_LD_PCREL20_S2",		/* name.  */
+	 false,					/* partial_inplace.  */
+	 0,					/* src_mask.  */
+	 0x1ffffe0,				/* dst_mask.  */
+	 false,					/* pcrel_offset.  */
+	 BFD_RELOC_LARCH_TLS_LD_PCREL20_S2,	/* bfd_reloc_code_real_type.  */
+	 reloc_sign_bits,			/* adjust_reloc_bits.  */
+	 "ld_pcrel_20"),			/* larch_reloc_type_name.  */
+
+  /* For pcaddi, gd_pc_hi20 + gd_pc_lo12 can relax to gd_pcrel20_s2.  */
+  LOONGARCH_HOWTO (R_LARCH_TLS_GD_PCREL20_S2,	/* type (122).  */
+	 2,					/* rightshift.  */
+	 4,					/* size.  */
+	 20,					/* bitsize.  */
+	 false,					/* pc_relative.  */
+	 5,					/* bitpos.  */
+	 complain_overflow_signed,		/* complain_on_overflow.  */
+	 bfd_elf_generic_reloc,			/* special_function.  */
+	 "R_LARCH_TLS_GD_PCREL20_S2",		/* name.  */
+	 false,					/* partial_inplace.  */
+	 0,					/* src_mask.  */
+	 0x1ffffe0,				/* dst_mask.  */
+	 false,					/* pcrel_offset.  */
+	 BFD_RELOC_LARCH_TLS_GD_PCREL20_S2,	/* bfd_reloc_code_real_type.  */
+	 reloc_sign_bits,			/* adjust_reloc_bits.  */
+	 "gd_pcrel_20"),			/* larch_reloc_type_name.  */
+
+  /* For pcaddi, desc_pc_hi20 + desc_pc_lo12 can relax to desc_pcrel20_s2.  */
+  LOONGARCH_HOWTO (R_LARCH_TLS_DESC_PCREL20_S2,	/* type (123).  */
+	 2,					/* rightshift.  */
+	 4,					/* size.  */
+	 20,					/* bitsize.  */
+	 false,					/* pc_relative.  */
+	 5,					/* bitpos.  */
+	 complain_overflow_signed,		/* complain_on_overflow.  */
+	 bfd_elf_generic_reloc,			/* special_function.  */
+	 "R_LARCH_TLS_DESC_PCREL20_S2",		/* name.  */
+	 false,					/* partial_inplace.  */
+	 0,					/* src_mask.  */
+	 0x1ffffe0,				/* dst_mask.  */
+	 false,					/* pcrel_offset.  */
+	 BFD_RELOC_LARCH_TLS_DESC_PCREL20_S2,	/* bfd_reloc_code_real_type.  */
+	 reloc_sign_bits,			/* adjust_reloc_bits.  */
+	 "desc_pcrel_20"),			/* larch_reloc_type_name.  */
 };
 
 reloc_howto_type *
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 6ee021e84b5..6151eec50a2 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -3611,6 +3611,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_LARCH_TLS_DESC64_LO20",
   "BFD_RELOC_LARCH_TLS_DESC64_HI12",
   "BFD_RELOC_LARCH_TLS_DESC_CALL",
+  "BFD_RELOC_LARCH_TLS_LD_PCREL20_S2",
+  "BFD_RELOC_LARCH_TLS_GD_PCREL20_S2",
+  "BFD_RELOC_LARCH_TLS_DESC_PCREL20_S2",
  "@@overflow: BFD_RELOC_UNUSED@@",
 };
 #endif
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 0e354ef4b80..aa0575ad839 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -8321,6 +8321,13 @@ ENUMX
 ENUMX
   BFD_RELOC_LARCH_TLS_DESC_CALL
 
+ENUMX
+  BFD_RELOC_LARCH_TLS_LD_PCREL20_S2
+ENUMX
+  BFD_RELOC_LARCH_TLS_GD_PCREL20_S2
+ENUMX
+  BFD_RELOC_LARCH_TLS_DESC_PCREL20_S2
+
 ENUMDOC
   LARCH relocations.
 
diff --git a/gas/config/tc-loongarch.c b/gas/config/tc-loongarch.c
index e1d5453b14f..a14c23fb45b 100644
--- a/gas/config/tc-loongarch.c
+++ b/gas/config/tc-loongarch.c
@@ -694,7 +694,11 @@ loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2,
 		    && (BFD_RELOC_LARCH_PCALA_HI20 == reloc_type
 			|| BFD_RELOC_LARCH_PCALA_LO12 == reloc_type
 			|| BFD_RELOC_LARCH_GOT_PC_HI20 == reloc_type
-			|| BFD_RELOC_LARCH_GOT_PC_LO12 == reloc_type))
+			|| BFD_RELOC_LARCH_GOT_PC_LO12 == reloc_type
+			|| BFD_RELOC_LARCH_TLS_LD_PC_HI20 == reloc_type
+			|| BFD_RELOC_LARCH_TLS_GD_PC_HI20 == reloc_type
+			|| BFD_RELOC_LARCH_TLS_DESC_PC_HI20 == reloc_type
+			|| BFD_RELOC_LARCH_TLS_DESC_ADD_PC_LO12 == reloc_type))
 		{
 		  ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX;
 		  ip->reloc_info[ip->reloc_num].value = const_0;
diff --git a/gas/testsuite/gas/loongarch/macro_op.d b/gas/testsuite/gas/loongarch/macro_op.d
index 32860864704..47f8f45c663 100644
--- a/gas/testsuite/gas/loongarch/macro_op.d
+++ b/gas/testsuite/gas/loongarch/macro_op.d
@@ -2,70 +2,72 @@
 #objdump: -dr
 #skip: loongarch32-*-*
 
-.*:[    ]+file format .*
+.*:     file format .*
 
 
 Disassembly of section .text:
 
-00000000.* <.text>:
-[ 	]+0:[ 	]+00150004[ 	]+move[ 	]+\$a0,[ 	]+\$zero
-[ 	]+4:[ 	]+02bffc04[ 	]+li\.w[ 	]+\$a0,[ 	]+-1
-[ 	]+8:[ 	]+00150004[ 	]+move[ 	]+\$a0,[ 	]+\$zero
-[ 	]+c:[ 	]+02bffc04[ 	]+li\.w[ 	]+\$a0,[ 	]+-1
-[ 	]+10:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+10:[ 	]+R_LARCH_GOT_PC_HI20[ 	]+\.L1
-[ 	]+10:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+14:[ 	]+28c00084[ 	]+ld\.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+14:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+\.L1
-[ 	]+14:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+18:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+18:[ 	]+R_LARCH_GOT_PC_HI20[ 	]+\.L1
-[ 	]+18:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+1c:[ 	]+28c00084[ 	]+ld\.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+1c:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+\.L1
-[ 	]+1c:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+20:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+20:[ 	]+R_LARCH_PCALA_HI20[ 	]+\.L1
-[ 	]+20:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+24:[ 	]+02c00084[ 	]+addi\.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+24:[ 	]+R_LARCH_PCALA_LO12[ 	]+\.L1
-[ 	]+24:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+28:[ 	]+14000004[ 	]+lu12i\.w[ 	]+\$a0,[ 	]+0
-[ 	]+28:[ 	]+R_LARCH_MARK_LA[ 	]+\*ABS\*
-[ 	]+28:[ 	]+R_LARCH_ABS_HI20[ 	]+\.L1
-[ 	]+2c:[ 	]+03800084[ 	]+ori[ 	]+\$a0,[ 	]+\$a0,[ 	]+0x0
-[ 	]+2c:[ 	]+R_LARCH_ABS_LO12[ 	]+\.L1
-[ 	]+30:[ 	]+16000004[ 	]+lu32i\.d[ 	]+\$a0,[ 	]+0
-[ 	]+30:[ 	]+R_LARCH_ABS64_LO20[ 	]+\.L1
-[ 	]+34:[ 	]+03000084[ 	]+lu52i\.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+34:[ 	]+R_LARCH_ABS64_HI12[ 	]+\.L1
-[ 	]+38:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+38:[ 	]+R_LARCH_PCALA_HI20[ 	]+\.L1
-[ 	]+38:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+3c:[ 	]+02c00084[ 	]+addi\.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+3c:[ 	]+R_LARCH_PCALA_LO12[ 	]+\.L1
-[ 	]+3c:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+40:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+40:[ 	]+R_LARCH_GOT_PC_HI20[ 	]+\.L1
-[ 	]+40:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+44:[ 	]+28c00084[ 	]+ld\.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+44:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+\.L1
-[ 	]+44:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+48:[ 	]+14000004[ 	]+lu12i\.w[ 	]+\$a0,[ 	]+0
-[ 	]+48:[ 	]+R_LARCH_TLS_LE_HI20[ 	]+TLS1
-[ 	]+4c:[ 	]+03800084[ 	]+ori[ 	]+\$a0,[ 	]+\$a0,[ 	]+0x0
-[ 	]+4c:[ 	]+R_LARCH_TLS_LE_LO12[ 	]+TLS1
-[ 	]+50:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+50:[ 	]+R_LARCH_TLS_IE_PC_HI20[ 	]+TLS1
-[ 	]+54:[ 	]+28c00084[ 	]+ld\.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+54:[ 	]+R_LARCH_TLS_IE_PC_LO12[ 	]+TLS1
-[ 	]+58:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+58:[ 	]+R_LARCH_TLS_LD_PC_HI20[ 	]+TLS1
-[ 	]+5c:[ 	]+02c00084[ 	]+addi\.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+5c:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+TLS1
-[ 	]+5c:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+60:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+60:[ 	]+R_LARCH_TLS_GD_PC_HI20[ 	]+TLS1
-[ 	]+64:[ 	]+02c00084[ 	]+addi\.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+64:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+TLS1
-[ 	]+64:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
+0+ <.*>:
+   0:	00150004 	move        	\$a0, \$zero
+   4:	02bffc04 	li.w        	\$a0, -1
+   8:	00150004 	move        	\$a0, \$zero
+   c:	02bffc04 	li.w        	\$a0, -1
+  10:	1a000004 	pcalau12i   	\$a0, 0
+			10: R_LARCH_GOT_PC_HI20	.L1
+			10: R_LARCH_RELAX	\*ABS\*
+  14:	28c00084 	ld.d        	\$a0, \$a0, 0
+			14: R_LARCH_GOT_PC_LO12	.L1
+			14: R_LARCH_RELAX	\*ABS\*
+  18:	1a000004 	pcalau12i   	\$a0, 0
+			18: R_LARCH_GOT_PC_HI20	.L1
+			18: R_LARCH_RELAX	\*ABS\*
+  1c:	28c00084 	ld.d        	\$a0, \$a0, 0
+			1c: R_LARCH_GOT_PC_LO12	.L1
+			1c: R_LARCH_RELAX	\*ABS\*
+  20:	1a000004 	pcalau12i   	\$a0, 0
+			20: R_LARCH_PCALA_HI20	.L1
+			20: R_LARCH_RELAX	\*ABS\*
+  24:	02c00084 	addi.d      	\$a0, \$a0, 0
+			24: R_LARCH_PCALA_LO12	.L1
+			24: R_LARCH_RELAX	\*ABS\*
+  28:	14000004 	lu12i.w     	\$a0, 0
+			28: R_LARCH_MARK_LA	\*ABS\*
+			28: R_LARCH_ABS_HI20	.L1
+  2c:	03800084 	ori         	\$a0, \$a0, 0x0
+			2c: R_LARCH_ABS_LO12	.L1
+  30:	16000004 	lu32i.d     	\$a0, 0
+			30: R_LARCH_ABS64_LO20	.L1
+  34:	03000084 	lu52i.d     	\$a0, \$a0, 0
+			34: R_LARCH_ABS64_HI12	.L1
+  38:	1a000004 	pcalau12i   	\$a0, 0
+			38: R_LARCH_PCALA_HI20	.L1
+			38: R_LARCH_RELAX	\*ABS\*
+  3c:	02c00084 	addi.d      	\$a0, \$a0, 0
+			3c: R_LARCH_PCALA_LO12	.L1
+			3c: R_LARCH_RELAX	\*ABS\*
+  40:	1a000004 	pcalau12i   	\$a0, 0
+			40: R_LARCH_GOT_PC_HI20	.L1
+			40: R_LARCH_RELAX	\*ABS\*
+  44:	28c00084 	ld.d        	\$a0, \$a0, 0
+			44: R_LARCH_GOT_PC_LO12	.L1
+			44: R_LARCH_RELAX	\*ABS\*
+  48:	14000004 	lu12i.w     	\$a0, 0
+			48: R_LARCH_TLS_LE_HI20	TLS1
+  4c:	03800084 	ori         	\$a0, \$a0, 0x0
+			4c: R_LARCH_TLS_LE_LO12	TLS1
+  50:	1a000004 	pcalau12i   	\$a0, 0
+			50: R_LARCH_TLS_IE_PC_HI20	TLS1
+  54:	28c00084 	ld.d        	\$a0, \$a0, 0
+			54: R_LARCH_TLS_IE_PC_LO12	TLS1
+  58:	1a000004 	pcalau12i   	\$a0, 0
+			58: R_LARCH_TLS_LD_PC_HI20	TLS1
+			58: R_LARCH_RELAX	\*ABS\*
+  5c:	02c00084 	addi.d      	\$a0, \$a0, 0
+			5c: R_LARCH_GOT_PC_LO12	TLS1
+			5c: R_LARCH_RELAX	\*ABS\*
+  60:	1a000004 	pcalau12i   	\$a0, 0
+			60: R_LARCH_TLS_GD_PC_HI20	TLS1
+			60: R_LARCH_RELAX	\*ABS\*
+  64:	02c00084 	addi.d      	\$a0, \$a0, 0
+			64: R_LARCH_GOT_PC_LO12	TLS1
+			64: R_LARCH_RELAX	\*ABS\*
diff --git a/gas/testsuite/gas/loongarch/macro_op_32.d b/gas/testsuite/gas/loongarch/macro_op_32.d
index 188026a5780..a7349aa8dc0 100644
--- a/gas/testsuite/gas/loongarch/macro_op_32.d
+++ b/gas/testsuite/gas/loongarch/macro_op_32.d
@@ -2,66 +2,68 @@
 #objdump: -dr
 #skip: loongarch64-*-*
 
-.*:[    ]+file format .*
+.*:     file format .*
 
 
 Disassembly of section .text:
 
-00000000.* <.L1>:
-[ 	]+0:[ 	]+00150004[ 	]+move[ 	]+\$a0,[ 	]+\$zero
-[ 	]+4:[ 	]+02bffc04[ 	]+li\.w[ 	]+\$a0,[ 	]+-1
-[ 	]+8:[ 	]+00150004[ 	]+move[ 	]+\$a0,[ 	]+\$zero
-[ 	]+c:[ 	]+02bffc04[ 	]+li\.w[ 	]+\$a0,[ 	]+-1
-[ 	]+10:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+10:[ 	]+R_LARCH_GOT_PC_HI20[ 	]+.L1
-[ 	]+10:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+14:[ 	]+28800084[ 	]+ld.w[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+14:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+.L1
-[ 	]+14:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+18:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+18:[ 	]+R_LARCH_GOT_PC_HI20[ 	]+.L1
-[ 	]+18:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+1c:[ 	]+28800084[ 	]+ld.w[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+1c:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+.L1
-[ 	]+1c:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+20:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+20:[ 	]+R_LARCH_PCALA_HI20[ 	]+.L1
-[ 	]+20:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+24:[ 	]+02800084[ 	]+addi.w[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+24:[ 	]+R_LARCH_PCALA_LO12[ 	]+.L1
-[ 	]+24:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+28:[ 	]+14000004[ 	]+lu12i.w[ 	]+\$a0,[ 	]+0
-[ 	]+28:[ 	]+R_LARCH_MARK_LA[ 	]+\*ABS\*
-[ 	]+28:[ 	]+R_LARCH_ABS_HI20[ 	]+.L1
-[ 	]+2c:[ 	]+03800084[ 	]+ori[ 	]+\$a0,[ 	]+\$a0,[ 	]+0x0
-[ 	]+2c:[ 	]+R_LARCH_ABS_LO12[ 	]+.L1
-[ 	]+30:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+30:[ 	]+R_LARCH_PCALA_HI20[ 	]+.L1
-[ 	]+30:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+34:[ 	]+02800084[ 	]+addi.w[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+34:[ 	]+R_LARCH_PCALA_LO12[ 	]+.L1
-[ 	]+34:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+38:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+38:[ 	]+R_LARCH_GOT_PC_HI20[ 	]+.L1
-[ 	]+38:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+3c:[ 	]+28800084[ 	]+ld.w[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+3c:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+.L1
-[ 	]+3c:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+40:[ 	]+14000004[ 	]+lu12i.w[ 	]+\$a0,[ 	]+0
-[ 	]+40:[ 	]+R_LARCH_TLS_LE_HI20[ 	]+TLS1
-[ 	]+44:[ 	]+03800084[ 	]+ori[ 	]+\$a0,[ 	]+\$a0,[ 	]+0x0
-[ 	]+44:[ 	]+R_LARCH_TLS_LE_LO12[ 	]+TLS1
-[ 	]+48:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+48:[ 	]+R_LARCH_TLS_IE_PC_HI20[ 	]+TLS1
-[ 	]+4c:[ 	]+28800084[ 	]+ld.w[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+4c:[ 	]+R_LARCH_TLS_IE_PC_LO12[ 	]+TLS1
-[ 	]+50:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+50:[ 	]+R_LARCH_TLS_LD_PC_HI20[ 	]+TLS1
-[ 	]+54:[ 	]+02800084[ 	]+addi.w[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+54:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+TLS1
-[ 	]+54:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+58:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+58:[ 	]+R_LARCH_TLS_GD_PC_HI20[ 	]+TLS1
-[ 	]+5c:[ 	]+02800084[ 	]+addi.w[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+5c:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+TLS1
-[ 	]+5c:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
+0+ <.L1>:
+   0:	00150004 	move        	\$a0, \$zero
+   4:	02bffc04 	li.w        	\$a0, -1
+   8:	00150004 	move        	\$a0, \$zero
+   c:	02bffc04 	li.w        	\$a0, -1
+  10:	1a000004 	pcalau12i   	\$a0, 0
+			10: R_LARCH_GOT_PC_HI20	.L1
+			10: R_LARCH_RELAX	\*ABS\*
+  14:	28800084 	ld.w        	\$a0, \$a0, 0
+			14: R_LARCH_GOT_PC_LO12	.L1
+			14: R_LARCH_RELAX	\*ABS\*
+  18:	1a000004 	pcalau12i   	\$a0, 0
+			18: R_LARCH_GOT_PC_HI20	.L1
+			18: R_LARCH_RELAX	\*ABS\*
+  1c:	28800084 	ld.w        	\$a0, \$a0, 0
+			1c: R_LARCH_GOT_PC_LO12	.L1
+			1c: R_LARCH_RELAX	\*ABS\*
+  20:	1a000004 	pcalau12i   	\$a0, 0
+			20: R_LARCH_PCALA_HI20	.L1
+			20: R_LARCH_RELAX	\*ABS\*
+  24:	02800084 	addi.w      	\$a0, \$a0, 0
+			24: R_LARCH_PCALA_LO12	.L1
+			24: R_LARCH_RELAX	\*ABS\*
+  28:	14000004 	lu12i.w     	\$a0, 0
+			28: R_LARCH_MARK_LA	\*ABS\*
+			28: R_LARCH_ABS_HI20	.L1
+  2c:	03800084 	ori         	\$a0, \$a0, 0x0
+			2c: R_LARCH_ABS_LO12	.L1
+  30:	1a000004 	pcalau12i   	\$a0, 0
+			30: R_LARCH_PCALA_HI20	.L1
+			30: R_LARCH_RELAX	\*ABS\*
+  34:	02800084 	addi.w      	\$a0, \$a0, 0
+			34: R_LARCH_PCALA_LO12	.L1
+			34: R_LARCH_RELAX	\*ABS\*
+  38:	1a000004 	pcalau12i   	\$a0, 0
+			38: R_LARCH_GOT_PC_HI20	.L1
+			38: R_LARCH_RELAX	\*ABS\*
+  3c:	28800084 	ld.w        	\$a0, \$a0, 0
+			3c: R_LARCH_GOT_PC_LO12	.L1
+			3c: R_LARCH_RELAX	\*ABS\*
+  40:	14000004 	lu12i.w     	\$a0, 0
+			40: R_LARCH_TLS_LE_HI20	TLS1
+  44:	03800084 	ori         	\$a0, \$a0, 0x0
+			44: R_LARCH_TLS_LE_LO12	TLS1
+  48:	1a000004 	pcalau12i   	\$a0, 0
+			48: R_LARCH_TLS_IE_PC_HI20	TLS1
+  4c:	28800084 	ld.w        	\$a0, \$a0, 0
+			4c: R_LARCH_TLS_IE_PC_LO12	TLS1
+  50:	1a000004 	pcalau12i   	\$a0, 0
+			50: R_LARCH_TLS_LD_PC_HI20	TLS1
+			50: R_LARCH_RELAX	\*ABS\*
+  54:	02800084 	addi.w      	\$a0, \$a0, 0
+			54: R_LARCH_GOT_PC_LO12	TLS1
+			54: R_LARCH_RELAX	\*ABS\*
+  58:	1a000004 	pcalau12i   	\$a0, 0
+			58: R_LARCH_TLS_GD_PC_HI20	TLS1
+			58: R_LARCH_RELAX	\*ABS\*
+  5c:	02800084 	addi.w      	\$a0, \$a0, 0
+			5c: R_LARCH_GOT_PC_LO12	TLS1
+			5c: R_LARCH_RELAX	\*ABS\*
diff --git a/gas/testsuite/gas/loongarch/macro_op_large_abs.d b/gas/testsuite/gas/loongarch/macro_op_large_abs.d
index 0c49f68e2ab..729e878ffb8 100644
--- a/gas/testsuite/gas/loongarch/macro_op_large_abs.d
+++ b/gas/testsuite/gas/loongarch/macro_op_large_abs.d
@@ -1,85 +1,89 @@
-#as: -mla-global-with-abs
+#as:
 #objdump: -dr
 #skip: loongarch32-*-*
 
-.*:[    ]+file format .*
+.*:     file format .*
 
 
 Disassembly of section .text:
 
-00000000.* <.L1>:
-[ 	]+0:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+0:[ 	]+R_LARCH_PCALA_HI20[ 	]+.L1
-[ 	]+0:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+4:[ 	]+02c00005[ 	]+li\.d[ 	]+\$a1,[ 	]+0
-[ 	]+4:[ 	]+R_LARCH_PCALA_LO12[ 	]+.L1
-[ 	]+4:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+8:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
-[ 	]+8:[ 	]+R_LARCH_PCALA64_LO20[ 	]+.L1
-[ 	]+c:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
-[ 	]+c:[ 	]+R_LARCH_PCALA64_HI12[ 	]+.L1
-[ 	]+10:[ 	]+00109484[ 	]+add.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
-[ 	]+14:[ 	]+14000004[ 	]+lu12i.w[ 	]+\$a0,[ 	]+0
-[ 	]+14:[ 	]+R_LARCH_MARK_LA[ 	]+\*ABS\*
-[ 	]+14:[ 	]+R_LARCH_ABS_HI20[ 	]+.L1
-[ 	]+18:[ 	]+03800084[ 	]+ori[ 	]+\$a0,[ 	]+\$a0,[ 	]+0x0
-[ 	]+18:[ 	]+R_LARCH_ABS_LO12[ 	]+.L1
-[ 	]+1c:[ 	]+16000004[ 	]+lu32i.d[ 	]+\$a0,[ 	]+0
-[ 	]+1c:[ 	]+R_LARCH_ABS64_LO20[ 	]+.L1
-[ 	]+20:[ 	]+03000084[ 	]+lu52i.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+20:[ 	]+R_LARCH_ABS64_HI12[ 	]+.L1
-[ 	]+24:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+24:[ 	]+R_LARCH_PCALA_HI20[ 	]+.L1
-[ 	]+24:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+28:[ 	]+02c00005[ 	]+li\.d[ 	]+\$a1,[ 	]+0
-[ 	]+28:[ 	]+R_LARCH_PCALA_LO12[ 	]+.L1
-[ 	]+28:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+2c:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
-[ 	]+2c:[ 	]+R_LARCH_PCALA64_LO20[ 	]+.L1
-[ 	]+30:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
-[ 	]+30:[ 	]+R_LARCH_PCALA64_HI12[ 	]+.L1
-[ 	]+34:[ 	]+00109484[ 	]+add.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
-[ 	]+38:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+38:[ 	]+R_LARCH_GOT_PC_HI20[ 	]+.L1
-[ 	]+38:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+3c:[ 	]+02c00005[ 	]+li\.d[ 	]+\$a1,[ 	]+0
-[ 	]+3c:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+.L1
-[ 	]+3c:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+40:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
-[ 	]+40:[ 	]+R_LARCH_GOT64_PC_LO20[ 	]+.L1
-[ 	]+44:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
-[ 	]+44:[ 	]+R_LARCH_GOT64_PC_HI12[ 	]+.L1
-[ 	]+48:[ 	]+380c1484[ 	]+ldx.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
-[ 	]+4c:[ 	]+14000004[ 	]+lu12i.w[ 	]+\$a0,[ 	]+0
-[ 	]+4c:[ 	]+R_LARCH_TLS_LE_HI20[ 	]+TLS1
-[ 	]+50:[ 	]+03800084[ 	]+ori[ 	]+\$a0,[ 	]+\$a0,[ 	]+0x0
-[ 	]+50:[ 	]+R_LARCH_TLS_LE_LO12[ 	]+TLS1
-[ 	]+54:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+54:[ 	]+R_LARCH_TLS_IE_PC_HI20[ 	]+TLS1
-[ 	]+58:[ 	]+02c00005[ 	]+li\.d[ 	]+\$a1,[ 	]+0
-[ 	]+58:[ 	]+R_LARCH_TLS_IE_PC_LO12[ 	]+TLS1
-[ 	]+5c:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
-[ 	]+5c:[ 	]+R_LARCH_TLS_IE64_PC_LO20[ 	]+TLS1
-[ 	]+60:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
-[ 	]+60:[ 	]+R_LARCH_TLS_IE64_PC_HI12[ 	]+TLS1
-[ 	]+64:[ 	]+380c1484[ 	]+ldx.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
-[ 	]+68:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+68:[ 	]+R_LARCH_TLS_LD_PC_HI20[ 	]+TLS1
-[ 	]+6c:[ 	]+02c00005[ 	]+li\.d[ 	]+\$a1,[ 	]+0
-[ 	]+6c:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+TLS1
-[ 	]+6c:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+70:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
-[ 	]+70:[ 	]+R_LARCH_GOT64_PC_LO20[ 	]+TLS1
-[ 	]+74:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
-[ 	]+74:[ 	]+R_LARCH_GOT64_PC_HI12[ 	]+TLS1
-[ 	]+78:[ 	]+00109484[ 	]+add.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
-[ 	]+7c:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+7c:[ 	]+R_LARCH_TLS_GD_PC_HI20[ 	]+TLS1
-[ 	]+80:[ 	]+02c00005[ 	]+li\.d[ 	]+\$a1,[ 	]+0
-[ 	]+80:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+TLS1
-[ 	]+80:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+84:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
-[ 	]+84:[ 	]+R_LARCH_GOT64_PC_LO20[ 	]+TLS1
-[ 	]+88:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
-[ 	]+88:[ 	]+R_LARCH_GOT64_PC_HI12[ 	]+TLS1
-[ 	]+8c:[ 	]+00109484[ 	]+add.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
+0+ <.L1>:
+   0:	1a000004 	pcalau12i   	\$a0, 0
+			0: R_LARCH_PCALA_HI20	.L1
+			0: R_LARCH_RELAX	\*ABS\*
+   4:	02c00005 	li.d        	\$a1, 0
+			4: R_LARCH_PCALA_LO12	.L1
+			4: R_LARCH_RELAX	\*ABS\*
+   8:	16000005 	lu32i.d     	\$a1, 0
+			8: R_LARCH_PCALA64_LO20	.L1
+   c:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			c: R_LARCH_PCALA64_HI12	.L1
+  10:	00109484 	add.d       	\$a0, \$a0, \$a1
+  14:	1a000004 	pcalau12i   	\$a0, 0
+			14: R_LARCH_GOT_PC_HI20	.L1
+			14: R_LARCH_RELAX	\*ABS\*
+  18:	02c00005 	li.d        	\$a1, 0
+			18: R_LARCH_GOT_PC_LO12	.L1
+			18: R_LARCH_RELAX	\*ABS\*
+  1c:	16000005 	lu32i.d     	\$a1, 0
+			1c: R_LARCH_GOT64_PC_LO20	.L1
+  20:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			20: R_LARCH_GOT64_PC_HI12	.L1
+  24:	380c1484 	ldx.d       	\$a0, \$a0, \$a1
+  28:	1a000004 	pcalau12i   	\$a0, 0
+			28: R_LARCH_PCALA_HI20	.L1
+			28: R_LARCH_RELAX	\*ABS\*
+  2c:	02c00005 	li.d        	\$a1, 0
+			2c: R_LARCH_PCALA_LO12	.L1
+			2c: R_LARCH_RELAX	\*ABS\*
+  30:	16000005 	lu32i.d     	\$a1, 0
+			30: R_LARCH_PCALA64_LO20	.L1
+  34:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			34: R_LARCH_PCALA64_HI12	.L1
+  38:	00109484 	add.d       	\$a0, \$a0, \$a1
+  3c:	1a000004 	pcalau12i   	\$a0, 0
+			3c: R_LARCH_GOT_PC_HI20	.L1
+			3c: R_LARCH_RELAX	\*ABS\*
+  40:	02c00005 	li.d        	\$a1, 0
+			40: R_LARCH_GOT_PC_LO12	.L1
+			40: R_LARCH_RELAX	\*ABS\*
+  44:	16000005 	lu32i.d     	\$a1, 0
+			44: R_LARCH_GOT64_PC_LO20	.L1
+  48:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			48: R_LARCH_GOT64_PC_HI12	.L1
+  4c:	380c1484 	ldx.d       	\$a0, \$a0, \$a1
+  50:	14000004 	lu12i.w     	\$a0, 0
+			50: R_LARCH_TLS_LE_HI20	TLS1
+  54:	03800084 	ori         	\$a0, \$a0, 0x0
+			54: R_LARCH_TLS_LE_LO12	TLS1
+  58:	1a000004 	pcalau12i   	\$a0, 0
+			58: R_LARCH_TLS_IE_PC_HI20	TLS1
+  5c:	02c00005 	li.d        	\$a1, 0
+			5c: R_LARCH_TLS_IE_PC_LO12	TLS1
+  60:	16000005 	lu32i.d     	\$a1, 0
+			60: R_LARCH_TLS_IE64_PC_LO20	TLS1
+  64:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			64: R_LARCH_TLS_IE64_PC_HI12	TLS1
+  68:	380c1484 	ldx.d       	\$a0, \$a0, \$a1
+  6c:	1a000004 	pcalau12i   	\$a0, 0
+			6c: R_LARCH_TLS_LD_PC_HI20	TLS1
+			6c: R_LARCH_RELAX	\*ABS\*
+  70:	02c00005 	li.d        	\$a1, 0
+			70: R_LARCH_GOT_PC_LO12	TLS1
+			70: R_LARCH_RELAX	\*ABS\*
+  74:	16000005 	lu32i.d     	\$a1, 0
+			74: R_LARCH_GOT64_PC_LO20	TLS1
+  78:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			78: R_LARCH_GOT64_PC_HI12	TLS1
+  7c:	00109484 	add.d       	\$a0, \$a0, \$a1
+  80:	1a000004 	pcalau12i   	\$a0, 0
+			80: R_LARCH_TLS_GD_PC_HI20	TLS1
+			80: R_LARCH_RELAX	\*ABS\*
+  84:	02c00005 	li.d        	\$a1, 0
+			84: R_LARCH_GOT_PC_LO12	TLS1
+			84: R_LARCH_RELAX	\*ABS\*
+  88:	16000005 	lu32i.d     	\$a1, 0
+			88: R_LARCH_GOT64_PC_LO20	TLS1
+  8c:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			8c: R_LARCH_GOT64_PC_HI12	TLS1
+  90:	00109484 	add.d       	\$a0, \$a0, \$a1
diff --git a/gas/testsuite/gas/loongarch/macro_op_large_pc.d b/gas/testsuite/gas/loongarch/macro_op_large_pc.d
index 0c49f68e2ab..729e878ffb8 100644
--- a/gas/testsuite/gas/loongarch/macro_op_large_pc.d
+++ b/gas/testsuite/gas/loongarch/macro_op_large_pc.d
@@ -1,85 +1,89 @@
-#as: -mla-global-with-abs
+#as:
 #objdump: -dr
 #skip: loongarch32-*-*
 
-.*:[    ]+file format .*
+.*:     file format .*
 
 
 Disassembly of section .text:
 
-00000000.* <.L1>:
-[ 	]+0:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+0:[ 	]+R_LARCH_PCALA_HI20[ 	]+.L1
-[ 	]+0:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+4:[ 	]+02c00005[ 	]+li\.d[ 	]+\$a1,[ 	]+0
-[ 	]+4:[ 	]+R_LARCH_PCALA_LO12[ 	]+.L1
-[ 	]+4:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+8:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
-[ 	]+8:[ 	]+R_LARCH_PCALA64_LO20[ 	]+.L1
-[ 	]+c:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
-[ 	]+c:[ 	]+R_LARCH_PCALA64_HI12[ 	]+.L1
-[ 	]+10:[ 	]+00109484[ 	]+add.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
-[ 	]+14:[ 	]+14000004[ 	]+lu12i.w[ 	]+\$a0,[ 	]+0
-[ 	]+14:[ 	]+R_LARCH_MARK_LA[ 	]+\*ABS\*
-[ 	]+14:[ 	]+R_LARCH_ABS_HI20[ 	]+.L1
-[ 	]+18:[ 	]+03800084[ 	]+ori[ 	]+\$a0,[ 	]+\$a0,[ 	]+0x0
-[ 	]+18:[ 	]+R_LARCH_ABS_LO12[ 	]+.L1
-[ 	]+1c:[ 	]+16000004[ 	]+lu32i.d[ 	]+\$a0,[ 	]+0
-[ 	]+1c:[ 	]+R_LARCH_ABS64_LO20[ 	]+.L1
-[ 	]+20:[ 	]+03000084[ 	]+lu52i.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+20:[ 	]+R_LARCH_ABS64_HI12[ 	]+.L1
-[ 	]+24:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+24:[ 	]+R_LARCH_PCALA_HI20[ 	]+.L1
-[ 	]+24:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+28:[ 	]+02c00005[ 	]+li\.d[ 	]+\$a1,[ 	]+0
-[ 	]+28:[ 	]+R_LARCH_PCALA_LO12[ 	]+.L1
-[ 	]+28:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+2c:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
-[ 	]+2c:[ 	]+R_LARCH_PCALA64_LO20[ 	]+.L1
-[ 	]+30:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
-[ 	]+30:[ 	]+R_LARCH_PCALA64_HI12[ 	]+.L1
-[ 	]+34:[ 	]+00109484[ 	]+add.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
-[ 	]+38:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+38:[ 	]+R_LARCH_GOT_PC_HI20[ 	]+.L1
-[ 	]+38:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+3c:[ 	]+02c00005[ 	]+li\.d[ 	]+\$a1,[ 	]+0
-[ 	]+3c:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+.L1
-[ 	]+3c:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+40:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
-[ 	]+40:[ 	]+R_LARCH_GOT64_PC_LO20[ 	]+.L1
-[ 	]+44:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
-[ 	]+44:[ 	]+R_LARCH_GOT64_PC_HI12[ 	]+.L1
-[ 	]+48:[ 	]+380c1484[ 	]+ldx.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
-[ 	]+4c:[ 	]+14000004[ 	]+lu12i.w[ 	]+\$a0,[ 	]+0
-[ 	]+4c:[ 	]+R_LARCH_TLS_LE_HI20[ 	]+TLS1
-[ 	]+50:[ 	]+03800084[ 	]+ori[ 	]+\$a0,[ 	]+\$a0,[ 	]+0x0
-[ 	]+50:[ 	]+R_LARCH_TLS_LE_LO12[ 	]+TLS1
-[ 	]+54:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+54:[ 	]+R_LARCH_TLS_IE_PC_HI20[ 	]+TLS1
-[ 	]+58:[ 	]+02c00005[ 	]+li\.d[ 	]+\$a1,[ 	]+0
-[ 	]+58:[ 	]+R_LARCH_TLS_IE_PC_LO12[ 	]+TLS1
-[ 	]+5c:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
-[ 	]+5c:[ 	]+R_LARCH_TLS_IE64_PC_LO20[ 	]+TLS1
-[ 	]+60:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
-[ 	]+60:[ 	]+R_LARCH_TLS_IE64_PC_HI12[ 	]+TLS1
-[ 	]+64:[ 	]+380c1484[ 	]+ldx.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
-[ 	]+68:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+68:[ 	]+R_LARCH_TLS_LD_PC_HI20[ 	]+TLS1
-[ 	]+6c:[ 	]+02c00005[ 	]+li\.d[ 	]+\$a1,[ 	]+0
-[ 	]+6c:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+TLS1
-[ 	]+6c:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+70:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
-[ 	]+70:[ 	]+R_LARCH_GOT64_PC_LO20[ 	]+TLS1
-[ 	]+74:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
-[ 	]+74:[ 	]+R_LARCH_GOT64_PC_HI12[ 	]+TLS1
-[ 	]+78:[ 	]+00109484[ 	]+add.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
-[ 	]+7c:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+7c:[ 	]+R_LARCH_TLS_GD_PC_HI20[ 	]+TLS1
-[ 	]+80:[ 	]+02c00005[ 	]+li\.d[ 	]+\$a1,[ 	]+0
-[ 	]+80:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+TLS1
-[ 	]+80:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+84:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
-[ 	]+84:[ 	]+R_LARCH_GOT64_PC_LO20[ 	]+TLS1
-[ 	]+88:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
-[ 	]+88:[ 	]+R_LARCH_GOT64_PC_HI12[ 	]+TLS1
-[ 	]+8c:[ 	]+00109484[ 	]+add.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
+0+ <.L1>:
+   0:	1a000004 	pcalau12i   	\$a0, 0
+			0: R_LARCH_PCALA_HI20	.L1
+			0: R_LARCH_RELAX	\*ABS\*
+   4:	02c00005 	li.d        	\$a1, 0
+			4: R_LARCH_PCALA_LO12	.L1
+			4: R_LARCH_RELAX	\*ABS\*
+   8:	16000005 	lu32i.d     	\$a1, 0
+			8: R_LARCH_PCALA64_LO20	.L1
+   c:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			c: R_LARCH_PCALA64_HI12	.L1
+  10:	00109484 	add.d       	\$a0, \$a0, \$a1
+  14:	1a000004 	pcalau12i   	\$a0, 0
+			14: R_LARCH_GOT_PC_HI20	.L1
+			14: R_LARCH_RELAX	\*ABS\*
+  18:	02c00005 	li.d        	\$a1, 0
+			18: R_LARCH_GOT_PC_LO12	.L1
+			18: R_LARCH_RELAX	\*ABS\*
+  1c:	16000005 	lu32i.d     	\$a1, 0
+			1c: R_LARCH_GOT64_PC_LO20	.L1
+  20:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			20: R_LARCH_GOT64_PC_HI12	.L1
+  24:	380c1484 	ldx.d       	\$a0, \$a0, \$a1
+  28:	1a000004 	pcalau12i   	\$a0, 0
+			28: R_LARCH_PCALA_HI20	.L1
+			28: R_LARCH_RELAX	\*ABS\*
+  2c:	02c00005 	li.d        	\$a1, 0
+			2c: R_LARCH_PCALA_LO12	.L1
+			2c: R_LARCH_RELAX	\*ABS\*
+  30:	16000005 	lu32i.d     	\$a1, 0
+			30: R_LARCH_PCALA64_LO20	.L1
+  34:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			34: R_LARCH_PCALA64_HI12	.L1
+  38:	00109484 	add.d       	\$a0, \$a0, \$a1
+  3c:	1a000004 	pcalau12i   	\$a0, 0
+			3c: R_LARCH_GOT_PC_HI20	.L1
+			3c: R_LARCH_RELAX	\*ABS\*
+  40:	02c00005 	li.d        	\$a1, 0
+			40: R_LARCH_GOT_PC_LO12	.L1
+			40: R_LARCH_RELAX	\*ABS\*
+  44:	16000005 	lu32i.d     	\$a1, 0
+			44: R_LARCH_GOT64_PC_LO20	.L1
+  48:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			48: R_LARCH_GOT64_PC_HI12	.L1
+  4c:	380c1484 	ldx.d       	\$a0, \$a0, \$a1
+  50:	14000004 	lu12i.w     	\$a0, 0
+			50: R_LARCH_TLS_LE_HI20	TLS1
+  54:	03800084 	ori         	\$a0, \$a0, 0x0
+			54: R_LARCH_TLS_LE_LO12	TLS1
+  58:	1a000004 	pcalau12i   	\$a0, 0
+			58: R_LARCH_TLS_IE_PC_HI20	TLS1
+  5c:	02c00005 	li.d        	\$a1, 0
+			5c: R_LARCH_TLS_IE_PC_LO12	TLS1
+  60:	16000005 	lu32i.d     	\$a1, 0
+			60: R_LARCH_TLS_IE64_PC_LO20	TLS1
+  64:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			64: R_LARCH_TLS_IE64_PC_HI12	TLS1
+  68:	380c1484 	ldx.d       	\$a0, \$a0, \$a1
+  6c:	1a000004 	pcalau12i   	\$a0, 0
+			6c: R_LARCH_TLS_LD_PC_HI20	TLS1
+			6c: R_LARCH_RELAX	\*ABS\*
+  70:	02c00005 	li.d        	\$a1, 0
+			70: R_LARCH_GOT_PC_LO12	TLS1
+			70: R_LARCH_RELAX	\*ABS\*
+  74:	16000005 	lu32i.d     	\$a1, 0
+			74: R_LARCH_GOT64_PC_LO20	TLS1
+  78:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			78: R_LARCH_GOT64_PC_HI12	TLS1
+  7c:	00109484 	add.d       	\$a0, \$a0, \$a1
+  80:	1a000004 	pcalau12i   	\$a0, 0
+			80: R_LARCH_TLS_GD_PC_HI20	TLS1
+			80: R_LARCH_RELAX	\*ABS\*
+  84:	02c00005 	li.d        	\$a1, 0
+			84: R_LARCH_GOT_PC_LO12	TLS1
+			84: R_LARCH_RELAX	\*ABS\*
+  88:	16000005 	lu32i.d     	\$a1, 0
+			88: R_LARCH_GOT64_PC_LO20	TLS1
+  8c:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			8c: R_LARCH_GOT64_PC_HI12	TLS1
+  90:	00109484 	add.d       	\$a0, \$a0, \$a1
diff --git a/include/elf/loongarch.h b/include/elf/loongarch.h
index da2fd119181..66a47c6c3f2 100644
--- a/include/elf/loongarch.h
+++ b/include/elf/loongarch.h
@@ -271,6 +271,10 @@ RELOC_NUMBER (R_LARCH_TLS_DESC64_HI12, 119)
 
 RELOC_NUMBER (R_LARCH_TLS_DESC_CALL, 120)
 
+RELOC_NUMBER (R_LARCH_TLS_LD_PCREL20_S2, 121)
+RELOC_NUMBER (R_LARCH_TLS_GD_PCREL20_S2, 122)
+RELOC_NUMBER (R_LARCH_TLS_DESC_PCREL20_S2, 123)
+
 END_RELOC_NUMBERS (R_LARCH_count)
 
 /* Processor specific flags for the ELF header e_flags field.  */
diff --git a/ld/testsuite/ld-loongarch-elf/macro_op.d b/ld/testsuite/ld-loongarch-elf/macro_op.d
index edc71bc0dbf..f0d87c03802 100644
--- a/ld/testsuite/ld-loongarch-elf/macro_op.d
+++ b/ld/testsuite/ld-loongarch-elf/macro_op.d
@@ -1,200 +1,205 @@
 #as:
 #objdump: -dr
+#skip: loongarch32-*-*
 
-.*:[    ]+file format .*
+.*:     file format .*
 
 
 Disassembly of section .text:
 
-00000000.* <.L1>:
-[ 	]+0:[ 	]+00150004[ 	]+move[ 	]+\$a0,[ 	]+\$zero
-[ 	]+4:[ 	]+02bffc04[ 	]+li\.w[ 	]+\$a0,[ 	]+-1
-[ 	]+8:[ 	]+00150004[ 	]+move[ 	]+\$a0,[ 	]+\$zero
-[ 	]+c:[ 	]+02bffc04[ 	]+li\.w[ 	]+\$a0,[ 	]+-1
-[ 	]+10:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+10:[ 	]+R_LARCH_GOT_PC_HI20[ 	]+.L1
-[ 	]+10:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+14:[ 	]+28c00084[ 	]+ld.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+14:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+.L1
-[ 	]+14:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+18:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+18:[ 	]+R_LARCH_GOT_PC_HI20[ 	]+.L1
-[ 	]+18:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+1c:[ 	]+28c00084[ 	]+ld.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+1c:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+.L1
-[ 	]+1c:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+20:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+20:[ 	]+R_LARCH_GOT_PC_HI20[ 	]+.L1
-[ 	]+20:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+24:[ 	]+02c00005[ 	]+li\.d[ 	]+\$a1,[ 	]+0
-[ 	]+24:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+.L1
-[ 	]+24:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+28:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
-[ 	]+28:[ 	]+R_LARCH_GOT64_PC_LO20[ 	]+.L1
-[ 	]+2c:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
-[ 	]+2c:[ 	]+R_LARCH_GOT64_PC_HI12[ 	]+.L1
-[ 	]+30:[ 	]+380c1484[ 	]+ldx.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
-[ 	]+34:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+34:[ 	]+R_LARCH_GOT_PC_HI20[ 	]+.L1
-[ 	]+34:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+38:[ 	]+28c00084[ 	]+ld.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+38:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+.L1
-[ 	]+38:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+3c:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+3c:[ 	]+R_LARCH_GOT_PC_HI20[ 	]+.L1
-[ 	]+3c:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+40:[ 	]+02c00005[ 	]+li\.d[ 	]+\$a1,[ 	]+0
-[ 	]+40:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+.L1
-[ 	]+40:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+44:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
-[ 	]+44:[ 	]+R_LARCH_GOT64_PC_LO20[ 	]+.L1
-[ 	]+48:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
-[ 	]+48:[ 	]+R_LARCH_GOT64_PC_HI12[ 	]+.L1
-[ 	]+4c:[ 	]+380c1484[ 	]+ldx.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
-[ 	]+50:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+50:[ 	]+R_LARCH_GOT_PC_HI20[ 	]+.L1
-[ 	]+50:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+54:[ 	]+28c00084[ 	]+ld.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+54:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+.L1
-[ 	]+54:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+58:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+58:[ 	]+R_LARCH_GOT_PC_HI20[ 	]+.L1
-[ 	]+58:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+5c:[ 	]+02c00005[ 	]+li\.d[ 	]+\$a1,[ 	]+0
-[ 	]+5c:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+.L1
-[ 	]+5c:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+60:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
-[ 	]+60:[ 	]+R_LARCH_GOT64_PC_LO20[ 	]+.L1
-[ 	]+64:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
-[ 	]+64:[ 	]+R_LARCH_GOT64_PC_HI12[ 	]+.L1
-[ 	]+68:[ 	]+380c1484[ 	]+ldx.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
-[ 	]+6c:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+6c:[ 	]+R_LARCH_PCALA_HI20[ 	]+.L1
-[ 	]+6c:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+70:[ 	]+02c00084[ 	]+addi.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+70:[ 	]+R_LARCH_PCALA_LO12[ 	]+.L1
-[ 	]+70:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+74:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+74:[ 	]+R_LARCH_PCALA_HI20[ 	]+.L1
-[ 	]+74:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+78:[ 	]+02c00005[ 	]+li\.d[ 	]+\$a1,[ 	]+0
-[ 	]+78:[ 	]+R_LARCH_PCALA_LO12[ 	]+.L1
-[ 	]+78:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+7c:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
-[ 	]+7c:[ 	]+R_LARCH_PCALA64_LO20[ 	]+.L1
-[ 	]+80:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
-[ 	]+80:[ 	]+R_LARCH_PCALA64_HI12[ 	]+.L1
-[ 	]+84:[ 	]+00109484[ 	]+add.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
-[ 	]+88:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+88:[ 	]+R_LARCH_PCALA_HI20[ 	]+.L1
-[ 	]+88:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+8c:[ 	]+02c00084[ 	]+addi.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+8c:[ 	]+R_LARCH_PCALA_LO12[ 	]+.L1
-[ 	]+8c:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+90:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+90:[ 	]+R_LARCH_PCALA_HI20[ 	]+.L1
-[ 	]+90:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+94:[ 	]+02c00005[ 	]+li\.d[ 	]+\$a1,[ 	]+0
-[ 	]+94:[ 	]+R_LARCH_PCALA_LO12[ 	]+.L1
-[ 	]+94:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+98:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
-[ 	]+98:[ 	]+R_LARCH_PCALA64_LO20[ 	]+.L1
-[ 	]+9c:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
-[ 	]+9c:[ 	]+R_LARCH_PCALA64_HI12[ 	]+.L1
-[ 	]+a0:[ 	]+00109484[ 	]+add.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
-[ 	]+a4:[ 	]+14000004[ 	]+lu12i.w[ 	]+\$a0,[ 	]+0
-[ 	]+a4:[ 	]+R_LARCH_MARK_LA[ 	]+\*ABS\*
-[ 	]+a4:[ 	]+R_LARCH_ABS_HI20[ 	]+.L1
-[ 	]+a8:[ 	]+03800084[ 	]+ori[ 	]+\$a0,[ 	]+\$a0,[ 	]+0x0
-[ 	]+a8:[ 	]+R_LARCH_ABS_LO12[ 	]+.L1
-[ 	]+ac:[ 	]+16000004[ 	]+lu32i.d[ 	]+\$a0,[ 	]+0
-[ 	]+ac:[ 	]+R_LARCH_ABS64_LO20[ 	]+.L1
-[ 	]+b0:[ 	]+03000084[ 	]+lu52i.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+b0:[ 	]+R_LARCH_ABS64_HI12[ 	]+.L1
-[ 	]+b4:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+b4:[ 	]+R_LARCH_PCALA_HI20[ 	]+.L1
-[ 	]+b4:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+b8:[ 	]+02c00084[ 	]+addi.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+b8:[ 	]+R_LARCH_PCALA_LO12[ 	]+.L1
-[ 	]+b8:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+bc:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+bc:[ 	]+R_LARCH_PCALA_HI20[ 	]+.L1
-[ 	]+bc:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+c0:[ 	]+02c00084[ 	]+addi.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+c0:[ 	]+R_LARCH_PCALA_LO12[ 	]+.L1
-[ 	]+c0:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+c4:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+c4:[ 	]+R_LARCH_PCALA_HI20[ 	]+.L1
-[ 	]+c4:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+c8:[ 	]+02c00005[ 	]+li\.d[ 	]+\$a1,[ 	]+0
-[ 	]+c8:[ 	]+R_LARCH_PCALA_LO12[ 	]+.L1
-[ 	]+c8:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+cc:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
-[ 	]+cc:[ 	]+R_LARCH_PCALA64_LO20[ 	]+.L1
-[ 	]+d0:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
-[ 	]+d0:[ 	]+R_LARCH_PCALA64_HI12[ 	]+.L1
-[ 	]+d4:[ 	]+00109484[ 	]+add.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
-[ 	]+d8:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+d8:[ 	]+R_LARCH_GOT_PC_HI20[ 	]+.L1
-[ 	]+d8:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+dc:[ 	]+28c00084[ 	]+ld.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+dc:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+.L1
-[ 	]+dc:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+e0:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+e0:[ 	]+R_LARCH_GOT_PC_HI20[ 	]+.L1
-[ 	]+e0:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+e4:[ 	]+02c00005[ 	]+li\.d[ 	]+\$a1,[ 	]+0
-[ 	]+e4:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+.L1
-[ 	]+e4:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+e8:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
-[ 	]+e8:[ 	]+R_LARCH_GOT64_PC_LO20[ 	]+.L1
-[ 	]+ec:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
-[ 	]+ec:[ 	]+R_LARCH_GOT64_PC_HI12[ 	]+.L1
-[ 	]+f0:[ 	]+380c1484[ 	]+ldx.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
-[ 	]+f4:[ 	]+14000004[ 	]+lu12i.w[ 	]+\$a0,[ 	]+0
-[ 	]+f4:[ 	]+R_LARCH_TLS_LE_HI20[ 	]+TLS1
-[ 	]+f8:[ 	]+03800084[ 	]+ori[ 	]+\$a0,[ 	]+\$a0,[ 	]+0x0
-[ 	]+f8:[ 	]+R_LARCH_TLS_LE_LO12[ 	]+TLS1
-[ 	]+fc:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+fc:[ 	]+R_LARCH_TLS_IE_PC_HI20[ 	]+TLS1
-[ 	]+100:[ 	]+28c00084[ 	]+ld.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+100:[ 	]+R_LARCH_TLS_IE_PC_LO12[ 	]+TLS1
-[ 	]+104:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+104:[ 	]+R_LARCH_TLS_IE_PC_HI20[ 	]+TLS1
-[ 	]+108:[ 	]+02c00005[ 	]+li\.d[ 	]+\$a1,[ 	]+0
-[ 	]+108:[ 	]+R_LARCH_TLS_IE_PC_LO12[ 	]+TLS1
-[ 	]+10c:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
-[ 	]+10c:[ 	]+R_LARCH_TLS_IE64_PC_LO20[ 	]+TLS1
-[ 	]+110:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
-[ 	]+110:[ 	]+R_LARCH_TLS_IE64_PC_HI12[ 	]+TLS1
-[ 	]+114:[ 	]+380c1484[ 	]+ldx.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
-[ 	]+118:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+118:[ 	]+R_LARCH_TLS_LD_PC_HI20[ 	]+TLS1
-[ 	]+11c:[ 	]+02c00084[ 	]+addi.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+11c:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+TLS1
-[ 	]+11c:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+120:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+120:[ 	]+R_LARCH_TLS_LD_PC_HI20[ 	]+TLS1
-[ 	]+124:[ 	]+02c00005[ 	]+li\.d[ 	]+\$a1,[ 	]+0
-[ 	]+124:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+TLS1
-[ 	]+124:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+128:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
-[ 	]+128:[ 	]+R_LARCH_GOT64_PC_LO20[ 	]+TLS1
-[ 	]+12c:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
-[ 	]+12c:[ 	]+R_LARCH_GOT64_PC_HI12[ 	]+TLS1
-[ 	]+130:[ 	]+00109484[ 	]+add.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
-[ 	]+134:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+134:[ 	]+R_LARCH_TLS_GD_PC_HI20[ 	]+TLS1
-[ 	]+138:[ 	]+02c00084[ 	]+addi.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+138:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+TLS1
-[ 	]+138:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+13c:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+13c:[ 	]+R_LARCH_TLS_GD_PC_HI20[ 	]+TLS1
-[ 	]+140:[ 	]+02c00005[ 	]+li\.d[ 	]+\$a1,[ 	]+0
-[ 	]+140:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+TLS1
-[ 	]+140:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+144:[ 	]+16000005[ 	]+lu32i.d[ 	]+\$a1,[ 	]+0
-[ 	]+144:[ 	]+R_LARCH_GOT64_PC_LO20[ 	]+TLS1
-[ 	]+148:[ 	]+030000a5[ 	]+lu52i.d[ 	]+\$a1,[ 	]+\$a1,[ 	]+0
-[ 	]+148:[ 	]+R_LARCH_GOT64_PC_HI12[ 	]+TLS1
-[ 	]+14c:[ 	]+00109484[ 	]+add.d[ 	]+\$a0,[ 	]+\$a0,[ 	]+\$a1
+0+ <.L1>:
+   0:	00150004 	move        	\$a0, \$zero
+   4:	02bffc04 	li.w        	\$a0, -1
+   8:	00150004 	move        	\$a0, \$zero
+   c:	02bffc04 	li.w        	\$a0, -1
+  10:	1a000004 	pcalau12i   	\$a0, 0
+			10: R_LARCH_GOT_PC_HI20	.L1
+			10: R_LARCH_RELAX	\*ABS\*
+  14:	28c00084 	ld.d        	\$a0, \$a0, 0
+			14: R_LARCH_GOT_PC_LO12	.L1
+			14: R_LARCH_RELAX	\*ABS\*
+  18:	1a000004 	pcalau12i   	\$a0, 0
+			18: R_LARCH_GOT_PC_HI20	.L1
+			18: R_LARCH_RELAX	\*ABS\*
+  1c:	28c00084 	ld.d        	\$a0, \$a0, 0
+			1c: R_LARCH_GOT_PC_LO12	.L1
+			1c: R_LARCH_RELAX	\*ABS\*
+  20:	1a000004 	pcalau12i   	\$a0, 0
+			20: R_LARCH_GOT_PC_HI20	.L1
+			20: R_LARCH_RELAX	\*ABS\*
+  24:	02c00005 	li.d        	\$a1, 0
+			24: R_LARCH_GOT_PC_LO12	.L1
+			24: R_LARCH_RELAX	\*ABS\*
+  28:	16000005 	lu32i.d     	\$a1, 0
+			28: R_LARCH_GOT64_PC_LO20	.L1
+  2c:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			2c: R_LARCH_GOT64_PC_HI12	.L1
+  30:	380c1484 	ldx.d       	\$a0, \$a0, \$a1
+  34:	1a000004 	pcalau12i   	\$a0, 0
+			34: R_LARCH_GOT_PC_HI20	.L1
+			34: R_LARCH_RELAX	\*ABS\*
+  38:	28c00084 	ld.d        	\$a0, \$a0, 0
+			38: R_LARCH_GOT_PC_LO12	.L1
+			38: R_LARCH_RELAX	\*ABS\*
+  3c:	1a000004 	pcalau12i   	\$a0, 0
+			3c: R_LARCH_GOT_PC_HI20	.L1
+			3c: R_LARCH_RELAX	\*ABS\*
+  40:	02c00005 	li.d        	\$a1, 0
+			40: R_LARCH_GOT_PC_LO12	.L1
+			40: R_LARCH_RELAX	\*ABS\*
+  44:	16000005 	lu32i.d     	\$a1, 0
+			44: R_LARCH_GOT64_PC_LO20	.L1
+  48:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			48: R_LARCH_GOT64_PC_HI12	.L1
+  4c:	380c1484 	ldx.d       	\$a0, \$a0, \$a1
+  50:	1a000004 	pcalau12i   	\$a0, 0
+			50: R_LARCH_GOT_PC_HI20	.L1
+			50: R_LARCH_RELAX	\*ABS\*
+  54:	28c00084 	ld.d        	\$a0, \$a0, 0
+			54: R_LARCH_GOT_PC_LO12	.L1
+			54: R_LARCH_RELAX	\*ABS\*
+  58:	1a000004 	pcalau12i   	\$a0, 0
+			58: R_LARCH_GOT_PC_HI20	.L1
+			58: R_LARCH_RELAX	\*ABS\*
+  5c:	02c00005 	li.d        	\$a1, 0
+			5c: R_LARCH_GOT_PC_LO12	.L1
+			5c: R_LARCH_RELAX	\*ABS\*
+  60:	16000005 	lu32i.d     	\$a1, 0
+			60: R_LARCH_GOT64_PC_LO20	.L1
+  64:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			64: R_LARCH_GOT64_PC_HI12	.L1
+  68:	380c1484 	ldx.d       	\$a0, \$a0, \$a1
+  6c:	1a000004 	pcalau12i   	\$a0, 0
+			6c: R_LARCH_PCALA_HI20	.L1
+			6c: R_LARCH_RELAX	\*ABS\*
+  70:	02c00084 	addi.d      	\$a0, \$a0, 0
+			70: R_LARCH_PCALA_LO12	.L1
+			70: R_LARCH_RELAX	\*ABS\*
+  74:	1a000004 	pcalau12i   	\$a0, 0
+			74: R_LARCH_PCALA_HI20	.L1
+			74: R_LARCH_RELAX	\*ABS\*
+  78:	02c00005 	li.d        	\$a1, 0
+			78: R_LARCH_PCALA_LO12	.L1
+			78: R_LARCH_RELAX	\*ABS\*
+  7c:	16000005 	lu32i.d     	\$a1, 0
+			7c: R_LARCH_PCALA64_LO20	.L1
+  80:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			80: R_LARCH_PCALA64_HI12	.L1
+  84:	00109484 	add.d       	\$a0, \$a0, \$a1
+  88:	1a000004 	pcalau12i   	\$a0, 0
+			88: R_LARCH_PCALA_HI20	.L1
+			88: R_LARCH_RELAX	\*ABS\*
+  8c:	02c00084 	addi.d      	\$a0, \$a0, 0
+			8c: R_LARCH_PCALA_LO12	.L1
+			8c: R_LARCH_RELAX	\*ABS\*
+  90:	1a000004 	pcalau12i   	\$a0, 0
+			90: R_LARCH_PCALA_HI20	.L1
+			90: R_LARCH_RELAX	\*ABS\*
+  94:	02c00005 	li.d        	\$a1, 0
+			94: R_LARCH_PCALA_LO12	.L1
+			94: R_LARCH_RELAX	\*ABS\*
+  98:	16000005 	lu32i.d     	\$a1, 0
+			98: R_LARCH_PCALA64_LO20	.L1
+  9c:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			9c: R_LARCH_PCALA64_HI12	.L1
+  a0:	00109484 	add.d       	\$a0, \$a0, \$a1
+  a4:	14000004 	lu12i.w     	\$a0, 0
+			a4: R_LARCH_MARK_LA	\*ABS\*
+			a4: R_LARCH_ABS_HI20	.L1
+  a8:	03800084 	ori         	\$a0, \$a0, 0x0
+			a8: R_LARCH_ABS_LO12	.L1
+  ac:	16000004 	lu32i.d     	\$a0, 0
+			ac: R_LARCH_ABS64_LO20	.L1
+  b0:	03000084 	lu52i.d     	\$a0, \$a0, 0
+			b0: R_LARCH_ABS64_HI12	.L1
+  b4:	1a000004 	pcalau12i   	\$a0, 0
+			b4: R_LARCH_PCALA_HI20	.L1
+			b4: R_LARCH_RELAX	\*ABS\*
+  b8:	02c00084 	addi.d      	\$a0, \$a0, 0
+			b8: R_LARCH_PCALA_LO12	.L1
+			b8: R_LARCH_RELAX	\*ABS\*
+  bc:	1a000004 	pcalau12i   	\$a0, 0
+			bc: R_LARCH_PCALA_HI20	.L1
+			bc: R_LARCH_RELAX	\*ABS\*
+  c0:	02c00084 	addi.d      	\$a0, \$a0, 0
+			c0: R_LARCH_PCALA_LO12	.L1
+			c0: R_LARCH_RELAX	\*ABS\*
+  c4:	1a000004 	pcalau12i   	\$a0, 0
+			c4: R_LARCH_PCALA_HI20	.L1
+			c4: R_LARCH_RELAX	\*ABS\*
+  c8:	02c00005 	li.d        	\$a1, 0
+			c8: R_LARCH_PCALA_LO12	.L1
+			c8: R_LARCH_RELAX	\*ABS\*
+  cc:	16000005 	lu32i.d     	\$a1, 0
+			cc: R_LARCH_PCALA64_LO20	.L1
+  d0:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			d0: R_LARCH_PCALA64_HI12	.L1
+  d4:	00109484 	add.d       	\$a0, \$a0, \$a1
+  d8:	1a000004 	pcalau12i   	\$a0, 0
+			d8: R_LARCH_GOT_PC_HI20	.L1
+			d8: R_LARCH_RELAX	\*ABS\*
+  dc:	28c00084 	ld.d        	\$a0, \$a0, 0
+			dc: R_LARCH_GOT_PC_LO12	.L1
+			dc: R_LARCH_RELAX	\*ABS\*
+  e0:	1a000004 	pcalau12i   	\$a0, 0
+			e0: R_LARCH_GOT_PC_HI20	.L1
+			e0: R_LARCH_RELAX	\*ABS\*
+  e4:	02c00005 	li.d        	\$a1, 0
+			e4: R_LARCH_GOT_PC_LO12	.L1
+			e4: R_LARCH_RELAX	\*ABS\*
+  e8:	16000005 	lu32i.d     	\$a1, 0
+			e8: R_LARCH_GOT64_PC_LO20	.L1
+  ec:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			ec: R_LARCH_GOT64_PC_HI12	.L1
+  f0:	380c1484 	ldx.d       	\$a0, \$a0, \$a1
+  f4:	14000004 	lu12i.w     	\$a0, 0
+			f4: R_LARCH_TLS_LE_HI20	TLS1
+  f8:	03800084 	ori         	\$a0, \$a0, 0x0
+			f8: R_LARCH_TLS_LE_LO12	TLS1
+  fc:	1a000004 	pcalau12i   	\$a0, 0
+			fc: R_LARCH_TLS_IE_PC_HI20	TLS1
+ 100:	28c00084 	ld.d        	\$a0, \$a0, 0
+			100: R_LARCH_TLS_IE_PC_LO12	TLS1
+ 104:	1a000004 	pcalau12i   	\$a0, 0
+			104: R_LARCH_TLS_IE_PC_HI20	TLS1
+ 108:	02c00005 	li.d        	\$a1, 0
+			108: R_LARCH_TLS_IE_PC_LO12	TLS1
+ 10c:	16000005 	lu32i.d     	\$a1, 0
+			10c: R_LARCH_TLS_IE64_PC_LO20	TLS1
+ 110:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			110: R_LARCH_TLS_IE64_PC_HI12	TLS1
+ 114:	380c1484 	ldx.d       	\$a0, \$a0, \$a1
+ 118:	1a000004 	pcalau12i   	\$a0, 0
+			118: R_LARCH_TLS_LD_PC_HI20	TLS1
+			118: R_LARCH_RELAX	\*ABS\*
+ 11c:	02c00084 	addi.d      	\$a0, \$a0, 0
+			11c: R_LARCH_GOT_PC_LO12	TLS1
+			11c: R_LARCH_RELAX	\*ABS\*
+ 120:	1a000004 	pcalau12i   	\$a0, 0
+			120: R_LARCH_TLS_LD_PC_HI20	TLS1
+			120: R_LARCH_RELAX	\*ABS\*
+ 124:	02c00005 	li.d        	\$a1, 0
+			124: R_LARCH_GOT_PC_LO12	TLS1
+			124: R_LARCH_RELAX	\*ABS\*
+ 128:	16000005 	lu32i.d     	\$a1, 0
+			128: R_LARCH_GOT64_PC_LO20	TLS1
+ 12c:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			12c: R_LARCH_GOT64_PC_HI12	TLS1
+ 130:	00109484 	add.d       	\$a0, \$a0, \$a1
+ 134:	1a000004 	pcalau12i   	\$a0, 0
+			134: R_LARCH_TLS_GD_PC_HI20	TLS1
+			134: R_LARCH_RELAX	\*ABS\*
+ 138:	02c00084 	addi.d      	\$a0, \$a0, 0
+			138: R_LARCH_GOT_PC_LO12	TLS1
+			138: R_LARCH_RELAX	\*ABS\*
+ 13c:	1a000004 	pcalau12i   	\$a0, 0
+			13c: R_LARCH_TLS_GD_PC_HI20	TLS1
+			13c: R_LARCH_RELAX	\*ABS\*
+ 140:	02c00005 	li.d        	\$a1, 0
+			140: R_LARCH_GOT_PC_LO12	TLS1
+			140: R_LARCH_RELAX	\*ABS\*
+ 144:	16000005 	lu32i.d     	\$a1, 0
+			144: R_LARCH_GOT64_PC_LO20	TLS1
+ 148:	030000a5 	lu52i.d     	\$a1, \$a1, 0
+			148: R_LARCH_GOT64_PC_HI12	TLS1
+ 14c:	00109484 	add.d       	\$a0, \$a0, \$a1
diff --git a/ld/testsuite/ld-loongarch-elf/macro_op_32.d b/ld/testsuite/ld-loongarch-elf/macro_op_32.d
index 188026a5780..a7349aa8dc0 100644
--- a/ld/testsuite/ld-loongarch-elf/macro_op_32.d
+++ b/ld/testsuite/ld-loongarch-elf/macro_op_32.d
@@ -2,66 +2,68 @@
 #objdump: -dr
 #skip: loongarch64-*-*
 
-.*:[    ]+file format .*
+.*:     file format .*
 
 
 Disassembly of section .text:
 
-00000000.* <.L1>:
-[ 	]+0:[ 	]+00150004[ 	]+move[ 	]+\$a0,[ 	]+\$zero
-[ 	]+4:[ 	]+02bffc04[ 	]+li\.w[ 	]+\$a0,[ 	]+-1
-[ 	]+8:[ 	]+00150004[ 	]+move[ 	]+\$a0,[ 	]+\$zero
-[ 	]+c:[ 	]+02bffc04[ 	]+li\.w[ 	]+\$a0,[ 	]+-1
-[ 	]+10:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+10:[ 	]+R_LARCH_GOT_PC_HI20[ 	]+.L1
-[ 	]+10:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+14:[ 	]+28800084[ 	]+ld.w[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+14:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+.L1
-[ 	]+14:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+18:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+18:[ 	]+R_LARCH_GOT_PC_HI20[ 	]+.L1
-[ 	]+18:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+1c:[ 	]+28800084[ 	]+ld.w[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+1c:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+.L1
-[ 	]+1c:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+20:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+20:[ 	]+R_LARCH_PCALA_HI20[ 	]+.L1
-[ 	]+20:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+24:[ 	]+02800084[ 	]+addi.w[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+24:[ 	]+R_LARCH_PCALA_LO12[ 	]+.L1
-[ 	]+24:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+28:[ 	]+14000004[ 	]+lu12i.w[ 	]+\$a0,[ 	]+0
-[ 	]+28:[ 	]+R_LARCH_MARK_LA[ 	]+\*ABS\*
-[ 	]+28:[ 	]+R_LARCH_ABS_HI20[ 	]+.L1
-[ 	]+2c:[ 	]+03800084[ 	]+ori[ 	]+\$a0,[ 	]+\$a0,[ 	]+0x0
-[ 	]+2c:[ 	]+R_LARCH_ABS_LO12[ 	]+.L1
-[ 	]+30:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+30:[ 	]+R_LARCH_PCALA_HI20[ 	]+.L1
-[ 	]+30:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+34:[ 	]+02800084[ 	]+addi.w[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+34:[ 	]+R_LARCH_PCALA_LO12[ 	]+.L1
-[ 	]+34:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+38:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+38:[ 	]+R_LARCH_GOT_PC_HI20[ 	]+.L1
-[ 	]+38:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+3c:[ 	]+28800084[ 	]+ld.w[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+3c:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+.L1
-[ 	]+3c:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+40:[ 	]+14000004[ 	]+lu12i.w[ 	]+\$a0,[ 	]+0
-[ 	]+40:[ 	]+R_LARCH_TLS_LE_HI20[ 	]+TLS1
-[ 	]+44:[ 	]+03800084[ 	]+ori[ 	]+\$a0,[ 	]+\$a0,[ 	]+0x0
-[ 	]+44:[ 	]+R_LARCH_TLS_LE_LO12[ 	]+TLS1
-[ 	]+48:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+48:[ 	]+R_LARCH_TLS_IE_PC_HI20[ 	]+TLS1
-[ 	]+4c:[ 	]+28800084[ 	]+ld.w[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+4c:[ 	]+R_LARCH_TLS_IE_PC_LO12[ 	]+TLS1
-[ 	]+50:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+50:[ 	]+R_LARCH_TLS_LD_PC_HI20[ 	]+TLS1
-[ 	]+54:[ 	]+02800084[ 	]+addi.w[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+54:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+TLS1
-[ 	]+54:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
-[ 	]+58:[ 	]+1a000004[ 	]+pcalau12i[ 	]+\$a0,[ 	]+0
-[ 	]+58:[ 	]+R_LARCH_TLS_GD_PC_HI20[ 	]+TLS1
-[ 	]+5c:[ 	]+02800084[ 	]+addi.w[ 	]+\$a0,[ 	]+\$a0,[ 	]+0
-[ 	]+5c:[ 	]+R_LARCH_GOT_PC_LO12[ 	]+TLS1
-[ 	]+5c:[ 	]+R_LARCH_RELAX[ 	]+\*ABS\*
+0+ <.L1>:
+   0:	00150004 	move        	\$a0, \$zero
+   4:	02bffc04 	li.w        	\$a0, -1
+   8:	00150004 	move        	\$a0, \$zero
+   c:	02bffc04 	li.w        	\$a0, -1
+  10:	1a000004 	pcalau12i   	\$a0, 0
+			10: R_LARCH_GOT_PC_HI20	.L1
+			10: R_LARCH_RELAX	\*ABS\*
+  14:	28800084 	ld.w        	\$a0, \$a0, 0
+			14: R_LARCH_GOT_PC_LO12	.L1
+			14: R_LARCH_RELAX	\*ABS\*
+  18:	1a000004 	pcalau12i   	\$a0, 0
+			18: R_LARCH_GOT_PC_HI20	.L1
+			18: R_LARCH_RELAX	\*ABS\*
+  1c:	28800084 	ld.w        	\$a0, \$a0, 0
+			1c: R_LARCH_GOT_PC_LO12	.L1
+			1c: R_LARCH_RELAX	\*ABS\*
+  20:	1a000004 	pcalau12i   	\$a0, 0
+			20: R_LARCH_PCALA_HI20	.L1
+			20: R_LARCH_RELAX	\*ABS\*
+  24:	02800084 	addi.w      	\$a0, \$a0, 0
+			24: R_LARCH_PCALA_LO12	.L1
+			24: R_LARCH_RELAX	\*ABS\*
+  28:	14000004 	lu12i.w     	\$a0, 0
+			28: R_LARCH_MARK_LA	\*ABS\*
+			28: R_LARCH_ABS_HI20	.L1
+  2c:	03800084 	ori         	\$a0, \$a0, 0x0
+			2c: R_LARCH_ABS_LO12	.L1
+  30:	1a000004 	pcalau12i   	\$a0, 0
+			30: R_LARCH_PCALA_HI20	.L1
+			30: R_LARCH_RELAX	\*ABS\*
+  34:	02800084 	addi.w      	\$a0, \$a0, 0
+			34: R_LARCH_PCALA_LO12	.L1
+			34: R_LARCH_RELAX	\*ABS\*
+  38:	1a000004 	pcalau12i   	\$a0, 0
+			38: R_LARCH_GOT_PC_HI20	.L1
+			38: R_LARCH_RELAX	\*ABS\*
+  3c:	28800084 	ld.w        	\$a0, \$a0, 0
+			3c: R_LARCH_GOT_PC_LO12	.L1
+			3c: R_LARCH_RELAX	\*ABS\*
+  40:	14000004 	lu12i.w     	\$a0, 0
+			40: R_LARCH_TLS_LE_HI20	TLS1
+  44:	03800084 	ori         	\$a0, \$a0, 0x0
+			44: R_LARCH_TLS_LE_LO12	TLS1
+  48:	1a000004 	pcalau12i   	\$a0, 0
+			48: R_LARCH_TLS_IE_PC_HI20	TLS1
+  4c:	28800084 	ld.w        	\$a0, \$a0, 0
+			4c: R_LARCH_TLS_IE_PC_LO12	TLS1
+  50:	1a000004 	pcalau12i   	\$a0, 0
+			50: R_LARCH_TLS_LD_PC_HI20	TLS1
+			50: R_LARCH_RELAX	\*ABS\*
+  54:	02800084 	addi.w      	\$a0, \$a0, 0
+			54: R_LARCH_GOT_PC_LO12	TLS1
+			54: R_LARCH_RELAX	\*ABS\*
+  58:	1a000004 	pcalau12i   	\$a0, 0
+			58: R_LARCH_TLS_GD_PC_HI20	TLS1
+			58: R_LARCH_RELAX	\*ABS\*
+  5c:	02800084 	addi.w      	\$a0, \$a0, 0
+			5c: R_LARCH_GOT_PC_LO12	TLS1
+			5c: R_LARCH_RELAX	\*ABS\*
-- 
2.36.0


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2023-12-15 10:11 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-15 10:11 [PATCH v4 0/5] Add support for TLS Descriptors (TLSDESC) Lulu Cai
2023-12-15 10:11 ` [PATCH v4 1/5] LoongArch: Add new relocs and macro for TLSDESC Lulu Cai
2023-12-15 10:11 ` [PATCH v4 2/5] LoongArch: Add support for TLSDESC in ld Lulu Cai
2023-12-15 10:11 ` [PATCH v4 3/5] LoongArch: Add tls transition support. Transitions between DESC->IE/LE and IE->LE are supported now Lulu Cai
2023-12-15 10:11 ` [PATCH v4 4/5] LoongArch: TLS LD/GD/DESC relaxation Lulu Cai

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).