diff options
author | Fangrui Song <i@maskray.me> | 2022-09-26 14:20:27 -0700 |
---|---|---|
committer | Tobias Hieta <tobias@hieta.se> | 2022-09-28 08:16:35 +0200 |
commit | 2eba4dd78e2a47a36a65617f17d5ea156cfb6448 (patch) | |
tree | 8fa463aebff0d0e0c3f9cab53862a1ae46e54b13 /lld | |
parent | 451e3b68306d0d8a9be9065420924530053ff29b (diff) | |
download | llvm-2eba4dd78e2a47a36a65617f17d5ea156cfb6448.zip llvm-2eba4dd78e2a47a36a65617f17d5ea156cfb6448.tar.gz llvm-2eba4dd78e2a47a36a65617f17d5ea156cfb6448.tar.bz2 |
[ELF] Rewrite R_RISCV_ALIGN nops when r.addend%4 != 0
For RVC, GNU assembler and LLVM integrated assembler add c.nop followed by a
sequence of 4-byte nops. Even if remove % 4 == 0, we have to split one 4-byte
nop and therefore need to write the code sequence, otherwise we create an
incorrect c.unimp.
(cherry picked from commit 78084d9e77b9a2017e2215491b71b37c2671c292)
Diffstat (limited to 'lld')
-rw-r--r-- | lld/ELF/Arch/RISCV.cpp | 9 | ||||
-rw-r--r-- | lld/test/ELF/riscv-relax-align-rvc.s | 13 |
2 files changed, 18 insertions, 4 deletions
diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp index 8fca1a6..56a516f 100644 --- a/lld/ELF/Arch/RISCV.cpp +++ b/lld/ELF/Arch/RISCV.cpp @@ -750,12 +750,13 @@ void elf::riscvFinalizeRelax(int passes) { p += size; // For R_RISCV_ALIGN, we will place `offset` in a location (among NOPs) - // to satisfy the alignment requirement. If `remove` is a multiple of 4, - // it is as if we have skipped some NOPs. Otherwise we are in the middle - // of a 4-byte NOP, and we need to rewrite the NOP sequence. + // to satisfy the alignment requirement. If both `remove` and r.addend + // are multiples of 4, it is as if we have skipped some NOPs. Otherwise + // we are in the middle of a 4-byte NOP, and we need to rewrite the NOP + // sequence. int64_t skip = 0; if (r.type == R_RISCV_ALIGN) { - if (remove % 4 != 0) { + if (remove % 4 || r.addend % 4) { skip = r.addend - remove; int64_t j = 0; for (; j + 4 <= skip; j += 4) diff --git a/lld/test/ELF/riscv-relax-align-rvc.s b/lld/test/ELF/riscv-relax-align-rvc.s index 37758ed..01cbbd8b 100644 --- a/lld/test/ELF/riscv-relax-align-rvc.s +++ b/lld/test/ELF/riscv-relax-align-rvc.s @@ -50,6 +50,12 @@ # CHECK-NEXT: c.addi a0, 8 # CHECK-EMPTY: +# CHECK: <.text2>: +# CHECK-NEXT: addi a0, a1, 1 +# CHECK-NEXT: c.addi a0, 1 +# CHECK-NEXT: c.nop +# CHECK-NEXT: c.addi a0, 2 + .global _start _start: c.addi a0, 1 @@ -73,3 +79,10 @@ d: c.addi a0, 8 .size d, . - d .size _start, . - _start + +.section .text2,"ax" +.balign 16 + addi a0, a1, 1 + c.addi a0, 1 +.balign 8 + c.addi a0, 2 |