RISC-V:__global_pointer$

RISC-V:__global_pointer$

原文出处:https://gnu-mcu-eclipse.github.io/arch/riscv/programmer/#the-gp-global-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-gcc  main.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 的范围内。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值