riscv的整数调用约定描述如下:
最多 XLEN 位宽的标量在单个 参数寄存器,或者如果没有可用的则按值在堆栈上。什么时候 在寄存器或堆栈中传递,整数标量比 XLEN 位根据其类型的符号加宽至 32 位,然后符号扩展为 XLEN 位。
结果是,“unsigned Short”类型的参数将被零扩展为64位,而“unsigned int”类型的参数将被符号扩展为64位。为什么不全部进行零扩展?
例如,
void foo(unsigned short x)
void bar(unsigned int x);
void main(void)
{
foo(0xffffU);
bar(0xffffffffU);
}
生成的代码:
main:
...
li a5,65536
addi a0,a5,-1
call foo
li a0,-1
call bar
一致性:通过始终进行符号扩展,调用约定可确保所有比 XLEN 窄的整数参数的高位是一致的(符号位的副本)。
操作的一致性
更简单的代码生成:当编译器可以假设所有整数参数都符号扩展为 64 位时,它们可以生成更高效的代码
没有信息丢失,并且高位被忽略。
对于 32 位扩展,由于明显的原因,这是不可能的 - 即保留正确的值。