Архитектура RISC-V
| Imm[11:0] | rs1 | funct3 | rd | opcode | I-type | |
|---|---|---|---|---|---|---|
Rd = rs1+imm NOP encoded as ADDI x0, x0, 0. |
imm[11:0] | rs1 | 000 | rd | 0010011 | ADDI |
Rd= 1 if Rs< imm else 0 |
imm[11:0] | rs1 | 010 | rd | 0010011 | SLTI |
Rd= 1 if Rs< uimm else 0 |
imm[11:0] | rs1 | 011 | rd | 0010011 | SLTIU |
Rd = rs1 XOR imm |
imm[11:0] | rs1 | 100 | rd | 0010011 | XORI |
Rd = rs1 OR imm |
imm[11:0] | rs1 | 110 | rd | 0010011 | ORI |
Rd = rs1 AND imm |
imm[11:0] | rs1 | 111 | rd | 0010011 | ANDI |
Rd = @(Rs1 + imm) 8bit |
imm[11:0] | rs1 | 000 | rd | 0000011 | LB |
Rd = @(Rs1 + imm) 16bit |
imm[11:0] | rs1 | 001 | rd | 0000011 | LH |
Rd = @(Rs1 + imm) 32bit |
imm[11:0] | rs1 | 010 | rd | 0000011 | LW |
Rd = @(Rs1 + imm) 8bit zero ext |
imm[11:0] | rs1 | 100 | rd | 0000011 | LBU |
Rd = @(Rs1 + imm) 16bit zero ext |
imm[11:0] | rs1 | 101 | rd | 0000011 | LHU |
Rd = pc+4 PC= Rs + imm&0xFFE |
imm[11:0] | rs1 | 000 | rd | 1100111 | JALR |
Операции регистр-регистр
Группа регистровых операций (R-типа). (Собственно, то что RISC-машины должны уметь делать лучще всего.) Интересно, что поля опкодов и коды функций(3битные) операций сложения и вычитания, а также сдвигов и арифметических сдвигов одинаковы, и отличаются только значениями поля funct7. Это может быть полезно как при построении дешифратора команд, так и АЛУ процессорного ядра.
| funct7 | rs2 | rs1 | funct3 | rd | opcode | R-type | |
|---|---|---|---|---|---|---|---|
Rd = Rs1 + Rs2 |
0000000 | rs2 | rs1 | 000 | rd | 0110011 | ADD |
Rd = Rs1 - Rs2 |
0100000 | rs2 | rs1 | 000 | rd | 0110011 | SUB |
Rd = Rs1 + Rs2 |
0000000 | rs2 | rs1 | 001 | rd | 0110011 | SLL |
Rd= 1 if Rs1 < Rs2 else 0 |
0000000 | rs2 | rs1 | 010 | rd | 0110011 | SLT |
Rd= 1 if Rs1 < Rs2 else 0(unsign) SLTU rd, x0, rs2 sets rd to 1 if rs2 is not equal to zero |
0000000 | rs2 | rs1 | 011 | rd | 0110011 | SLTU |
Rd = Rs1 XOR Rs2 |
0000000 | rs2 | rs1 | 100 | rd | 0110011 | XOR |
Rd = Rs1 << Rs2 |
0000000 | rs2 | rs1 | 101 | rd | 0110011 | SRL |
Rd = Rs1 >> Rs2 (sign ext) |
0100000 | rs2 | rs1 | 101 | rd | 0110011 | SRA |
Rd = Rs1 OR Rs2 |
0000000 | rs2 | rs1 | 110 | rd | 0110011 | OR |
Rd = Rs1 AND Rs2 |
0000000 | rs2 | rs1 | 111 | rd | 0110011 | AND |
Rd = Rs1 << imm |
0000000 | shft | rs1 | 001 | rd | 0010011 | SLLI |
Rd = Rs1 >> imm (0 ext) |
0000000 | shft | rs1 | 101 | rd | 0010011 | SRLI |
Rd = Rs1 >> imm (sign ext) |
0100000 | shft | rs1 | 101 | rd | 0010011 | SRAI |
Команды условных переходов
Все инструкции перехода используют формат команд B-типа. 12-разрядный B-immediate со знаком (выравнивание по границе 2 байт), и добавляется к текущему PC для получения целевого адреса. Условный диапазон перехода составляет 4 Кб.
| imm[12|10:5] | rs2 | rs1 | funct3 | imm[4:1|11] | opcode | B-type | |
|---|---|---|---|---|---|---|---|
If (Rs1 == Rs2)
Pc=Pc+imm &0xFFE |
imm[12|10:5] | rs2 | rs1 | 000 | imm[4:1|11] | 1100011 | BEQ |
If (Rs1 != Rs2)
Pc=Pc+imm &0xFFE |
imm[12|10:5] | rs2 | rs1 | 001 | imm[4:1|11] | 1100011 | BNE |
If (Rs1 <Rs2)
Pc=Pc+imm &0xFFE |
imm[12|10:5] | rs2 | rs1 | 100 | imm[4:1|11] | 1100011 | BLT |
If (Rs1 >Rs2)
Pc=Pc+imm &0xFFE |
imm[12|10:5] | rs2 | rs1 | 101 | imm[4:1|11] | 1100011 | BGE |
If (Rs1 <Rs2) -usign
Pc=Pc+imm &0xFFE |
imm[12|10:5] | rs2 | rs1 | 110 | imm[4:1|11] | 1100011 | BLTU |
If (Rs1 >Rs2) -usign
Pc=Pc+imm &0xFFE |
imm[12|10:5] | rs2 | rs1 | 111 | imm[4:1|11] | 1100011 | BGEU |
Инструкции записи в память - S-тип.
Инструкции SW, SH и SB сохраняют в памяти 32-разрядные, 16-разрядные и 8-разрядные значения из младших разрядов регистра rs2.
Для достижения наилучшей производительности эффективный адрес для всех загрузок и хранилищ должен быть естественным образом выровнен для каждого типа данных (т.е. по четырехбайтовой границе для 32-разрядных обращений и двухбайтовой границе для 16-разрядных обращений) - выравнивание - забота компилятора. Базовый ISA поддерживает несогласованные обращения, но они могут выполняться чрезвычайно медленно в зависимости от реализации. Кроме того, гарантируется естественное выравнивание загрузки и сохранения для выполнения атомарно, в то время как несогласованные загрузки и хранилища могут и не выполняться, и, следовательно, требуется дополнительная синхронизация для обеспечения атомарности.
| imm[11:5] | rs2 | rs1 | funct3 | imm[4:0] | opcode | S-type | |
|---|---|---|---|---|---|---|---|
[rs1+imm]=rs2(byte) |
imm[11:5] | rs2 | rs1 | 000 | imm[4:0] | 0100011 | SB |
[rs1+imm]=rs2(half) |
imm[11:5] | rs2 | rs1 | 001 | imm[4:0] | 0100011 | SH |
[rs1+imm]=rs2(word) |
imm[11:5] | rs2 | rs1 | 010 | imm[4:0] | 0100011 | SW |
Загрузка "длинных" непосредственных значений в регистры
Основная "почти" головная боль ISA с фиксированной длиной команд - это загрузка или передача в регистры непосредственные значения (immediate) , особенно это касается "больших" значений, которые могут быть или просто большими числовами константами, или адресами памяти.
LUI (load upper immediate) используется для построения 32-разрядных констант и использует формат U-типа. LUI помещает значение U-immediate в верхние 20 бит регистра назначения Rd, заполняя младшие 12 бит нулями. (желаемое 32-битное значение может быть.
AUIPC (add upper immediate to pc) используется для построения относительных к PC адресов и использует формат U-type. AUIPC формирует 32-разрядное число из 20-разрядного U-immediate, заполняя младшие 12 бит нулями и добавляя его к значению PC, затем помещает результат в регистр rd.
| imm[31:12] | rd | opcode | U-type | |
|---|---|---|---|---|
![]() |
imm[31:12] | rd | 0110111 | LUI |
![]() |
imm[31:12] | rd | 0010111 | AUIPC |
Инструкция AUIPC поддерживает последовательности из двух команд для доступа к произвольным наборам данных с ПК как для передачи потока управления, так и для доступа к данным. Комбинация AUIPC и 12-разрядного immediate в JALR может передавать управление на любой 32-разрядный адрес, относящийся к ПК, в то время как AUIPC плюс 12-разрядный immediate, установленный в обычных инструкциях загрузки или сохранения, могут получать доступ к любому 32-разрядному адресу данных, относящемуся к ПК.
Безусловные переходы
Инструкция jump and link (JAL) использует формат J-типа, где J-immediate - знаковое смещение, кратное 2 байтам. Смещение прибавлется к программному счетчику для формирования целевого адреса перехода. Таким образом, переходы могут совершаться в пределах 1 Мб от текущего адреса.
JAL также сохраняет адрес инструкции, следующей за переходом (pc+4), в регистре rd. Стандартное соглашение о вызове программного обеспечения использует x1 в качестве регистра обратного адреса и x5 в качестве альтернативного регистра связи.
Простой безусловный переход без сохранения адреса возврата осуществляется, если в качестве регистра указан x0 - такая операция в ассемблере идет как псевдооперация J.
| Imm[20|10:1|11|19:12] | rd | opcode | J-type | |
|---|---|---|---|---|
Rd = PC + 4 PC = PC + imm |
imm[20|10:1|11|19:12] | rd | 1101111 | JAL |
Набор инструкций для работы с регистрами специального назначения
Формально набор инструкций для работы с регистрами специального назначения относится к расширению Zicsr.
Инструкция CSRRW (Atomic Read/Write CSR) атомарно меняет местами значения в регистре CSRS и целочисленном регистре. CSRRW считывает старое значение CSR, нулями-расширяет значение до полной целочисленной разрядности, затем записывает его в целочисленный регистр Rd. Значение из Rs1 записывается в CSR. Если Rd=x0, то команда не должна считывать CSR и не должна вызывать никаких побочных эффектов, которые могут возникнуть при считывании CSR.
Инструкция CSRRS (Атомарные биты чтения и установки в CSR) считывает значение CSR, нулями-расширяет значение до полной целочисленной разрядности и записывает его в целочисленный регистр Rd. Начальное значение в целочисленном регистре Rs1 обрабатывается как битовая маска, которая определяет позиции битов, которые должны быть установлены в CSR. Любой бит, имеющий высокое значение в Rs1, приведет к установке соответствующего бита в CSR, если этот бит CSR доступен для записи. Другие биты в CSR не затрагиваются (хотя CSR могут иметь побочные эффекты при записи).
Инструкция CSRRC (Атомарные биты чтения и очистки в CSR) считывает значение CSR, обнуляет значение до X битов LEN и записывает его в целочисленный регистр rd. Начальное значение в целочисленном регистре Rs1 обрабатывается как битовая маска, которая определяет позиции битов, подлежащие сбросу в CSR. Любой бит, имеющий высокое значение в Rs1, приведет к очистке соответствующего бита в CSR, если этот бит CSR доступен для записи. Другие биты в CSR не затронуты.
Варианты CSRRWI, CSRRSI и CSRRCI аналогичны CSR, CSRRS и CSRRC соответственно, за исключением того, что они обновляют CSR, используя полноразрядное значение, полученное путем расширения нулями 5-разрядного поля без знака uimm[4:0], закодированного в поле rs1, вместо значение из целочисленного регистра.
Для CSRRSI и CSRRCI, если поле uimm[4:0] равно нулю, то эти инструкции не будут выполнять запись в CSR и не вызовут никаких побочных эффектов, которые в противном случае могли бы возникнуть при записи CSR. Для CSRRWI, если rd=x0, то инструкция не должна считывать CSR и не должна вызывать никаких побочных эффектах, которые могут возникнуть при чтении CSR.
RV32I предоставляет ряд 64-разрядных счетчиков пользовательского уровня, доступных только для чтения, которые отображаются в 12-разрядное адресное пространство CSR и доступны в 32-разрядных фрагментах с использованием инструкций CSRRS.
| Работа со спец.регистрами | ||||||
|---|---|---|---|---|---|---|
| Адрес спец.регистра (12 бит) | Регистр источник | Регистр Приемник | Опкод | |||
Rd= CSR CSR = Rs1 |
csr | rs1 | 001 | Rd | 1110011 | CSRRW |
Rd= CSR CSR = CSR or Rs1 |
csr | rs1 | 010 | Rd | 1110011 | CSRRS |
Rd= CSR CSR = CSR and (~Rs1) |
csr | rs1 | 011 | Rd | 1110011 | CSRRC |
Rd= CSR CSR = zimm |
csr | zimm | 101 | Rd | 1110011 | CSRRWI |
Rd= CSR CSR = CSR or zimm |
csr | zimm | 110 | Rd | 1110011 | CSRRSI |
Rd= CSR CSR = CSR and (~zimm) |
csr | zimm | 111 | rd | 1110011 | CSRRCI |
![Rd = imm[31:12][0_{12}]](/sites/default/files/tex_cache/dc6f8721919074723a7a785656ccbd79.png)
![Rd=PC+ imm[31:12] [0_{12}]](/sites/default/files/tex_cache/53a5a99ec65cf6e649bf7efd1bfea04f.png)