[llvm] [AVR] Fix parsing & emitting relative jumps (PR #102936)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 26 05:08:18 PDT 2024
aykevl wrote:
This patch makes it so that relative branches are typically resolved at compile time, with no emitted relocations.
That's not like avr-gcc which _does_ seem to emit relocations every time.
For example, with this code:
```c
void asdf(void);
void foobar(char x) {
while (x != 0) {
asdf();
x--;
}
}
```
I get the following output for avr-gcc 5.4.0 (Debian), which includes relocations:
```
00000000 <foobar>:
0: push r28
2: mov r28, r24
4: and r28, r28
6: breq .+0 ; 0x8 <foobar+0x8>
6: R_AVR_7_PCREL .text+0xe
8: rcall .+0 ; 0xa <foobar+0xa>
8: R_AVR_13_PCREL asdf
a: subi r28, 0x01 ; 1
c: rjmp .+0 ; 0xe <foobar+0xe>
c: R_AVR_13_PCREL .text+0x4
e: pop r28
10: ret
```
And the following for avr-gcc 14.1.0 in Fedora 40, which also includes relocations:
```
00000000 <foobar>:
0: push r28
2: mov r28, r24
00000004 <.L2>:
4: cpse r28, r1
6: rjmp .+0 ; 0x8 <.L2+0x4>
6: R_AVR_13_PCREL .L3
8: pop r28
a: ret
0000000c <.L3>:
c: rcall .+0 ; 0xe <.L3+0x2>
c: R_AVR_13_PCREL asdf
e: subi r28, 0x01 ; 1
10: rjmp .+0 ; 0x12 <.L3+0x6>
10: R_AVR_13_PCREL .L2
```
But Clang outputs the following, with no relocations:
```
00000000 <foobar>:
0: push r17
2: mov r17, r24
4: cpi r17, 0x00 ; 0
6: breq .+8 ; 0x10 <foobar+0x10>
8: call 0 ; 0x0 <foobar>
8: R_AVR_CALL asdf
c: dec r17
e: rjmp .-12 ; 0x4 <foobar+0x4>
10: pop r17
12: ret
```
(In all cases, I compiled to an object file and disassembled using `avr-objdump -dr`).
I don't know why this is, but my guess would be to support linker relaxation.
In any case:
> ... which causes most of the relative jumps to be actually resolved late, by the linker, which applies the offsetting logic on its own, hiding the issue within LLVM.
I think that would in fact be a reasonable solution: to let the linker deal with relocation offsets in all cases.
https://github.com/llvm/llvm-project/pull/102936
More information about the llvm-commits
mailing list