RISC-V gp全局指針寄存器說明


RISC-V gp全局指針寄存器說明

gpglobal pointer,全局指針寄存器,RISC-V 32個寄存器之一,為了優化±2KB內全局變量的訪問。

gp寄存器在啟動代碼中加載為__global_pointer$的地址,並且之后不能被改變。

linker時使用__global_pointer$來比較全局變量的地址,如果在范圍內,就替換掉luipuipc指令的 absolute/pc-relative尋址,變為gp-relative尋址,使得代碼效率更高。該過程被稱為linker relaxation(鏈接器松弛),也可以使用-Wl,--no-relax來disable此功能。

如:需要讀取全局變量 tao_global的值,地址位0x20000100,gp指針地址為0x20000800

  • 普通調用方式為:
lui a5,0x20000   /* 將0x20000100高20位0x20000 左移12位賦給a5寄存器 */
lw  a5,256(a5)   /* 加載a5+256(0x100,0x20000100低12位)的值至a5寄存器 */
  • gp指針優化調用方式:
lw a5,-1792(gp) /* 加載gp-1792地址處的值至a5,即0x20000100處的值*/

通過gp指針,訪問其值±2KB,即4KB范圍內的全局變量,可以節約一條指令。

4KB區域可以位於尋址內存中任意位置,但是為了使優化更有效率,最好覆蓋最頻繁使用的RAM區域。對於標准的newlib應用程序,這是分配.sdata部分的區域,因為它包含了諸如_impure_ptr、malloc_sbrk_base等變量。因此,定義應該被放在.sdata部分之前。具體分配在ld文件中定義:

.data :
	{
    	*(.gnu.linkonce.r.*)
    	*(.data .data.*)
    	*(.gnu.linkonce.d.*)
		. = ALIGN(8);
    	PROVIDE( __global_pointer$ = . + 0x800 ); /* __global_pointer地址*/
    	*(.sdata .sdata.*)
		*(.sdata2.*)
    	*(.gnu.linkonce.s.*)
    	. = ALIGN(8);
    	*(.srodata.cst16)
    	*(.srodata.cst8)
    	*(.srodata.cst4)
    	*(.srodata.cst2)
    	*(.srodata .srodata.*)
    	. = ALIGN(4);
		PROVIDE( _edata = .);
	} >RAM AT>FLASH


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM