https://github.com/heiher created https://github.com/llvm/llvm-project/pull/172618
This patch adds support for processing the relocation types introduced in la-abi-specs v2.50. Link: https://github.com/loongson/la-abi-specs/pull/16 Link: https://sourceware.org/pipermail/binutils/2025-December/146091.html >From aa7aa53e7cc77eb153688605f511b1e94d7e7db3 Mon Sep 17 00:00:00 2001 From: WANG Rui <[email protected]> Date: Thu, 4 Sep 2025 14:08:53 +0800 Subject: [PATCH] [lld][LoongArch] Add reloc types for LA32R/LA32S This patch adds support for processing the relocation types introduced in la-abi-specs v2.50. Link: https://github.com/loongson/la-abi-specs/pull/16 Link: https://sourceware.org/pipermail/binutils/2025-December/146091.html --- lld/ELF/Arch/LoongArch.cpp | 67 +++++++++- lld/ELF/InputSection.cpp | 62 ++++++++++ lld/ELF/Relocations.cpp | 2 +- lld/ELF/Relocations.h | 1 + lld/test/ELF/loongarch-call30.s | 64 ++++++++++ lld/test/ELF/loongarch-relax-call30-2.s | 65 ++++++++++ lld/test/ELF/loongarch-relax-call30.s | 136 +++++++++++++++++++++ lld/test/ELF/loongarch-relax-emit-relocs.s | 101 ++++++++++----- lld/test/ELF/loongarch-tls-gd-edge-case.s | 10 +- lld/test/ELF/loongarch-tls-gd.s | 10 +- lld/test/ELF/loongarch-tls-ie.s | 21 ++-- lld/test/ELF/loongarch-tls-ld.s | 10 +- lld/test/ELF/loongarch-tlsdesc.s | 30 ++++- 13 files changed, 514 insertions(+), 65 deletions(-) create mode 100644 lld/test/ELF/loongarch-call30.s create mode 100644 lld/test/ELF/loongarch-relax-call30-2.s create mode 100644 lld/test/ELF/loongarch-relax-call30.s diff --git a/lld/ELF/Arch/LoongArch.cpp b/lld/ELF/Arch/LoongArch.cpp index c6cdf05547d3f..1cea0d41bf74c 100644 --- a/lld/ELF/Arch/LoongArch.cpp +++ b/lld/ELF/Arch/LoongArch.cpp @@ -184,6 +184,10 @@ static uint32_t setJ5(uint32_t insn, uint32_t imm) { return (insn & 0xfffffc1f) | (extractBits(imm, 4, 0) << 5); } +static uint32_t setK10(uint32_t insn, uint32_t imm) { + return (insn & 0xffc003ff) | (extractBits(imm, 9, 0) << 10); +} + static uint32_t setK12(uint32_t insn, uint32_t imm) { return (insn & 0xffc003ff) | (extractBits(imm, 11, 0) << 10); } @@ -439,6 +443,13 @@ RelExpr LoongArch::getRelExpr(const RelType type, const Symbol &s, // [1]: https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=9f482b73f41a9a1bbfb173aad0733d1c824c788a // [2]: https://github.com/loongson/la-abi-specs/pull/3 return isJirl(read32le(loc)) ? R_PLT : R_ABS; + case R_LARCH_PCADD_LO12: + case R_LARCH_GOT_PCADD_LO12: + case R_LARCH_TLS_IE_PCADD_LO12: + case R_LARCH_TLS_LD_PCADD_LO12: + case R_LARCH_TLS_GD_PCADD_LO12: + case R_LARCH_TLS_DESC_PCADD_LO12: + return RE_LOONGARCH_PC_INDIRECT; case R_LARCH_TLS_DTPREL32: case R_LARCH_TLS_DTPREL64: return R_DTPREL; @@ -469,10 +480,12 @@ RelExpr LoongArch::getRelExpr(const RelType type, const Symbol &s, case R_LARCH_32_PCREL: case R_LARCH_64_PCREL: case R_LARCH_PCREL20_S2: + case R_LARCH_PCADD_HI20: return R_PC; case R_LARCH_B16: case R_LARCH_B21: case R_LARCH_B26: + case R_LARCH_CALL30: case R_LARCH_CALL36: return R_PLT_PC; case R_LARCH_GOT_PC_HI20: @@ -482,6 +495,9 @@ RelExpr LoongArch::getRelExpr(const RelType type, const Symbol &s, case R_LARCH_TLS_IE64_PC_LO20: case R_LARCH_TLS_IE64_PC_HI12: return RE_LOONGARCH_GOT_PAGE_PC; + case R_LARCH_GOT_PCADD_HI20: + case R_LARCH_TLS_IE_PCADD_HI20: + return R_GOT_PC; case R_LARCH_GOT_PC_LO12: case R_LARCH_TLS_IE_PC_LO12: return RE_LOONGARCH_GOT; @@ -545,12 +561,15 @@ RelExpr LoongArch::getRelExpr(const RelType type, const Symbol &s, case R_LARCH_TLS_DESC_LO12: case R_LARCH_TLS_DESC64_LO20: case R_LARCH_TLS_DESC64_HI12: + case R_LARCH_TLS_DESC_PCADD_HI20: return R_TLSDESC; case R_LARCH_TLS_DESC_CALL: return R_TLSDESC_CALL; case R_LARCH_TLS_LD_PCREL20_S2: + case R_LARCH_TLS_LD_PCADD_HI20: return R_TLSLD_PC; case R_LARCH_TLS_GD_PCREL20_S2: + case R_LARCH_TLS_GD_PCADD_HI20: return R_TLSGD_PC; case R_LARCH_TLS_DESC_PCREL20_S2: return R_TLSDESC_PC; @@ -628,6 +647,22 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel, write32le(loc, setD10k16(read32le(loc), val >> 2)); return; + case R_LARCH_CALL30: { + // This relocation is designed for adjacent pcaddu12i+jirl pairs that + // are patched in one time. + // The relocation range is [-4G, +4G) (of course must be 4-byte aligned). + if ((int64_t)val != llvm::SignExtend64(val, 32)) + reportRangeError(ctx, loc, rel, Twine(val), llvm::minIntN(32), + llvm::maxIntN(32)); + checkAlignment(ctx, loc, val, 4, rel); + uint32_t hi20 = extractBits(val, 31, 12); + // Despite the name, the lower part is actually 12 bits with 4-byte aligned. + uint32_t lo10 = extractBits(val, 11, 2); + write32le(loc, setJ20(read32le(loc), hi20)); + write32le(loc + 4, setK10(read32le(loc + 4), lo10)); + return; + } + case R_LARCH_CALL36: { // This relocation is designed for adjacent pcaddu18i+jirl pairs that // are patched in one time. Because of sign extension of these insns' @@ -671,6 +706,12 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel, case R_LARCH_TLS_LE_LO12_R: case R_LARCH_TLS_DESC_PC_LO12: case R_LARCH_TLS_DESC_LO12: + case R_LARCH_PCADD_LO12: + case R_LARCH_GOT_PCADD_LO12: + case R_LARCH_TLS_IE_PCADD_LO12: + case R_LARCH_TLS_LD_PCADD_LO12: + case R_LARCH_TLS_GD_PCADD_LO12: + case R_LARCH_TLS_DESC_PCADD_LO12: write32le(loc, setK12(read32le(loc), extractBits(val, 11, 0))); return; @@ -690,6 +731,17 @@ void LoongArch::relocate(uint8_t *loc, const Relocation &rel, case R_LARCH_TLS_DESC_HI20: write32le(loc, setJ20(read32le(loc), extractBits(val, 31, 12))); return; + case R_LARCH_PCADD_HI20: + case R_LARCH_GOT_PCADD_HI20: + case R_LARCH_TLS_IE_PCADD_HI20: + case R_LARCH_TLS_LD_PCADD_HI20: + case R_LARCH_TLS_GD_PCADD_HI20: + case R_LARCH_TLS_DESC_PCADD_HI20: { + uint64_t hi = val + 0x800; + checkInt(ctx, loc, SignExtend64(hi, 32) >> 12, 20, rel); + write32le(loc, setJ20(read32le(loc), extractBits(hi, 31, 12))); + return; + } case R_LARCH_TLS_LE_HI20_R: write32le(loc, setJ20(read32le(loc), extractBits(val + 0x800, 31, 12))); return; @@ -998,12 +1050,16 @@ static void relaxPCHi20Lo12(Ctx &ctx, const InputSection &sec, size_t i, // Relax code sequence. // From: -// pcaddu18i $ra, %call36(foo) -// jirl $ra, $ra, 0 +// la32r: +// pcaddu12i $ra, %call30(foo) +// jirl $ra, $ra, 0 +// la32s/la64: +// pcaddu18i $ra, %call36(foo) +// jirl $ra, $ra, 0 // To: // b/bl foo -static void relaxCall36(Ctx &ctx, const InputSection &sec, size_t i, - uint64_t loc, Relocation &r, uint32_t &remove) { +static void relaxMediumCall(Ctx &ctx, const InputSection &sec, size_t i, + uint64_t loc, Relocation &r, uint32_t &remove) { const uint64_t dest = (r.expr == R_PLT_PC ? r.sym->getPltVA(ctx) : r.sym->getVA(ctx)) + r.addend; @@ -1108,9 +1164,10 @@ static bool relax(Ctx &ctx, InputSection &sec) { } else if (isPairRelaxable(relocs, i)) relaxPCHi20Lo12(ctx, sec, i, loc, r, relocs[i + 2], remove); break; + case R_LARCH_CALL30: case R_LARCH_CALL36: if (relaxable(relocs, i)) - relaxCall36(ctx, sec, i, loc, r, remove); + relaxMediumCall(ctx, sec, i, loc, r, remove); break; case R_LARCH_TLS_LE_HI20_R: case R_LARCH_TLS_LE_ADD_R: diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index ff7ef2dce5c79..3b0fab23481c1 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -714,6 +714,63 @@ static Relocation *getRISCVPCRelHi20(Ctx &ctx, const InputSectionBase *loSec, return nullptr; } +// For RE_LARCH_PC_INDIRECT (R_LARCH_*PCADD_LO12), the symbol actually points +// the corresponding R_LARCH_*PCADD_HI20 relocation, and the target VA is +// calculated using PCADD_HI20's symbol. +// +// This function returns the R_LARCH_*PCADD_HI20 relocation from the +// R_LARCH_*PCADD_LO12 relocation. +static Relocation *getLoongArchPCAddHi20(Ctx &ctx, + const InputSectionBase *loSec, + const Relocation &loReloc) { + int64_t addend = loReloc.addend; + Symbol *sym = loReloc.sym; + + const Defined *d = cast<Defined>(sym); + if (!d->section) { + Err(ctx) << loSec->getLocation(loReloc.offset) + << ": R_LARCH_*PCADD_LO12 relocation points to an absolute symbol: " + << sym->getName(); + return nullptr; + } + InputSection *hiSec = cast<InputSection>(d->section); + + if (hiSec != loSec) + Err(ctx) << loSec->getLocation(loReloc.offset) + << ": R_LARCH_*PCADD_LO12 relocation points to a symbol '" + << sym->getName() << "' in a different section '" << hiSec->name + << "'"; + + if (addend != 0) + Warn(ctx) << loSec->getLocation(loReloc.offset) + << ": non-zero addend in R_LARCH_*PCADD_LO12 relocation to " + << hiSec->getObjMsg(d->value) << " is ignored"; + + // Relocations are sorted by offset, so we can use std::equal_range to do + // binary search. + Relocation hiReloc; + hiReloc.offset = d->value + addend; + auto range = + std::equal_range(hiSec->relocs().begin(), hiSec->relocs().end(), hiReloc, + [](const Relocation &lhs, const Relocation &rhs) { + return lhs.offset < rhs.offset; + }); + + for (auto it = range.first; it != range.second; ++it) + if (it->type == R_LARCH_PCADD_HI20 || it->type == R_LARCH_GOT_PCADD_HI20 || + it->type == R_LARCH_TLS_IE_PCADD_HI20 || + it->type == R_LARCH_TLS_LD_PCADD_HI20 || + it->type == R_LARCH_TLS_GD_PCADD_HI20 || + it->type == R_LARCH_TLS_DESC_PCADD_HI20) + return &*it; + + Err(ctx) << loSec->getLocation(loReloc.offset) + << ": R_LARCH_*PCADD_LO12 relocation points to " + << hiSec->getObjMsg(d->value) + << " without an associated R_LARCH_*PCADD_HI20 relocation"; + return nullptr; +} + // A TLS symbol's virtual address is relative to the TLS segment. Add a // target-specific adjustment to produce a thread-pointer-relative offset. static int64_t getTlsTpOffset(Ctx &ctx, const Symbol &s) { @@ -891,6 +948,11 @@ uint64_t InputSectionBase::getRelocTargetVA(Ctx &ctx, const Relocation &r, return getRelocTargetVA(ctx, *hiRel, r.sym->getVA(ctx)); return 0; } + case RE_LOONGARCH_PC_INDIRECT: { + if (const Relocation *hiRel = getLoongArchPCAddHi20(ctx, this, r)) + return getRelocTargetVA(ctx, *hiRel, r.sym->getVA(ctx, a)); + return 0; + } case RE_LOONGARCH_PAGE_PC: return getLoongArchPageDelta(r.sym->getVA(ctx, a), p, r.type); case R_PC: diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp index 59aa43036ce01..ae3578d8e7cb3 100644 --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -148,7 +148,7 @@ static bool isRelExpr(RelExpr expr) { return oneof<R_PC, R_GOTREL, R_GOTPLTREL, RE_ARM_PCA, RE_MIPS_GOTREL, RE_PPC64_CALL, RE_PPC64_RELAX_TOC, RE_AARCH64_PAGE_PC, R_RELAX_GOT_PC, RE_RISCV_PC_INDIRECT, RE_PPC64_RELAX_GOT_PC, - RE_LOONGARCH_PAGE_PC>(expr); + RE_LOONGARCH_PAGE_PC, RE_LOONGARCH_PC_INDIRECT>(expr); } static RelExpr toPlt(RelExpr expr) { diff --git a/lld/ELF/Relocations.h b/lld/ELF/Relocations.h index 86ca298cd7a56..bff899d5c4d0c 100644 --- a/lld/ELF/Relocations.h +++ b/lld/ELF/Relocations.h @@ -132,6 +132,7 @@ enum RelExpr { // also reused for TLS, making the semantics differ from other architectures. RE_LOONGARCH_GOT, RE_LOONGARCH_GOT_PAGE_PC, + RE_LOONGARCH_PC_INDIRECT, RE_LOONGARCH_TLSGD_PAGE_PC, RE_LOONGARCH_TLSDESC_PAGE_PC, RE_LOONGARCH_RELAX_TLS_GD_TO_IE_PAGE_PC, diff --git a/lld/test/ELF/loongarch-call30.s b/lld/test/ELF/loongarch-call30.s new file mode 100644 index 0000000000000..907e8704e908b --- /dev/null +++ b/lld/test/ELF/loongarch-call30.s @@ -0,0 +1,64 @@ +# REQUIRES: loongarch + +# RUN: rm -rf %t && split-file %s %t +# RUN: llvm-mc --filetype=obj --triple=loongarch32-unknown-elf %t/a.s -o %t/a.o + +# RUN: ld.lld %t/a.o --section-start=.text=0x20010 --section-start=.sec.foo=0x21020 -o %t/exe1 +# RUN: llvm-objdump --no-show-raw-insn -d %t/exe1 | FileCheck --match-full-lines %s --check-prefix=EXE1 +## hi20 = target - pc >> 12 = 0x21020 - 0x20010 >> 12 = 1 +## lo12 = target - pc & (1 << 12) - 1 = 0x21020 - 0x20010 & 0xfff = 16 +# EXE1: 20010: pcaddu12i $t0, 1 +# EXE1-NEXT: 20014: jirl $zero, $t0, 16 + +# RUN: ld.lld %t/a.o --section-start=.text=0x20010 --section-start=.sec.foo=0x21820 -o %t/exe2 +# RUN: llvm-objdump --no-show-raw-insn -d %t/exe2 | FileCheck --match-full-lines %s --check-prefix=EXE2 +## hi20 = target - pc >> 12 = 0x21820 - 0x20010 >> 12 = 1 +## lo12 = target - pc & (1 << 12) - 1 = 0x21820 - 0x20010 & 0xfff = 2064 +# EXE2: 20010: pcaddu12i $t0, 1 +# EXE2-NEXT: 20014: jirl $zero, $t0, 2064 + +# RUN: ld.lld %t/a.o -shared -T %t/a.t -o %t/a.so +# RUN: llvm-readelf -x .got.plt %t/a.so | FileCheck --check-prefix=GOTPLT %s +# RUN: llvm-objdump -d --no-show-raw-insn %t/a.so | FileCheck --check-prefix=SO %s +## PLT should be present in this case. +# SO: Disassembly of section .plt: +# SO: <.plt>: +## foo@plt: +# SO: 1234520: pcaddu12i $t3, 64{{$}} +# SO-NEXT: ld.w $t3, $t3, 444{{$}} +# SO-NEXT: jirl $t1, $t3, 0 +# SO-NEXT: nop + +# SO: Disassembly of section .text: +# SO: <_start>: +## hi20 = foo@plt - pc >> 12 = 0x1234520 - 0x1274670 >> 12 = -65 +## lo18 = foo@plt - pc & (1 << 12) - 1 = 0x1234520 - 0x1274670 & 0xfff = 3760 +# SO-NEXT: pcaddu12i $t0, -65{{$}} +# SO-NEXT: jirl $zero, $t0, 3760{{$}} + +# GOTPLT: section '.got.plt': +# GOTPLT-NEXT: 0x012746d4 00000000 00000000 00452301 + +## Impossible case in reality becasue all LoongArch instructions are fixed 4-bytes long. +# RUN: not ld.lld %t/a.o --section-start=.text=0x20000 --section-start=.sec.foo=0x40001 -o /dev/null 2>&1 | \ +# RUN: FileCheck -DFILE=%t/a.o --check-prefix=ERROR-ALIGN %s +# ERROR-ALIGN: error: [[FILE]]:(.text+0x0): improper alignment for relocation R_LARCH_CALL30: 0x20001 is not aligned to 4 bytes + +#--- a.t +SECTIONS { + .plt 0x1234500: { *(.plt) } + .text 0x1274670: { *(.text) } +} + +#--- a.s +.text +.global _start +_start: + .reloc ., R_LARCH_CALL30, foo + pcaddu12i $t0, 0 + jirl $zero, $t0, 0 + +.section .sec.foo,"awx" +.global foo +foo: + ret diff --git a/lld/test/ELF/loongarch-relax-call30-2.s b/lld/test/ELF/loongarch-relax-call30-2.s new file mode 100644 index 0000000000000..45584f4e14dc8 --- /dev/null +++ b/lld/test/ELF/loongarch-relax-call30-2.s @@ -0,0 +1,65 @@ +# REQUIRES: loongarch +## Relax R_LARCH_CALL30. This test tests boundary cases and some special symbols. + +# RUN: rm -rf %t && split-file %s %t && cd %t +# RUN: llvm-mc -filetype=obj -triple=loongarch32 -mattr=+relax a.s -o a.o + +# RUN: ld.lld -T lds a.o -o a +# RUN: llvm-objdump -d --no-show-raw-insn a | FileCheck %s --check-prefixes=RELAX,RELAX-MID + +## Unsure whether this needs a diagnostic. GNU ld allows this. +# RUN: ld.lld -T lds -pie a.o -o a.pie +# RUN: llvm-objdump -d --no-show-raw-insn a.pie | FileCheck %s --check-prefixes=RELAX,RELAX-MID + +# RUN: ld.lld -T lds -pie -z notext -z ifunc-noplt a.o -o a.ifunc-noplt +# RUN: llvm-objdump -d --no-show-raw-insn a.ifunc-noplt | FileCheck %s --check-prefixes=RELAX,NORELAX-MID + +# RELAX-LABEL: <_start>: +## offset = 0x10000000 - 0x8000000 = 0x8000000(134217728), hi=512, lo18=0 +# RELAX-NEXT: 8000000: pcaddu12i $ra, 32768 +# RELAX-NEXT: jirl $ra, $ra, 0 +# RELAX-NEXT: bl 134217720 +# RELAX-NEXT: bl -134217728 +## offset = 12 - 0x8000010 = -0x8000004(-134217732), hi=512, lo18=-4 +# RELAX-NEXT: 8000010: pcaddu12i $ra, -32769 +# RELAX-NEXT: jirl $ra, $ra, 4092 +# RELAX-EMPTY: + +# RELAX-MID-LABEL: <.mid>: +## offset = 0x8010000 - 0x8008000 = 32768 +# RELAX-MID-NEXT: 8008000: bl 32768 +# RELAX-MID-NEXT: b 32764 +# RELAX-MID-EMPTY: + +# NORELAX-MID-LABEL: <.mid>: +# NORELAX-MID-NEXT: 8008000: pcaddu12i $ra, 0 +# NORELAX-MID-NEXT: jirl $ra, $ra, 0 +# NORELAX-MID-NEXT: pcaddu12i $t0, 0 +# NORELAX-MID-NEXT: jr $t0 +# NORELAX-MID-EMPTY: + +#--- a.s +.global _start, ifunc +_start: + call30 pos # exceed positive range (.text+0x7fffffc), not relaxed + call30 pos # relaxed + call30 neg # relaxed + call30 neg # exceed negative range (.text+16-0x8000000), not relaxed + +.section .mid,"ax",@progbits +.balign 16 + call30 ifunc # enable ifunc, not relaxed + tail30 $t0, ifunc # enable ifunc, not relaxed + +.type ifunc, @gnu_indirect_function +ifunc: + ret + +#--- lds +SECTIONS { + .text 0x8000000 : { *(.text) } + .mid 0x8008000 : { *(.mid) } + .iplt 0x8010000 : { *(.iplt) } +} +neg = 12; +pos = 0x10000000; diff --git a/lld/test/ELF/loongarch-relax-call30.s b/lld/test/ELF/loongarch-relax-call30.s new file mode 100644 index 0000000000000..f3172897f47fb --- /dev/null +++ b/lld/test/ELF/loongarch-relax-call30.s @@ -0,0 +1,136 @@ +# REQUIRES: loongarch +## Relax R_LARCH_CALL30, which involves the macro instructions call30/tail30. + +# RUN: rm -rf %t && split-file %s %t && cd %t + +# RUN: llvm-mc -filetype=obj -triple=loongarch32 -mattr=+relax a.s -o a.32.o +# RUN: llvm-mc -filetype=obj -triple=loongarch32 -mattr=+relax b.s -o b.32.o +# RUN: ld.lld -shared -soname=b.so b.32.o -o b.32.so +# RUN: ld.lld -T lds a.32.o b.32.so -o 32 +# RUN: llvm-objdump -td --no-show-raw-insn 32 | FileCheck %s --check-prefix=RELAX + +## --no-relax disables relaxation. +# RUN: ld.lld -T lds a.32.o b.32.so --no-relax -o 32.norelax +# RUN: llvm-objdump -td --no-show-raw-insn 32.norelax | FileCheck %s --check-prefix=NORELAX + +# RELAX: {{0*}}00010000 g .text {{0*}}0000001c _start +# RELAX: {{0*}}0001001c g .text {{0*}}00000000 _start_end +# RELAX: {{0*}}00010808 g .mid {{0*}}00000000 mid_end +# RELAX: {{0*}}10010010 g .high {{0*}}00000000 high_end + +# RELAX-LABEL: <_start>: +## offset = 0x10018 - 0x10000 = 24 +# RELAX-NEXT: 10000: bl 24 <a> +# RELAX-NEXT: b 20 <a> +# RELAX-NEXT: nop +# RELAX-NEXT: nop +## offset = .plt(0x10400)+32 - 0x10010 = 1040 +# RELAX-NEXT: 10010: bl 1040 <bar+0x10420> +# RELAX-NEXT: b 1036 <bar+0x10420> +# RELAX-EMPTY: +# RELAX-NEXT: <a>: +# RELAX-NEXT: 10018: ret +# RELAX-EMPTY: + +# RELAX-LABEL: <.mid>: +## offset = 0x10000 - 0x10800 = -2048 +# RELAX-NEXT: 10800: bl -2048 <_start> +# RELAX-NEXT: b -2052 <_start> +# RELAX-EMPTY: + +# RELAX-LABEL: <.mid2>: +## offset = 0x10000 - 0x1010000 = -16777216 +# RELAX-NEXT: 1010000: bl -16777216 <_start> +# RELAX-NEXT: b -16777220 <_start> +# RELAX-EMPTY: + +# RELAX-LABEL: <.high>: +## offset = 0x10000 - 0x10010000 = -0x10000000, hi=-1024, lo18=0 +# RELAX-NEXT: 10010000: pcaddu12i $ra, -65536 +# RELAX-NEXT: jirl $ra, $ra, 0 +# RELAX-NEXT: pcaddu12i $t0, -65537 +# RELAX-NEXT: jirl $zero, $t0, 4088 +# RELAX-EMPTY: + + +# NORELAX-LABEL: <_start>: +## offset = 0x10020 - 0x10000 = 0x20, hi=0, lo18=32 +# NORELAX-NEXT: 10000: pcaddu12i $ra, 0 +# NORELAX-NEXT: jirl $ra, $ra, 32 +## offset = 0x10020 - 0x10008 = 0x18, hi=0, lo18=24 +# NORELAX-NEXT: 10008: pcaddu12i $t0, 0 +# NORELAX-NEXT: jirl $zero, $t0, 24 +## offset = .plt(0x10400)+32 - 0x10010 = 0x410, hi=0, lo18=1040 +# NORELAX-NEXT: 10010: pcaddu12i $ra, 0 +# NORELAX-NEXT: jirl $ra, $ra, 1040 +## offset = .plt(0x10400)+32 - 0x10018 = 0x408, hi=0, lo18=1032 +# NORELAX-NEXT: 10018: pcaddu12i $t0, 0 +# NORELAX-NEXT: jirl $zero, $t0, 1032 +# NORELAX-EMPTY: +# NORELAX-NEXT: <a>: +# NORELAX-NEXT: 10020: ret +# NORELAX-EMPTY: + +# NORELAX-LABEL: <.mid>: +## offset = 0x10000 - 0x10800 = -0x800, hi=0, lo18=-2048 +# NORELAX-NEXT: 10800: pcaddu12i $ra, -1 +# NORELAX-NEXT: jirl $ra, $ra, 2048 +# NORELAX-NEXT: pcaddu12i $t0, -1 +# NORELAX-NEXT: jirl $zero, $t0, 2040 +# NORELAX-EMPTY: + +# NORELAX-LABEL: <.mid2>: +## offset = 0x10000 - 0x1010000 = -0x1000000, hi=-64, lo18=0 +# NORELAX-NEXT: 1010000: pcaddu12i $ra, -4096 +# NORELAX-NEXT: jirl $ra, $ra, 0 +# NORELAX-NEXT: pcaddu12i $t0, -4097 +# NORELAX-NEXT: jirl $zero, $t0, 4088 +# NORELAX-EMPTY: + +# NORELAX-LABEL: <.high>: +## offset = 0x10000 - 0x10010000 = -0x10000000, hi=-1024, lo18=0 +# NORELAX-NEXT: 10010000: pcaddu12i $ra, -65536 +# NORELAX-NEXT: jirl $ra, $ra, 0 +# NORELAX-NEXT: pcaddu12i $t0, -65537 +# NORELAX-NEXT: jirl $zero, $t0, 4088 +# NORELAX-EMPTY: + +#--- a.s +.global _start, _start_end +_start: + call30 a # relaxed. la32: bl + tail30 $t0, a # relaxed. la32: b +.balign 16 + call30 bar # PLT call30 can be relaxed. la32: bl + tail30 $t0, bar # PLT tail30 can be relaxed. la32: bl + +a: + ret +.size _start, . - _start +_start_end: + +.section .mid,"ax",@progbits + call30 _start # relaxed. la32: bl + tail30 $t0, _start # relaxed. la32: b + +.section .mid2,"ax",@progbits + call30 _start # relaxed. la32: bl + tail30 $t0, _start # relaxed. la32: b + +.section .high,"ax",@progbits + call30 _start # exceed range, not relaxed + tail30 $t0, _start # exceed range, not relaxed + +#--- b.s +.globl bar +bar: + ret + +#--- lds +SECTIONS { + .text 0x10000 : { *(.text) } + .plt 0x10400 : { *(.plt) } + .mid 0x10800 : { *(.mid); mid_end = .; } + .mid2 0x1010000 : { *(.mid2) } + .high 0x10010000 : { *(.high); high_end = .; } +} diff --git a/lld/test/ELF/loongarch-relax-emit-relocs.s b/lld/test/ELF/loongarch-relax-emit-relocs.s index 6e1e85c004439..f2d6edc97d27a 100644 --- a/lld/test/ELF/loongarch-relax-emit-relocs.s +++ b/lld/test/ELF/loongarch-relax-emit-relocs.s @@ -1,7 +1,7 @@ # REQUIRES: loongarch ## Test that we can handle --emit-relocs while relaxing. -# RUN: llvm-mc --filetype=obj --triple=loongarch32 --mattr=+32s,+relax %s -o %t.32.o +# RUN: llvm-mc --filetype=obj --triple=loongarch32 --mattr=+relax %s -o %t.32.o # RUN: llvm-mc --filetype=obj --triple=loongarch64 --mattr=+relax --defsym ELF64=1 %s -o %t.64.o # RUN: ld.lld -Ttext=0x10000 -section-start=.got=0x20000 --emit-relocs %t.32.o -o %t.32 # RUN: ld.lld -Ttext=0x10000 -section-start=.got=0x20000 --emit-relocs %t.64.o -o %t.64 @@ -16,17 +16,39 @@ # RUN: ld.lld -Ttext=0x10000 -section-start=.got=0x20000 --emit-relocs --no-relax %t.64.o -o %t.64.norelax # RUN: llvm-objdump -dr %t.64.norelax | FileCheck %s --check-prefix=NORELAX -# RELAX: 00010000 <_start>: -# RELAX-NEXT: pcaddi $a0, 0 -# RELAX-NEXT: R_LARCH_RELAX _start -# RELAX-NEXT: R_LARCH_RELAX *ABS* -# RELAX-NEXT: R_LARCH_PCREL20_S2 _start -# RELAX-NEXT: R_LARCH_RELAX *ABS* -# RELAX-NEXT: pcaddi $a0, -1 -# RELAX-NEXT: R_LARCH_RELAX _start -# RELAX-NEXT: R_LARCH_RELAX *ABS* -# RELAX-NEXT: R_LARCH_PCREL20_S2 _start -# RELAX-NEXT: R_LARCH_RELAX *ABS* +# RELAX32: 00010000 <_start>: +# RELAX32-NEXT: pcaddu12i $a0, 0 +# RELAX32-NEXT: R_LARCH_PCADD_HI20 _start +# RELAX32-NEXT: R_LARCH_RELAX *ABS* +# RELAX32-NEXT: addi.w $a0, $a0, 0 +# RELAX32-NEXT: R_LARCH_PCADD_LO12 .Lpcadd_hi0 +# RELAX32-NEXT: R_LARCH_RELAX *ABS* +# RELAX32: 00010008 <.Lpcadd_hi1>: +# RELAX32-NEXT: pcaddu12i $a0, 16 +# RELAX32-NEXT: R_LARCH_GOT_PCADD_HI20 _start +# RELAX32-NEXT: R_LARCH_RELAX *ABS* +# RELAX32-NEXT: ld.w $a0, $a0, 0 +# RELAX32-NEXT: R_LARCH_GOT_PCADD_LO12 .Lpcadd_hi1 +# RELAX32-NEXT: R_LARCH_RELAX *ABS* + +# RELAX64: 00010000 <_start>: +# RELAX64-NEXT: pcaddi $a0, 0 +# RELAX64-NEXT: R_LARCH_RELAX _start +# RELAX64-NEXT: R_LARCH_RELAX *ABS* +# RELAX64-NEXT: R_LARCH_PCREL20_S2 _start +# RELAX64-NEXT: R_LARCH_RELAX *ABS* +# RELAX64-NEXT: pcaddi $a0, -1 +# RELAX64-NEXT: R_LARCH_RELAX _start +# RELAX64-NEXT: R_LARCH_RELAX *ABS* +# RELAX64-NEXT: R_LARCH_PCREL20_S2 _start +# RELAX64-NEXT: R_LARCH_RELAX *ABS* + +# RELAX32-NEXT: bl -16 +# RELAX32-NEXT: R_LARCH_B26 _start +# RELAX32-NEXT: R_LARCH_RELAX *ABS* +# RELAX32-NEXT: b -20 +# RELAX32-NEXT: R_LARCH_B26 _start +# RELAX32-NEXT: R_LARCH_RELAX *ABS* # RELAX64-NEXT: bl -8 # RELAX64-NEXT: R_LARCH_B26 _start @@ -39,16 +61,34 @@ # RELAX-NEXT: R_LARCH_TLS_LE_HI20 a # RELAX-NEXT: ori $a0, $a0, 0 # RELAX-NEXT: R_LARCH_TLS_LE_LO12 a -# RELAX-NEXT: pcaddi $a0, [[#]] -# RELAX-NEXT: R_LARCH_RELAX a -# RELAX-NEXT: R_LARCH_RELAX *ABS* -# RELAX-NEXT: R_LARCH_TLS_GD_PCREL20_S2 a -# RELAX-NEXT: R_LARCH_RELAX *ABS* -# RELAX-NEXT: pcaddi $a0, [[#]] -# RELAX-NEXT: R_LARCH_RELAX a -# RELAX-NEXT: R_LARCH_RELAX *ABS* -# RELAX-NEXT: R_LARCH_TLS_LD_PCREL20_S2 a -# RELAX-NEXT: R_LARCH_RELAX *ABS* + +# RELAX32: 00010020 <.Lpcadd_hi2>: +# RELAX32-NEXT: pcaddu12i $a0, 16 +# RELAX32-NEXT: R_LARCH_TLS_GD_PCADD_HI20 a +# RELAX32-NEXT: R_LARCH_RELAX *ABS* +# RELAX32-NEXT: addi.w $a0, $a0, -20 +# RELAX32-NEXT: R_LARCH_TLS_GD_PCADD_LO12 .Lpcadd_hi2 +# RELAX32-NEXT: R_LARCH_RELAX *ABS* + +# RELAX32: 00010028 <.Lpcadd_hi3>: +# RELAX32-NEXT: pcaddu12i $a0, 16 +# RELAX32-NEXT: R_LARCH_TLS_LD_PCADD_HI20 a +# RELAX32-NEXT: R_LARCH_RELAX *ABS* +# RELAX32-NEXT: addi.w $a0, $a0, -40 +# RELAX32-NEXT: R_LARCH_TLS_LD_PCADD_LO12 .Lpcadd_hi3 +# RELAX32-NEXT: R_LARCH_RELAX *ABS* + +# RELAX64-NEXT: pcaddi $a0, [[#]] +# RELAX64-NEXT: R_LARCH_RELAX a +# RELAX64-NEXT: R_LARCH_RELAX *ABS* +# RELAX64-NEXT: R_LARCH_TLS_GD_PCREL20_S2 a +# RELAX64-NEXT: R_LARCH_RELAX *ABS* +# RELAX64-NEXT: pcaddi $a0, [[#]] +# RELAX64-NEXT: R_LARCH_RELAX a +# RELAX64-NEXT: R_LARCH_RELAX *ABS* +# RELAX64-NEXT: R_LARCH_TLS_LD_PCREL20_S2 a +# RELAX64-NEXT: R_LARCH_RELAX *ABS* + # RELAX-NEXT: addi.{{[dw]}} $a0, $tp, 0 # RELAX-NEXT: R_LARCH_RELAX a # RELAX-NEXT: R_LARCH_RELAX *ABS* @@ -57,15 +97,11 @@ # RELAX-NEXT: R_LARCH_TLS_LE_LO12_R a # RELAX-NEXT: R_LARCH_RELAX *ABS* -# RELAX32-NEXT: nop -# RELAX32-NEXT: R_LARCH_ALIGN *ABS*+0xc -# RELAX32-NEXT: ret - -# RELAX64-NEXT: nop -# RELAX64-NEXT: R_LARCH_ALIGN *ABS*+0xc -# RELAX64-NEXT: nop -# RELAX64-NEXT: nop -# RELAX64-NEXT: ret +# RELAX-NEXT: nop +# RELAX-NEXT: R_LARCH_ALIGN *ABS*+0xc +# RELAX-NEXT: nop +# RELAX-NEXT: nop +# RELAX-NEXT: ret # NORELAX: <_start>: # NORELAX-NEXT: pcalau12i $a0, 0 @@ -195,6 +231,9 @@ _start: .ifdef ELF64 call36 _start tail36 $a0, _start +.else + call30 _start + tail30 $a0, _start .endif la.tls.le $a0, a # without R_LARCH_RELAX reloaction diff --git a/lld/test/ELF/loongarch-tls-gd-edge-case.s b/lld/test/ELF/loongarch-tls-gd-edge-case.s index dd87d3002b180..1ebc69990b403 100644 --- a/lld/test/ELF/loongarch-tls-gd-edge-case.s +++ b/lld/test/ELF/loongarch-tls-gd-edge-case.s @@ -3,7 +3,7 @@ ## Edge case: when a TLS symbol is being accessed in both GD and IE manners, ## correct reloc behavior should be preserved for both kinds of accesses. -# RUN: llvm-mc --filetype=obj --triple=loongarch32 --mattr=+32s %s -o %t.la32.o +# RUN: llvm-mc --filetype=obj --triple=loongarch32 --mattr=-32s %s -o %t.la32.o # RUN: ld.lld %t.la32.o -shared -o %t.la32 # RUN: llvm-mc --filetype=obj --triple=loongarch64 %s -o %t.la64.o # RUN: ld.lld %t.la64.o -shared -o %t.la64 @@ -24,10 +24,10 @@ # LA64-REL-NEXT: 00000000000203a8 0000000200000009 R_LARCH_TLS_DTPREL64 0000000000000000 y + 0 # LA64-REL-NEXT: 00000000000203b0 000000020000000b R_LARCH_TLS_TPREL64 0000000000000000 y + 0 -# LA32: 101d4: pcalau12i $a0, 16 -# LA32-NEXT: ld.w $a0, $a0, 580 -# LA32-NEXT: pcalau12i $a1, 16 -# LA32-NEXT: addi.w $a1, $a1, 572 +# LA32: 101d4: pcaddu12i $a0, 16 +# LA32-NEXT: ld.w $a0, $a0, 112 +# LA32: 101dc: pcaddu12i $a1, 16 +# LA32-NEXT: addi.w $a1, $a1, 96 # LA64: 102e0: pcalau12i $a0, 16 # LA64-NEXT: ld.d $a0, $a0, 944 diff --git a/lld/test/ELF/loongarch-tls-gd.s b/lld/test/ELF/loongarch-tls-gd.s index 9a4ccfa2201a4..c52690e9a1297 100644 --- a/lld/test/ELF/loongarch-tls-gd.s +++ b/lld/test/ELF/loongarch-tls-gd.s @@ -5,7 +5,7 @@ ## (a) code sequence can be converted from `pcalau12i+addi.[wd]` to `pcaddi`. ## (b) dynamic relocations can be omitted for GD->LE relaxation. -# RUN: llvm-mc --filetype=obj --triple=loongarch32 -mattr=+32s %t/a.s -o %t/a.32.o +# RUN: llvm-mc --filetype=obj --triple=loongarch32 -mattr=-32s %t/a.s -o %t/a.32.o # RUN: llvm-mc --filetype=obj --triple=loongarch32 -mattr=+32s,+relax %t/a.s -o %t/a.32.relax.o # RUN: llvm-mc --filetype=obj --triple=loongarch32 -mattr=+32s %t/bc.s -o %t/bc.32.o # RUN: ld.lld -shared -soname=bc.so %t/bc.32.o -o %t/bc.32.so @@ -66,13 +66,13 @@ # GD32-REL-NEXT: } ## &DTPMOD(a) - . = 0x20310 - 0x10250: 0x10 pages, page offset 0x310 -# GD32: 10250: pcalau12i $a0, 16 -# GD32-NEXT: addi.w $a0, $a0, 784 +# GD32: 10250: pcaddu12i $a0, 16 +# GD32-NEXT: addi.w $a0, $a0, 192 # GD32-NEXT: bl 56 ## &DTPMOD(b) - . = 0x20318 - 0x1025c: 0x10 pages, page offset 0x318 -# GD32: 1025c: pcalau12i $a0, 16 -# GD32-NEXT: addi.w $a0, $a0, 792 +# GD32: 1025c: pcaddu12i $a0, 16 +# GD32-NEXT: addi.w $a0, $a0, 188 # GD32-NEXT: bl 44 # GD32-REL-RELAX: .rela.dyn { diff --git a/lld/test/ELF/loongarch-tls-ie.s b/lld/test/ELF/loongarch-tls-ie.s index e7e9617dd3efc..3b3fd944712fe 100644 --- a/lld/test/ELF/loongarch-tls-ie.s +++ b/lld/test/ELF/loongarch-tls-ie.s @@ -1,7 +1,7 @@ # REQUIRES: loongarch # RUN: rm -rf %t && split-file %s %t -# RUN: llvm-mc --filetype=obj --triple=loongarch32 --mattr=+32s %t/32.s -o %t/32.o +# RUN: llvm-mc --filetype=obj --triple=loongarch32 --mattr=-32s %t/32.s -o %t/32.o # RUN: llvm-mc --filetype=obj --triple=loongarch64 %t/64.s -o %t/64.o ## LA32 IE @@ -41,11 +41,11 @@ ## LA32: ## &.got[0] - . = 0x20214 - 0x101a4: 0x10 pages, page offset 0x214 ## &.got[1] - . = 0x20218 - 0x101b0: 0x10 pages, page offset 0x218 -# IE32: 101a4: pcalau12i $a4, 16 -# IE32-NEXT: ld.w $a4, $a4, 532 +# IE32: 101a4: pcaddu12i $a4, 16 +# IE32-NEXT: ld.w $a4, $a4, 112 # IE32-NEXT: add.w $a4, $a4, $tp -# IE32-NEXT: 101b0: pcalau12i $a5, 16 -# IE32-NEXT: ld.w $a5, $a5, 536 +# IE32: 101b0: pcaddu12i $a5, 16 +# IE32-NEXT: ld.w $a5, $a5, 104 # IE32-NEXT: add.w $a5, $a5, $tp ## LA64: @@ -62,15 +62,16 @@ # a@tprel = st_value(a) = 0x8 # b@tprel = st_value(a) = 0xc -# LE32-GOT: could not find section '.got' +# LE32-GOT: section '.got': +# LE32-GOT-NEXT: 0x0003012c 08000000 0c000000 # LE64-GOT: could not find section '.got' ## LA32: -# LE32: 200d4: nop -# LE32-NEXT: ori $a4, $zero, 8 +# LE32: 20114: pcaddu12i $a4, 16 +# LE32-NEXT: ld.w $a4, $a4, 24 # LE32-NEXT: add.w $a4, $a4, $tp -# LE32-NEXT: 200e0: nop -# LE32-NEXT: ori $a5, $zero, 12 +# LE32: 20120: pcaddu12i $a5, 16 +# LE32-NEXT: ld.w $a5, $a5, 16 # LE32-NEXT: add.w $a5, $a5, $tp ## LA64: diff --git a/lld/test/ELF/loongarch-tls-ld.s b/lld/test/ELF/loongarch-tls-ld.s index 65be2f8fd36e4..179bd50aa47be 100644 --- a/lld/test/ELF/loongarch-tls-ld.s +++ b/lld/test/ELF/loongarch-tls-ld.s @@ -5,7 +5,7 @@ ## (a) code sequence can be converted from `pcalau12i+addi.[wd]` to `pcaddi`. ## (b) dynamic relocations can be omitted for LD->LE relaxation. -# RUN: llvm-mc --filetype=obj --triple=loongarch32 --position-independent -mattr=+32s %t/a.s -o %t/a.32.o +# RUN: llvm-mc --filetype=obj --triple=loongarch32 --position-independent -mattr=-32s %t/a.s -o %t/a.32.o # RUN: llvm-mc --filetype=obj --triple=loongarch32 --position-independent -mattr=+32s,+relax %t/a.s -o %t/a.32.relax.o # RUN: llvm-mc --filetype=obj --triple=loongarch32 -mattr=+32s %t/tga.s -o %t/tga.32.o # RUN: llvm-mc --filetype=obj --triple=loongarch64 --position-independent %t/a.s -o %t/a.64.o @@ -60,8 +60,8 @@ # LD64-GOT-NEXT: 0x00020400 00000000 00000000 00000000 00000000 ## LA32: &DTPMOD(a) - . = 0x20280 - 0x101cc: 0x10 pages, page offset 0x280 -# LD32: 101cc: pcalau12i $a0, 16 -# LD32-NEXT: addi.w $a0, $a0, 640 +# LD32: 101cc: pcaddu12i $a0, 16 +# LD32-NEXT: addi.w $a0, $a0, 180 # LD32-NEXT: bl 44 ## LA64: &DTPMOD(a) - . = 0x20400 - 0x102e0: 0x10 pages, page offset 0x400 @@ -94,8 +94,8 @@ # LE64-GOT-RELAX-NEXT: 0x000301d0 01000000 00000000 00000000 00000000 ## LA32: DTPMOD(.LANCHOR0) - . = 0x30120 - 0x20114: 0x10 pages, page offset 0x120 -# LE32: 20114: pcalau12i $a0, 16 -# LE32-NEXT: addi.w $a0, $a0, 288 +# LE32: 20114: pcaddu12i $a0, 16 +# LE32-NEXT: addi.w $a0, $a0, 12 # LE32-NEXT: bl 4 ## LA64: DTPMOD(.LANCHOR0) - . = 0x301d8 - 0x201c8: 0x10 pages, page offset 0x1d8 diff --git a/lld/test/ELF/loongarch-tlsdesc.s b/lld/test/ELF/loongarch-tlsdesc.s index 7d07c66606a87..835e98907516c 100644 --- a/lld/test/ELF/loongarch-tlsdesc.s +++ b/lld/test/ELF/loongarch-tlsdesc.s @@ -3,8 +3,8 @@ # RUN: llvm-mc -filetype=obj -triple=loongarch64 a.s -o a.64.o # RUN: llvm-mc -filetype=obj -triple=loongarch64 c.s -o c.64.o # RUN: ld.lld -shared -soname=c.64.so c.64.o -o c.64.so -# RUN: llvm-mc -filetype=obj -triple=loongarch32 --mattr=+32s --defsym ELF32=1 a.s -o a.32.o -# RUN: llvm-mc -filetype=obj -triple=loongarch32 --mattr=+32s --defsym ELF32=1 c.s -o c.32.o +# RUN: llvm-mc -filetype=obj -triple=loongarch32 --defsym ELF32=1 a.s -o a.32.o +# RUN: llvm-mc -filetype=obj -triple=loongarch32 --defsym ELF32=1 c.s -o c.32.o # RUN: ld.lld -shared -soname=c.32.so c.32.o -o c.32.so # RUN: ld.lld -shared -z now a.64.o c.64.o -o a.64.so @@ -27,6 +27,7 @@ # RUN: ld.lld -shared -z now a.32.o c.32.o -o rel.32.so -z rel # RUN: llvm-readobj -r -x .got rel.32.so | FileCheck --check-prefix=GD32-REL %s +# RUN: llvm-objdump --no-show-raw-insn -h -d rel.32.so | FileCheck %s --check-prefix=GD32 # GD64-RELA: .rela.dyn { # GD64-RELA-NEXT: 0x20400 R_LARCH_TLS_DESC64 - 0x7FF @@ -64,7 +65,7 @@ # GD64-NEXT: jirl $ra, $ra, 0 # GD64-NEXT: add.d $a2, $a0, $tp -## &.got[c]-. = 0x23e0+16 - 0x10308: 0x10 pages, page offset 0x3f0 +## &.got[c]-. = 0x203e0+16 - 0x10308: 0x10 pages, page offset 0x3f0 # GD64: 10308: pcalau12i $a0, 16 # GD64-NEXT: addi.d $a0, $a0, 1008 # GD64-NEXT: ld.d $ra, $a0, 0 @@ -127,6 +128,29 @@ # GD32-REL-NEXT: 0x00020260 00000000 00000000 00000000 00000000 . # GD32-REL-NEXT: 0x00020270 00000000 ff070000 . +# GD32: .got 00000018 00020260 + +## &.got[a]-. = 0x20260 - 0x101c4 +# GD32: 101c4: pcaddu12i $a0, 32 +# GD32-NEXT: addi.w $a0, $a0, 608 +# GD32-NEXT: ld.w $ra, $a0, 0 +# GD32-NEXT: jirl $ra, $ra, 0 +# GD32-NEXT: add.w $a1, $a0, $tp + +## &.got[b]-. = 0x20260+16 - 0x101d8 +# GD32: 101d8: pcaddu12i $a0, 32 +# GD32-NEXT: addi.w $a0, $a0, 624 +# GD32-NEXT: ld.w $ra, $a0, 0 +# GD32-NEXT: jirl $ra, $ra, 0 +# GD32-NEXT: add.w $a2, $a0, $tp + +## &.got[c]-. = 0x20260+8 - 0x101ec +# GD32: 101ec: pcaddu12i $a0, 32 +# GD32-NEXT: addi.w $a0, $a0, 616 +# GD32-NEXT: ld.w $ra, $a0, 0 +# GD32-NEXT: jirl $ra, $ra, 0 +# GD32-NEXT: add.w $a3, $a0, $tp + #--- a.s .macro add dst, src1, src2 .ifdef ELF32 _______________________________________________ llvm-branch-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
