diff options
Diffstat (limited to 'doc/spec/isa_reference.md')
| -rw-r--r-- | doc/spec/isa_reference.md | 899 |
1 files changed, 899 insertions, 0 deletions
diff --git a/doc/spec/isa_reference.md b/doc/spec/isa_reference.md new file mode 100644 index 0000000..ab7b1da --- /dev/null +++ b/doc/spec/isa_reference.md @@ -0,0 +1,899 @@ +--- +title: "Fyntv Instruction Set Architecture" +subtitle: "Reference Manual" +version: "0.0.0.1" +date: "June 2026" +status: "Draft" +geometry: margin=1in +toc: true +numbersections: true +--- + +\newpage + +# Revision History + +| Version | Date | Description | +|---------|------|-------------| +| 0.0.0.1 | June 2026 | Initial Fyntv release | + +\newpage + +\tableofcontents + +\newpage + +# Introduction + +This document defines the **Fyntv Instruction Set Architecture (ISA)** version 0.0.0.1. + +## Scope + +This specification covers: + +- Instruction formats and encoding +- Register file and calling convention +- All base and extension instructions +- Control and status registers (CSRs) +- Exception and trap handling + +## ISA Overview + +The Fyntv ISA is a load-store architecture with: + +- 32 general-purpose registers (x0–x31) +- Fixed-width 32-bit instructions +- Three operand formats: register (R-type), immediate (I-type), and store (S-type) +- Branch (B-type) and upper-immediate (U-type) variants +- A separate jump-and-link (J-type) format + +\newpage + +# Registers + +## General-Purpose Registers + +The architecture provides 32 general-purpose registers (x0–x31), each 32 bits wide. Register x0 is hardwired to the constant zero. + +| Register | ABI Name | Description | Callee-Saved | +|----------|----------|-------------|--------------| +| x0 | zero | Always-zero register — reads return 0, writes are discarded | — | +| x1 | ra | Return address link register | No | +| x2 | sp | Stack pointer | Yes | +| x3 | gp | Global pointer | Yes | +| x4 | tp | Thread pointer | Yes | +| x5 | t0 | Temporary register 0 | No | +| x6 | t1 | Temporary register 1 | No | +| x7 | t2 | Temporary register 2 | No | +| x8 | s0 | Saved register 0 / frame pointer | Yes | +| x9 | s1 | Saved register 1 | Yes | +| x10 | a0 | Function argument 0 / return value 0 | No | +| x11 | a1 | Function argument 1 / return value 1 | No | +| x12 | a2 | Function argument 2 | No | +| x13 | a3 | Function argument 3 | No | +| x14 | a4 | Function argument 4 | No | +| x15 | a5 | Function argument 5 | No | +| x16 | a6 | Function argument 6 | No | +| x17 | a7 | Function argument 7 | No | +| x18 | s2 | Saved register 2 | Yes | +| x19 | s3 | Saved register 3 | Yes | +| x20 | s4 | Saved register 4 | Yes | +| x21 | s5 | Saved register 5 | Yes | +| x22 | s6 | Saved register 6 | Yes | +| x23 | s7 | Saved register 7 | Yes | +| x24 | s8 | Saved register 8 | Yes | +| x25 | s9 | Saved register 9 | Yes | +| x26 | s10 | Saved register 10 | Yes | +| x27 | s11 | Saved register 11 | Yes | +| x28 | t3 | Temporary register 3 | No | +| x29 | t4 | Temporary register 4 | No | +| x30 | t5 | Temporary register 5 | No | +| x31 | t6 | Temporary register 6 | No | + +### ABI Calling Convention + +| Register | ABI Name | Caller-Saved | Argument | +|----------|----------|-------------|----------| +| x0 | zero | No | No | +| x1 | ra | No | No | +| x2 | sp | No | No | +| x3 | gp | No | No | +| x4 | tp | No | No | +| x5 | t0 | Yes | No | +| x6 | t1 | Yes | No | +| x7 | t2 | Yes | No | +| x8 | s0 | No | No | +| x9 | s1 | No | No | +| x10 | a0 | Yes | Yes | +| x11 | a1 | Yes | Yes | +| x12 | a2 | Yes | Yes | +| x13 | a3 | Yes | Yes | +| x14 | a4 | Yes | Yes | +| x15 | a5 | Yes | Yes | +| x16 | a6 | Yes | Yes | +| x17 | a7 | Yes | Yes | +| x18 | s2 | No | No | +| x19 | s3 | No | No | +| x20 | s4 | No | No | +| x21 | s5 | No | No | +| x22 | s6 | No | No | +| x23 | s7 | No | No | +| x24 | s8 | No | No | +| x25 | s9 | No | No | +| x26 | s10 | No | No | +| x27 | s11 | No | No | +| x28 | t3 | Yes | No | +| x29 | t4 | Yes | No | +| x30 | t5 | Yes | No | +| x31 | t6 | Yes | No | + +\newpage + +# Instruction Formats + +Instructions are encoded in one of several fixed formats. All formats share the same opcode placement (bits 6:0) to allow efficient decoding. + +### R-Type Format + +Bit width: **32 bits** + +``` + 31:25 |24:20|19:15|14:12|11:7| 6:0 +funct7 | rs2 | rs1 |funct3| rd |opcode + 7 | 5 | 5 | 3 | 5 | 7 +``` + +### I-Type Format + +Bit width: **32 bits** + +``` + 31:20 |19:15|14:12|11:7| 6:0 + imm | rs1 |funct3| rd |opcode + 12 | 5 | 3 | 5 | 7 +``` + +### S-Type Format + +Bit width: **32 bits** + +``` + 31:25 |24:20|19:15|14:12|11:7| 6:0 +imm_hi | rs2 | rs1 |funct3|imm_lo|opcode + 7 | 5 | 5 | 3 | 5 | 7 +``` + +### B-Type Format + +Bit width: **32 bits** + +``` +31:31|30:25 |24:20|19:15|14:12|11:7| 6:0 +imm_12|imm_10_5| rs2 | rs1 |funct3|imm_4_1|opcode +1| 6 | 5 | 5 | 3 | 5 | 7 +``` + +### U-Type Format + +Bit width: **32 bits** + +``` + 31:12 |11:7| 6:0 + imm | rd |opcode + 20 | 5 | 7 +``` + +### J-Type Format + +Bit width: **32 bits** + +``` +31:31| 30:21 |20:20| 19:12 |11:7| 6:0 +imm_20| imm_10_1 |imm_11|imm_19_12| rd |opcode +1| 10 |1| 8 | 5 | 7 +``` + +\newpage + +# Instruction Set + +## Branch Operations + +| Mnemonic | Format | Opcode | Funct3 | Funct7 | Operands | Description | +|----------|--------|--------|--------|--------|----------|-------------| +| `BNE` | B | `0x63` | 0x1 | — | rs1, rs2, label | Branch not equal | +| `BEQ` | B | `0x63` | 0x0 | — | rs1, rs2, label | Branch equal | +| `BLT` | B | `0x63` | 0x4 | — | rs1, rs2, label | Branch less than (signed) | +| `BGE` | B | `0x63` | 0x5 | — | rs1, rs2, label | Branch greater than or equal (signed) | +| `BLTU` | B | `0x63` | 0x6 | — | rs1, rs2, label | Branch less than (unsigned) | +| `BGEU` | B | `0x63` | 0x7 | — | rs1, rs2, label | Branch greater than or equal (unsigned) | +## Integer Operations + +| Mnemonic | Format | Opcode | Funct3 | Funct7 | Operands | Description | +|----------|--------|--------|--------|--------|----------|-------------| +| `AUIPC` | U | `0x17` | — | — | rd, imm20 | Add upper immediate to PC — forms PC-relative address | +| `SLT` | R | `0x33` | 0x2 | 0x00 | rd, rs1, rs2 | Set if rs1 is less than rs2 (signed) | +| `SLTU` | R | `0x33` | 0x3 | 0x00 | rd, rs1, rs2 | Set if rs1 is less than rs2 (unsigned) | +| `SLTI` | I | `0x13` | 0x2 | — | rd, rs1, imm12 | Set if rs1 is less than immediate (signed) | +| `SLTIU` | I | `0x13` | 0x3 | — | rd, rs1, imm12 | Set if rs1 is less than immediate (unsigned) | +| `LUI` | U | `0x37` | — | — | rd, imm20 | Load upper immediate — places 20-bit immediate in upper 20 bits of rd | +| `ADD` | R | `0x33` | 0x0 | 0x00 | rd, rs1, rs2 | Add registers | +| `SUB` | R | `0x33` | 0x0 | 0x20 | rd, rs1, rs2 | Subtract registers | +| `ADDI` | I | `0x13` | 0x0 | — | rd, rs1, imm12 | Add sign-extended 12-bit immediate to register rs1 | +## Jump Operations + +| Mnemonic | Format | Opcode | Funct3 | Funct7 | Operands | Description | +|----------|--------|--------|--------|--------|----------|-------------| +| `JAL` | J | `0x6F` | — | — | rd, label | Jump and link — jump to PC+offset, save return address to rd | +| `JALR` | I | `0x67` | 0x0 | — | rd, rs1, offset | Jump and link register — jump to rs1+offset, save return address | +## Logical Operations + +| Mnemonic | Format | Opcode | Funct3 | Funct7 | Operands | Description | +|----------|--------|--------|--------|--------|----------|-------------| +| `XOR` | R | `0x33` | 0x4 | 0x00 | rd, rs1, rs2 | Bitwise XOR | +| `OR` | R | `0x33` | 0x6 | 0x00 | rd, rs1, rs2 | Bitwise OR | +| `AND` | R | `0x33` | 0x7 | 0x00 | rd, rs1, rs2 | Bitwise AND | +| `ORI` | I | `0x13` | 0x6 | — | rd, rs1, imm12 | Bitwise OR with immediate | +| `XORI` | I | `0x13` | 0x4 | — | rd, rs1, imm12 | Bitwise XOR with immediate | +| `ANDI` | I | `0x13` | 0x7 | — | rd, rs1, imm12 | Bitwise AND with immediate | +## Memory Operations + +| Mnemonic | Format | Opcode | Funct3 | Funct7 | Operands | Description | +|----------|--------|--------|--------|--------|----------|-------------| +| `SW` | S | `0x23` | 0x2 | — | rs2, offset(rs1) | Store word | +| `LB` | I | `0x03` | 0x0 | — | rd, offset(rs1) | Load byte (sign-extended) | +| `LH` | I | `0x03` | 0x1 | — | rd, offset(rs1) | Load halfword (sign-extended) | +| `LW` | I | `0x03` | 0x2 | — | rd, offset(rs1) | Load word | +| `LBU` | I | `0x03` | 0x4 | — | rd, offset(rs1) | Load byte (zero-extended) | +| `LHU` | I | `0x03` | 0x5 | — | rd, offset(rs1) | Load halfword (zero-extended) | +| `SB` | S | `0x23` | 0x0 | — | rs2, offset(rs1) | Store byte | +| `SH` | S | `0x23` | 0x1 | — | rs2, offset(rs1) | Store halfword | +## Shift Operations + +| Mnemonic | Format | Opcode | Funct3 | Funct7 | Operands | Description | +|----------|--------|--------|--------|--------|----------|-------------| +| `SRAI` | I | `0x13` | 0x5 | — | rd, rs1, shamt5 | Arithmetic right shift by immediate shift amount | +| `SLLI` | I | `0x13` | 0x1 | — | rd, rs1, shamt5 | Logical left shift by immediate shift amount | +| `SRA` | R | `0x33` | 0x5 | 0x20 | rd, rs1, rs2 | Arithmetic right shift by lower 5 bits of rs2 | +| `SRL` | R | `0x33` | 0x5 | 0x00 | rd, rs1, rs2 | Logical right shift by lower 5 bits of rs2 | +| `SLL` | R | `0x33` | 0x1 | 0x00 | rd, rs1, rs2 | Logical left shift by lower 5 bits of rs2 | +| `SRLI` | I | `0x13` | 0x5 | — | rd, rs1, shamt5 | Logical right shift by immediate shift amount | +## Synchronization Operations + +| Mnemonic | Format | Opcode | Funct3 | Funct7 | Operands | Description | +|----------|--------|--------|--------|--------|----------|-------------| +| `FENCEI` | I | `0x0F` | 0x1 | — | — | Instruction fence — synchronizes instruction and data streams | +| `FENCE` | I | `0x0F` | 0x0 | — | pred, succ | Memory ordering fence | +## System Operations + +| Mnemonic | Format | Opcode | Funct3 | Funct7 | Operands | Description | +|----------|--------|--------|--------|--------|----------|-------------| +| `CSRRCI` | I | `0x73` | 0x7 | — | rd, csr, uimm5 | Atomic read and clear bits in CSR with immediate | +| `ECALL` | I | `0x73` | 0x0 | — | — | Environment call — raises a system call exception | +| `EBREAK` | I | `0x73` | 0x0 | — | — | Breakpoint — raises a breakpoint exception | +| `CSRRW` | I | `0x73` | 0x1 | — | rd, csr, rs1 | Atomic read/write CSR — writes rs1 to CSR, returns old value in rd | +| `CSRRS` | I | `0x73` | 0x2 | — | rd, csr, rs1 | Atomic read and set bits in CSR | +| `CSRRC` | I | `0x73` | 0x3 | — | rd, csr, rs1 | Atomic read and clear bits in CSR | +| `CSRRWI` | I | `0x73` | 0x5 | — | rd, csr, uimm5 | Atomic read/write CSR with immediate | +| `CSRRSI` | I | `0x73` | 0x6 | — | rd, csr, uimm5 | Atomic read and set bits in CSR with immediate | + +\newpage + +## Instruction Details + +### BNE + +- **Format:** B +- **Opcode:** `0x63` +- **Funct3:** `0x1` +- **Operands:** `rs1, rs2, label` +- **Description:** Branch not equal +- **Operation:** `if (rs1 != rs2) PC += sext(offset)` + +### BEQ + +- **Format:** B +- **Opcode:** `0x63` +- **Funct3:** `0x0` +- **Operands:** `rs1, rs2, label` +- **Description:** Branch equal +- **Operation:** `if (rs1 == rs2) PC += sext(offset)` + +### BLT + +- **Format:** B +- **Opcode:** `0x63` +- **Funct3:** `0x4` +- **Operands:** `rs1, rs2, label` +- **Description:** Branch less than (signed) +- **Operation:** `if (rs1 < rs2) PC += sext(offset)` + +### BGE + +- **Format:** B +- **Opcode:** `0x63` +- **Funct3:** `0x5` +- **Operands:** `rs1, rs2, label` +- **Description:** Branch greater than or equal (signed) +- **Operation:** `if (rs1 >= rs2) PC += sext(offset)` + +### BLTU + +- **Format:** B +- **Opcode:** `0x63` +- **Funct3:** `0x6` +- **Operands:** `rs1, rs2, label` +- **Description:** Branch less than (unsigned) +- **Operation:** `if (rs1 < rs2) PC += sext(offset)` + +### BGEU + +- **Format:** B +- **Opcode:** `0x63` +- **Funct3:** `0x7` +- **Operands:** `rs1, rs2, label` +- **Description:** Branch greater than or equal (unsigned) +- **Operation:** `if (rs1 >= rs2) PC += sext(offset)` + +### AUIPC + +- **Format:** U +- **Opcode:** `0x17` +- **Operands:** `rd, imm20` +- **Description:** Add upper immediate to PC — forms PC-relative address +- **Operation:** `rd = PC + (imm20 << 12)` + +### SLT + +- **Format:** R +- **Opcode:** `0x33` +- **Funct3:** `0x2` +- **Funct7:** `0x00` +- **Operands:** `rd, rs1, rs2` +- **Description:** Set if rs1 is less than rs2 (signed) +- **Operation:** `rd = (rs1 < rs2) ? 1 : 0` + +### SLTU + +- **Format:** R +- **Opcode:** `0x33` +- **Funct3:** `0x3` +- **Funct7:** `0x00` +- **Operands:** `rd, rs1, rs2` +- **Description:** Set if rs1 is less than rs2 (unsigned) +- **Operation:** `rd = (rs1 < rs2) ? 1 : 0` + +### SLTI + +- **Format:** I +- **Opcode:** `0x13` +- **Funct3:** `0x2` +- **Operands:** `rd, rs1, imm12` +- **Description:** Set if rs1 is less than immediate (signed) +- **Operation:** `rd = (rs1 < sext(imm12)) ? 1 : 0` + +### SLTIU + +- **Format:** I +- **Opcode:** `0x13` +- **Funct3:** `0x3` +- **Operands:** `rd, rs1, imm12` +- **Description:** Set if rs1 is less than immediate (unsigned) +- **Operation:** `rd = (rs1 < sext(imm12)) ? 1 : 0` + +### LUI + +- **Format:** U +- **Opcode:** `0x37` +- **Operands:** `rd, imm20` +- **Description:** Load upper immediate — places 20-bit immediate in upper 20 bits of rd +- **Operation:** `rd = imm20 << 12` + +### ADD + +- **Format:** R +- **Opcode:** `0x33` +- **Funct3:** `0x0` +- **Funct7:** `0x00` +- **Operands:** `rd, rs1, rs2` +- **Description:** Add registers +- **Operation:** `rd = rs1 + rs2` + +### SUB + +- **Format:** R +- **Opcode:** `0x33` +- **Funct3:** `0x0` +- **Funct7:** `0x20` +- **Operands:** `rd, rs1, rs2` +- **Description:** Subtract registers +- **Operation:** `rd = rs1 - rs2` + +### ADDI + +- **Format:** I +- **Opcode:** `0x13` +- **Funct3:** `0x0` +- **Operands:** `rd, rs1, imm12` +- **Description:** Add sign-extended 12-bit immediate to register rs1 +- **Operation:** `rd = rs1 + sext(imm12)` + +### JAL + +- **Format:** J +- **Opcode:** `0x6F` +- **Operands:** `rd, label` +- **Description:** Jump and link — jump to PC+offset, save return address to rd +- **Operation:** `rd = PC + 4; PC += sext(offset)` + +### JALR + +- **Format:** I +- **Opcode:** `0x67` +- **Funct3:** `0x0` +- **Operands:** `rd, rs1, offset` +- **Description:** Jump and link register — jump to rs1+offset, save return address +- **Operation:** `rd = PC + 4; PC = (rs1 + sext(offset)) & ~1` + +### XOR + +- **Format:** R +- **Opcode:** `0x33` +- **Funct3:** `0x4` +- **Funct7:** `0x00` +- **Operands:** `rd, rs1, rs2` +- **Description:** Bitwise XOR +- **Operation:** `rd = rs1 ^ rs2` + +### OR + +- **Format:** R +- **Opcode:** `0x33` +- **Funct3:** `0x6` +- **Funct7:** `0x00` +- **Operands:** `rd, rs1, rs2` +- **Description:** Bitwise OR +- **Operation:** `rd = rs1 | rs2` + +### AND + +- **Format:** R +- **Opcode:** `0x33` +- **Funct3:** `0x7` +- **Funct7:** `0x00` +- **Operands:** `rd, rs1, rs2` +- **Description:** Bitwise AND +- **Operation:** `rd = rs1 & rs2` + +### ORI + +- **Format:** I +- **Opcode:** `0x13` +- **Funct3:** `0x6` +- **Operands:** `rd, rs1, imm12` +- **Description:** Bitwise OR with immediate +- **Operation:** `rd = rs1 | sext(imm12)` + +### XORI + +- **Format:** I +- **Opcode:** `0x13` +- **Funct3:** `0x4` +- **Operands:** `rd, rs1, imm12` +- **Description:** Bitwise XOR with immediate +- **Operation:** `rd = rs1 ^ sext(imm12)` + +### ANDI + +- **Format:** I +- **Opcode:** `0x13` +- **Funct3:** `0x7` +- **Operands:** `rd, rs1, imm12` +- **Description:** Bitwise AND with immediate +- **Operation:** `rd = rs1 & sext(imm12)` + +### SW + +- **Format:** S +- **Opcode:** `0x23` +- **Funct3:** `0x2` +- **Operands:** `rs2, offset(rs1)` +- **Description:** Store word +- **Operation:** `MEM[rs1 + offset][31:0] = rs2[31:0]` + +### LB + +- **Format:** I +- **Opcode:** `0x03` +- **Funct3:** `0x0` +- **Operands:** `rd, offset(rs1)` +- **Description:** Load byte (sign-extended) +- **Operation:** `rd = sext(MEM[rs1 + offset][7:0])` + +### LH + +- **Format:** I +- **Opcode:** `0x03` +- **Funct3:** `0x1` +- **Operands:** `rd, offset(rs1)` +- **Description:** Load halfword (sign-extended) +- **Operation:** `rd = sext(MEM[rs1 + offset][15:0])` + +### LW + +- **Format:** I +- **Opcode:** `0x03` +- **Funct3:** `0x2` +- **Operands:** `rd, offset(rs1)` +- **Description:** Load word +- **Operation:** `rd = MEM[rs1 + offset][31:0]` + +### LBU + +- **Format:** I +- **Opcode:** `0x03` +- **Funct3:** `0x4` +- **Operands:** `rd, offset(rs1)` +- **Description:** Load byte (zero-extended) +- **Operation:** `rd = MEM[rs1 + offset][7:0]` + +### LHU + +- **Format:** I +- **Opcode:** `0x03` +- **Funct3:** `0x5` +- **Operands:** `rd, offset(rs1)` +- **Description:** Load halfword (zero-extended) +- **Operation:** `rd = MEM[rs1 + offset][15:0]` + +### SB + +- **Format:** S +- **Opcode:** `0x23` +- **Funct3:** `0x0` +- **Operands:** `rs2, offset(rs1)` +- **Description:** Store byte +- **Operation:** `MEM[rs1 + offset][7:0] = rs2[7:0]` + +### SH + +- **Format:** S +- **Opcode:** `0x23` +- **Funct3:** `0x1` +- **Operands:** `rs2, offset(rs1)` +- **Description:** Store halfword +- **Operation:** `MEM[rs1 + offset][15:0] = rs2[15:0]` + +### SRAI + +- **Format:** I +- **Opcode:** `0x13` +- **Funct3:** `0x5` +- **Operands:** `rd, rs1, shamt5` +- **Description:** Arithmetic right shift by immediate shift amount +- **Operation:** `rd = rs1 >>> shamt` + +### SLLI + +- **Format:** I +- **Opcode:** `0x13` +- **Funct3:** `0x1` +- **Operands:** `rd, rs1, shamt5` +- **Description:** Logical left shift by immediate shift amount +- **Operation:** `rd = rs1 << shamt` + +### SRA + +- **Format:** R +- **Opcode:** `0x33` +- **Funct3:** `0x5` +- **Funct7:** `0x20` +- **Operands:** `rd, rs1, rs2` +- **Description:** Arithmetic right shift by lower 5 bits of rs2 +- **Operation:** `rd = rs1 >>> rs2[4:0]` + +### SRL + +- **Format:** R +- **Opcode:** `0x33` +- **Funct3:** `0x5` +- **Funct7:** `0x00` +- **Operands:** `rd, rs1, rs2` +- **Description:** Logical right shift by lower 5 bits of rs2 +- **Operation:** `rd = rs1 >> rs2[4:0]` + +### SLL + +- **Format:** R +- **Opcode:** `0x33` +- **Funct3:** `0x1` +- **Funct7:** `0x00` +- **Operands:** `rd, rs1, rs2` +- **Description:** Logical left shift by lower 5 bits of rs2 +- **Operation:** `rd = rs1 << rs2[4:0]` + +### SRLI + +- **Format:** I +- **Opcode:** `0x13` +- **Funct3:** `0x5` +- **Operands:** `rd, rs1, shamt5` +- **Description:** Logical right shift by immediate shift amount +- **Operation:** `rd = rs1 >> shamt` + +### FENCEI + +- **Format:** I +- **Opcode:** `0x0F` +- **Funct3:** `0x1` +- **Operands:** `—` +- **Description:** Instruction fence — synchronizes instruction and data streams +- **Operation:** `Flushes instruction cache after data writes` + +### FENCE + +- **Format:** I +- **Opcode:** `0x0F` +- **Funct3:** `0x0` +- **Operands:** `pred, succ` +- **Description:** Memory ordering fence +- **Operation:** `Orders memory accesses as specified by pred and succ fields` + +### CSRRCI + +- **Format:** I +- **Opcode:** `0x73` +- **Funct3:** `0x7` +- **Operands:** `rd, csr, uimm5` +- **Description:** Atomic read and clear bits in CSR with immediate +- **Operation:** `rd = CSR[csr]; CSR[csr] &= ~zimm` + +### ECALL + +- **Format:** I +- **Opcode:** `0x73` +- **Funct3:** `0x0` +- **Operands:** `—` +- **Description:** Environment call — raises a system call exception +- **Operation:** `Traps to the configured exception handler` + +### EBREAK + +- **Format:** I +- **Opcode:** `0x73` +- **Funct3:** `0x0` +- **Operands:** `—` +- **Description:** Breakpoint — raises a breakpoint exception +- **Operation:** `Used by debuggers to halt program execution` + +### CSRRW + +- **Format:** I +- **Opcode:** `0x73` +- **Funct3:** `0x1` +- **Operands:** `rd, csr, rs1` +- **Description:** Atomic read/write CSR — writes rs1 to CSR, returns old value in rd +- **Operation:** `rd = CSR[csr]; CSR[csr] = rs1` + +### CSRRS + +- **Format:** I +- **Opcode:** `0x73` +- **Funct3:** `0x2` +- **Operands:** `rd, csr, rs1` +- **Description:** Atomic read and set bits in CSR +- **Operation:** `rd = CSR[csr]; CSR[csr] |= rs1` + +### CSRRC + +- **Format:** I +- **Opcode:** `0x73` +- **Funct3:** `0x3` +- **Operands:** `rd, csr, rs1` +- **Description:** Atomic read and clear bits in CSR +- **Operation:** `rd = CSR[csr]; CSR[csr] &= ~rs1` + +### CSRRWI + +- **Format:** I +- **Opcode:** `0x73` +- **Funct3:** `0x5` +- **Operands:** `rd, csr, uimm5` +- **Description:** Atomic read/write CSR with immediate +- **Operation:** `rd = CSR[csr]; CSR[csr] = zimm` + +### CSRRSI + +- **Format:** I +- **Opcode:** `0x73` +- **Funct3:** `0x6` +- **Operands:** `rd, csr, uimm5` +- **Description:** Atomic read and set bits in CSR with immediate +- **Operation:** `rd = CSR[csr]; CSR[csr] |= zimm` + +\newpage + +# Opcode Map + +The following table shows the top-level opcode mapping. The opcode occupies bits 6:0 of every instruction. + +| opcode[6:0] | Type | Instructions | +|-------------|------|-------------| +| `0x33` (51) | R | ADD, SUB, SLT, SLTU, AND, OR, XOR, SLL, SRL, SRA (10 inst)s | +| `0x13` (19) | I | ADDI, SLTI, SLTIU, ANDI, ORI, XORI, SLLI, SRLI, SRAI (9 inst)s | +| `0x37` (55) | U | LUI (1 inst) | +| `0x17` (23) | U | AUIPC (1 inst) | +| `0x03` (3) | I | LB, LH, LW, LBU, LHU (5 inst)s | +| `0x23` (35) | S | SB, SH, SW (3 inst)s | +| `0x63` (99) | B | BEQ, BNE, BLT, BGE, BLTU, BGEU (6 inst)s | +| `0x6F` (111) | J | JAL (1 inst) | +| `0x67` (103) | I | JALR (1 inst) | +| `0x0F` (15) | I | FENCE, FENCEI (2 inst)s | +| `0x73` (115) | I | ECALL, EBREAK, CSRRW, CSRRS, CSRRC, CSRRWI, CSRRSI, CSRRCI (8 inst)s | + +### Encoding Matrix + +| opcode \ funct3 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | +|---|---|---|---|---|---|---|---|---| +| `0x33` | ADD | SLL | SLT | SLTU | XOR | SRL | OR | AND | +| `0x13` | ADDI | SLLI | SLTI | SLTIU | XORI | SRLI | ORI | ANDI | +| `0x37` | — | — | — | — | — | — | — | — | +| `0x17` | — | — | — | — | — | — | — | — | +| `0x03` | LB | LH | LW | — | LBU | LHU | — | — | +| `0x23` | SB | SH | SW | — | — | — | — | — | +| `0x63` | BEQ | BNE | — | — | BLT | BGE | BLTU | BGEU | +| `0x6F` | — | — | — | — | — | — | — | — | +| `0x67` | JALR | — | — | — | — | — | — | — | +| `0x0F` | FENCE | FENCEI | — | — | — | — | — | — | +| `0x73` | ECALL | CSRRW | CSRRS | CSRRC | — | CSRRWI | CSRRSI | CSRRCI | + +\newpage + +# Exception and Trap Handling + +## Exception Types + +| Exception Code | Name | Description | +|----------------|------|-------------| +| 0 | Instruction address misaligned | PC not aligned to 4 bytes | +| 1 | Instruction access fault | Failed to fetch instruction | +| 2 | Illegal instruction | Unrecognized opcode | +| 3 | Breakpoint | EBREAK instruction executed | +| 4 | Load address misaligned | Load address not properly aligned | +| 5 | Load access fault | Failed to load from memory | +| 6 | Store address misaligned | Store address not properly aligned | +| 7 | Store access fault | Failed to store to memory | +| 8 | Environment call from U-mode | ECALL in user mode | +| 9 | Environment call from S-mode | ECALL in supervisor mode | +| 11 | Environment call from M-mode | ECALL in machine mode | + +## Trap Vector + +On taking a trap, the implementation: + +1. Sets `mepc` to the PC of the trapping instruction (or next PC for ECALL/EBREAK) +2. Sets `mcause` to the exception code +3. Sets `mtval` to exception-specific information +4. Sets `mstatus.MPP` to the current privilege mode +5. Sets `mstatus.MPIE` to `mstatus.MIE` +6. Clears `mstatus.MIE` +7. Sets PC to `mtvec` + +\newpage + +# Pseudo-Instructions + +| Pseudo-instruction | Expansion | Description | +|-------------------|-----------|-------------| +| `NOP` | `ADDI x0, x0, 0` | No operation | +| `MV rd, rs` | `ADDI rd, rs, 0` | Copy register | +| `NOT rd, rs` | `XORI rd, rs, -1` | Bitwise NOT | +| `NEG rd, rs` | `SUB rd, x0, rs` | Negate register | +| `LI rd, imm` | (multiple) | Load immediate | +| `LA rd, label` | (multiple) | Load address | +| `RET` | `JALR x0, x1, 0` | Return from subroutine | +| `CALL label` | (multiple) | Call subroutine | +| `J label` | `JAL x0, label` | Unconditional jump | +| `JR rs` | `JALR x0, rs, 0` | Jump register | + +\newpage + +# Control and Status Registers + +The following CSRs are accessible via the `CSRRW`, `CSRRS`, `CSRRC`, and their immediate variants. + +| Address | Name | Description | +|---------|------|-------------| +| `0x300` | mstatus | Machine status register — holds global interrupt enable and privilege state | +| `0x301` | misa | Machine ISA register — encodes supported ISA extensions | +| `0x302` | medeleg | Machine exception delegation register | +| `0x303` | mideleg | Machine interrupt delegation register | +| `0x304` | mie | Machine interrupt-enable register | +| `0x305` | mtvec | Machine trap-handler base address | +| `0x306` | mcounteren | Machine counter enable register | +| `0x340` | mscratch | Scratch register for machine-mode trap handlers | +| `0x341` | mepc | Machine exception program counter — holds PC of trapping instruction | +| `0x342` | mcause | Machine trap cause — encodes exception or interrupt cause | +| `0x343` | mtval | Machine trap value — exception-specific information | +| `0x344` | mip | Machine interrupt pending register | +| `0x3A0` | pmpcfg0 | Physical memory protection configuration 0 | +| `0x3B0` | pmpaddr0 | Physical memory protection address 0 | +| `0x3B1` | pmpaddr1 | Physical memory protection address 1 | +| `0x3B2` | pmpaddr2 | Physical memory protection address 2 | +| `0x3B3` | pmpaddr3 | Physical memory protection address 3 | +| `0xB00` | mcycle | Machine cycle counter — counts number of clock cycles | +| `0xB02` | minstret | Machine instructions-retired counter | +| `0xB03` | mhpmcounter3 | Machine hardware performance counter 3 | +| `0xB04` | mhpmcounter4 | Machine hardware performance counter 4 | +| `0xB05` | mhpmcounter5 | Machine hardware performance counter 5 | +| `0x323` | mhpmevent3 | Machine hardware performance event selector 3 | +| `0x324` | mhpmevent4 | Machine hardware performance event selector 4 | +| `0x325` | mhpmevent5 | Machine hardware performance event selector 5 | +| `0xC00` | ucycle | User-mode cycle counter read | +| `0xC02` | uinstret | User-mode instructions-retired read | +| `0xC80` | ucycleh | Upper 32 bits of user-mode cycle counter | +| `0xC82` | uinstreth | Upper 32 bits of user-mode instructions-retired counter | +| `0x100` | sstatus | Supervisor status register | +| `0x104` | sie | Supervisor interrupt-enable register | +| `0x105` | stvec | Supervisor trap-handler base address | +| `0x140` | sscratch | Scratch register for supervisor-mode trap handlers | +| `0x141` | sepc | Supervisor exception program counter | +| `0x142` | scause | Supervisor trap cause register | +| `0x143` | stval | Supervisor trap value register | +| `0x144` | sip | Supervisor interrupt pending register | +| `0x180` | satp | Supervisor address translation and protection — controls page tables | + +\newpage + +# Quick Reference + +## Instruction Encoding Quick Reference + +### R-Type + +``` + 31:27 | 26:25 | 24:20 | 19:15 | 14:12 | 11:7 | 6:0 + funct7 | — | rs2 | rs1 | funct3 | rd | opcode + 7 | 2 | 5 | 5 | 3 | 5 | 7 +``` + +### I-Type + +``` + 31:20 | 19:15 | 14:12 | 11:7 | 6:0 + imm[11:0]| rs1 | funct3 | rd | opcode + 12 | 5 | 3 | 5 | 7 +``` + +### S-Type + +``` + 31:27 | 26:25 | 24:20 | 19:15 | 14:12 | 11:7 | 6:0 + imm[11:5]| — | rs2 | rs1 | funct3 | imm[4:0]| opcode + 7 | 2 | 5 | 5 | 3 | 5 | 7 +``` + +### B-Type + +``` + 31 | 30:27 | 26:25 | 24:20 | 19:15 | 14:12 | 11:8 | 7 | 6:0 + imm[12]| imm[10:5]| — | rs2 | rs1 | funct3 | imm[4:1]| imm[11]| opcode + 1 | 6 | 2 | 5 | 5 | 3 | 4 | 1 | 7 +``` + +### U-Type + +``` + 31:12 | 11:7 | 6:0 + imm[31:12] | rd | opcode + 20 | 5 | 7 +``` + +### J-Type + +``` + 31 | 30:21 | 20 | 19:12 | 11:7 | 6:0 + imm[20]| imm[10:1]| imm[11]| imm[19:12]| rd | opcode + 1 | 10 | 1 | 8 | 5 | 7 +``` + |
