{"id":29861021,"url":"https://github.com/shalan/zx16","last_synced_at":"2025-07-30T04:10:11.617Z","repository":{"id":281644905,"uuid":"945911526","full_name":"shalan/zx16","owner":"shalan","description":"A 16-bit RISC-V Inspired ISA","archived":false,"fork":false,"pushed_at":"2025-07-19T09:16:51.000Z","size":1109,"stargazers_count":23,"open_issues_count":12,"forks_count":21,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-07-19T13:26:13.894Z","etag":null,"topics":["assembler","computer-architecture","isa"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/shalan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-03-10T10:17:17.000Z","updated_at":"2025-07-19T09:16:54.000Z","dependencies_parsed_at":"2025-03-10T11:46:27.457Z","dependency_job_id":"04015404-207f-4a95-a631-296eaaf52d2a","html_url":"https://github.com/shalan/zx16","commit_stats":null,"previous_names":["shalan/z16","shalan/zx16"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/shalan/zx16","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shalan%2Fzx16","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shalan%2Fzx16/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shalan%2Fzx16/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shalan%2Fzx16/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/shalan","download_url":"https://codeload.github.com/shalan/zx16/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/shalan%2Fzx16/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267808215,"owners_count":24147388,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-30T02:00:09.044Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["assembler","computer-architecture","isa"],"created_at":"2025-07-30T04:10:08.728Z","updated_at":"2025-07-30T04:10:11.589Z","avatar_url":"https://github.com/shalan.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ZX16 RISC ISA Specification\n\n## Overview\nThe ZX16 RISC ISA is a 16-bit reduced-instruction-set architecture designed for simplicity, efficiency, and educational use. It features:\n- **16-bit fixed-width** instructions and data  \n- **8 general-purpose registers** (x0–x7) plus a 16-bit PC  \n- **64 KB flat address space** for code, data, MMIO, and interrupt vectors  \n- **8 instruction formats** selected by bits [2:0]  \n- **50+ real \u0026 pseudo-instructions** covering ALU, branches, loads/stores, jumps, upper-immediates, and syscalls  \n- **Smart immediates**: any immediate \u003c 16 bits is sign-extended  \n- **PC-relative control flow**: all branches, J and JAL use PC-relative offsets  \n- **Memory-mapped I/O** at 0xF000–0xFFFF  \n- **16 interrupt vectors** at 0x0000–0x001F (2 bytes each; reset at 0x0000)\n\n---\n\n## Key Features\n- Compact 16-bit instructions  \n- Two-operand ALU (rd/rs1 is both destination \u0026 first source)  \n- Smart assembler handles large constants via pseudo-ops  \n- Rich syscall interface for I/O, graphics, audio  \n- Little-endian byte order\n- Aligned memory access required for word operations\n- Byte-addressable memory\n\n---\n\n## Register Architecture\n\n### General-Purpose Registers\n\n| Register | ABI | Role                    | Notes                       |\n|:--------:|:---:|:-----------------------:|:----------------------------|\n| x0       | t0  | Temporary               | Caller-saved scratch/Assembler Temporary        |\n| x1       | ra  | Return address          | Used by JAL/JALR            |\n| x2       | sp  | Stack pointer           | Initialized to 0xEFFE       |\n| x3       | s0  | Saved / Frame pointer   | Callee-saved                |\n| x4       | s1  | Saved                   | Callee-saved                |\n| x5       | t1  | Temporary               | Caller-saved scratch        |\n| x6       | a0  | Arg0 / Return value     |                             |\n| x7       | a1  | Arg1                    | Further args spill to stack |\n\n### Special Registers\n- **PC**: 16-bit program counter  \n\n### Reset Behavior\n- **PC**: Initialized to 0x0000 on reset\n- **x0-x7**: Undefined values on reset (not initialized)\n\n---\n\n## Memory Map\n\n| Range         | Usage                                        |\n|:-------------:|:---------------------------------------------|\n| 0x0000–0x001F | Interrupt vector table (16 entries × 2 bytes)|\n| 0x0020–0xEFFF | RAM \u0026 ROM                                    |\n| 0xF000–0xFFFF | MMIO (I/O registers start at 0xF000)         |\n\n### Memory Properties\n- **Endianness**: Little-endian\n- **Addressing**: Byte-addressable\n- **Alignment**: Word accesses (SW/LW) must be aligned to even addresses\n- **Stack**: Grows downward from 0xEFFE\n\n## Interrupt Vector Table\n- 16 fixed entries at 0x0000–0x001E (2 bytes each)  \n- Reset handler at 0x0000; others at 0x0002, 0x0004, …, 0x001E  \n\n---\n\n## Instruction Formats\n\nEvery instruction is 16 bits, with bits [2:0] as primary opcode:\n\n| opcode ([2:0]) | Format    |\n|:--------------:|:----------|\n| 000            | R-Type    |\n| 001            | I-Type    |\n| 010            | B-Type    |\n| 011            | S-Type    |\n| 100            | L-Type    |\n| 101            | J-Type    |\n| 110            | U-Type    |\n| 111            | SYS-Type  |\n\n---\n\n## ZX16 Instruction Format Field Layouts\n\nAll instructions are 16 bits. Bits [2:0] select the format/opcode.\n## Instruction Formats\n\nAll instructions are 16 bits with bits [2:0] as primary opcode:\n\n### R-Type (opcode = `000`)\n```\n15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0\n┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐\n│    funct4     │    rs2    │  rd/rs1   │   func3   │ 0 │ 0 │ 0 │\n└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘\n```\n- **[15:12]** funct4  \n- **[11:9]** rs2  \n- **[8:6]** rd/rs1 (two‐operand: dest \u0026 first source)  \n- **[5:3]** func3  \n- **[2:0]** 000  \n\n### I-Type (opcode = `001`)\n```\n15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0\n┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐\n│        imm7 (signed)      │  rd/rs1   │   func3   │ 0 │ 0 │ 1 │\n└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘\n```\n- **[15:9]** imm7 (7-bit signed immediate, sign-extended)  \n- **[8:6]** rd/rs1  \n- **[5:3]** func3  \n- **[2:0]** 001  \n\n**Note**: For shift instructions: `shift_amt = imm7[3:0]}`; `imm7[6:4]` are used to determine the shift type.\n\n### B-Type (opcode = `010`)\n```\n15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0\n┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐\n│   imm[4:1]    │    rs2    │   rs1     │   func3   │ 0 │ 1 │ 0 │\n└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘\n```\n- **[15:12]** imm[4:1] (high 4 bits of 5-bit signed offset, imm[0] = 0) -- Range: -16 to 14.  \n- **[11:9]** rs2 (ignored for BZ/BNZ)  \n- **[8:6]** rs1  \n- **[5:3]** func3  \n- **[2:0]** 010  \n\n### S-Type (opcode = `011`)\n```\n15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0\n┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐\n│   imm[3:0]    │    rs2    │   rs1     │   func3   │ 0 │ 1 │ 1 │\n└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘\n```\n- **[15:12]** imm[3:0] (4-bit signed store offset) -- Range: -8 to +7 \n- **[11:9]** rs2 (data register)  \n- **[8:6]** rs1 (base register)  \n- **[5:3]** func3  \n- **[2:0]** 011  \n\n### L-Type (opcode = `100`)\n```\n15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0\n┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐\n│   imm[3:0]    │    rs2    │    rd     │   func3   │ 1 │ 0 │ 0 │\n└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘\n```\n- **[15:12]** imm[3:0] (4-bit signed load offset) -- Range: -8 to +7\n- **[11:9]** rs2 (base register)  \n- **[8:6]** rd (destination register)  \n- **[5:3]** func3  \n- **[2:0]** 100  \n\n### J-Type (opcode = `101`)\n```\n15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0\n┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐\n│ L │         imm[9:4]      │    rd     │ imm[3:1]  │ 1 │ 0 │ 1 │\n└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘\n```\n- **[15]** link flag (0 = J, 1 = JAL)  \n- **[14:9]** imm[9:4] (high 6 bits of 10-bit signed offset, imm[0] = 0) -- Range: -1024 to +1022 \n- **[8:6]** rd (link register for JAL)  \n- **[5:3]** imm[3:1] (low 3 bits of offset)  \n- **[2:0]** 101  \n\n### U-Type (opcode = `110`)\n```\n15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0\n┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐\n│ F │   imm[15:10]      │    rd     │ imm[9:7]  │ 1 │ 1 │ 0 │\n└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘\n```\n\n- **[15]** flag (0 = LUI, 1 = AUIPC)  \n- **[14:9]** imm[15:10] (high 6 bits of immediate)  \n- **[8:6]** rd  \n- **[5:3]** imm[9:7] (mid 3 bits of immediate)  \n- **[2:0]** 110  \n\n### SYS-Type (opcode = `111`)\n```\n15  14  13  12  11  10   9   8   7   6   5   4   3   2   1   0\n┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐\n│              svc[9:0]                 │ 0 │ 0 │ 0 │ 1 │ 1 │ 1 │\n└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘\n```\n\n- **[15:6]** svc (10-bit system-call number)  \n- **[5:3]** 000  \n- **[2:0]** 111  \n\n---\n\n## Instruction Set Reference\n\n### R-Type Instructions\n| Mnemonic | Description                               |\n|:--------:|:------------------------------------------|\n| **ADD**  | rd ← rd + rs2                             |\n| **SUB**  | rd ← rd – rs2                             |\n| **SLT**  | rd ← (rd \u003c rs2) ? 1 : 0                   |\n| **SLTU** | rd ← (unsigned rd \u003c unsigned rs2) ? 1 : 0 |\n| **SLL**  | rd ← rd \u003c\u003c (rs2 \u0026 0xF)                    |\n| **SRL**  | rd ← rd \u003e\u003e (rs2 \u0026 0xF) (logical)          |\n| **SRA**  | rd ← rd \u003e\u003e (rs2 \u0026 0xF) (arithmetic)       |\n| **OR**   | rd ← rd ∣ rs2                             |\n| **AND**  | rd ← rd ∧ rs2                             |\n| **XOR**  | rd ← rd ⊕ rs2                             |\n| **MV**   | rd ← rs2                                  |\n| **JR**   | PC ← rd                                   |\n| **JALR** | rd ← PC + 2; PC ← rs2                     |\n\n### I-Type Instructions\n| Mnemonic  | Description                                     |\n|:---------:|:------------------------------------------------|\n| **ADDI**  | rd ← rd + sext(imm7)                            |\n| **SLTI**  | rd ← (rd \u003c sext(imm7)) ? 1 : 0                  |\n| **SLTUI** | rd ← (unsigned rd \u003c unsigned sext(imm7)) ? 1 : 0|\n| **SLLI**  | rd ← rd \u003c\u003c imm[3:0]                             |\n| **SRLI**  | rd ← rd \u003e\u003e imm[3:0] (logical)                   |\n| **SRAI**  | rd ← rd \u003e\u003e imm[3:0] (arithmetic)                |\n| **ORI**   | rd ← rd ∣ sext(imm7)                            |\n| **ANDI**  | rd ← rd ∧ sext(imm7)                            |\n| **XORI**  | rd ← rd ⊕ sext(imm7)                            |\n| **LI**    | rd ← sext(imm7)                                 |\n\n### B-Type Instructions\n| Mnemonic | Description                                          |\n|:--------:|:-----------------------------------------------------|\n| **BEQ**  | PC ← PC + offset if x[rs1] == x[rs2]                 |\n| **BNE**  | PC ← PC + offset if x[rs1] != x[rs2]                 |\n| **BZ**   | PC ← PC + offset if x[rs1] == 0                     |\n| **BNZ**  | PC ← PC + offset if x[rs1] != 0                     |\n| **BLT**  | PC ← PC + offset if x[rs1] \u003c x[rs2]                  |\n| **BGE**  | PC ← PC + offset if x[rs1] ≥ x[rs2]                  |\n| **BLTU** | PC ← PC + offset if unsigned x[rs1] \u003c unsigned x[rs2]|\n| **BGEU** | PC ← PC + offset if unsigned x[rs1] ≥ unsigned x[rs2]|\n\n### S-Type Instructions\n| Mnemonic | Description                                                      |\n|:--------:|:-----------------------------------------------------------------|\n| **SB**   | Mem[x[rs1] + sext(imm4)] ← least-significant byte of x[rs2]     |\n| **SW**   | Mem[x[rs1] + sext(imm4)] ← x[rs2] (16 bits)                     |\n\n### L-Type Instructions\n| Mnemonic | Description                                                   |\n|:--------:|:--------------------------------------------------------------|\n| **LB**   | rd ← sign-extended byte at Mem[x[rs2] + sext(imm4)]          |\n| **LW**   | rd ← word at Mem[x[rs2] + sext(imm4)] (16 bits)              |\n| **LBU**  | rd ← zero-extended byte at Mem[x[rs2] + sext(imm4)]          |\n\n### J-Type Instructions\n| Mnemonic | Description                           |\n|:--------:|:--------------------------------------|\n| **J**    | PC ← PC + offset                      |\n| **JAL**  | x[rd] ← PC + 2; PC ← PC + offset      |\n\n### U-Type Instructions\n| Mnemonic  | Description                      |\n|:---------:|:---------------------------------|\n| **LUI**   | rd ← (imm[15:7] \u003c\u003c 7)            |\n| **AUIPC** | rd ← PC + (imm[15:7] \u003c\u003c 7)       |\n\n### SYS-Type Instructions\n| Mnemonic | Description                              |\n|:--------:|:-----------------------------------------|\n| **ECALL**| Trap to service number in bits [15:6]   |\n\n---\n\n## Instruction Identification Table\n\nThis table shows, for each instruction, the key fields used to distinguish it: the primary opcode (bits [2:0]), plus any `funct4`, `func3`, `link` or `flag` bits, or immediate‐pattern conditions.\n\n| Mnemonic | Format | opcode [2:0] | funct4 [15:12] | func3 [5:3] | link/flag (bit15)      | imm‐pattern/notes             |\n|:--------:|:------:|:------------:|:--------------:|:-----------:|:-----------------------:|:------------------------------|\n| **R-Type** |||||||\n| ADD      | R      | `000`        | `0000`         | `000`       | —                       | two‐operand                    |\n| SUB      | R      | `000`        | `0001`         | `000`       | —                       |                                |\n| SLT      | R      | `000`        | `0010`         | `001`       | —                       |                                |\n| SLTU     | R      | `000`        | `0011`         | `010`       | —                       |                                |\n| SLL      | R      | `000`        | `0100`         | `011`       | —                       | logical left shift            |\n| SRL      | R      | `000`        | `0101`         | `011`       | —                       | logical right shift           |\n| SRA      | R      | `000`        | `0110`         | `011`       | —                       | arithmetic right shift        |\n| OR       | R      | `000`        | `0111`         | `100`       | —                       |                                |\n| AND      | R      | `000`        | `1000`         | `101`       | —                       |                                |\n| XOR      | R      | `000`        | `1001`         | `110`       | —                       |                                |\n| MV       | R      | `000`        | `1010`         | `111`       | —                       | move                           |\n| JR       | R      | `000`        | `1011`         | `000`       | —                       | PC ← rd                        |\n| JALR     | R      | `000`        | `1100`         | `000`       | —                       | link in rd, then PC ← rs2     |\n| **I-Type** |||||||\n| ADDI     | I      | `001`        | —              | `000`       | —                       | imm7 signed                   |\n| SLTI     | I      | `001`        | —              | `001`       | —                       | imm7 signed                   |\n| SLTUI    | I      | `001`        | —              | `010`       | —                       | imm7 unsigned compare         |\n| SLLI     | I      | `001`        | —              | `011`       | —                       | shift left logical, imm7[6:4]=`001` |\n| SRLI     | I      | `001`        | —              | `011`       | —                       | shift right logical, imm7[6:4]=`010` |\n| SRAI     | I      | `001`        | —              | `011`       | —                       | shift right arithmetic, imm7[6:4]=`100` |\n| ORI      | I      | `001`        | —              | `100`       | —                       |                                |\n| ANDI     | I      | `001`        | —              | `101`       | —                       |                                |\n| XORI     | I      | `001`        | —              | `110`       | —                       |                                |\n| LI       | I      | `001`        | —              | `111`       | —                       | load imm7                     |\n| **B-Type** |||||||\n| BEQ      | B      | `010`        | —              | `000`       | —                       | offset = sext(imm[4:1]∥0)     |\n| BNE      | B      | `010`        | —              | `001`       | —                       |                                |\n| BZ       | B      | `010`        | —              | `010`       | —                       | ignore rs2                    |\n| BNZ      | B      | `010`        | —              | `011`       | —                       | ignore rs2                    |\n| BLT      | B      | `010`        | —              | `100`       | —                       |                                |\n| BGE      | B      | `010`        | —              | `101`       | —                       |                                |\n| BLTU     | B      | `010`        | —              | `110`       | —                       | unsigned compare              |\n| BGEU     | B      | `010`        | —              | `111`       | —                       | unsigned compare              |\n| **S-Type** |||||||\n| SB       | S      | `011`        | —              | `000`       | —                       | store byte, offset=sext(imm[3:0]) |\n| SW       | S      | `011`        | —              | `001`       | —                       | store word                    |\n| **L-Type** |||||||\n| LB       | L      | `100`        | —              | `000`       | —                       | load byte                     |\n| LW       | L      | `100`        | —              | `001`       | —                       | load word                     |\n| LBU      | L      | `100`        | —              | `100`       | —                       | load byte unsigned            |\n| **J-Type** |||||||\n| J        | J      | `101`        | —              | —           | link=0                  | offset = sext({imm[9:4],imm[3:1],0}) |\n| JAL      | J      | `101`        | —              | —           | link=1                  | link in rd, then PC-relative  |\n| **U-Type** |||||||\n| LUI      | U      | `110`        | —              | —           | flag=0                  | imm from bits [15:7]\u003c\u003c7      |\n| AUIPC    | U      | `110`        | —              | —           | flag=1                  | PC + (imm\u003c\u003c7)                |\n| **SYS-Type** |||||||\n| ECALL    | SYS    | `111`        | —              | —           | —                       | trap to service number [15:6] |\n\n---\n\n## Pseudo-Instructions\n\nZX16 supports several pseudo-instructions that expand to one or more real instructions:\n\n### **LI16 rd, imm16** - Load 16-bit immediate\n#### Standard case (bit 6 clear):\n```LI16 x1, 0x1234```\nExpands to:\n```assembly\nLUI  x1, 0x24      # Load upper 9 bits (0x1234 \u003e\u003e 7 = 0x24)\nADDI x1, 0x34      # Add lower 7 bits (0x1234 \u0026 0x7F = 0x34)\n```\n#### Corner case (bit 6 set - ADDI immediate will be negative):\n```assembly\nLI16 x1, 0x00FF\n```\nExpands to:\n```assembly\nLUI  x1, 0x02      # Load upper 9 bits + 1 ((0x00FF \u003e\u003e 7) + 1 = 0x02)\nADDI x1, -1        # Add lower 7 bits as signed (0xFF \u0026 0x7F = 0x7F = -1 in 7-bit signed)\n```\n### **LA rd, label** - Load address\n```assembly\nLA x1, data_label\n# Expands to:\nAUIPC x1, ((label - PC) \u003e\u003e 7)    # PC + upper bits of relative offset\nADDI  x1, ((label - PC) \u0026 0x7F)  # Add lower 7 bits of relative offset\n```\nNote: The same `LI16` bit 6 corner case must be handled.\n\n### **LJ label*** - Long Jump (for distances beyond J range)\n```assembly\nLJ distant_label\n# Expands to:\nLI16 x0, distant_label    # Load full address into temp register  \nJR   x0                   # Jump to address in register\n```\n\n### **PUSH rd** - Push register to stack\n```assembly\nPUSH x1\n# Expands to:\nADDI x2, -2        # SP -= 2 (decrement stack pointer)\nSW   x1, 0(x2)     # Store register at new SP\n```\n\n### **POP rd** - Pop from stack to register\n```assembly\nPOP x1\n# Expands to:\nLW   x1, 0(x2)     # Load from current SP\nADDI x2, 2         # SP += 2 (increment stack pointer)\n```\n\n### **CALL label** - Call function\n```assembly\nCALL func_name\n# Expands to:\nJAL x1, offset     # Jump and link (return address in x1/ra)\n```\n\n### **RET** - Return from function\n```assembly\nRET\n# Expands to:\nJR x1              # Jump to return address (x1/ra)\n```\n\n### **INC rd** - Increment register\n```assembly\nINC x1\n# Expands to:\nADDI x1, 1         # rd = rd + 1\n```\n\n### **DEC rd** - Decrement register\n```assembly\nDEC x1\n# Expands to:\nADDI x1, -1        # rd = rd - 1\n```\n\n### **NEG rd** - Negate register (two's complement)\n```assembly\nNEG x1\n# Expands to:\nXORI x1, -1        # Invert all bits (XOR with 0x7F sign-extended)\nADDI x1, 1         # Add 1 to complete two's complement\n```\n\n### **NOT rd** - Bitwise NOT\n```assembly\nNOT x1\n# Expands to:\nXORI x1, -1        # XOR with all 1s (0x7F sign-extended to 0xFFFF)\n```\n\n### **CLR rd** - Clear register to zero\n```assembly\nCLR x1\n# Expands to:\nXOR x1, x1         # x1 = x1 XOR x1 = 0\n```\n\n### **NOP** - No operation\n```assembly\nNOP\n# Expands to:\nORI x0, 0         # x0 = x0 + x0 (does nothing useful)\n```\n\n---\n\n## Calling Convention\n\n### Function Calls\n- **Arguments**: x6 (a0), x7 (a1); additional arguments spill to stack\n- **Return value**: x6 (a0)\n- **Return address**: x1 (ra) - set by JAL/JALR, used by RET\n- **Stack pointer**: x2 (sp) - points to top of stack\n\n### Register Usage\n- **Caller-saved**: x0 (t0), x5 (t1), x6 (a0), x7 (a1)\n- **Callee-saved**: x3 (s0), x4 (s1)\n- **Special**: x1 (ra), x2 (sp)\n\n### Stack Management\n- Stack grows downward (toward lower addresses)\n- Callee must restore stack pointer before returning\n- Word-aligned stack operations recommended\n\n---\n\n## Implementation Notes\n\n### Immediate Ranges\n- **I-Type**: -64 to +63 (7-bit signed)\n- **S-Type/L-Type**: -8 to +7 (4-bit signed)\n- **B-Type**: -16 to +14 bytes (5-bit signed, word-aligned)\n- **J-Type**: -1024 to +1022 bytes (10-bit signed, word-aligned)\n- **U-Type**: 0 to 511 (9-bit unsigned immediate 0-511, shifted left 7 bits) \n\n### Shift Operations\n- **Shift amount**: Limited to 0-15 (4 bits)\n- **R-Type shifts**: Use `rs2 \u0026 0xF` as shift amount\n- **I-Type shifts**: Use `imm[3:0]` as shift amount, `imm[6:4]` selects operation\n\n### Memory Access\n- **Byte operations**: SB, LB, LBU - no alignment required\n- **Word operations**: SW, LW - must be aligned to even addresses\n- **Endianness**: Little-endian (LSB at lower address)\n\n### Control Flow\n- **Branches**: PC-relative, word-aligned targets\n- **Jumps**: PC-relative, word-aligned targets  \n- **Register jumps**: JR, JALR - absolute addressing\n\n---\n\n## Contribution\nPlease refer to the contribution guide [here](docs/contribute.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshalan%2Fzx16","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fshalan%2Fzx16","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fshalan%2Fzx16/lists"}