mulh

mulh

RISC-V Assembly Reference

lyszt.net covers mulh and other RISC-V instructions in more detail.

Encoding format

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

Description

mulh returns the upper 32 bits of a product. Two 32-bit numbers can multiply to a result as wide as 64 bits, while a register holds 32. The mul instruction keeps the lower 32 bits and discards the rest. mulh (multiply high) keeps the upper 32 bits.

Run both instructions on the same inputs and you have the whole product. mulh writes the top half to one register, mul writes the bottom half to another, and the pair holds the full 64-bit result.

The upper half indicates overflow, which means a product too large for 32 bits. A meaningful value in the upper half means the product does not fit in one register. Arithmetic on very large numbers and cryptography rely on both halves.

The RISC-V manual defines two more variants beside mulh. mulhu multiplies two unsigned numbers, and mulhsu multiplies a signed number in rs1 by an unsigned number in rs2. According to the manual, mulhsu appears in multiword signed multiplication, where the most significant word of one number, which carries the sign bit, is multiplied by the less significant words of the other, which are unsigned.

The h stands for high. This version treats its operands as signed, so they can be negative. The RISC-V specification also defines unsigned variants, and this simulator provides the signed mulh. As with all multiply and divide instructions, no constant form exists, so both inputs come from registers.

Example

li t0, 100000
li t1, 100000
mulh t2, t0, t1   # t2 = 2 (high bits of 100000 * 100000)