Многоточная арифметика на MIPS - PullRequest
1 голос
/ 21 апреля 2010

Я просто пытаюсь реализовать многоточную арифметику на родном MIPS. Предположим, что одно 64-разрядное целое число находится в регистрах $ 12 и $ 13, а другое - в регистрах $ 14 и $ 15. Сумма должна быть внесена в регистры 10 и 11 долларов. Наиболее значимое слово из 64-битного целого находится в регистрах с четными номерами, а наименее значимое слово - в регистрах с нечетными номерами. В интернете говорится, что это самая короткая реализация.

addu  $11, $13, $15    # add least significant word
sltu  $10, $11, $15    # set carry-in bit 
addu  $10, $10, $12    # add in first most significant word
addu  $10, $10, $14    # add in second most significant word

Я просто хочу проверить, правильно ли я понимаю. Sltu проверяет, если сумма двух наименее значимых слов меньше или равна одному из операнды. Если это так, то почему произошел перенос, верно?

Для проверки наличия переноса при добавлении двух наиболее значимых слова и сохранить результат в $ 9, я должен сделать:

sltu  $9, $10, $12    # set carry-in bit 

Имеет ли это какой-то смысл?

1 Ответ

0 голосов
/ 22 апреля 2010

sltu проверяет, является ли сумма двух наименее значимых слов меньше или равна одному из операндов.

Не совсем: устанавливается $10 в 1, если сумма двух наименее значимых слов строго меньше, чем один из операндов (рассматривается как 32-разрядные значения без знака); и 0, если сумма равна или больше этого операнда.

Если это так, то когда произошел перенос, верно?

Да.

Рассмотрим, что может произойти при добавлении различных возможных значений b к некоторому конкретному значению a (где все является 32-разрядным значением без знака):

  • Если переполнение не произошло, мы должны иметь a <= sum <= 0xFFFFFFFF, поэтому 0 <= <em>b <= (0xFFFFFFFF - <em>a ) .
  • Остальные случаи для b вызывают переполнение; фактическая сумма в этих случаях должна быть 0x100000000 <= sum <= <em>a + 0xFFFFFFFF, что при усечении до 32 битов дает 0 <= sum <= <em>a - 1.

Чтобы проверить, произошел ли перенос, при добавлении двух наиболее значимых слов и сохранить результат в $ 9 Я должен сделать:

sltu $9, $10, $12 # set carry-in bit

Не совсем.

Проблема в том, что вы добавляете два 32-битных значения и , возможно, перенос из суммы наименее значимых слов. Например, рассмотрим случай, когда есть перенос, и оба наиболее значимых слова - 0xFFFFFFFF: сумма будет 1+ 0xFFFFFFFF + 0xFFFFFFFF = 0xFFFFFFFF, и поэтому перенос не будет установлен (но так и должно быть).

Один из способов справиться с этим - проверить наличие переноса после добавления $12 к $10 и повторить проверку после добавления $11 к этой сумме. Только одна из этих сумм может вызвать перенос ($12 + $10 переполняется только тогда, когда $12 равно 0xFFFFFFFF, поскольку $10 равно 0 или 1; в этом случае сумма равна 0, поэтому вторая сумма не может быть переполнена как хорошо).

Так что это может (отказ от ответственности: уже поздно, и это не проверено), добиваться цели:

addu $11, $13, $15
sltu $10, $11, $15  # carry from low word
addu $10, $10, $12
sltu  $9, $10, $12  # possible carry from high word (1)
addu $10, $10, $14
sltu  $8, $10, $14  # possible carry from high word (2)
or    $9,  $8,  $9  # carry in result if either (1) or (2) were true (can't both be true at once)
...