RISC-V assembler instructions
This is a list of the instructions supported by the RISC-V Lisp assembler at: RISC-V assembler in uLisp.
Operation | Example | Action | Notes | |
Move |
Register to register |
($mv 'a0 'a1) |
a0 = a1 |
|
Arithmetic |
Add Add immed. Subtract Negate Add upper immed. to PC |
($add 'a0 'a1 'a2) ($addi 'a0 'a1 8) ($sub 'a0 'a1 'a2) ($neg 'a0 'a1) ($auipc 'a0 imm) |
a0 = a1 + a2 a0 = a1 + imm a0 = a1 - a2
a0 = PC + imm[31:12] |
Range: -0x800 to 0x7FF
Range 0 to 1020 (word aligned) |
Multiply/ |
Multiply Multiply upper word Multiply upper word Multiply upper word Divide Divide unsigned Remainder Remainder unsigned |
($mul 'a0 'a1 'a2) ($mulh 'a0 'a1 'a2) ($mulhsu 'a0 'a1 'a2) ($mulhu 'a0 'a1 'a2) ($div 'a0 'a1 'a2) ($divu 'a0 'a1 'a2) ($rem 'a0 'a1 'a2) ($remu 'a0 'a1 'a2) |
a0 = a1 * a2
a0 = a1 / a2
a0 = a1 % a2 |
Lower result word Upper result word signed x signed Upper result word unsigned x unsigned Upper result word signed x unsigned Signed division Unsigned division Signed remainder Unsigned remainder |
Compare |
Set if less than Set if less than unsigned Set if less than immed. Set if less than immed. unsigned Set if equal to zero Set if not equal to zero Set if less than zero Set if greater than zero |
($slt 'a0 'a1 'a2) ($sltu 'a0 'a1 'a2) ($slti 'a0 'a1 immed) ($sltiu 'a0 'a1 immed) ($seqz 'a0 'a1) ($snez 'a0 'a1) ($sltz 'a0 'a1) ($sgtz 'a0 'a1) |
Result false=0, true=1 |
Immed. range: -0x800 to 0x7FF |
Logical |
AND AND immed. OR OR immed. XOR XOR immed. NOT |
($and 'a0 'a1 'a2) ($andi 'a0 'a1 imm) ($or 'a0 'a1 'a2) ($ori 'a0 'a1 imm) ($xor 'a0 'a1 'a2) ($xori 'a0 'a1 imm) ($not 'a0 'a1) |
a0 = a1 AND a2 a0 = a1 AND imm a0 = a1 OR a2 a0 = a1 OR imm a0 = a1 XOR a2 a0 = a1 XOR imm a0 = NOT a1 |
Immed. range: -0x800 to 0x7FF |
Shift/ |
Shift left logical Shift left logical immed. Shift right logical Shift right logical immed. Shift right arithmetic Shift right arith immed. |
($sll 'a0 'a1 'a2) ($slli 'a0 'a1 imm) ($srl 'a0 'a1 'a2) ($srli 'a0 'a1 imm) ($sra 'a0 'a1 'a2) ($srai 'a0 'a1 imm) |
a0 = a1 << a2 a0 = a1 << imm a0 = a1 >> a2 a0 = a1 >> imm a0 = a1 >> a2 a0 = a1 >> imm |
Sign extended Sign extended |
Load |
Load byte Load byte unsigned Load half Load half unsigned Load word Load immed. Load upper immed. |
($lb 'a0 imm '(a1)) ($lbu 'a0 imm '(a1)) ($lh 'a0 imm '(a1)) ($lhu 'a0 imm '(a1)) ($lw 'a0 imm '(a1)) ($li 'a0 imm) ($lui 'a0 imm) |
a0 = (a1 + imm) a0 = (a1 + imm) a0 = (a1 + imm) a0 = (a1 + imm) a0 = (a1 + imm) a0 = imm a0 = imm[31:12] |
Sign extended * Zero extended * Sign extended * Zero extended * Sign extended * Zero extended Immed. range 0 to #xfffff |
Store |
Store byte Store half Store word |
($sb 'a0 imm '(a1)) ($sh 'a0 imm '(a1)) ($sw 'a0 imm '(a1)) |
(a1 + imm) = a0 (a1 + imm) = a0 (a1 + imm) = a0 |
* * * |
Extend | Sign extend word | ($sext.w 'a0 'a1) | a0 = sign extend a1 | Any except pc. |
Branch |
Branch = Branch = 0 Branch ≠ Branch ≠ 0 Branch ≤ Branch ≤ unsigned Branch ≤ 0 Branch ≥ Branch ≥ unsigned Branch ≥ 0 Branch < Branch < unsigned Branch < 0 Branch > Branch > unsigned Branch > 0 |
($beq 'a0 'a1 label) ($beqz 'a0 label) ($bne 'a0 'a1 label) ($bnez 'a0 label) ($ble 'a0 'a1 label) ($bleu 'a0 'a1 label) ($blez 'a0 label) ($bge 'a0 'a1 label) ($bgeu 'a0 'a1 label) ($bgez 'a0 label) ($blt 'a0 'a1 label) ($bltu 'a0 'a1 label) ($bltz 'a0 label) ($bgt 'a0 'a1 label) ($bgtu 'a0 'a1 label) ($bgtz 'a0 label) |
|
Range PC-4096 to PC+4095 |
Jump and link |
Jump Jump and link Jump and link Jump & link register Jump register Return |
($j label) ($jal label) ($jal 'a0 label) ($jalr label '(a0)) ($jr 'a0) ($ret) |
PC = label PC = label, ra = next PC = label, a0 = next PC = label+a0, ra = next PC = a0 |
|
State | Fence | ($fence) | ||
No op | No operation | ($nop) |
* imm can be omitted and defaults to 0.
I recommend this RISC-V quick ref card for a good introduction to programming in RISC-V assembler.