aboutsummaryrefslogtreecommitdiffstats
path: root/notes.md
blob: cc051da9dea862cddddc416138f31b598d99da1f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
# RISC-V full size Instructions Formats (32bit):

## R-format: op(rs1, rs2) -> rd
`opcode[7] rd[5] funct3[3] rs1[5] rs2[5] funct7[7]`

register arithmetic/logical
opcode: 0b0110011 / 0x33

| funct7 | funct3 | operation |
|========|========|===========|
| 0x0    | 0x0    | ADD       |
| 0x20   | 0x0    | SUB       |
| 0x0    | 0x1    | SLL       |
| 0x0    | 0x2    | SLT       |
| 0x0    | 0x3    | SLTU      |
| 0x0    | 0x4    | XOR       |
| 0x0    | 0x5    | SRL       |
| 0x20   | 0x5    | SRA       |
| 0x0    | 0x6    | OR        |
| 0x0    | 0x7    | AND       |

## I-Format: op(rs1, imm12) -> rd
`opcode[7] rd[5] funct3[3] rs1[5] imm[12]`

load
opcode: 0b0000011 / 0x03

- rs1: base address
- imm12: offset (scaled/signed by funct3)

| funct3 | operation |     |
|========|===========|=====|
| 0x0    | LB        | i8  |
| 0x1    | LH        | i16 |
| 0x2    | LW        | i32 |
| 0x4    | LBU       | u8  |
| 0x5    | LHU       | u16 |


immediate arhitmetic/logical
opcode: 0b0010011 / 0x13

- rs1: base address
- imm12: offset (scaled/signed by funct3)

| funct3 | operation |                              |
|========|===========|==============================|
| 0x0    | ADDI      |                              |
| 0x2    | SLTI      |                              |
| 0x3    | SLTIU     |                              |
| 0x4    | XORI      |                              |
| 0x6    | ORI       |                              |
| 0x7    | ANDI      |                              |
| 0x1    | SLLI      | imm12 = 0b0000000 , shamt[5] |
| 0x5    | SRLI      | imm12 = 0b0000000 , shamt[5] |
| 0x5    | SRAI      | imm12 = 0b0100000 , shamt[5] |


jalr
opcode = 0b1100111 / 0x67

- rs1: base address
- imm12: offset (bytes)
- save PC+4 in rd
- jump to offset

## S-format: op(rs1, rs2, imm12)
`opcode[7] imm4:0[5] funct3[3] rs1[5] rs2[5] imm11:5[7]`

store
opcode: 0b0100011 / 0x23

- rs1: base address
- rs2: data
- imm12: offset (scaled/signed by funct3)

| funct3 | operation |                          |
|========|===========|==========================|
| 0x0    | SB        | i8,  imm12 in bytes      |
| 0x1    | SH        | i16, imm12 in half-words |
| 0x2    | SW        | i32, imm13 in words      |

## SB-format: op(rs1, rs2, imm12/13)
`opcode[7] imm11[1] imm4:1[4] funct3[3] rs1[5] rs2[5] imm10:5[6] imm12[1]`

branch
opcode = 0b1100011 / 0x63

- rs1, rs2: registers to compare
- imm12/13: PC offset in half-words

| funct3 | operation |
|========|===========|
| 0x0    | BEQ       |
| 0x1    | BNE       |
| 0x4    | BLT       |
| 0x5    | BGE       |
| 0x6    | BLTU      |
| 0x7    | BGEU      |

## U-Format: op(imm20/32) -> rd
`opcode[7] rd[5] imm31:12[20]`
upper-bit immediates (lui, auipc)

lui
opcode: 0b0110111 / 0x37

- imm20: top 20 bits of rd
- clears bottom 12 bits
- combine lui + addi to load 32bit immediate
  NOTE: sign extension requires some trickery.

auipc:
opcode: 0b0010111 / 0x17

- imm20: top 20 bits of offset added to PC
- result stored in rd

## J-Format: op(imm20/21) -> rd
`opcode[7] rd[5] imm31:12[20]`
immediates on a 32bit scale (jal)

jal
opcode = 0b1101111 / 0x6f

- save PC+4 in rd
- imm20/21: PC offset in half-words