This is another yet-unnamed fantasy CPU instruction set inspired by RISC-V, MIPS, and Professor Bruce Jacob's RiSC-16. It has fixed-length 16 bit instructions, 7 general purpose registers, and a zero register.
The eight registers directly available contain 16 bit, two's-compliment integers. The zero register always returns 0, and all writes to it are ignored. Whether an instruction's immediate value is interpreted as signed or unsigned depends on the opcode.
A fault will be triggered if the program counter or a SW/LW is not word-aligned.
F E D C B A 9 8 7 6 5 4 3 2 1 0 Bit ├───┼───────────┼───────────┼───────────┼───────────────────┤ │ 0 │ rs2 │ rs1 │ rd │ opcode │ RRR Type └───┴───────────┴───────────┴───────────┴───────────────────┘
F E D C B A 9 8 7 6 5 4 3 2 1 0 Bit ├───────────────┼───────────┼───────────┼───────────────────┤ │ imm5 │ rs1 │ rd │ opcode │ RRI Type └───────────────┴───────────┴───────────┴───────────────────┘
F E D C B A 9 8 7 6 5 4 3 2 1 0 Bit ├───────────────────────────┼───────────┼───────────────────┤ │ imm8 │ rd │ opcode │ RI Type └───────────────────────────┴───────────┴───────────────────┘
┌─────┬──┬───┬─────┐ │00000│00│RRR│ ADD│ rd := rs1 + rs2 ├─────┼──┼───┼─────┤ │00001│01│RRR│ SUB│ rd := rs1 - rs2 ├─────┼──┼───┼─────┤ │00010│02│RRR│ SLL│ rd := rs1 << rs2 ├─────┼──┼───┼─────┤ │00011│03│RRR│ SRL│ rd := rs1 >>> rs2 ├─────┼──┼───┼─────┤ │00100│04│RRR│ SRA│ rd := rs1 >> rs2 ├─────┼──┼───┼─────┤ │00101│05│RRI│ ADDI│ rd := rs1 + (signed)imm5 ├─────┼──┼───┼─────┤ │00110│06│RI │ LUI│ rd := imm8 << 8 ├─────┼──┼───┼─────┤ │00111│07│RI │ LLI│ rd := (rd & 0xFF00) | imm8 └─────┴──┴───┴─────┘
┌─────┬──┬───┬─────┐ │01000│08│RRI│ SW│ *(u16)(rd + imm5) := rs1 ├─────┼──┼───┼─────┤ │01001│09│RRI│ LW│ rd := *(u16)(rs1 + imm5) ├─────┼──┼───┼─────┤ │01010│0A│RRI│ SB│ *(u8)(rd + imm5) := rs1 & 0xFF ├─────┼──┼───┼─────┤ │01011│0B│RRI│ LB│ rd := *(u8)(rs1 + imm5) ├─────┼──┼───┼─────┤ │01100│0C│RRI│ LBU│ rd := *(i8)(rs1 + imm5) ├─────┼──┼───┼─────┤ │01101│0D│ │ │ │01110│0E│ │ │ Reserved │01111│0F│ │ │ └─────┴──┴───┴─────┘
┌─────┬──┬───┬─────┐ │10000│10│RRR│ AND│ rd := rs1 & rs2 ├─────┼──┼───┼─────┤ │10001│11│RRR│ OR│ rd := rs1 | rs2 ├─────┼──┼───┼─────┤ │10010│12│RRR│ XOR│ rd := rs1 ^ rs2 └─────┴──┴───┴─────┘
┌─────┬──┬───┬─────┐ │10011│13│RRR│ EQ│ rd := rs1 == rs2 ├─────┼──┼───┼─────┤ │10100│14│RRR│ GT│ rd := (signed)rs1 > (signed)rs2 ├─────┼──┼───┼─────┤ │10101│15│RRR│ GE│ rd := (signed)rs1 >= (signed)rs2 ├─────┼──┼───┼─────┤ │10110│16│RRR│ GTU│ rd := (unsigned)rs1 > (unsigned)rs2 ├─────┼──┼───┼─────┤ │10111│17│RRR│ GEU│ rd := (unsigned)rs1 >= (unsigned)rs2 └─────┴──┴───┴─────┘
┌─────┬──┬───┬─────┐ │11000│18│RRR│ JLR│ rd := pc + 2; pc := rs1 + (signed)rs2 ├─────┼──┼───┼─────┤ │11001│19│RI │ BNS│ if rd == 0 then pc := pc + (signed)(imm8 * 2) ├─────┼──┼───┼─────┤ │11010│1A│RI │ BS│ if rd != 0 then pc := pc + (signed)(imm8 * 2) ├─────┼──┼───┼─────┤ │11011│1B│ │ │ Reserved └─────┴──┴───┴─────┘
┌─────┬──┬───┬─────┐ │11100│1C│RI │ SF│ csr[imm8] := rd ├─────┼──┼───┼─────┤ │11101│1D│RI │ LF│ rd := csr[imm8] ├─────┼──┼───┼─────┤ │11110│1E│RI │ SYC│ System call ├─────┼──┼───┼─────┤ │11111│1F│RI │ BRK│ Break to debugger/environment └─────┴──┴───┴─────┘
# routine that prints 'hello, world\n' to an imaginary uart .org $0100 Start: li r1, Hello addi r2, r0, 13 addi r3, r0, 4 # the imaginary uart's address @Loop: lbu r4, r1, 0 sb r1, r4, 0 addi r1, r1, 1 addi r2, r2, -1 eq r4, r2, r0 bns r4, @Loop brk $00 .org $0200 Hello: .ascii "hello, world" .byte $0a
┌───┬────────────────────────────────────────┐ │nop│ add r0, r0, r0│ ├───┼────────────────────────────────────────┤ │not│ sub A, B, r0│ ├───┼────────────────────────────────────────┤ │li │lui A, IMM & 0xFF00; lli A, IMM & 0x00FF│ └───┴────────────────────────────────────────┘
A reference assembler written in Lua will be available soon.