Расширяя или избегая addiu в MIPS - PullRequest
3 голосов
/ 05 июля 2019

Я реализовал программу (полностью подключенный слой) на C, которую нужно скомпилировать в MIPS для запуска на конкретном микропроцессоре, чтобы протестировать функцию микропроцессора.Поскольку инструкция ADDIU не является частью набора команд этого процессора, я редактирую программу на C, чтобы во время компиляции выдавать меньше инструкций ADDIU, и пытаюсь отредактировать оставшиеся из кода MIPS (ADD и ADDU разрешены).Тем не менее, я новичок в MIPS и хочу убедиться, что мои изменения не меняют функции программы.Есть ли расширение для ADDIU с использованием других инструкций?Если нет, есть идеи, как мне изменить логику моей программы, чтобы избежать их использования?

Я занимаюсь разработкой теста для конкретного микропроцессора с ограниченным набором инструкций MIPS.Многие проблемные инструкции в скомпилированном коде могут быть расширены для использования только инструкций из набора, поэтому я отредактирую скомпилированный код, чтобы включить эти расширения.Тем не менее, ADDIU, похоже, не имеет расширения в соответствии с руководствами по расширению, которые я видел.

Я уже избавился от некоторых инструкций ADDIU, сохранив часто используемые значения в качестве констант, чтобы я мог обратиться кпеременные вместо литералов в остальной части кода C, что приводит к инструкциям ADDU (которые разрешены).Инструкции ADDIU, которые я испытываю при редактировании, возникают в следующих местах:

  1. Управление или доступ к значениям указателей стека и фрейма.Я думал о жестком кодировании аддендов как констант, но я не уверен, возможно ли это или это изменит значения, о которых идет речь.
    e.g. addiu   $sp,$sp,-3840
    e.g. addiu   $3,$fp,52
Доступ к верхним / нижним частям 32-битных целых по отдельности с использованием% hi и% lo и сложение их вместе
e.g.    lui     $2,%hi(output_layer.3511)
        addiu   $2,$2,%lo(output_layer.3511)

Примечание: output_layer - это массив 32-битных целых.

Дополнительные инструкции, которые появляются, когда я компилирую функцию "mod" в C (расширение функции mod для получения остатка "трудным путем" не помогло) Например, fracPart = currentInput % 256; в C компилируется в
lw      $3,40($fp)
        li      $2,-2147483648                  # 0xffffffff80000000
        ori     $2,$2,0xff
        and     $2,$3,$2
        bgez    $2,$L17
        nop

        addiu   $2,$2,-1
        li      $3,-256           # 0xffffffffffffff00
        or      $2,$2,$3
        addiu   $2,$2,1
$L17:
        sw      $2,48($fp)

Целью является работа кода MIPS, который содержит только инструкции в наборе команд этого конкретного микропроцессора, который не включает ADDIU.

Ответы [ 2 ]

1 голос
/ 05 июля 2019

Аддиу и Адди почти идентичны. Единственное отличие состоит в том, что addi генерирует исключение при переполнении в дополнении, в то время как addiu не генерирует переполнение.

Итак, вы можете заменить все addiu на addi.

Управление или доступ к значениям указателей стека и кадра. Я думал о жестком кодировании аддендов как констант, но я не уверен, возможно ли это или это изменит значения.

Нет проблем заменить addi на addi. Никакое вменяемое программное обеспечение не может создать адреса в sp / fp, которые могут вызвать переполнение в этой ситуации

Доступ к верхним / нижним частям 32-разрядных целых чисел по отдельности с использованием% hi и% lo и сложение их вместе

Вы можете использовать addi, но люди обычно используют ori для этой операции.

lui     $2,%hi(output_layer.3511)
ori     $2,$2,%lo(output_layer.3511)

В любом случае риск переполнения отсутствует (поскольку 16 LSB очищаются с помощью lui), а addi, addiu и ori строго эквивалентны.

Дополнительные инструкции, которые появляются, когда я компилирую функцию "mod" в C (расширение функции mod для получения остатка "трудным путем" не помогло), например. fracPart = currentInput% 256; в Си компилируется в

   lw      $3,40($fp)
   li      $2,-2147483648                  # 0xffffffff80000000
   ori     $2,$2,0xff
   and     $2,$3,$2
   bgez    $2,$L17
   nop

   addiu   $2,$2,-1
   li      $3,-256           # 0xffffffffffffff00
   or      $2,$2,$3
   addiu   $2,$2,1
$L17:
   sw      $2,48($fp)

Этот код кажется очень странным. Почему бы не заменить две строки (li + ori) на

    li      $2, 0xffffffff800000ff

Последняя часть (после bgez) выполняется только строго отрицательными числами и для них она эквивалентна or с 0xffffffffffffff00, и пара addiu кажется бесполезной ...
В любом случае их также можно заменить на addi.

EDIT:

Если addi недоступен, вы можете скопировать немедленный в бесплатный регистр, а затем выполнить добавление / addu с этим регистром. В большинстве соглашений MIPS $ 1 используется для хранения временных значений asm и никогда используется компиляторами. Так что вы можете свободно использовать его (при условии, что вы не используете макросы, которые могут использовать этот регистр).

Систематический перевод addiu может быть

    addiu $d, $s, imm
## ->
    ori   $1, $0, imm
    add   $d, $s, $1

И ori, и add являются настоящими инструкциями, и 1 доллар можно безопасно использовать. В некоторых ассемблерах вы должны использовать $ at (временный ассемблер) вместо $ 1.

0 голосов
/ 05 июля 2019

Я работаю в лаборатории, которая разрабатывает новые микропроцессоры, так что этот микроэлемент не является коммерчески доступным.

Согласно моему пониманию, основанному на вашем утверждении, компилятор также находится в стадии разработки.Вам следует обсудить эту проблему с командой, разрабатывающей компилятор, чтобы они могли учесть ваши потребности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...