Умножение трех целых чисел в MIPS

Я хочу умножить три целых числа в MIPS. Первой моей мыслью было умножить первое и второе, а потом результат на третий (как я сделал это с помощью сложения). Но результат представлен в HI и LOW в 64-битном формате. Так как я могу умножить это на третий множитель?

И: 32-битное целое число * 32-битное целое число = 64-битное целое число. Что (в теории) даст это:

32-битное int * 32-битное int * 32-битное int = ??

96-битный? 128?

Спасибо за подсказки.


person fuuman    schedule 09.07.2014    source источник


Ответы (1)


Умножение n-битного числа на m-битное число дает (n + m) битовое число. Таким образом, умножение трех 32-битных чисел дает 96-битное произведение

Предположим, что три числа - это a, b и c, мы имеем следующий результат

  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

где H и L - это старшая и младшая части результата, которые сохраняются в регистрах HI и LO соответственно. Здесь умножение на 2 32 и 2 64 будет заменено сдвигом влево на 32 и 64 соответственно.

Итак, в MIPS32, если a, b и c хранятся в $ s0, $ s1 и $ s2, мы можем выполнить математику, как показано ниже.

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

Результат сохраняется в кортеже ($ s5, $ s6, $ s7)

В 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

Вам может потребоваться небольшая модификация для подписанных операций

Вот пример вывода сборки из GCC на Godbolt

person phuclv    schedule 10.08.2014