yud*_*dre 2 assembly sign-extension riscv zero-extension
对于x86和x64编译器,生成类似的零/符号扩展MOVSX和MOVZX.扩展本身并不是免费的,但允许处理器执行无序魔术加速.
但是在RISC-V上:
因此,无符号和带符号的32位整数之间的转换是无操作,从有符号的32位整数到带符号的64位整数的转换也是如此.
添加和移位需要一些新指令(ADD [I] W/SUBW/SxxW)以确保32位值的合理性能.
(C)RISC-V Spec
但与此同时,新的现代RISC-V 64位处理器包含32位有符号整数的指令.为什么?提高性能?那么8位和16位呢?我已经什么都不懂了.
完整的引用对我来说似乎很清楚:
编译器和调用约定保持一个不变量,即所有32位值都以64位寄存器中的符号扩展格式保存.甚至32位无符号整数也将位31扩展为位63到32.
因此,无符号和带符号的32位整数之间的转换是无操作,从有符号的32位整数到带符号的64位整数的转换也是如此.
现有的64位宽SLTU和无符号分支比较在此不变量下仍可在无符号32位整数上正确运行.
类似地,32位符号扩展整数上的现有64位宽逻辑运算保留了符号扩展属性.添加和移位需要一些新指令(ADD [I] W/SUBW/SxxW)以确保32位值的合理性能.
它表示32位值存储在64位寄存器中,其MSb(最高有效位)通过位32-63重复.
这是针对有符号和无符号整数完成的.
这允许一些优化,如引用中所述:
但是,添加(名称为1)不会保留此不变量:0x000000007fffffff + 0x0000000000000001 = 0x0000000080000000,这违反了该假设.
因为a)经常使用32位值并且b)修复结果需要额外的工作(我可以想到使用slli/ sraipair)已经引入了新格式的指令.
这些指令在64位寄存器上运行,但仅使用其较低的32位值,并将对32位结果进行符号扩展.
这很容易在硬件中完成,所以值得拥有这种新的指令.
正如评论中所指出的那样,8位和16位算术很少见,因此没有花费任何工程努力为它寻找新的空间(无论是在所需的门数还是所使用的操作码空间方面).