div
div
rd, rs1, rs2
rd = rs1 / rs2
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

div divides one register by another. It reads source registers rs1 and rs2, divides the first by the second, and writes the result into destination register rd: div rd, rs1, rs2 means rd = rs1 / rs2. Like multiply, it belongs to the M extension of optional math instructions, which this simulator includes.

This is integer division, meaning the fractional part is thrown away rather than rounded. 7 divided by 2 gives 3, not 3.5 — the remainder (the 1 left over) simply vanishes. If you need that leftover, a companion instruction rem computes it from the same two numbers. For negative results the discarding goes toward zero, so -7 / 2 gives -3, not -4.

Division has two dangerous edge cases that on many processors would crash the program. RISC-V chose instead to never crash: dividing by zero does not halt anything — it simply returns -1 (a register with every bit set to 1) by definition. The handling is quiet, so if dividing by zero would be a bug in your logic, you must check for a zero divisor yourself before dividing; the hardware will not warn you.

A practical note: division is the slowest arithmetic a processor does, often many times slower than multiplication. When dividing by a power of two (2, 4, 8…), a right shift does the same job far faster (see srai). The example divides 17 by 5, and since 5 goes into 17 three whole times with 2 left over, the quotient 3 lands in t2.

li t0, 17
li t1, 5
div t2, t0, t1   # t2 = 3