RISC-V Detect Integer Multiplication Overflow

Introduction

In RISC-V, integer computational instructions do not cause hardware traps or exceptions on arithmetic overflow. When multiplying two 32-bit integers using the standard mul instruction from the "M" Standard Extension, the processor quietly ignores the overflow and simply returns the lower 32 bits of the mathematically true 64-bit product.

Because there are no condition codes or overflow flags in the base RISC-V architecture, you must manually check for overflow using software sequence branches.

Understanding the 64-bit Full Product

Multiplying two 32-bit integers always yields a 64-bit result, which mathematically cannot overflow a 64-bit space. RISC-V handles this by providing separate instructions to capture either the lower or upper half of that 64-bit product:

How to Detect Multiplication Overflow in Assembly

To check if a 32-bit multiplication overflowed, you can use the mulh or mulhu instructions to examine whether the bits discarded by mul contain relevant data.

  1. Unsigned 32-bit Multiplication Overflow

    For unsigned multiplication, an overflow occurs if the upper 32 bits of the full 64-bit product are anything other than zero.

    # Inputs: rs1, rs2 (Unsigned 32-bit integers) # Outputs: rd (Lower 32-bit product), or branches to overflow handler mulhsu t0, rs1, rs2 # Get upper 32 bits of the unsigned product mul rd, rs1, rs2 # Get lower 32 bits of the product bnez t0, overflow # If upper 32 bits != 0, an overflow occurred!

  2. Signed 32-bit Multiplication Overflow

    For signed multiplication, the upper 32 bits must be a valid sign extension of the lower 32 bits. This means if the result is positive, the upper bits must be all 0. If the result is negative, the upper bits must be all 1 (or -1 when viewed as a signed integer). Additionally, the sign of the upper bits must match the sign bit (bit 31) of the lower bits.

    # Inputs: rs1, rs2 (Signed 32-bit integers) # Outputs: rd (Lower 32-bit product), or branches to overflow handler mulh t0, rs1, rs2 # Get upper 32 bits of signed product mul rd, rs1, rs2 # Get lower 32 bits of signed product srai t1, rd, 31 # Arithmetic right shift lower product # by 31 bits # (t1 becomes all 0s if rd is positive, # all 1s if negative) bne t0, t1, overflow # If upper bits don't match sign extension, # overflow!


Introduction

To detect a double-word (64-bit) integer multiplication overflow in RISC-V (RV64), you must use a widening multiplication approach by comparing the high-order bits (MULH/MULHU) with an arithmetic shift of the low-order result.

Signed 64-bit Overflow Detection

For signed 64-bit integers (a and b), multiplying them produces a 128-bit result split into low 64 bits (low) and high 64 bits (high). Overflow occurs if the high 64-bit word is not merely the sign-extension of the low 64-bit word.

  1. Compute the low 64 bits: mul t2, a, b (using MUL)

  2. Compute the high signed 64 bits: mulh t3, a, b (using MULH)

  3. Shift the low result right arithmetically by 63 to replicate the sign bit: srai t4, t2, 63

  4. Compare the sign-extension mask (t4) with the high product (t3). If they are not equal (bne), an overflow occurred.

Unsigned 64-bit Overflow Detection

For unsigned 64-bit integers, overflow occurs if any of the upper 64 bits in the 128-bit product are non-zero.

  1. Compute the low 64 bits: mul t2, a, b

  2. Compute the high unsigned 64 bits: mulhu t3, a, b (using MULHU)

  3. Check if t3 is non-zero (bnez t3 indicates overflow).