programmer helper
ABI
Assembler mnemonics for RISC-V integer and floating-point registers.
Register | ABI Name | Description | Caller | Calee |
---|---|---|---|---|
x0 | zero | Hard-wired zero | ||
x1 | ra | Return address | * | |
x2 | sp | Stack pointer | * | |
x3 | gp | Global pointer | ||
x4 | tp | Thread pointer | ||
x5 | t0 | Temporary/alternate link register | * | |
x6–x7 | t1-t2 | Temporaries | * | |
x8 | s0/fp | Saved register/frame pointer | * | |
x9 | s1 | Saved register | * | |
x10–x11 | a0-a1 | Function arguments/return values | * | |
x12–x17 | a2-a7 | Function arguments | * | |
x18–x27 | s2-s11 | Saved registers | * | |
x28–x31 | t3-t6 | Temporaries | * | |
f0–f7 | ft0-ft7 | FP temporaries | * | |
f8–f9 | fs0-fs1 | FP saved registers | * | |
f10–f11 | fa0-fa1 | FP arguments/return values | * | |
f12–f17 | fa2-fa7 | FP arguments | * | |
f18–f27 | fs2-fs11 | FP saved registers | * | |
f28–f31 | ft8-ft11 | FP temporaries | * |
Preprocessor macros
32 bits
1 | $ ./riscv-none-embed-gcc -march=rv32i -mabi=ilp32 -E -dM - < /dev/null | egrep -i 'risc|fp[^-]|version|abi|lp' | sort |
64 bits
1 | $ ./riscv-none-embed-gcc -march=rv64i -mabi=lp64 -E -dM - < /dev/null | egrep -i 'risc|fp[^-]|version|abi|lp' | sort |
misc
1 | #define __riscv_xlen 32 |
1 | #define __riscv_cmodel_medlow 1 |
1 | #define __riscv_float_abi_soft 1 |
The gp
(Global Pointer) register
gp
寄存器是为了优化4K内memory访问的一种解决办法。
linker使用__global_pointer$
来比较memory地址,如果在范围内,就替换掉 absolute/pc-relative寻址为gp-relative寻址,这使得代码更有效率。这个处理过程被称为relaxing,也可以使用-Wl,--no-relax
来disable掉这个功能。
1 | $ cat main.c |
gp寄存器应该在启动代码中加载为__global_pointer$
的地址,并且之后不能被改变。
1 | .section .reset_entry,"ax",@progbits |
4K区域可以位于寻址内存中任意位置,但是为了使优化更有效率,它最好覆盖最频繁使用的RAM区域。对于标准的newlib应用程序,这是分配.sdata部分的区域,因为它包含了诸如_impure_ptr、malloc_sbrk_base等变量。因此,定义应该被放在.sdata部分之前。例如:
1 | PROVIDE( __global_pointer$ = . + (4K / 2) ); |
区域大小是4K是一位内RISCV立即数为12bit signed值,那就是+/- 2048或+/- 0x800。因为只是有符号的,所以__global_pointer$
必须指向区域中间。
源自: