bltu
lyszt.net 更详细地介绍了 bltu 和其他 RISC-V 指令。
编码格式
R
31–25funct7
24–20rs2
19–15rs1
14–12funct3
11–7rd
6–0opcode
I
31–20imm[11:0]
19–15rs1
14–12funct3
11–7rd
6–0opcode
S
31–25imm[11:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:0]
6–0opcode
B
31–25imm[12,10:5]
24–20rs2
19–15rs1
14–12funct3
11–7imm[4:1,11]
6–0opcode
U
31–12imm[31:12]
11–7rd
6–0opcode
J
31–12imm[20,10:1,11,19:12]
11–7rd
6–0opcode
描述
bltu 执行与 blt 相同的分支,但将两个寄存器都按无符号读取。该名称代表 branch if less than, unsigned。当 rs1 小于 rs2 时分支成立,两个值都按从 0 到约 40 亿的非负数读取。blt 页面介绍分支本身。本页解释为什么无符号读取需要有自己的指令。
同样的 32 位,根据最高位被读作符号还是值的一部分,会表示不同的数。blt 将这些位读作有符号,bltu 将其读作无符号,两种读法不一致。所有位都设为 1 的寄存器对 blt 来说是 -1,一个非常小的值,而对 bltu 来说是可能的最大值。选错指令会产生错误结果,而且没有错误消息。
bltu 适用于任何不可能为负的东西,例如内存地址、大小、计数和位置。用有符号的 blt 比较地址,一旦地址大到最高位被置位就会失败,因为有符号读法会把它当作负数。
RISC-V 手册也提到了同样的范围检查。有符号的数组边界可以用一条 bltu 检查,因为任何负索引都会比任何非负边界大。
一条 bltu 就能检查索引是否在范围内,即至少为 0 且小于大小 n。
bltu i, n, ok
如果 i 为负,其无符号读法是一个非常大的数,无法通过测试,因此一次无符号比较就能同时捕获过大和负数两种情况。
示例
li t0, 1 li t1, -1 bltu t0, t1, done # t1 read as unsigned is huge, so jump to 'done'
