Multiplication of three integers in MIPS

2019-08-03 17:31发布

问题:

I want to multiply three integers in MIPS. My first thought was to multiply the first and the second one, and after that the result with the third one (like I did it with add). But the result is given in HI and LOW in 64-bit. So how can I multiply it with the third factor?

And: 32-bit integer * 32-bit integer = 64-bit integer. What (in the theory) would give that:

32-bit int * 32-bit int * 32-bit int = ??

96-bit? 128?

Thanks for your hints.

回答1:

Multiplying an n-bit number with an m-bit number produces a (n+m) bit number. So multiplying three 32-bit numbers produces a 96-bit product

Suppose the three numbers are a, b and c, we have the following result

  a*b  =   ABH*2³² + ABL
c(a*b) = c(ABH*2³² + ABL)
       = c*ABH*2³² + c*ABL
       = (CABH_H*2³² + CABH_L)*2³² + (CABL_H*2³² + CABL_L)
       = CABH_H*2⁶⁴ + (CABH_L + CABL_H)*2³² + CABL_L

where H and L are the high and low parts of the result which are stored in the HI and LO registers respectively. Here the multiplications by 232 and 264 will be replaced by shifting left by 32 and 64 respectively.

So in MIPS32 if a, b and c are stored in $s0, $s1 and $s2 we can do the math as below

multu   $s0, $s1        # (HI, LO) = a*b
mfhi    $t0             # t0 = ABH
mflo    $t1             # t1 = ABL

multu   $s2, $t1        # (HI, LO) = c*ABL
mfhi    $t4             # t4 = CABL_H
mflo    $s7             # s7 = CABL_L

multu   $s2, $t0        # (HI, LO) = c*ABH
mfhi    $s5             # s5 = CABH_H
mflo    $t3             # t3 = CABH_L

addu    $s6, $t3, $t4   # s6 = CABH_L + CABL_H
sltu    $t5, $s6, $t3   # carry if s6 overflows
addu    $s5, $s5, $t5   # add carry to s5
# result = (s5 << 64) | (s6 << 32) | s7

The result is stored in the tuple ($s5, $s6, $s7)

Things will be much simpler in MIPS64:

mul(unsigned int, unsigned int, unsigned int):
        multu   $4,$5
        dext    $6,$6,0,32
        mfhi    $3
        mflo    $2
        dins    $2,$3,32,32
        dmultu  $6,$2
        mflo    $3
        j       $31
        mfhi    $2

Here's some sample assembly output from GCC on Godbolt

You may need some slight modification for signed operations