Набор непривилегированных инструкций RISC-V
Обзор инструкций
Простой пример
Для понимания принципа использования инструкций, рассмотрим простой пример, в котором используется только одна инструкция: addi rd, rs1, imm, которая добавляет константное целое imm (в диапазоне 12-ти битного знакового: -2048…2047) к содержимому регистра rs1 и записывает результат в регистр rd. Другими словами выполняется операция rd = rs1 + imm. После получения инструкции программный счётчик инкрементируется и будет содержать адрес следующей инструкции, что можно условно записать как pc = cp + 4, поскольку размер инструкции в машинном коде равен 4 байтам.
Инструкция addi x1, x0, 1 добавляет число 1 к значению 0, которое хранится в регистре x0 (в регистре x0 всегда хранится значение 0) и пишет результат, равный 1, в регистр x1. Машинный код инструкции addi x1, x0, 1 - это (в шестнадцатеричном представлении) 0x00100093. Префикс 0x перед числом показывает, что число задано в шестнадцатеричной системе счисления. Далее мы увидим, как именно работает кодирование чисел. По аналогии, инструкция addi x1, x1, 1 добавляет значение 1 к содержимому регистра x1 и записывает результат обратно в регистр x1. Машинный код этой инструкции - 0x00108093.
Теперь представим, что эти машинные коды располагаются в памяти начиная с адреса 0x0. Поскольку каждая инструкция занимает 4 байта, первая инструкция располагается по адресу 0x0, а вторая - по адресу 0x4. Программный счётчик указывает на начало исполняемого кода, следовательно, он равен значению 0x0:
Адрес Машинный код Инструкции 0x0 0x00100093 addi x1, x0, 1 0x4 0x00108093 addi x1, x1, 1
После запуска этих двух строк кода микропроцессор начинает выполнение с адреса 0x0. Как уже было объяснено выше, в результате выполнения первой строки в регистре x1 будет получено число 1, при этом программный счётчик будет инкрементирован до значения 0x4. Выполнение второй строки приведёт к увеличению значения регистра x1 на 1. Так как его значение было равно 1 в результате предыдущей операции, регистр после выполнения второй строки примет значение, равное 2.
На рис.3.1 показан пример того, как этот исходный код запускается в симуляторе Ripes.
Кодирование инструкций
Базовые целочисленные инструкции в микропроцессорах архитектуры RISC-V разделены на пять типов, каждый из которых имеет свой тип кодирования. Типы соответствуют задачам, выполняемым машинной инструкцией: R-type (register, регистр), I-type (immediate, непосредственное значение), S-type (store, хранение), B-type (branch, ветвление), U-type (upper immediate, верхнее непосредственное значение), и J-type (jump, переход). Таблица 3.3 ниже показывает принцип кодирования:
Рассмотрим предыдущий пример. Машинный код инструкции addi x1, x0, 1 - это значение 0x00100093. Побайтное представление кода может быть получено из таблицы выше, зная, что код операции равен 0x13, значение funct3 равно 0x0, и что код типа I (целочисленная операция).
Таким образом, машинный код инструкции addi x1, x0, 1 в побитовом представлении формируется следующим образом:
Поскольку каждые 4 бита могут быть объединены в шестнадцатеричное число, машинный код получается равным 0x00100093.
Арифметические и логические операции (с непосредственными значениями)
Приведённая ниже таблица 3.4 содержит инструкции, которые используют непосредственные данные. Программный счётчик обновляется после выполнения каждой инструкции и не приводится.
Инструкция | Тип | Формат | Код | funct3 | Описание |
---|---|---|---|---|---|
addi | ADD Immediate | I | 0010011 | 0x0 | rd = rs1 + imm |
xori | XOR Immediate | I | 0010011 | 0x4 | rd = rs1 ^ imm |
ori | OR Immediate | I | 0010011 | 0x4 | rd = rs1 | imm |
andi | AND Immediate | I | 0010011 | 0x7 | rd = rs1 & imm |
slli | Shift Left Logical Imm. | I | 0010011 | 0x1 | imm[11:5]=0x00, rd = rs1 << imm[4:0] |
srli | Shift Right Logical Imm. | I | 0010011 | 0x5 | imm[11:5]=0x00, rd = rs1 << imm[4:0] |
srai | Shift Right Arith. Imm. | I | 0010011 | 0x5 | imm[11:5]=0x20, rd = rs1 >> imm[4:0] |
slti | Set Less Than Imm. | I | 0010011 | 0x2 | rd = (rs1 < imm)? 0:1 |
sltiu | Set Less Than Imm. Un. | I | 0010011 | 0x3 | rd = (rs1 < imm)? 0:1 |