Почему MIPS включает шамт и различает функцию / код операции?

15

Меня смущает, почему разработчики MIPS включают 5 бит, предназначенных для сдвига, и имеют отдельные биты кода операции и функции.

Поскольку MIPS является настолько RISC, я предполагаю, что в нескольких инструкциях будет выполнено только смещение, поэтому эти 5 бит кажутся бесполезными, когда их можно сразу же поместить. Я предполагаю, что коды операций и функции раздельно используются для различения команд R и I-типа, но это можно сделать, расширив код операции на 1 бит. С обеими этими инструкциями R-типа длина может быть 22 бита. Это не сработает, если инструкции I-типа и J-типа хотят сохранить свои немедленные адреса и адреса, но обе они кажутся ненужными.

qwr
источник

Ответы:

10

Здесь происходит несколько разных компромиссов.

Во-первых, мы хотим, чтобы инструкции были фиксированной ширины (32 бита). Это гарантирует, что инструкции выровнены по кеш-блокам и страницам, что упрощает проверку наличия и доступа к кешу и страницам.

Во-вторых, мы хотим, чтобы различные поля инструкций ( opcode/ source regs/ immediates) были фиксированной ширины и фиксированной позиции. Это делает их быстрее / меньше логики для декодирования, и они необходимы на ранних стадиях конвейера. ( destinationРегистр не нужен до конца конвейера, поэтому он может находиться в разных местах Rи в Iинструкциях.) Положение и ширина functionполя имеют значение немного меньше, потому что для этого нужно контролировать функцию ALU, но это на третьем этапе конвейера, так что у вас есть немного времени для работы с ним, если это необходимо.

IJJ228228Iинструкция также хороша для авторов компиляторов / компоновщиков. (На SPARC, где непосредственное поле было только 12 битами, они должны были добавить целый специальный load-highкласс команд с 20-битным немедленным.)

26знак равно64JRI

Но это оставляет некоторое пространство для маневра с Rинструкциями. Помимо 6-битного кода операции, им требуется только 15 дополнительных битов для спецификации регистра, что оставляет 11 битов для расширенного кода операции и / или величины сдвига.

Вы должны думать о functionполе как о расширенном коде операции для Rинструкции. Существует только один Rкод операции инструкции, но есть 64 различных варианта functionsвыполнения Rинструкции.

Ладно. У нас есть 60 разных Iинструкций и 64 разных Rинструкции, так куда же нам поместить инструкции для смены?

Ну, не только меньше Iинструкций, но есть и другие вещи, которые мы хотим сделать с I инструкциями. Напомним, что все инструкции перехода должны быть Iинструкциями, поскольку они имеют относительное (немедленное) смещение. Также все инструкции по загрузке и хранению Iотформатированы в MIPS. И, наконец, нам нужно, чтобы инструкция загрузки-немедленного была Iинструкцией. Не только это, но и Rинструкции по-прежнему имеют 5 дополнительных неиспользуемых битов (что нам нужно для немедленной смены-немедленного в этой архитектуре), так что это дает дополнительный стимул для превращения сменных немедленных в специальные (странные) Rинструкции ,

Многие из этих решений - больше искусство, чем наука, но есть основополагающая логика, которую можно различить. Цель ключ не сделать число инструкций как можно, это сделать высокопроизводительнуюконвейерная сборка на одном чипе (так что крошечные компании, такие как MIPS и Sun в 1980-х годах, могли конкурировать с IBM и DEC). (Название RISC, придуманное Дэвидом Паттерсоном, несколько неудачно. Оно завоевало популярность, потому что это было мило, а не потому, что «сокращенные инструкции» - это точное описание того, что архитектуры MIPS и SPARC действительно пытались сделать.) Итак, вы хотите инструкции фиксированной ширины (и относительно малы, чтобы вы могли улучшить поведение I-кэша), чтобы упростить и ускорить выборку, разбиение на страницы и декодирование. Вы хотите, чтобы части инструкции, которые должны быть декодированы рано (opcode, два исходных регистра и знак с немедленным расширением) должны быть фиксированной ширины и фиксированной позиции. Вы хотите, чтобы немедленные действия были как можно дольше, и вы хотите столько разных видов инструкций, сколько будет соответствовать, учитывая все эти другие ограничения.

Блуждающая логика
источник
Спасибо за ваш информативный ответ, особенно часть о целях дизайнеров архитектуры. Мне интересно сравнить MIPS с MOS 6502, потому что, если я правильно понимаю, у 6502 никогда не было шамта (я все еще пытаюсь понять форматы инструкций).
qwr
1
6502 был микропроцессором первого поколения (pre-CISC), хотя он и предполагал конвейерную обработку, поскольку он мог выполнять обратную запись в регистр одновременно с загрузкой следующей инструкции. У 6502 были байтовые операционные коды, как у большинства 8-битных микро. Другой архитектурой, которую следует рассмотреть, является ARM, который был разработан группой высококвалифицированных инженеров-электронщиков, которые прочитали документы RISC Беркли и посетили фабрику MOS и решили: «Эй, мы можем это сделать».
псевдоним
Интересно, каковы были бы последствия, если бы существовал шаблон битов шамта, который означал «не выполняйте следующую инструкцию, а используйте 32 бита, которые были для нее извлечены, в качестве исходного операнда для этой инструкции»? В качестве альтернативы или дополнения, я хотел бы знать, было бы целесообразно иметь достаточно места для кода операции, выделенного для пар простых непрерывных инструкций - концепция, отчасти похожая на Thumb, но свободно перемежаемая с 32-битными инструкциями и без возможности перейти сразу ко второй инструкции слова?
суперкат
5

Чтобы понять форматы команд MIPS I, вам нужно понять конвейер MIPS, а также вспомнить технологию реализации ЦП около 1985 года. Если вы посмотрите на диаграмму (вы знаете одну), вы увидите, что чтение файла регистра находится в ID этап, сразу после IF.

Для целей инструкции R-типа на этапе идентификации необходимо выполнить следующие задачи:

  1. Определить , что это на самом деле является инструкцией R-типа.
  2. Если это так, скажите файлу регистров загрузить значения из регистров.

Для целей этого обсуждения это первое задание, о котором вам нужно подумать. Если вам нужно проделать большую работу по декодированию команд, чтобы даже отработать, если вам нужны какие-либо значения из регистров, это увеличивает задержку, прежде чем вы сможете начать чтение регистров. Это также увеличивает сложность этапа идентификации. Резервируя один код операции для всех команд R-типа, вы сводите сложность к минимуму.

Кажется немного странным, что вы посвящаете пять бит просто переключению. Я могу придумать несколько возможных объяснений. Во-первых, это упрощает маршрутизацию (эти пять битов ВСЕГДА подаются прямо в регистровый файл, эти пять битов ВСЕГДА подаются в устройство сдвига ствола, эти шесть битов ВСЕГДА направляются в АЛУ, чтобы определить, какую функцию выполнять).

Возможно, они думали о введении комбинированных команд shift-left-and-add в будущем. Это предположительно будет иметь вид:

$d = $s + ($t << shamt)

2s+1s

Сегодня, вероятно, мы бы дважды не задумывались о том, чтобы иметь более сложную стадию декодирования, тем более что обращения к файлам регистров, как правило, происходят позже в конвейере типичного суперскалярного ЦП. Многие современные процессоры даже выполняют грубое декодирование команд во время вставки команды в кэш L1 . Вы делаете линии I-кеша на несколько бит шире, чтобы хранить дополнительную информацию (благодаря закону Мура у вас много транзисторов, чтобы тратить впустую), чтобы сделать «правильное» декодирование команд проще и быстрее.

Одна из причин, по которой они, вероятно, хотели, чтобы поле кода операции было как можно меньшим, заключается в том, чтобы оно не влекло за собой чрезмерное наказание за команды J-типа. Как вы, вероятно, знаете, инструкции типа J используют псевдо-прямую адресацию. Для тех, кто играет дома, я кратко объясню.

Поле адреса инструкции J-типа составляет 26 бит. Поскольку инструкции всегда выровнены по 4 байта, вам не нужно хранить младшие два бита, что означает, что у вас фактически есть 28-битный адрес. Однако адресное пространство в MIPS I составляет 32 бита. Таким образом, верхние четыре бита местоположения перехода взяты из счетчика программы.

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

lui $r,target >> 16
    ori $r,$r,target & 0xFFFF
    jr $r

Сегодня это не так уж и плохо, но в 1985 году было много тактов.

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

Псевдоним
источник
"комбинированные инструкции shift-left-and-add" того типа, который позже можно увидеть в ARM?
Дамиан Йеррик