diff options
Diffstat (limited to 'doc/spec')
| -rw-r--r-- | doc/spec/isa_reference.html | 106 | ||||
| -rw-r--r-- | doc/spec/isa_reference.md | 899 | ||||
| -rw-r--r-- | doc/spec/isa_reference.pdf | bin | 0 -> 90197 bytes |
3 files changed, 1005 insertions, 0 deletions
diff --git a/doc/spec/isa_reference.html b/doc/spec/isa_reference.html new file mode 100644 index 0000000..b2a8353 --- /dev/null +++ b/doc/spec/isa_reference.html @@ -0,0 +1,106 @@ +<!DOCTYPE html> +<html lang="en"> +<head> +<meta charset="UTF-8"> +<title>Fyntv ISA Reference Manual</title> +<link rel="stylesheet" href="style.css"> +</head> +<body> +<article> +<header> +<h1>Fyntv Instruction Set Architecture</h1> +<p class="subtitle">Reference Manual</p> +<p><strong>Version:</strong> 0.0.0.1 | <strong>Date:</strong> June 2026</p> +</header> +<section id="registers"> +<h2>Registers</h2> +<table><thead><tr><th>Register</th><th>ABI Name</th><th>Description</th><th>Saved</th></tr></thead><tbody> +<tr><td>x0</td><td>zero</td><td>Always-zero register — reads return 0, writes are discarded</td><td>No</td></tr> +<tr><td>x1</td><td>ra</td><td>Return address link register</td><td>No</td></tr> +<tr><td>x2</td><td>sp</td><td>Stack pointer</td><td>Yes</td></tr> +<tr><td>x3</td><td>gp</td><td>Global pointer</td><td>Yes</td></tr> +<tr><td>x4</td><td>tp</td><td>Thread pointer</td><td>Yes</td></tr> +<tr><td>x5</td><td>t0</td><td>Temporary register 0</td><td>No</td></tr> +<tr><td>x6</td><td>t1</td><td>Temporary register 1</td><td>No</td></tr> +<tr><td>x7</td><td>t2</td><td>Temporary register 2</td><td>No</td></tr> +<tr><td>x8</td><td>s0</td><td>Saved register 0 / frame pointer</td><td>Yes</td></tr> +<tr><td>x9</td><td>s1</td><td>Saved register 1</td><td>Yes</td></tr> +<tr><td>x10</td><td>a0</td><td>Function argument 0 / return value 0</td><td>No</td></tr> +<tr><td>x11</td><td>a1</td><td>Function argument 1 / return value 1</td><td>No</td></tr> +<tr><td>x12</td><td>a2</td><td>Function argument 2</td><td>No</td></tr> +<tr><td>x13</td><td>a3</td><td>Function argument 3</td><td>No</td></tr> +<tr><td>x14</td><td>a4</td><td>Function argument 4</td><td>No</td></tr> +<tr><td>x15</td><td>a5</td><td>Function argument 5</td><td>No</td></tr> +<tr><td>x16</td><td>a6</td><td>Function argument 6</td><td>No</td></tr> +<tr><td>x17</td><td>a7</td><td>Function argument 7</td><td>No</td></tr> +<tr><td>x18</td><td>s2</td><td>Saved register 2</td><td>Yes</td></tr> +<tr><td>x19</td><td>s3</td><td>Saved register 3</td><td>Yes</td></tr> +<tr><td>x20</td><td>s4</td><td>Saved register 4</td><td>Yes</td></tr> +<tr><td>x21</td><td>s5</td><td>Saved register 5</td><td>Yes</td></tr> +<tr><td>x22</td><td>s6</td><td>Saved register 6</td><td>Yes</td></tr> +<tr><td>x23</td><td>s7</td><td>Saved register 7</td><td>Yes</td></tr> +<tr><td>x24</td><td>s8</td><td>Saved register 8</td><td>Yes</td></tr> +<tr><td>x25</td><td>s9</td><td>Saved register 9</td><td>Yes</td></tr> +<tr><td>x26</td><td>s10</td><td>Saved register 10</td><td>Yes</td></tr> +<tr><td>x27</td><td>s11</td><td>Saved register 11</td><td>Yes</td></tr> +<tr><td>x28</td><td>t3</td><td>Temporary register 3</td><td>No</td></tr> +<tr><td>x29</td><td>t4</td><td>Temporary register 4</td><td>No</td></tr> +<tr><td>x30</td><td>t5</td><td>Temporary register 5</td><td>No</td></tr> +<tr><td>x31</td><td>t6</td><td>Temporary register 6</td><td>No</td></tr> +</tbody></table> +</section> +<section id="instructions"> +<h2>Instruction Set</h2> +<table><thead><tr><th>Mnemonic</th><th>Format</th><th>Opcode</th><th>Operands</th><th>Description</th></tr></thead><tbody> +<tr><td><code>ADD</code></td><td>R</td><td><code>0x33</code></td><td><code>rd, rs1, rs2</code></td><td>Add registers</td></tr> +<tr><td><code>SUB</code></td><td>R</td><td><code>0x33</code></td><td><code>rd, rs1, rs2</code></td><td>Subtract registers</td></tr> +<tr><td><code>ADDI</code></td><td>I</td><td><code>0x13</code></td><td><code>rd, rs1, imm12</code></td><td>Add sign-extended 12-bit immediate to register rs1</td></tr> +<tr><td><code>SLT</code></td><td>R</td><td><code>0x33</code></td><td><code>rd, rs1, rs2</code></td><td>Set if rs1 is less than rs2 (signed)</td></tr> +<tr><td><code>SLTU</code></td><td>R</td><td><code>0x33</code></td><td><code>rd, rs1, rs2</code></td><td>Set if rs1 is less than rs2 (unsigned)</td></tr> +<tr><td><code>SLTI</code></td><td>I</td><td><code>0x13</code></td><td><code>rd, rs1, imm12</code></td><td>Set if rs1 is less than immediate (signed)</td></tr> +<tr><td><code>SLTIU</code></td><td>I</td><td><code>0x13</code></td><td><code>rd, rs1, imm12</code></td><td>Set if rs1 is less than immediate (unsigned)</td></tr> +<tr><td><code>LUI</code></td><td>U</td><td><code>0x37</code></td><td><code>rd, imm20</code></td><td>Load upper immediate — places 20-bit immediate in upper 20 bits of rd</td></tr> +<tr><td><code>AUIPC</code></td><td>U</td><td><code>0x17</code></td><td><code>rd, imm20</code></td><td>Add upper immediate to PC — forms PC-relative address</td></tr> +<tr><td><code>AND</code></td><td>R</td><td><code>0x33</code></td><td><code>rd, rs1, rs2</code></td><td>Bitwise AND</td></tr> +<tr><td><code>OR</code></td><td>R</td><td><code>0x33</code></td><td><code>rd, rs1, rs2</code></td><td>Bitwise OR</td></tr> +<tr><td><code>XOR</code></td><td>R</td><td><code>0x33</code></td><td><code>rd, rs1, rs2</code></td><td>Bitwise XOR</td></tr> +<tr><td><code>ANDI</code></td><td>I</td><td><code>0x13</code></td><td><code>rd, rs1, imm12</code></td><td>Bitwise AND with immediate</td></tr> +<tr><td><code>ORI</code></td><td>I</td><td><code>0x13</code></td><td><code>rd, rs1, imm12</code></td><td>Bitwise OR with immediate</td></tr> +<tr><td><code>XORI</code></td><td>I</td><td><code>0x13</code></td><td><code>rd, rs1, imm12</code></td><td>Bitwise XOR with immediate</td></tr> +<tr><td><code>SLL</code></td><td>R</td><td><code>0x33</code></td><td><code>rd, rs1, rs2</code></td><td>Logical left shift by lower 5 bits of rs2</td></tr> +<tr><td><code>SRL</code></td><td>R</td><td><code>0x33</code></td><td><code>rd, rs1, rs2</code></td><td>Logical right shift by lower 5 bits of rs2</td></tr> +<tr><td><code>SRA</code></td><td>R</td><td><code>0x33</code></td><td><code>rd, rs1, rs2</code></td><td>Arithmetic right shift by lower 5 bits of rs2</td></tr> +<tr><td><code>SLLI</code></td><td>I</td><td><code>0x13</code></td><td><code>rd, rs1, shamt5</code></td><td>Logical left shift by immediate shift amount</td></tr> +<tr><td><code>SRLI</code></td><td>I</td><td><code>0x13</code></td><td><code>rd, rs1, shamt5</code></td><td>Logical right shift by immediate shift amount</td></tr> +<tr><td><code>SRAI</code></td><td>I</td><td><code>0x13</code></td><td><code>rd, rs1, shamt5</code></td><td>Arithmetic right shift by immediate shift amount</td></tr> +<tr><td><code>LB</code></td><td>I</td><td><code>0x03</code></td><td><code>rd, offset(rs1)</code></td><td>Load byte (sign-extended)</td></tr> +<tr><td><code>LH</code></td><td>I</td><td><code>0x03</code></td><td><code>rd, offset(rs1)</code></td><td>Load halfword (sign-extended)</td></tr> +<tr><td><code>LW</code></td><td>I</td><td><code>0x03</code></td><td><code>rd, offset(rs1)</code></td><td>Load word</td></tr> +<tr><td><code>LBU</code></td><td>I</td><td><code>0x03</code></td><td><code>rd, offset(rs1)</code></td><td>Load byte (zero-extended)</td></tr> +<tr><td><code>LHU</code></td><td>I</td><td><code>0x03</code></td><td><code>rd, offset(rs1)</code></td><td>Load halfword (zero-extended)</td></tr> +<tr><td><code>SB</code></td><td>S</td><td><code>0x23</code></td><td><code>rs2, offset(rs1)</code></td><td>Store byte</td></tr> +<tr><td><code>SH</code></td><td>S</td><td><code>0x23</code></td><td><code>rs2, offset(rs1)</code></td><td>Store halfword</td></tr> +<tr><td><code>SW</code></td><td>S</td><td><code>0x23</code></td><td><code>rs2, offset(rs1)</code></td><td>Store word</td></tr> +<tr><td><code>BEQ</code></td><td>B</td><td><code>0x63</code></td><td><code>rs1, rs2, label</code></td><td>Branch equal</td></tr> +<tr><td><code>BNE</code></td><td>B</td><td><code>0x63</code></td><td><code>rs1, rs2, label</code></td><td>Branch not equal</td></tr> +<tr><td><code>BLT</code></td><td>B</td><td><code>0x63</code></td><td><code>rs1, rs2, label</code></td><td>Branch less than (signed)</td></tr> +<tr><td><code>BGE</code></td><td>B</td><td><code>0x63</code></td><td><code>rs1, rs2, label</code></td><td>Branch greater than or equal (signed)</td></tr> +<tr><td><code>BLTU</code></td><td>B</td><td><code>0x63</code></td><td><code>rs1, rs2, label</code></td><td>Branch less than (unsigned)</td></tr> +<tr><td><code>BGEU</code></td><td>B</td><td><code>0x63</code></td><td><code>rs1, rs2, label</code></td><td>Branch greater than or equal (unsigned)</td></tr> +<tr><td><code>JAL</code></td><td>J</td><td><code>0x6F</code></td><td><code>rd, label</code></td><td>Jump and link — jump to PC+offset, save return address to rd</td></tr> +<tr><td><code>JALR</code></td><td>I</td><td><code>0x67</code></td><td><code>rd, rs1, offset</code></td><td>Jump and link register — jump to rs1+offset, save return address</td></tr> +<tr><td><code>FENCE</code></td><td>I</td><td><code>0x0F</code></td><td><code>pred, succ</code></td><td>Memory ordering fence</td></tr> +<tr><td><code>FENCEI</code></td><td>I</td><td><code>0x0F</code></td><td><code>—</code></td><td>Instruction fence — synchronizes instruction and data streams</td></tr> +<tr><td><code>ECALL</code></td><td>I</td><td><code>0x73</code></td><td><code>—</code></td><td>Environment call — raises a system call exception</td></tr> +<tr><td><code>EBREAK</code></td><td>I</td><td><code>0x73</code></td><td><code>—</code></td><td>Breakpoint — raises a breakpoint exception</td></tr> +<tr><td><code>CSRRW</code></td><td>I</td><td><code>0x73</code></td><td><code>rd, csr, rs1</code></td><td>Atomic read/write CSR — writes rs1 to CSR, returns old value in rd</td></tr> +<tr><td><code>CSRRS</code></td><td>I</td><td><code>0x73</code></td><td><code>rd, csr, rs1</code></td><td>Atomic read and set bits in CSR</td></tr> +<tr><td><code>CSRRC</code></td><td>I</td><td><code>0x73</code></td><td><code>rd, csr, rs1</code></td><td>Atomic read and clear bits in CSR</td></tr> +<tr><td><code>CSRRWI</code></td><td>I</td><td><code>0x73</code></td><td><code>rd, csr, uimm5</code></td><td>Atomic read/write CSR with immediate</td></tr> +<tr><td><code>CSRRSI</code></td><td>I</td><td><code>0x73</code></td><td><code>rd, csr, uimm5</code></td><td>Atomic read and set bits in CSR with immediate</td></tr> +<tr><td><code>CSRRCI</code></td><td>I</td><td><code>0x73</code></td><td><code>rd, csr, uimm5</code></td><td>Atomic read and clear bits in CSR with immediate</td></tr> +</tbody></table> +</section> +</article> +</body> +</html> 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 +``` + diff --git a/doc/spec/isa_reference.pdf b/doc/spec/isa_reference.pdf Binary files differnew file mode 100644 index 0000000..73f0733 --- /dev/null +++ b/doc/spec/isa_reference.pdf |
