From 07d3bf55d2844bd1b76a1ba4c0ff85ee44ae9e43 Mon Sep 17 00:00:00 2001 From: Will Green Date: Wed, 12 Jun 2024 16:25:19 +0100 Subject: [PATCH] Add additional explanations. --- posts/riscv-cheat-sheet/index.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/posts/riscv-cheat-sheet/index.html b/posts/riscv-cheat-sheet/index.html index d5c8775d..5f0adb91 100644 --- a/posts/riscv-cheat-sheet/index.html +++ b/posts/riscv-cheat-sheet/index.html @@ -1,5 +1,5 @@ RISC-V Assembler Cheat Sheet - Project F -

This cheat sheet provides a handy guide to 32-bit RISC-V instructions. I’ve aimed it at software developers, so group instructions by purpose and include common pseudoinstructions. Clicking on a Guide link takes you to the relevant section of the Project F RISC-V assembler guide for instruction explanation and examples.

Instructions are from the base integer instruction set (RV32I) unless otherwise noted.

Share your thoughts with @WillFlux on Mastodon or X. If you like what I do, sponsor me. 🙏

DRAFT POST - NOT YET PUBLIC

Arithmetic

InstrDescriptionUseResultGuide
addAddadd rd, rs1, rs2rd = rs1 + rs2arithmetic
addiAdd Immediateaddi rd, rs1, immrd = rs1 + immarithmetic
negNegate (p)neg rd, rs2rd = -rs2arithmetic
subSubtractsub rd, rs1, rs2rd = rs1 - rs2arithmetic
mulMultiplymul rd, rs1, rs2rd = (rs1 * rs2)[31:0]multiply
mulhMultiply Highmulh rd, rs1, rs2rd = (rs1 * rs2)[63:32]multiply
mulhuMultiply High Unsignedmulhu rd, rs1, rs2rd = (rs1 * rs2)[63:32]multiply
mulhsuMultiply High Signed Unsignedmulhsu rd, rs1, rs2rd = (rs1 * rs2)[63:32]multiply
divDividediv rd, rs1, rs2rd = rs1 / rs2divide
remRemainderrem rd, rs1, rs2rd = rs1 % rs2divide

Multiply and divide instructions require the M extension.

Bitwise Logic

InstrDescriptionUseResultGuide
andANDand rd, rs1, rs2rd = rs1 & rs2logical
andiAND Immediateandi rd, rs1, immrd = rs1 & immlogical
notNOT (p)not rd, rs1rd = ~rs1logical
orORor rd, rs1, rs2rd = rs1 | rs2logical
oriOR Immediateori rd, rs1, immrd = rs1 | immlogical
xorXORxor rd, rs1, rs2rd = rs1 ^ rs2logical
xoriXOR Immediatexori rd, rs1, immrd = rs1 ^ immlogical

Shift

InstrDescriptionUseResultGuide
sllShift Left Logicalsll rd, rs1, rs2rd = rs1 << rs2shift
slliShift Left Logical Immediateslli rd, rs1, immrd = rs1 << immshift
srlShift Right Logicalsrl rd, rs1, rs2rd = rs1 >> rs2shift
srliShift Right Logical Immediatesrli rd, rs1, immrd = rs1 >> immshift
sraShift Right Arithmeticsra rd, rs1, rs2rd = rs1 >>> rs2shift
sraiShift Right Arithmetic Immediatesrai rd, rs1, immrd = rs1 >>> immshift

Load Immediate

InstrDescriptionUseResultGuide
liLoad Immediate (p)li rd, immrd = immarithmetic
luiLoad Upper Immediatelui rd, immrd = imm << 12arithmetic
auipcAdd Upper Immediate to PCauipc rd, immrd = pc + (imm << 12)branch

Load and Store

InstrDescriptionUseResultGuide
lwLoad Wordlw rd, imm(rs1)rd = mem[rs1+imm]load
lhLoad Halflh rd, imm(rs1)rd = mem[rs1+imm][0:15]load
lhuLoad Half Unsignedlhu rd, imm(rs1)rd = mem[rs1+imm][0:15]load
lbLoad Bytelb rd, imm(rs1)rd = mem[rs1+imm][0:7]load
lbuLoad Byte Unsignedlbu rd, imm(rs1)rd = mem[rs1+imm][0:7]load
laLoad Symbol Address (p)la rd, symbolrd = &symbolload
swStore Wordsw rs2, imm(rs1)mem[rs1+imm] = rs2store
shStore Halfsh rs2, imm(rs1)mem[rs1+imm][0:15] = rs2store
sbStore Bytesb rs2, imm(rs1)mem[rs1+imm][0:7] = rs2store

Jump and Function

InstrDescriptionUseResultGuide
jJump (p)j immpc += immjump
jalJump and Linkjal rd, immrd = pc+4; pc += immjump
jalrJump and Link Registerjalr rd, rs1, immrd = pc+4; pc = rs1+immjump
callCall Function (p)call symbolra = pc+4; pc = &symbolfunction
retReturn from Function (p)retpc = rafunction

In asm use a label in place of a jump immediate, for example: j label_name

Branch

This page lists all branch instructions but you may prefer the branch instruction summary.

InstrDescriptionUseResultGuide
beqBranch Equalbeq rs1, rs2, immif(rs1 == rs2) pc += immbranch
beqzBranch Equal Zero (p)beqz rs1, immif(rs1 == 0) pc += immbranch
bneBranch Not Equalbne rs1, rs2, immif(rs1 ≠ rs2) pc += immbranch
bnezBranch Not Equal Zero (p)bnez rs1, rs2, immif(rs1 ≠ 0) pc += immbranch
bltBranch Less Thanblt rs1, rs2, immif(rs1 < rs2) pc += immbranch
bltuBranch Less Than Unsignedbltu rs1, rs2, immif(rs1 < rs2) pc += immbranch
bltzBranch Less Than Zero (p)bltz rs1, immif(rs1 < 0) pc += immbranch
bgtBranch Greater Than (p)bgt rs1, rs2, immif(rs1 > rs2) pc += immbranch
bgtuBranch Greater Than Unsigned (p)bgtu rs1, rs2, immif(rs1 > rs2) pc += immbranch
bgtzBranch Greater Than Zero (p)bgtz rs1, immif(rs1 > 0) pc += immbranch
bleBranch Less or Equal (p)ble rs1, rs2, immif(rs1 ≤ rs2) pc += immbranch
bleuBranch Less or Equal Unsigned (p)bleu rs1, rs2, immif(rs1 ≤ rs2) pc += immbranch
blezBranch Less or Equal Zero (p)blez rs1, immif(rs1 ≤ 0) pc += immbranch
bgeBranch Greater or Equalbge rs1, rs2, immif(rs1 ≥ rs2) pc += immbranch
bgeuBranch Greater or Equal Unsignedbgeu rs1, rs2, immif(rs1 ≥ rs2) pc += immbranch
bgezBranch Greater or Equal Zero (p)bgez rs1, immif(rs1 ≥ 0) pc += immbranch

In asm use a label in place of a branch immediate, for example: beq t0, t1, label_name

Set

InstrDescriptionUseResultGuide
sltSet Less Thanslt rd, rs1, rs2rd = (rs1 < rs2)set
sltiSet Less Than Immediateslti rd, rs1, immrd = (rs1 < imm)set
sltuSet Less Than Unsignedsltu rd, rs1, rs2rd = (rs1 < rs2)set
sltiuSet Less Than Immediate Unsignedsltui rd, rs1, immrd = (rs1 < imm)set
seqzSet Equal Zeroseqz rd, rs1rd = (rs1 == 0)set
snezSet Not Equal Zerosnez rd, rs1rd = (rs1 ≠ 0)set
sltzSet Less Than Zerosltz rd, rs1rd = (rs < 0)set
sgtzSet Greater Than Zerosgtz rd, rs1rd = (rs1 > 0)set

Counters

InstrDescriptionUseResultGuide
rdcycleCPU Cycle Count (p)rdcycle rdrd = csr_cycle[31:0]not yet avail
rdcyclehCPU Cycle Count High (p)rdcycleh rdrd = csr_cycle[63:32]not yet avail
rdtimeCurrent Time (p)rdtime rdrd = csr_time[31:0]not yet avail
rdtimehCurrent Time High (p)rdtimeh rdrd = csr_time[63:32]not yet avail
rdinstretCPU Instructions Retired (p)rdinstret rdrd = csr_instret[31:0]not yet avail
rdinstrethCPU Instructions Retired High (p)rdinstreth rdrd = csr_instret[63:32]not yet avail

The counter instructions require the Zicsr extension but were originally part of the base instruction set.

Misc

InstrDescriptionUseResultGuide
ebreakEnvironment Break (Debugger Call)ebreak-not yet avail
ecallEnvironment Call (OS Function)ecall-not yet avail
fenceI/O Orderingfence-not yet avail
mvCopy Register (p)mv rd, rs1rd = rs1arithmetic
nopNo Operation (p)nop-arithmetic

The fence instruction requires the Zifencei extension but was originally part of the base instruction set.

Abbreviations

What’s Next?

If you enjoyed this post, please sponsor me. Sponsors help me create more FPGA and RISC-V projects for everyone, and they get early access to blog posts and source code. 🙏

Other RISC-V posts include Load Store, Branch Set, Jump and Function. Or check out all my FPGA & RISC-V Tutorials and my series on early Macintosh History.

References

\ No newline at end of file