Long multiplication example
Here is the state of the art for long (36 x 36 -> 72-bit) unsigned multiplication. It now requires only 35 instructions, not including a presumed CALL
and RETURN
.
Here are three hints for understanding the below example:
- In this architecture,
++
is the infix operator that means “add with carry.” - The
MHL
- andDSL
instructions can be found on the ALU: multiply page. - The
LSL
instruction is a 6-bit, single-register left shift.
Sample code
; compute d:c = a * b mul35:: unsigned a b ; input unsigned c d ; output unsigned m t ; scratch keep a b c d ; these stay accessible to caller m = b mhl5 a d = m dsl 0 c = m lsl 060606060606`o c = c + m d = d ++ 0 m = b mhl4 a c = m + c d = c dsl d c = c lsl 060606060606`o c = c + m d = d ++ 0 m = b mhl3 a c = m + c d = c dsl d c = c lsl 060606060606`o c = c + m d = d ++ 0 m = b mhl2 a c = m + c d = c dsl d c = c lsl 060606060606`o c = c + m d = d ++ 0 m = b mhl1 a c = m + c d = c dsl d c = c lsl 060606060606`o c = c + m d = d ++ 0 m = b mhl0 a c = m + c d = c dsl d c = c lsl 060606060606`o c = c + m d = d ++ 0
Note
Although this code always computes the correct product, it sometimes falsely sets the R(ange) flag indicating overflow. This is a straightforward issue to fix, but before posting a fix here, I wish to regression test it as thoroughly as the above example has been.
If CALL
is used to reach this multiplication code, simply changing RETURN
to REVERT
would cover over the R(ange) flag with no ill effects. So that solution is available immediately without waiting for me—but I would prefer a solution that uses correct flag handling and RETURN
.
MWA 23 June 2023