皋陶 发表于 2020-8-24 10:30:20

RISC-V:__global_pointer$

本帖最后由 皋陶 于 2020-8-26 18:26 编辑

RISC-V:__global_pointer$原文出处:https://gnu-mcu-eclipse.github.i ... al-pointer-register
The gp (Global Pointer) register is a solution to further optimise memory accesses within a single 4KB region.
The linker uses the __global_pointer$ symbol definition to compare the memory addresses and, if within range, it replaces absolute/pc-relative addressing with gp-relative addressing, which makes the code more efficient. This process is also called relaxing, and can be disabled by -Wl,--no-relax.
$ cat main.c
int i;
int main()
{
return i;
}

$ riscv-none-embed-gccmain.c --save-temps
$ cat main.s
...
      lui      a5,%hi(i)
      lw      a5,%lo(i)(a5)
...
$ riscv-none-embed-objdump -d a.out
...
   101b4:       8341a783                lw      a5,-1996(gp) # 11fdc <i>
...
The gp register should be loaded during startup with the address of the __global_pointer$ symbol and should not be changed later.
.section .reset_entry,"ax",@progbits
      .align      1
      .globl      _reset_entry
      .type      _reset_entry, @function
_reset_entry:

.option push
.option norelax
      la gp, __global_pointer$
.option pop

      la sp, __stack

      j _start
The 4K region can be anywhere in the addressed memory, but, for the optimisation to be effective, it should preferably cover the most intensely used RAM area. For standard newlib applications, this is the area where the .sdata section is allocated, since it includes variables like _impure_ptr, __malloc_sbrk_base, etc. Thus, the definition should be placed right before the .sdata section. For example:
PROVIDE( __global_pointer$ = . + (4K / 2) );
*(.sdata .sdata.*)
The region size is 4K because RISC-V immediate values are 12-bit signed values, which are +/- 2048 in decimal or +/- 0x800 in hex; since the values are signed, the __global_pointer$ must point to the middle of the region.
注:要让 relaxing 优化起作用,编译时要加入 -msmall-data-limit=n 参数,有了这个参数,编译器会把内存空间小于 n 字节的静态变量放入 .sdata 或者 .sdata.* 节,然后链接器将这部分静态变量集中在 __global_pointer$ +/- 2K 的范围内。

本篇完,感谢关注:RISC-V单片机中文网
页: [1]
查看完整版本: RISC-V:__global_pointer$