> On 2 Aug 2017, at 13:18, Kito Cheng <
kito....@gmail.com> wrote:
>
> It's used for relax in bare metal toolchain for saving code size,
> and it's initialized at crt0.o which provide by newlib/libgloss [1]
> [1]
https://github.com/riscv/riscv-newlib/blob/riscv-newlib-2.5.0/libgloss/riscv/crt0.S#L12
yes, I know this, a similar code is present in the SiFive SDK examples.
> Here is a simple example: a lui and lw pair could be relaxed into a lw with gp instruction.
> However, you can disable this by -Wl,--no-relax, but GCC still can't use gp :P
>
> Full example:
> $ cat main.c
> int i;
> int main(){
> return i;
> }
>
> $ riscv32-unknown-elf-gcc main.c --save-temps
> $ cat main.s
> ...
> lui a5,%hi(i)
> lw a5,%lo(i)(a5)
> ...
> $ riscv32-unknown-elf-objdump -d a.out
> ...
> 101b4: 8341a783 lw a5,-1996(gp) # 11fdc <i>
> ...
ok, thank you for the explanation, but neither the link to crt0.S nor these code samples respond to the question: what is the purpose of the gp register and what value should be stored in it during startup?
the newlib crt0.S and the SiFive examples load gp with __global_pointer$, which is defined in the linker script somewhere in the data section as
__global_pointer$ = . + 0x800;
in other words, a RAM address, 2K past the end of the initialised data section. (for SiFive devices, the address is like 0x800011a0, right in the middle of nowhere)
what does this mean? and why 2K?
my feeling is that this comes via a careless copy/paste from some unix configuration, but it does not make much sense here.
Palmer? any comments?
regards,
Liviu