RISC-V assembler instructions

The RISC-V Lisp assembler supports the following instructions:

Operation   Example Action Notes
Move

Register to register

($mv 'a0 'a1)

a0 = a1

 
Arithmetic

Add

Add immediate

Add word

Add immediate word

Subtract

Subtract word

Add upper imm to PC

($add 'a0 'a1 'a2)

($addi 'a0 'a1 8)

($addw 'a0 'a1 'a2)

($addiw 'a0 'a1 8)

($sub 'a0 'a1 'a2)

($subw 'a0 'a1 'a2)

($auipc 'a0 imm)

a0 = a1 + a2

a0 = a1 + imm

a0 = a1 + a2

a0 = a1 + imm

r0 = sp + 4

 

a0 = PC + imm[31:12]

 

Range -2048 to 2047

 

Range -2048 to 2047

Range 0 to 1020 (word aligned)

 

Multiply/
divide/
remainder 

Multiply

Multiply upper word

Multiply upper word

Multiply upper word

Divide

Divide unsigned

Divide word

Divide unsigned word

Remainder

Remainder unsigned

Remainder word

Remainder un. word

($mul 'a0 'a1 'a2)

($mulh 'a0 'a1 'a2)

($mulhsu 'a0 'a1 'a2)

($mulhu 'a0 'a1 'a2)

($div 'a0 'a1 'a2)

($divu 'a0 'a1 'a2)

($divw 'a0 'a1 'a2)

($divuw 'a0 'a1 'a2)

($rem 'a0 'a1 'a2)

($remu 'a0 'a1 'a2)

($remw 'a0 'a1 'a2)

($remuw '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

Compare

Set less than

($slt 'a0 'a1 'a2)

 

 

Logical

AND

AND immediate

OR

OR immediate

XOR

XOR immediate

($and 'a0 'a1 'a2)

($andi 'a0 'a1 imm)

($or 'a0 'a1 'a2)

($ori 'a0 'a1 imm)

($xor 'a0 'a1 'a2)

($xori 'a0 'a1 imm)

a0 = a1 AND a2

a0 = a1 AND imm

a0 = a1 OR a2

a0 = a1 OR imm

a0 = a1 XOR a2

a0 = a1 XOR imm

 

Range -2048 to 2047

 

Range -2048 to 2047

 

Range -2048 to 2047

Shift/
rotate

Shift left logical

Shift left logical word

Shift left logical imm

Shift right logical

Shift right logical word

Shift right logical imm

Shift right arithmetic

Shift right arith word

Shift right arith imm

($sll a0 'a1 'a2)

($sllw a0 'a1 'a2)

($slli a0 'a1 imm)

($srl a0 'a1 'a2)

($srlw a0 'a1 'a2)

($srli a0 'a1 imm)

($sra a0 'a1 'a2)

($sraw a0 'a1 'a2)

($srai a0 'a1 imm)

r0 = r1 << 3

r0 = r0 << r2[7:0]

r0 = r1 >> 3

r0 = r0 >> r2[7:0]

r0 = r1 ASR 3

r0 = r0 ASR r2[7:0]

r0 = r0 ROR r2[7:0]

Range 0 to 31.

 

Range 0 to 31.

 

Range 0 to 31.

Load

Load byte

Load byte unsigned

Load half

Load half unsigned

Load word

Load word unsigned

Load double

Load immediate

Load upper imm.

($lb 'a0 imm '(a1))

($lbu 'a0 imm '(a1))

($lh 'a0 imm '(a1))

($lhu 'a0 imm '(a1))

($lw 'a0 imm '(a1))

($lwu 'a0 imm '(a1))

($ld '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 = (a1 + imm)

a0 = (a1 + imm)

a0 = imm

a0 = imm[31:12]

Sign extended

Zero extended

Sign extended

Zero extended

Sign extended

Zero extended

Store

Store byte

Store half

Store word

Store double

($sb 'a0 imm '(a1))

($sh 'a0 imm '(a1))

($sw 'a0 imm '(a1))

($sd 'a0 imm '(a1))

(a1 + imm) = a0

(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 ≤ 0

Branch ≥

Branch ≥ unsigned

Branch ≥ 0

Branch <

Branch < unsigned

Branch < 0

Branch >

Branch > 0

($beq 'a0 'a1 label)

($beqz 'a0 label)

($bne 'a0 'a1 label)

($bnez 'a0 label)

($ble '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)

($bgtz 'a0 label)

 

Range PC-4096 to PC+4095

Jump and link

Jump

Jump and link

Jump and link

Jump & link register

Jump register

($j label)

($jal label)

($jal 'a0 label)

($jalr label '(a0))

($jr 'a0)

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)    

I recommend this RISC-V quick ref card for a good introduction to programming in RISC-V assembler.