divu
lyszt.netはdivuおよびその他の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
説明
divu は符号なし除算を行います。レジスタの32ビットは2通りに解釈できます。符号付きの読み方では、最上位ビットが負の数を示すため、ビットは約 -20億から +20億までの値を表します。符号なしの読み方では負の数は存在せず、ビットは0から約40億までを数えます。ビットは変わりません。変わるのは解釈だけです。
div は入力を符号付きとして扱い、divu は符号なしとして扱います。範囲の上限付近では、この2つは異なる結果を生みます。すべてのビットが1に設定されたレジスタは、div にとっては -1 であり、divu にとっては 4,294,967,295 です。
divu は負になり得ない値に適しています。配列の位置、バイト単位のサイズ、ループ回数、ピクセル座標などです。これらの値が約20億を超えると、符号付きの div は誤った結果を返します。最上位ビットがオンになり、符号付きの読み方ではその値が負になります。
RISC-V のマニュアルでは、符号なし除算のゼロ除算の商はすべてのビットが1に設定された値と定義され、剰余は被除数と等しいと定義されています。マニュアルによれば、符号なし除算のオーバーフローは発生しません。すべてのビットが1に設定された値は最大の符号なし数であり、単純な符号なし除算回路はそれ自体でこれを生成します。だからこそマニュアルはそれを選んだのです。
ゼロ除算は最大の符号なし値を返し、すべてのビットが1に設定されます。除数が2の冪である場合、論理右シフト(srli)の方が速く除算できます。3ビット右にシフトすると、符号なし数を8で割ることになります。
例
li t0, -2 li t1, 2 divu t2, t0, t1 # t2 = 2147483647 (t0 read as unsigned)
