Risc-V定义了可选的RV32M,它定义了整数乘法除法指令。总共8条指令。
mul
mul rd, rs1, rs2 //x[rd] = x[rs1] × x[rs2]
乘(Multiply). R-type, RV32M and RV64M.
把寄存器 x[rs2]乘到寄存器 x[rs1]上,乘积写入 x[rd]。忽略算术溢出。
func7 | rs2 | rs1 | func3 | rd | opcode | ||||||||||||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
mul | R | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
例子:
00000000 <.text>:
0: 027302b3 mul x5,x6,x7
mulh
mulh rd, rs1, rs2 //x[rd] = (x[rs1] s ×s x[rs2]) ≫s XLEN
高位乘(Multiply High). R-type, RV32M and RV64M.
把寄存器 x[rs2]乘到寄存器 x[rs1]上,都视为 2 的补码,将乘积的高位写入 x[rd]。
func7 | rs2 | rs1 | func3 | rd | opcode | ||||||||||||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
mulh | R | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
例子:
00000000 <.text>:
0: 027312b3 mulh x5,x6,x7
mulhu
mulhu rd, rs1, rs2 //x[rd] = (x[rs1]u ×u x[rs2]) ≫u XLEN
高位无符号乘(Multiply High Unsigned). R-type, RV32M and RV64M.
把寄存器 x[rs2]乘到寄存器 x[rs1]上, x[rs1]、 x[rs2]均为无符号数,将乘积的高位写入 x[rd]。
func7 | rs2 | rs1 | func3 | rd | opcode | ||||||||||||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
mulhu | R | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
例子:
0: 027332b3 mulhu x5,x6,x7
mulhsu
mulhsu rd, rs1, rs2 //x[rd] = (x[rs1]u ×s x[rs2]) ≫s XLEN高位有符号-无符号乘(Multiply High Signed-Unsigned). R-type, RV32M and RV64M.
把寄存器 x[rs2]乘到寄存器 x[rs1]上, x[rs1]为 2 的补码, x[rs2]为无符号数,将乘积的高位写入 x[rd]
func7 | rs2 | rs1 | func3 | rd | opcode | ||||||||||||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
mulhsu | R | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
例子:
00000000 <.text>:
0: 027322b3 mulhsu x5,x6,x7
div
div rd, rs1, rs2 //x[rd] = x[rs1] ÷s x[rs2]
除法(Divide). R-type, RV32M and RV64M.
用寄存器 x[rs1]的值除以寄存器 x[rs2]的值,向零舍入,将这些数视为二进制补码,把商写入 x[rd]。
func7 | rs2 | rs1 | func3 | rd | opcode | ||||||||||||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
div | R | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
例子:
0: 027342b3 div x5,x6,x7
divu
divu rd, rs1, rs2 x[rd] = x[rs1] ÷u x[rs2]
无符号除法(Divide, Unsigned). R-type, RV32M and RV64M.
用寄存器 x[rs1]的值除以寄存器 x[rs2]的值,向零舍入,将这些数视为无符号数,把商写入x[rd]。
func7 | rs2 | rs1 | func3 | rd | opcode | ||||||||||||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
divu | R | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
例子:
0: 027352b3 divu x5,x6,x7
rem
rem rd, rs1, rs2 //x[rd] = x[rs1] %s x[rs2]
求余数(Remainder). R-type, RV32M and RV64M.
x[rs1]除以 x[rs2],向 0 舍入,都视为 2 的补码,余数写入 x[rd]。
func7 | rs2 | rs1 | func3 | rd | opcode | ||||||||||||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
rem | R | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
例子:
0: 027362b3 rem x5,x6,x7
remu
remu rd, rs1, rs2 x[rd] = x[rs1] %u x[rs2]
求无符号数的余数(Remainder, Unsigned). R-type, RV32M and RV64M.
x[rs1]除以 x[rs2],向 0 舍入,都视为无符号数,余数写入 x[rd]。
func7 | rs2 | rs1 | func3 | rd | opcode | ||||||||||||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
remu | R | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 0 | 0 | 1 | 1 |
例子:
0: 027372b3 remu x5,x6,x7
如果希望得到两个32位整数相乘的完整的64位结果,Risc-V推荐使用下面的指令:
mulh[s|u] rdh,rs1, rs2;
mul rdl rs1,rs2
其中要求:两条指令的源操作数索引号和顺序必须完全相同。第一条指令的rdh索引必须不能与rs1,rs2索引号相同。处理器实现的微架构可以把两条指令融合成一条指令执行,从而提高性能。
如果希望同时得到两个32位数相除的商和余数,Risc-V推荐用以下指令:
div[u] rdq, rs1, rs2;
rem[u] rdr,rs1,rs2;
其中要求:两条指令的源操作数索引号和顺序必须完全相同。第一条指令的rdh索引必须不能与rs1,rs2索引号相同。处理器实现的微架构可以把两条指令融合成一条指令执行,从而提高性能。
Risv-V中除以0,并不会产生异常,仍会产生一个特殊的结果。
RV32M是RV64M的子集,除了RV32M的8条指令,RV64M还增加以下5条RV32M中没有的指令。
mulw
mulw rd, rs1, rs2 //x[rd] = sext((x[rs1] × x[rs2])[31: 0])
乘字(Multiply Word). R-type, RV64M.
把寄存器 x[rs2]乘到寄存器 x[rs1]上,乘积截为 32 位,进行有符号扩展后写入 x[rd]。忽略算术溢出。
func7 | rs2 | rs1 | func3 | rd | opcode | ||||||||||||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
mulw | R | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 1 |
例子:
0: 027302bb mulw x5,x6,x7
remw
remw rd, rs1, rs2 //x[rd] = sext(x[rs1][31: 0] %s x[rs2][31: 0])
求余数字(Remainder Word). R-type, RV64M .
x[rs1]的低 32 位除以 x[rs2]的低 32 位,向 0 舍入,都视为 2 的补码,将余数的有符号扩展写入 x[rd]。
func7 | rs2 | rs1 | func3 | rd | opcode | ||||||||||||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
remw | R | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 1 |
例子:
0: 027362bb remw x5,x6,x7
divuw
divuw rd, rs1, rs2 //x[rd] = sext(x[rs1][31:0] ÷u x[rs2][31:0])
无符号字除法(Divide Word, Unsigned). R-type, RV64M.
用寄存器 x[rs1]的低 32 位除以寄存器 x[rs2]的低 32 位,向零舍入,将这些数视为无符号数,
把经符号位扩展的 32 位商写入 x[rd]。
func7 | rs2 | rs1 | func3 | rd | opcode | ||||||||||||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
divuw | R | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 0 | 1 | 1 |
例子:
0: 027352bb divuw x5,x6,x7
divw
divw rd, rs1, rs2 x //[rd] = sext(x[rs1][31:0] ÷s x[rs2][31:0])
字除法(Divide Word). R-type, RV64M.
用寄存器 x[rs1]的低 32 位除以寄存器 x[rs2]的低 32 位,向零舍入,将这些数视为二进制补码,把经符号位扩展的 32 位商写入 x[rd]。
func7 | rs2 | rs1 | func3 | rd | opcode | ||||||||||||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
divw | R | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 1 |
例子:
0: 027342bb divw x5,x6,x7
remuw
remuw rd, rs1, rs2 //x[rd] = sext(x[rs1][31: 0] %u x[rs2][31: 0])
求无符号数的余数字(Remainder Word, Unsigned). R-type, RV64M.
x[rs1]的低 32 位除以 x[rs2]的低 32 位,向 0 舍入,都视为无符号数,将余数的有符号扩展写入 x[rd]。
func7 | rs2 | rs1 | func3 | rd | opcode | ||||||||||||||||||||||||||||
name | type | 31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
remuw | R | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 1 | 1 |
例子:
0: 027372bb remuw x5,x6,x7