I’m facing a problem with constant pool in large functions.
The LLVM prints constant pool at the beginning of functions.
In large functions loads can be far from constant pool. GCC resolves this situations by spreading constants throughtout functions. A C test and the code generated by LLVM and GCC are attached.
As you can see in the following error the ldr is too far from constant:
$ arm-linux-gnueabi-as teste-llvm.s
teste-llvm.s: Assembler messages: teste-llvm.s:1039:
Error: bad immediate value for offset (4120)
Any ideas?
Lauro
teste.c (20.1 KB)
teste-llvm.s (20.4 KB)
teste-gcc.s (20.5 KB)
Hi Lauro,
This is a very tricky problem to resolve. Basically you need a pass just before code emission to find the proper locations for each constant pool. That means you need:
1. Exact size of each instruction. This can be added with a custom instrinfo that specify instruction length for each target instruction.
2. Probably some kind of constantpool pseudo instruction.
The pass can then insert new constantpool instructions at the right locations to solve this problem.
Evan
Hi,
Evan wrote:
> The LLVM prints constant pool at the beginning of functions.
>
> In large functions loads can be far from constant pool. GCC
> resolves this situations by spreading constants throughtout
> functions. A C test and the code generated by LLVM and GCC are
> attached.
This is a very tricky problem to resolve. Basically you need a pass
just before code emission to find the proper locations for each
constant pool. That means you need:
1. Exact size of each instruction. This can be added with a custom
instrinfo that specify instruction length for each target instruction.
2. Probably some kind of constantpool pseudo instruction.
The pass can then insert new constantpool instructions at the right
locations to solve this problem.
A bodgy alternative to get you over the hurdle is to construct constants
with instructions rather than load them from memory, e.g.
mov r9, #&3f8000 # r9 = 0x3f8000
sub r9, r9, #&400000 # r9 = 0xffff8000 (WDTCTRL)
comp.sys.arm may be able to point you to ARM's recommended way of coming
up with the needed instructions for a 32-bit constant.
Cheers,
Ralph.