[llvm-dev] Handling far branches with fixups or ELF relocs

Peter Smith via llvm-dev llvm-dev at lists.llvm.org
Wed Jul 1 03:10:32 PDT 2020

Hello Denis,

In Arm and AArch64 the limited range of immediates for branch instructions is addressed in two parts. The first is when there is a branch that is guaranteed to have a destination within the same section, in that case a 16-bit instruction is relaxed to a 32-bit one with a larger immediate. In Arm the range of the 32-bit instruction is considered large enough within a single section (-ffunction-sections may be needed for giant source files, not many single functions are larger than 16 megabytes). Branches that go across section boundaries and have relocations that the ABI says a linker must "veneer" are resolved at link time by redirecting to linker generated code (called many things from stub, thunk, veneer, trampoline ...) that completes the branch. There is support in LLD via Relocations.cpp, Thunks.cpp etc.


From: llvm-dev <llvm-dev-bounces at lists.llvm.org> on behalf of Denis Steckelmacher via llvm-dev <llvm-dev at lists.llvm.org>
Sent: 01 July 2020 09:47
To: llvm-dev at lists.llvm.org
Subject: [llvm-dev] Handling far branches with fixups or ELF relocs


I'm working on an LLVM backend for an experimental microprocessor. Work
is going on nicely, and I've until now found the answer to all my
questions directly in the LLVM source code, or in the documentation.

However, I'm having problems with the AsmBackend class and the handling
of fixups.

The processor I'm working with has a single conditional branch
instruction, JCC, that takes an IP-relative 9-bit immediate offset as
operand. A second version of the instruction takes a register as operand
and can therefore jump to any 32-bit address.

In AsmBackend, there are methods for relaxing instructions, that I
wanted to use to replace "JCC imm9" instructions with a sequence of
instructions that jumps further. However, I have two questions:

- relaxInstruction does not seem to be able to replace one instruction
with a sequence of instructions
- I've looked at many other LLVM backends (AVR, ARC, ARM, MIPS and
RISC-V), and none of them really seem to do interesting things in
relaxInstruction. ARM for instance relaxes Thumb instructions to normal
instructions, and RISC-V relaxes compressed instructions to normal ones
too. But in both cases, even the normal instructions have limited range,
for which there is an assertion, but no "solution" for when a branch
exceeds the range of the instruction.

It therefore seems that the problem of "conditional branches that jump
too far" is solved elsewhere, but I could not find that location. I
looked at LLD, and I've seen that RISC-V has some code there (related to
the PLT) that produces sequences of instructions, but not the other targets.

So, what would be the best way to change "JCC imm9" instructions to
something else when a branch has to jump further than 256 instructions
before or after the current one?

Best regards,
Denis Steckelmacher
LLVM Developers mailing list
llvm-dev at lists.llvm.org

More information about the llvm-dev mailing list