> On Jan 8, 2024, at 15:00, Lulu Cai wrote: > > On 1/8/24 8:22 AM, Fangrui Song wrote: >> On Sun, Jan 7, 2024 at 3:00 PM Tatsuyuki Ishi > wrote: >>> On Dec 29, 2023, at 19:45, Lulu Cai wrote: >>> >>> On 2023/12/28 at 10:38 PM, Tatsuyuki Ishi Wrote: >>> >>> On Dec 22, 2023, at 20:42, Lulu Cai wrote: >>> >>> From: mengqinggang >>> >>> The pcalau12i + addi.d of TLS LD/GD/DESC relax to pcaddi. >>> Relaxation is only performed when the TLS model transition is not possible. >>> --- >>> bfd/bfd-in2.h | 3 + >>> bfd/elfnn-loongarch.c | 174 +++++++- >>> bfd/elfxx-loongarch.c | 60 +++ >>> bfd/libbfd.h | 3 + >>> bfd/reloc.c | 7 + >>> gas/config/tc-loongarch.c | 8 +- >>> 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, 795 insertions(+), 543 deletions(-) >>> >>> diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h >>> index 85251aa0edd..782845926ea 100644 >>> --- a/bfd/bfd-in2.h >>> +++ b/bfd/bfd-in2.h >>> @@ -7473,6 +7473,9 @@ enum bfd_reloc_code_real >>> BFD_RELOC_LARCH_TLS_DESC64_HI12, >>> BFD_RELOC_LARCH_TLS_DESC_LD, >>> 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 1347d13d2e2..bd448cda453 100644 >>> --- a/bfd/elfnn-loongarch.c >>> +++ b/bfd/elfnn-loongarch.c >>> @@ -2285,7 +2285,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; >>> @@ -3674,6 +3676,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; >>> >>> @@ -3682,7 +3687,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; >>> @@ -3813,7 +3819,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_PC_LO12: >>> @@ -4244,6 +4254,85 @@ loongarch_relax_align (bfd *abfd, asection *sec, >>> addend - need_nop_bytes, link_info); >>> } >>> >>> +/* Relax pcalau12i + addi.d of TLS LD/GD/DESC to pcaddi. */ >>> +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_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, >>> @@ -4288,15 +4377,23 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec, >>> >>> 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); >>> - unsigned long r_type = ELFNN_R_TYPE (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); >>> >>> + /* Four 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 >>> @@ -4304,7 +4401,24 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec, >>> if (ELF_ST_TYPE (sym->st_info) == STT_GNU_IFUNC) >>> continue; >>> >>> - if (sym->st_shndx == SHN_UNDEF || R_LARCH_ALIGN == r_type) >>> + 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 >>> + { >>> + sym_sec = htab->elf.sgot; >>> + symval = elf_local_got_offsets (abfd)[r_symndx]; >>> + 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; >>> + } >>> + } >>> + else if (sym->st_shndx == SHN_UNDEF || R_LARCH_ALIGN == r_type) >>> { >>> sym_sec = sec; >>> symval = rel->r_offset; >>> @@ -4329,7 +4443,26 @@ 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 >>> + /* The GOT entry of tls symbols must in current execute file or >>> + shared object. */ >>> + 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 >>> + { >>> + sym_sec = htab->elf.sgot; >>> + symval = h->got.offset; >>> + 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; >>> + } >>> + } >>> + 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) >>> @@ -4358,7 +4491,7 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec, >>> if (symtype != STT_SECTION) >>> symval += rel->r_addend; >>> } >>> - /* For R_LARCH_ALIGN, symval is sec_addr (sym_sec) + rel->r_offset >>> + /* For R_LARCH_ALIGN, symval is sec_addr (sec) + rel->r_offset >>> + (alingmeng - 4). >>> If r_symndx is 0, alignmeng-4 is r_addend. >>> If r_symndx > 0, alignment-4 is 2^(r_addend & 0xff)-4. */ >>> @@ -4399,6 +4532,25 @@ 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_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 30a941a851f..310e6d62dc0 100644 >>> --- a/bfd/elfxx-loongarch.c >>> +++ b/bfd/elfxx-loongarch.c >>> @@ -1775,6 +1775,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 (124). */ >>> + 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. */ >>> + true, /* 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 (125). */ >>> + 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. */ >>> + true, /* 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 (126). */ >>> + 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. */ >>> + true, /* 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. */ >>> }; >>> >>> >>> >>> I think relaxation relocs is a concept internal to binutils and they should not be in the same number range as psABI defined relocs. Some linkers (e.g. mold) doesn’t create new relocs when relaxing and rewrites the instruction right away, therefore these relocs would have no purpose in the psABI. >>> >>> We recently refactored out all the linker-internal relocs to a different range [1]; LoongArch might want to follow suit. >>> >>> [1]: https://sourceware.org/pipermail/binutils/2023-November/130322.html >>> >>> >>> However, it should be noted that in handwritten assembly, these relocations can be directly used. >>> >>> >>> Sorry for the delay in reply. I’m not sure if there is any use cases to use relaxation-only relocations in assembly source. It’s one of the reasons we did away with this in RISC-V [1]. >>> >>> [1]: https://github.com/riscv-non-isa/riscv-elf-psabi-doc/issues/398 >> Agreed. If a relocation type is only used for internal relaxation >> purposes, it should not be defined in the psABI and there should not >> be an assembler directive generating it (except .reloc using a >> hard-coded integer). > > We have considered such a situation. For those familiar with LoongArch assembly, if you want to > use DESC to access "var" in assembly source, you can directly use pcaddi $a0,%desc_pcrel_20(var) > instead of pcalau12i $a0,%desc_pc_hi20(var) and addi.d $a0, $a0,% desc_pc_lo12(var). > The same situation applies to GD/LD. I see it now. LoongArch's “normal code model” restricts the addressing of program code to a 256MiB address space, so being able to write out the pcrel_20 variant makes perfect sense. Thanks for the clarification. >> >>> reloc_howto_type * >>> @@ -1783,7 +1837,9 @@ loongarch_elf_rtype_to_howto (bfd *abfd, unsigned int r_type) >>> if(r_type < R_LARCH_count) >>> { >>> /* For search table fast. */ >>> >>> + /* >>> BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count); >>> + */ >>> >>> >>> >>> Was this supposed to be commented out and committed as-is? >>> >>> >>> It has been deleted. >>> >>> >>> >>> if (loongarch_howto_table[r_type].howto.type == r_type) >>> return (reloc_howto_type *)&loongarch_howto_table[r_type]; >>> @@ -1802,7 +1858,9 @@ loongarch_elf_rtype_to_howto (bfd *abfd, unsigned int r_type) >>> reloc_howto_type * >>> loongarch_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name) >>> { >>> + /* >>> BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count); >>> + */ >>> >>> for (size_t i = 0; i < ARRAY_SIZE (loongarch_howto_table); i++) >>> if (loongarch_howto_table[i].howto.name >>> @@ -1821,7 +1879,9 @@ reloc_howto_type * >>> loongarch_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, >>> bfd_reloc_code_real_type code) >>> { >>> + /* >>> BFD_ASSERT (ARRAY_SIZE (loongarch_howto_table) == R_LARCH_count); >>> + */ >>> >>> /* Fast search for new reloc types. */ >>> if (BFD_RELOC_LARCH_B16 <= code && code < BFD_RELOC_LARCH_RELAX) >>> diff --git a/bfd/libbfd.h b/bfd/libbfd.h >>> index 71b03da14d9..8dab44110a6 100644 >>> --- a/bfd/libbfd.h >>> +++ b/bfd/libbfd.h >>> @@ -3612,6 +3612,9 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", >>> "BFD_RELOC_LARCH_TLS_DESC64_HI12", >>> "BFD_RELOC_LARCH_TLS_DESC_LD", >>> "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 f7fe0c7ffe3..6fd0f1fb547 100644 >>> --- a/bfd/reloc.c >>> +++ b/bfd/reloc.c >>> @@ -8324,6 +8324,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 1658025f918..def26daf634 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_TLS_DESC_CALL) >>> + && ip->reloc_info[0].type <= BFD_RELOC_LARCH_TLS_DESC_PCREL20_S2) >>> { >>> /* As we compact stack-relocs, it is no need for pop operation. >>> But break out until here in order to check the imm field. >>> @@ -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_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-*-* >>> >>> >>> >>> -- >>> 2.43.0