Лисья Нора

§ Набор инструкции

Чем хорош RISC-V, то это тем, что у него нет строго зафиксированного набора инструкции. То есть, они да, есть, некоторые базовые наборы, но благодаря модульности, их легко дополнять своими.
Самым базовым набором является RV32I, что означает "RISC-V 32-Integer". Это – самый минимум для того чтобы запустить программу любой сложности (включая даже DOOM – но тормозить он будет неистово). Есть и другие расширения и их немало. Например RV32IM к существующему набору из базовых инструкции добавляет инструкции умножения и деления. Все эти инструкции я буду реализовывать тоже (имею ввиду умножение и деление), но для начала потребуется создать именно основу.
Приведу список всех базовых инструкции, входящих в набор RV32I.
| 31 25 | 24 20 | 19 15 | 14 12 | 11 7 | 6 0 |
======+==============+=========+=========+=========+=============+==========+=======
mnem | funct7 | rs2 | rs1 | funct3 | rd | opcode | hex
======+==============+=========+=========+=========+=============+==========+=======
LUI | imm[31:12] | rd | 011_0111 | 37
AUIPC | imm[31:12] | rd | 001_0111 | 17
JAL | imm[20,10:1,11,19:12] | rd | 110_1111 | 6F
JALR | imm[11:0] | rs1 | 000 | rd | 110_0111 | 67
------+--------------+---------+---------+---------+-------------+----------+--------
BEQ | imm[12,10:5] | rs2 | rs1 | 000 | imm[4:1,11] | 110_0011 | 63:0
BNE | imm[12,10:5] | rs2 | rs1 | 001 | imm[4:1,11] | 110_0011 | 63:1
BLT | imm[12,10:5] | rs2 | rs1 | 100 | imm[4:1,11] | 110_0011 | 63:4
BGE | imm[12,10:5] | rs2 | rs1 | 101 | imm[4:1,11] | 110_0011 | 63:5
BLTU | imm[12,10:5] | rs2 | rs1 | 110 | imm[4:1,11] | 110_0011 | 63:6
BGEU | imm[12,10:5] | rs2 | rs1 | 111 | imm[4:1,11] | 110_0011 | 63:7
------+--------------+---------+---------+---------+-------------+----------+--------
LB | imm[11:0] | rs1 | 000 | rd | 000_0011 | 03:0
LH | imm[11:0] | rs1 | 001 | rd | 000_0011 | 03:1
LW | imm[11:0] | rs1 | 010 | rd | 000_0011 | 03:2
LBU | imm[11:0] | rs1 | 100 | rd | 000_0011 | 03:4
LHU | imm[11:0] | rs1 | 101 | rd | 000_0011 | 03:5
------+--------------+---------+---------+---------+-------------+----------+--------
SB | imm[11:5] | rs2 | rs1 | 000 | imm[4:0] | 010_0011 | 23:0
SH | imm[11:5] | rs2 | rs1 | 001 | imm[4:0] | 010_0011 | 23:1
SW | imm[11:5] | rs2 | rs1 | 010 | imm[4:0] | 010_0011 | 23:2
------+--------------+---------+---------+---------+-------------+----------+--------
ADDI | imm[11:0] | rs1 | 000 | rd | 001_0011 | 13:0
SLTI | imm[11:0] | rs1 | 010 | rd | 001_0011 | 13:2
SLTIU | imm[11:0] | rs1 | 011 | rd | 001_0011 | 13:3
XORI | imm[11:0] | rs1 | 100 | rd | 001_0011 | 13:4
ORI | imm[11:0] | rs1 | 110 | rd | 001_0011 | 13:6
ANDI | imm[11:0] | rs1 | 111 | rd | 001_0011 | 13:7
------+--------------+---------+---------+---------+-------------+----------+--------
SLLI | 0000000 | сдвиг | rs1 | 001 | rd | 001_0011 | 13:1
SRLI | 0000000 | сдвиг | rs1 | 101 | rd | 001_0011 | 13:5
SRAI | 0100000 | сдвиг | rs1 | 101 | rd | 001_0011 | 13:5
------+--------------+---------+---------+---------+-------------+----------+--------
ADD | 0000000 | rs2 | rs1 | 000 | rd | 011_0011 | 33:0
SUB | 0100000 | rs2 | rs1 | 000 | rd | 011_0011 | 33:0
SLL | 0000000 | rs2 | rs1 | 001 | rd | 011_0011 | 33:1
SLT | 0000000 | rs2 | rs1 | 010 | rd | 011_0011 | 33:2
SLTU | 0000000 | rs2 | rs1 | 011 | rd | 011_0011 | 33:3
XOR | 0000000 | rs2 | rs1 | 100 | rd | 011_0011 | 33:4
SRL | 0000000 | rs2 | rs1 | 101 | rd | 011_0011 | 33:5
SRA | 0100000 | rs2 | rs1 | 101 | rd | 011_0011 | 33:5
OR | 0000000 | rs2 | rs1 | 110 | rd | 011_0011 | 33:6
AND | 0000000 | rs2 | rs1 | 111 | rd | 011_0011 | 33:7
======+==============+=========+=========+=========+=============+==========+=======
Существуют также специальные инструкции такие как PAUSE, EBREAK, ECALL, которые кодируются точным указанием кода операции. На данный момент они пока не представляют интереса.
В таблице представлены 37 базовых инструкции, которых хватит на всё. Ну или почти всё. Есть некоторые инструкции, такие как работа с CSR (Control & State Register), который по своей идее похож на MSR в x86: он хранит конфигурацию процессора и вообще системы в целом. Существуют инструкции для загрузки и выгрузки данных оттуда, но об этом уже в следующих статьях.