Почему JALR кодирует младший бит смещения?

Мы знаем, что jal определяет 21-битное смещение. Однако он кодирует не 21-битное смещение, а 20-битное. Причина в том, что младший бит адреса всегда равен нулю, потому что минимально возможная инструкция RISC-V составляет 2 байта, поэтому этот бит не кодируется в инструкции.

Кодируя смещение таким образом, можно получить диапазон скачка ± 1 МБ. Если jal кодирует LSB, диапазон скачка составляет всего ± 512 КБ.

Однако инструкция jalr, которая определяет 12-битное смещение, кодирует LSB. Это уменьшает диапазон прыжка до ± 2киБ (вместо ± 4киБ). Я знаю, что jalr использует формат I-типа, который совпадает с addi, и для этого вида инструкций необходимо кодировать младший бит непосредственного значения. Однако я не вижу причин, по которым младший бит должен быть закодирован для jalr.


person Lui    schedule 25.12.2019    source источник
comment
В отличие от многих других подобных вопросов, я полагаю, что создатели этого набора инструкций все еще живы, и вы можете попытаться ответить на них. Поймите, что подобные решения не всегда являются техническими, это просто то, что они выбрали. Возможно, дальность не важна, реализация логики могла быть важнее, чем дальность прыжка. В любом случае этот путь был выбран кем-то, или собранием, или групповым мнением, и не обязательно иметь техническую / фиксированную / разумную причину.   -  person old_timer    schedule 26.12.2019
comment
Имена авторов должны быть указаны в спецификации risc-v. Вы можете связаться с одним или несколькими из них напрямую, чтобы задать вопрос, основанный на мнении.   -  person old_timer    schedule 26.12.2019


Ответы (2)


JALR используется для двух относительно разных целей:

  • indirect branches, e.g.
    • function return
    • косвенные вызовы функций (например, указатели функций; vtables / виртуальная диспетчеризация) и,
  • средние и дальние переходы (в последовательности из двух инструкций, с 32-битным диапазоном, относящимся к компьютеру).

Для первых, непрямых ветвей, непосредственное значение всегда равно 0, что означает, что фактически немедленное выполнение не используется вообще!

Для последнего эта инструкция используется вместе с AUIPC, который формирует верхние 20 битов относительной адресации компьютера, а затем JALR используется вместе для формирования младших 12 битов для общего смещения относительно компьютера 32- биты.

Однако AUIPC используется как для удаленных ветвей, так и для доступа к данным, относящимся к компьютеру. Таким образом, они оба разделяют 12-битное смещение - загрузка / сохранение использует их 12-битное немедленное выполнение, а JALR - следуя примеру, также используя 12-битное поле немедленного действия, точно так же, как загрузка и сохранение. Разработчики решили использовать AUIPC вместо двух разных AUIPC для этих двух применений (ссылка от кода к коду и ссылка от кода к данным).

Таким образом, диапазон JALR в основном не важен, если он может предоставить оставшиеся 12 битов для дополнения 20 битов AUIPC. Конечно, есть и другие подходы, но у этого есть то преимущество, что оно состоит из повторного использования и требует только одной AUIPC инструкции.

person Erik Eidt    schedule 25.12.2019

Обоснование изложено в спецификации RISC-V:

Обратите внимание, что инструкция JALR не обрабатывает 12-битные данные сразу как кратные 2 байтам, в отличие от инструкций условного перехода. Это позволяет избежать еще одного аппаратного форматирования. На практике в большинстве случаев использования JALR либо сразу устанавливается ноль, либо в сочетании с LUI или AUIPC, поэтому небольшое сокращение диапазона несущественно.

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

person phuclv    schedule 27.08.2020