Hwo to guess PC-relative offset

Dear LLVM crew,

I have been writing a new LLVM backend with a very simple instruction set.
moving a constant value to a register is selected as a load of the constant, with a PC-relative positive offset.
Thus, the constant should be stored in .text section, after the load instruction, and offset should be computed at compile time (not link time).

I struggle to find out :
- how llvm handle constant pool
- where I should compute the offset (MCCodeEmitter ? MCInstLowering ? ... ?)
ARM has a specific pass for this (ARMConstantIslandPass.cpp), but I wonder if such a processing is really needed, at least for simple case (i.e. small enough offset).
Handling this with relocations and linker-hacking seems odd, I'd prefer to avoid it.

Thanks for you help, either with some advice on the implementation strategy, or with and example in an existing backend.

The basic idea is to still create a relocation on the MC level, but fix
it up later. You didn't say if your ISA is fixed or variable length,
the former, can simplify this quite bit. The constant island pass
generally tries to address two issues:
(1) Merging of identical constants.
(2) Splitting the constant island if the function gets too large.

Joerg

De : Joerg Sonnenberger [mailto:joerg@britannica.bec.de]

The basic idea is to still create a relocation on the MC level, but fix it up later.
You didn't say if your ISA is fixed or variable length, the former, can simplify
this quite bit. The constant island pass generally tries to address two issues:
(1) Merging of identical constants.
(2) Splitting the constant island if the function gets too large.

Joerg

Hi Joerg,

ISA is actually fixed length.
If I get it right, unless the function gets too big,
I could at least have a suboptimal thus functional binary, without the constant island pass.
Could you spot the hook(s) I should use add a relocation (or do you mean fixup ?) and where I should fix it ?

Well, MCFixup is what a relocation is represented as internally. They
get resolved to a fixed value and replaced, if evaluateAsAbsolute is
true.

Joerg

De : Joerg Sonnenberger [mailto:joerg@britannica.bec.de]

Well, MCFixup is what a relocation is represented as internally. They get
resolved to a fixed value and replaced, if evaluateAsAbsolute is true.

Hi Joerg,

Actually it fails to get resolved to a fixed value.
When I compile to .o then objdump it I can see that a symbol holding the constant value was created in .rodata.cst4 section.
Since it is not in .text section, it sound logical that llvm cannot resolved it at assemble time.

Is there a way to tell llvm to put the constant in .text section ?

$ cat imm.c
int imm32(){
  return 0x04050607;
}

$ llvm-objdump -disassemble -s imm.o
[...]
Contents of section .rodata.cst4:
0000 07060504
[...]

You'd need some kind of stubbed version of ConstantIslands that just
put the islands at the beginning or end of a function. It would be
much simpler than the ARM version though (at least initially), most of
the complexity comes from finite reachability.

But there's a lot to be said for just letting it stay in .rodata. The
linker's going to be doing that kind of job anyway, so just let it get
on with resolving offsets. Both x86 and AArch64 take this approach (in
AArch64's case despite there being explicit instructions in the
architecture designed to handle inline constants -- we just decided it
wasn't worth the aggro of duplicating ARM's ConstantIsland mess so
they're unused in LLVM).

Cheers.

Tim.

X86 is a bad example, because the normal code models allow addressing
anything in the same object, pretty much independent of size
constraints and section order.

Joerg