RISC-V instructions (RV32)
Instruction reference: i386 · x64 · ARM32 (Thumb-2) · ARM64 (AArch64) · RISC-V (RV32)
143 instructions for .arch riscv32: name, operands, the bit encoding (32 bits, 16 bits for the compressed instructions) and a short description with the operation in pseudo code. Included is everything the RISC-V cores of the Raspberry Pi Pico 2 (Hazard3) run: the base set RV32I, multiplication and division (M), the atomic instructions (A), the control registers (Zicsr), fence.i (Zifencei), the bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) and the compressed instructions (C, Zcb). The pseudo instructions of the assembler (li, mv, j, ret …) are listed with the instruction they become. The Hazard3 has no floating point.
How to read the table
A RISC-V instruction is a word of 32 bits; its two lowest bits are then 11. A compressed instruction (a name with c.) has 16 bits and ends in 00, 01 or 10. The encoding shows the bits from left (highest bit number) to right: fixed bits as digits (opcode, funct3, funct7), the names are fields. Hover a field to see its range of bits. rd, rs1, rs2 are registers of 5 bits (x0 to x31); rd', rs1', rs2' in the compressed instructions have 3 bits and mean x8 to x15. Below is the value of the fixed bits and the mask in hex: an instruction belongs to this form if (word & mask) == value.
Constants are spread over several fields in RISC-V, so that the sign is always in bit 31 and the registers stay in fixed places. imm[12|10-5] is a field that holds the bits 12 and 10 to 5 of the number, in this order. For jumps and branches bit 0 of the distance is always 0 and is not stored. There are no flags: branches compare two registers themselves, slt writes the result of a comparison as 0 or 1 into a register.
The atomic instructions have the bits aq and rl for the order of the memory accesses; the disassembler writes them as a suffix of the name (amoadd.w.aq, .rl, .aqrl). Every encoding in this table is checked against the decoder of Asmonite: with random values in the fields it gives this instruction (or its pseudo name) again. The pseudo code is written in English like source code; <s and <u compare signed and unsigned, [x]32 is the word in memory at address x.
| Instruction | Operands | Encoding | Description |
|---|---|---|---|
| add | rd, rs1, rs2 | 0000000 rs2 rs1 000 rd 01100110x00000033 / mask 0xFE00707F | Addition of two registersrd = rs1 + rs2Arithmetic |
| addi | rd, rs1, imm12also shown as: li, mv, nop | imm[11-0] rs1 000 rd 00100110x00000013 / mask 0x0000707F | Addition of a constant (12 bit, signed)rd = rs1 + sext(imm12)Arithmetic |
| amoadd.w | rd, rs2, (rs1) | 00000 aq rl rs2 rs1 010 rd 01011110x0000202F / mask 0xF800707F | Atomic addition (A)rd = [rs1]; [rs1] = rd + rs2Atomic memory operations (A) |
| amoand.w | rd, rs2, (rs1) | 01100 aq rl rs2 rs1 010 rd 01011110x6000202F / mask 0xF800707F | Atomic AND (A)rd = [rs1]; [rs1] = rd & rs2Atomic memory operations (A) |
| amomax.w | rd, rs2, (rs1) | 10100 aq rl rs2 rs1 010 rd 01011110xA000202F / mask 0xF800707F | Atomic signed maximum (A)rd = [rs1]; [rs1] = max_s(rd, rs2)Atomic memory operations (A) |
| amomaxu.w | rd, rs2, (rs1) | 11100 aq rl rs2 rs1 010 rd 01011110xE000202F / mask 0xF800707F | Atomic unsigned maximum (A)rd = [rs1]; [rs1] = max_u(rd, rs2)Atomic memory operations (A) |
| amomin.w | rd, rs2, (rs1) | 10000 aq rl rs2 rs1 010 rd 01011110x8000202F / mask 0xF800707F | Atomic signed minimum (A)rd = [rs1]; [rs1] = min_s(rd, rs2)Atomic memory operations (A) |
| amominu.w | rd, rs2, (rs1) | 11000 aq rl rs2 rs1 010 rd 01011110xC000202F / mask 0xF800707F | Atomic unsigned minimum (A)rd = [rs1]; [rs1] = min_u(rd, rs2)Atomic memory operations (A) |
| amoor.w | rd, rs2, (rs1) | 01000 aq rl rs2 rs1 010 rd 01011110x4000202F / mask 0xF800707F | Atomic OR (A)rd = [rs1]; [rs1] = rd | rs2Atomic memory operations (A) |
| amoswap.w | rd, rs2, (rs1) | 00001 aq rl rs2 rs1 010 rd 01011110x0800202F / mask 0xF800707F | Atomic swap (A)rd = [rs1]; [rs1] = rs2Atomic memory operations (A) |
| amoxor.w | rd, rs2, (rs1) | 00100 aq rl rs2 rs1 010 rd 01011110x2000202F / mask 0xF800707F | Atomic exclusive OR (A)rd = [rs1]; [rs1] = rd ^ rs2Atomic memory operations (A) |
| and | rd, rs1, rs2 | 0000000 rs2 rs1 111 rd 01100110x00007033 / mask 0xFE00707F | ANDrd = rs1 & rs2Logic and bits |
| andi | rd, rs1, imm12 | imm[11-0] rs1 111 rd 00100110x00007013 / mask 0x0000707F | AND with a constantrd = rs1 & sext(imm12)Logic and bits |
| andn | rd, rs1, rs2 | 0100000 rs2 rs1 111 rd 01100110x40007033 / mask 0xFE00707F | AND with an inverted operand (Zbb, Zbkb)rd = rs1 & ~rs2Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| auipc | rd, imm20 | imm[31-12] rd 00101110x00000017 / mask 0x0000007F | Addition of the upper 20 bits to the pc (address relative to the instruction)rd = pc + (imm20 << 12)Constants and addresses |
| bclr | rd, rs1, rs2 | 0100100 rs2 rs1 001 rd 01100110x48001033 / mask 0xFE00707F | Clearing of one bit (Zbs)rd = rs1 & ~(1 << rs2[4:0])Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| bclri | rd, rs1, shamt | 0100100 shamt rs1 001 rd 00100110x48001013 / mask 0xFE00707F | Clearing of one bit, its number as a constant (Zbs)rd = rs1 & ~(1 << shamt)Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| beq | rs1, rs2, labelalso shown as: beqz | imm[12|10-5] rs2 rs1 000 imm[4-1|11] 11000110x00000063 / mask 0x0000707F | Branch if equalif rs1 == rs2 then pc = pc + sext(imm13)Branches and calls |
| bext | rd, rs1, rs2 | 0100100 rs2 rs1 101 rd 01100110x48005033 / mask 0xFE00707F | Extraction of one bit (Zbs)rd = (rs1 >> rs2[4:0]) & 1Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| bexti | rd, rs1, shamt | 0100100 shamt rs1 101 rd 00100110x48005013 / mask 0xFE00707F | Extraction of one bit, its number as a constant (Zbs)rd = (rs1 >> shamt) & 1Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| bge | rs1, rs2, labelalso shown as: bgez, blez | imm[12|10-5] rs2 rs1 101 imm[4-1|11] 11000110x00005063 / mask 0x0000707F | Branch if greater or equal (signed)if rs1 >=s rs2 then pc = pc + sext(imm13)Branches and calls |
| bgeu | rs1, rs2, label | imm[12|10-5] rs2 rs1 111 imm[4-1|11] 11000110x00007063 / mask 0x0000707F | Branch if greater or equal (unsigned)if rs1 >=u rs2 then pc = pc + sext(imm13)Branches and calls |
| binv | rd, rs1, rs2 | 0110100 rs2 rs1 001 rd 01100110x68001033 / mask 0xFE00707F | Inversion of one bit (Zbs)rd = rs1 ^ (1 << rs2[4:0])Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| binvi | rd, rs1, shamt | 0110100 shamt rs1 001 rd 00100110x68001013 / mask 0xFE00707F | Inversion of one bit, its number as a constant (Zbs)rd = rs1 ^ (1 << shamt)Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| blt | rs1, rs2, labelalso shown as: bltz, bgtz | imm[12|10-5] rs2 rs1 100 imm[4-1|11] 11000110x00004063 / mask 0x0000707F | Branch if less (signed)if rs1 <s rs2 then pc = pc + sext(imm13)Branches and calls |
| bltu | rs1, rs2, label | imm[12|10-5] rs2 rs1 110 imm[4-1|11] 11000110x00006063 / mask 0x0000707F | Branch if less (unsigned)if rs1 <u rs2 then pc = pc + sext(imm13)Branches and calls |
| bne | rs1, rs2, labelalso shown as: bnez | imm[12|10-5] rs2 rs1 001 imm[4-1|11] 11000110x00001063 / mask 0x0000707F | Branch if not equalif rs1 != rs2 then pc = pc + sext(imm13)Branches and calls |
| brev8 | rd, rs1 | 011010000111 rs1 101 rd 00100110x68705013 / mask 0xFFF0707F | Reversal of the bits in every byte (Zbkb)for every byte: rd.byte = bit_reverse(rs1.byte)Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| bset | rd, rs1, rs2 | 0010100 rs2 rs1 001 rd 01100110x28001033 / mask 0xFE00707F | Setting of one bit (Zbs)rd = rs1 | (1 << rs2[4:0])Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| bseti | rd, rs1, shamt | 0010100 shamt rs1 001 rd 00100110x28001013 / mask 0xFE00707F | Setting of one bit, its number as a constant (Zbs)rd = rs1 | (1 << shamt)Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| c.add | rd, rs2 | 100 1 rd rs2 100x9002 / mask 0xF003 | Addition of two registersrd = rd + rs2 (rs2 != 0)Compressed instructions (C, Zcb) |
| c.addi | rd, imm6also shown as: c.nop | 000 imm[5] rd imm[4-0] 010x0001 / mask 0xE003 | Addition of a constant (6 bit, signed)rd = rd + sext(imm6)Compressed instructions (C, Zcb) |
| c.addi16sp | sp, imm | 011 imm[9] 00010 imm[4|6|8-7|5] 010x6101 / mask 0xEF83 | Addition of a multiple of 16 to spsp = sp + sext(imm10) (imm != 0)Compressed instructions (C, Zcb) |
| c.addi4spn | rd', sp, uimm | 000 uimm[5-4|9-6|2|3] rd' 000x0000 / mask 0xE003 | Addition of a constant to sp (an address on the stack)rd' = sp + zext(uimm) (uimm != 0)Compressed instructions (C, Zcb) |
| c.and | rd', rs2' | 100 0 11 rd' 11 rs2' 010x8C61 / mask 0xFC63 | ANDrd' = rd' & rs2'Compressed instructions (C, Zcb) |
| c.andi | rd', imm6 | 100 imm[5] 10 rd' imm[4-0] 010x8801 / mask 0xEC03 | AND with a constant (6 bit, signed)rd' = rd' & sext(imm6)Compressed instructions (C, Zcb) |
| c.beqz | rs1', label | 110 imm[8|4-3] rs1' imm[7-6|2-1|5] 010xC001 / mask 0xE003 | Branch if zeroif rs1' == 0 then pc = pc + sext(imm9)Compressed instructions (C, Zcb) |
| c.bnez | rs1', label | 111 imm[8|4-3] rs1' imm[7-6|2-1|5] 010xE001 / mask 0xE003 | Branch if not zeroif rs1' != 0 then pc = pc + sext(imm9)Compressed instructions (C, Zcb) |
| c.ebreak | 100 1 00000 00000 100x9002 / mask 0xFFFF | Breakpoint for the debuggerraise breakpoint exception (or enter debug mode)Compressed instructions (C, Zcb) | |
| c.j | label | 101 imm[11|4|9-8|10|6|7|3-1|5] 010xA001 / mask 0xE003 | Jump (±2 KB)pc = pc + sext(imm12)Compressed instructions (C, Zcb) |
| c.jal | label | 001 imm[11|4|9-8|10|6|7|3-1|5] 010x2001 / mask 0xE003 | Jump and link to ra (±2 KB)ra = pc + 2; pc = pc + sext(imm12)Compressed instructions (C, Zcb) |
| c.jalr | rs1 | 100 1 rs1 00000 100x9002 / mask 0xF07F | Jump to the address in a register, and link to rat = rs1; ra = pc + 2; pc = tCompressed instructions (C, Zcb) |
| c.jr | rs1 | 100 0 rs1 00000 100x8002 / mask 0xF07F | Jump to the address in a registerpc = rs1 (rs1 != 0)Compressed instructions (C, Zcb) |
| c.lbu | rd', uimm(rs1') | 100 000 rs1' uimm[0|1] rd' 000x8000 / mask 0xFC03 | Load of a byte, unsigned (Zcb)rd' = zext([rs1' + uimm]8)Compressed instructions (C, Zcb) |
| c.lh | rd', uimm(rs1') | 100 001 rs1' 1 uimm[1] rd' 000x8440 / mask 0xFC43 | Load of a half word, signed (Zcb)rd' = sext([rs1' + uimm]16)Compressed instructions (C, Zcb) |
| c.lhu | rd', uimm(rs1') | 100 001 rs1' 0 uimm[1] rd' 000x8400 / mask 0xFC43 | Load of a half word, unsigned (Zcb)rd' = zext([rs1' + uimm]16)Compressed instructions (C, Zcb) |
| c.li | rd, imm6 | 010 imm[5] rd imm[4-0] 010x4001 / mask 0xE003 | Load of a constant (6 bit, signed)rd = sext(imm6)Compressed instructions (C, Zcb) |
| c.lui | rd, imm6also shown as: c.addi16sp | 011 imm[17] rd imm[16-12] 010x6001 / mask 0xE003 | Load of the bits 17 to 12 of a constantrd = sext(imm6 << 12) (rd != 0, 2)Compressed instructions (C, Zcb) |
| c.lw | rd', uimm(rs1') | 010 uimm[5-3] rs1' uimm[2|6] rd' 000x4000 / mask 0xE003 | Load of a wordrd' = [rs1' + zext(uimm)]32Compressed instructions (C, Zcb) |
| c.lwsp | rd, uimm(sp) | 010 uimm[5] rd uimm[4-2|7-6] 100x4002 / mask 0xE003 | Load of a word from the stackrd = [sp + zext(uimm)]32 (rd != 0)Compressed instructions (C, Zcb) |
| c.mul | rd', rs2' | 100 1 11 rd' 10 rs2' 010x9C41 / mask 0xFC63 | Multiplication, low 32 bits (Zcb)rd' = (rd' * rs2')[31:0]Compressed instructions (C, Zcb) |
| c.mv | rd, rs2 | 100 0 rd rs2 100x8002 / mask 0xF003 | Copy of a registerrd = rs2 (rs2 != 0)Compressed instructions (C, Zcb) |
| c.not | rd' | 100 1 11 rd' 11 101 010x9C75 / mask 0xFC7F | Bitwise inversion (Zcb)rd' = ~rd'Compressed instructions (C, Zcb) |
| c.or | rd', rs2' | 100 0 11 rd' 10 rs2' 010x8C41 / mask 0xFC63 | ORrd' = rd' | rs2'Compressed instructions (C, Zcb) |
| c.sb | rs2', uimm(rs1') | 100 010 rs1' uimm[0|1] rs2' 000x8800 / mask 0xFC03 | Store of a byte (Zcb)[rs1' + uimm]8 = rs2'[7:0]Compressed instructions (C, Zcb) |
| c.sext.b | rd' | 100 1 11 rd' 11 001 010x9C65 / mask 0xFC7F | Sign extension of a byte (Zcb)rd' = sext(rd'[7:0])Compressed instructions (C, Zcb) |
| c.sext.h | rd' | 100 1 11 rd' 11 011 010x9C6D / mask 0xFC7F | Sign extension of a half word (Zcb)rd' = sext(rd'[15:0])Compressed instructions (C, Zcb) |
| c.sh | rs2', uimm(rs1') | 100 011 rs1' 0 uimm[1] rs2' 000x8C00 / mask 0xFC43 | Store of a half word (Zcb)[rs1' + uimm]16 = rs2'[15:0]Compressed instructions (C, Zcb) |
| c.slli | rd, shamt | 000 0 rd shamt 100x0002 / mask 0xF003 | Shift left by a constantrd = rd << shamtCompressed instructions (C, Zcb) |
| c.srai | rd', shamt | 100 0 01 rd' shamt 010x8401 / mask 0xFC03 | Shift right signed by a constantrd' = rd' >>s shamtCompressed instructions (C, Zcb) |
| c.srli | rd', shamt | 100 0 00 rd' shamt 010x8001 / mask 0xFC03 | Shift right unsigned by a constantrd' = rd' >>u shamtCompressed instructions (C, Zcb) |
| c.sub | rd', rs2' | 100 0 11 rd' 00 rs2' 010x8C01 / mask 0xFC63 | Subtractionrd' = rd' - rs2'Compressed instructions (C, Zcb) |
| c.sw | rs2', uimm(rs1') | 110 uimm[5-3] rs1' uimm[2|6] rs2' 000xC000 / mask 0xE003 | Store of a word[rs1' + zext(uimm)]32 = rs2'Compressed instructions (C, Zcb) |
| c.swsp | rs2, uimm(sp) | 110 uimm[5-2|7-6] rs2 100xC002 / mask 0xE003 | Store of a word on the stack[sp + zext(uimm)]32 = rs2Compressed instructions (C, Zcb) |
| c.xor | rd', rs2' | 100 0 11 rd' 01 rs2' 010x8C21 / mask 0xFC63 | Exclusive ORrd' = rd' ^ rs2'Compressed instructions (C, Zcb) |
| c.zext.b | rd' | 100 1 11 rd' 11 000 010x9C61 / mask 0xFC7F | Zero extension of a byte (Zcb)rd' = zext(rd'[7:0])Compressed instructions (C, Zcb) |
| c.zext.h | rd' | 100 1 11 rd' 11 010 010x9C69 / mask 0xFC7F | Zero extension of a half word (Zcb)rd' = zext(rd'[15:0])Compressed instructions (C, Zcb) |
| clmul | rd, rs1, rs2 | 0000101 rs2 rs1 001 rd 01100110x0A001033 / mask 0xFE00707F | Carry-less multiplication, low 32 bits (Zbc)rd = clmul(rs1, rs2)[31:0]Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| clmulh | rd, rs1, rs2 | 0000101 rs2 rs1 011 rd 01100110x0A003033 / mask 0xFE00707F | Carry-less multiplication, high 32 bits (Zbc)rd = clmul(rs1, rs2)[63:32]Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| clmulr | rd, rs1, rs2 | 0000101 rs2 rs1 010 rd 01100110x0A002033 / mask 0xFE00707F | Carry-less multiplication, bits 62 to 31 (Zbc)rd = clmul(rs1, rs2)[62:31]Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| clz | rd, rs1 | 0110000 00000 rs1 001 rd 00100110x60001013 / mask 0xFFF0707F | Count of the leading zero bits (Zbb)rd = number of 0 bits above the highest 1 bit (32 for 0)Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| cpop | rd, rs1 | 0110000 00010 rs1 001 rd 00100110x60201013 / mask 0xFFF0707F | Count of the set bits (Zbb)rd = number of 1 bits in rs1Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| csrrc | rd, csr, rs1also shown as: csrc | csr rs1 011 rd 11100110x00003073 / mask 0x0000707F | Read of a control register and clearing of bitst = csr; csr = t & ~rs1; rd = tControl and status registers (Zicsr) |
| csrrci | rd, csr, uimm5also shown as: csrci | csr uimm 111 rd 11100110x00007073 / mask 0x0000707F | Read of a control register and clearing of the bits of a constantt = csr; csr = t & ~uimm5; rd = tControl and status registers (Zicsr) |
| csrrs | rd, csr, rs1also shown as: csrr, csrs | csr rs1 010 rd 11100110x00002073 / mask 0x0000707F | Read of a control register and setting of bitst = csr; csr = t | rs1; rd = tControl and status registers (Zicsr) |
| csrrsi | rd, csr, uimm5also shown as: csrsi | csr uimm 110 rd 11100110x00006073 / mask 0x0000707F | Read of a control register and setting of the bits of a constantt = csr; csr = t | uimm5; rd = tControl and status registers (Zicsr) |
| csrrw | rd, csr, rs1also shown as: csrw | csr rs1 001 rd 11100110x00001073 / mask 0x0000707F | Exchange of a control register with a registert = csr; csr = rs1; rd = tControl and status registers (Zicsr) |
| csrrwi | rd, csr, uimm5also shown as: csrwi | csr uimm 101 rd 11100110x00005073 / mask 0x0000707F | Exchange of a control register with a constant (5 bit)rd = csr; csr = uimm5Control and status registers (Zicsr) |
| ctz | rd, rs1 | 0110000 00001 rs1 001 rd 00100110x60101013 / mask 0xFFF0707F | Count of the trailing zero bits (Zbb)rd = number of 0 bits below the lowest 1 bit (32 for 0)Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| div | rd, rs1, rs2 | 0000001 rs2 rs1 100 rd 01100110x02004033 / mask 0xFE00707F | Signed division (M)rd = rs1 /s rs2 (by 0: -1)Arithmetic |
| divu | rd, rs1, rs2 | 0000001 rs2 rs1 101 rd 01100110x02005033 / mask 0xFE00707F | Unsigned division (M)rd = rs1 /u rs2 (by 0: all ones)Arithmetic |
| ebreak | 000000000001 00000 000 00000 11100110x00100073 / mask 0xFFFFFFFF | Breakpoint for the debuggerraise breakpoint exception (or enter debug mode)System and privileged | |
| ecall | 000000000000 00000 000 00000 11100110x00000073 / mask 0xFFFFFFFF | Call of the environment (exception)raise environment call exceptionSystem and privileged | |
| fence | pred, succ | 0000 pred succ 00000 000 00000 00011110x0000000F / mask 0xF00FFFFF | Memory barrier: accesses of the kind pred before those of the kind succorder memory accesses (i, o, r, w)Barriers and others |
| fence.i | 000000000000 00000 001 00000 00011110x0000100F / mask 0xFFFFFFFF | Synchronisation of the instruction stream with code written before (Zifencei)later instruction fetches see earlier storesBarriers and others | |
| jal | rd, labelalso shown as: j | imm[20|10-1|11|19-12] rd 11011110x0000006F / mask 0x0000007F | Jump and link (±1 MB)rd = pc + 4; pc = pc + sext(imm21)Branches and calls |
| jalr | rd, imm12(rs1)also shown as: jr, ret | imm[11-0] rs1 000 rd 11001110x00000067 / mask 0x0000707F | Jump to the address in a register, and linkt = rs1 + sext(imm12); rd = pc + 4; pc = t & ~1Branches and calls |
| lb | rd, imm12(rs1) | imm[11-0] rs1 000 rd 00000110x00000003 / mask 0x0000707F | Load of a byte, signedrd = sext([rs1 + sext(imm12)]8)Loads and stores |
| lbu | rd, imm12(rs1) | imm[11-0] rs1 100 rd 00000110x00004003 / mask 0x0000707F | Load of a byte, unsignedrd = zext([rs1 + sext(imm12)]8)Loads and stores |
| lh | rd, imm12(rs1) | imm[11-0] rs1 001 rd 00000110x00001003 / mask 0x0000707F | Load of a half word, signedrd = sext([rs1 + sext(imm12)]16)Loads and stores |
| lhu | rd, imm12(rs1) | imm[11-0] rs1 101 rd 00000110x00005003 / mask 0x0000707F | Load of a half word, unsignedrd = zext([rs1 + sext(imm12)]16)Loads and stores |
| lr.w | rd, (rs1) | 00010 aq rl 00000 rs1 010 rd 01011110x1000202F / mask 0xF9F0707F | Load reserved (A)rd = [rs1]32; reserve the addressAtomic memory operations (A) |
| lui | rd, imm20 | imm[31-12] rd 01101110x00000037 / mask 0x0000007F | Load of the upper 20 bits of a constantrd = imm20 << 12Constants and addresses |
| lw | rd, imm12(rs1) | imm[11-0] rs1 010 rd 00000110x00002003 / mask 0x0000707F | Load of a word (32 bit)rd = [rs1 + sext(imm12)]32Loads and stores |
| max | rd, rs1, rs2 | 0000101 rs2 rs1 110 rd 01100110x0A006033 / mask 0xFE00707F | Signed maximum (Zbb)rd = (rs1 >s rs2) ? rs1 : rs2Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| maxu | rd, rs1, rs2 | 0000101 rs2 rs1 111 rd 01100110x0A007033 / mask 0xFE00707F | Unsigned maximum (Zbb)rd = (rs1 >u rs2) ? rs1 : rs2Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| min | rd, rs1, rs2 | 0000101 rs2 rs1 100 rd 01100110x0A004033 / mask 0xFE00707F | Signed minimum (Zbb)rd = (rs1 <s rs2) ? rs1 : rs2Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| minu | rd, rs1, rs2 | 0000101 rs2 rs1 101 rd 01100110x0A005033 / mask 0xFE00707F | Unsigned minimum (Zbb)rd = (rs1 <u rs2) ? rs1 : rs2Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| mret | 0011000 00010 00000 000 00000 11100110x30200073 / mask 0xFFFFFFFF | Return from an exception in machine modepc = mepc; restore the mode from mstatusSystem and privileged | |
| mul | rd, rs1, rs2 | 0000001 rs2 rs1 000 rd 01100110x02000033 / mask 0xFE00707F | Multiplication, low 32 bits (M)rd = (rs1 * rs2)[31:0]Arithmetic |
| mulh | rd, rs1, rs2 | 0000001 rs2 rs1 001 rd 01100110x02001033 / mask 0xFE00707F | Signed multiplication, high 32 bits (M)rd = (sext(rs1) * sext(rs2))[63:32]Arithmetic |
| mulhsu | rd, rs1, rs2 | 0000001 rs2 rs1 010 rd 01100110x02002033 / mask 0xFE00707F | Signed by unsigned multiplication, high 32 bits (M)rd = (sext(rs1) * zext(rs2))[63:32]Arithmetic |
| mulhu | rd, rs1, rs2 | 0000001 rs2 rs1 011 rd 01100110x02003033 / mask 0xFE00707F | Unsigned multiplication, high 32 bits (M)rd = (zext(rs1) * zext(rs2))[63:32]Arithmetic |
| or | rd, rs1, rs2 | 0000000 rs2 rs1 110 rd 01100110x00006033 / mask 0xFE00707F | ORrd = rs1 | rs2Logic and bits |
| orc.b | rd, rs1 | 001010000111 rs1 101 rd 00100110x28705013 / mask 0xFFF0707F | Setting of every byte to 0x00 or 0xFF by whether one of its bits is set (Zbb)for every byte: rd.byte = (rs1.byte != 0) ? 0xFF : 0Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| ori | rd, rs1, imm12 | imm[11-0] rs1 110 rd 00100110x00006013 / mask 0x0000707F | OR with a constantrd = rs1 | sext(imm12)Logic and bits |
| orn | rd, rs1, rs2 | 0100000 rs2 rs1 110 rd 01100110x40006033 / mask 0xFE00707F | OR with an inverted operand (Zbb, Zbkb)rd = rs1 | ~rs2Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| pack | rd, rs1, rs2also shown as: zext.h | 0000100 rs2 rs1 100 rd 01100110x08004033 / mask 0xFE00707F | Packing of the low half words of two registers (Zbkb)rd = (rs2[15:0] << 16) | rs1[15:0]Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| packh | rd, rs1, rs2 | 0000100 rs2 rs1 111 rd 01100110x08007033 / mask 0xFE00707F | Packing of the low bytes of two registers (Zbkb)rd = (rs2[7:0] << 8) | rs1[7:0]Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| rem | rd, rs1, rs2 | 0000001 rs2 rs1 110 rd 01100110x02006033 / mask 0xFE00707F | Remainder of the signed division (M)rd = rs1 %s rs2 (by 0: rs1)Arithmetic |
| remu | rd, rs1, rs2 | 0000001 rs2 rs1 111 rd 01100110x02007033 / mask 0xFE00707F | Remainder of the unsigned division (M)rd = rs1 %u rs2 (by 0: rs1)Arithmetic |
| rev8 | rd, rs1 | 011010011000 rs1 101 rd 00100110x69805013 / mask 0xFFF0707F | Reversal of the order of the bytes (Zbb, Zbkb)rd = byte_reverse(rs1)Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| rol | rd, rs1, rs2 | 0110000 rs2 rs1 001 rd 01100110x60001033 / mask 0xFE00707F | Rotate left by a register (Zbb, Zbkb)rd = rotate_left(rs1, rs2[4:0])Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| ror | rd, rs1, rs2 | 0110000 rs2 rs1 101 rd 01100110x60005033 / mask 0xFE00707F | Rotate right by a register (Zbb, Zbkb)rd = rotate_right(rs1, rs2[4:0])Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| rori | rd, rs1, shamt | 0110000 shamt rs1 101 rd 00100110x60005013 / mask 0xFE00707F | Rotate right by a constant (Zbb, Zbkb)rd = rotate_right(rs1, shamt)Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| sb | rs2, imm12(rs1) | imm[11-5] rs2 rs1 000 imm[4-0] 01000110x00000023 / mask 0x0000707F | Store of a byte[rs1 + sext(imm12)]8 = rs2[7:0]Loads and stores |
| sc.w | rd, rs2, (rs1) | 00011 aq rl rs2 rs1 010 rd 01011110x1800202F / mask 0xF800707F | Store conditional after lr.w (A)if reserved then [rs1]32 = rs2; rd = 0 else rd = 1Atomic memory operations (A) |
| sext.b | rd, rs1 | 0110000 00100 rs1 001 rd 00100110x60401013 / mask 0xFFF0707F | Sign extension of a byte (Zbb)rd = sext(rs1[7:0])Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| sext.h | rd, rs1 | 0110000 00101 rs1 001 rd 00100110x60501013 / mask 0xFFF0707F | Sign extension of a half word (Zbb)rd = sext(rs1[15:0])Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| sh | rs2, imm12(rs1) | imm[11-5] rs2 rs1 001 imm[4-0] 01000110x00001023 / mask 0x0000707F | Store of a half word[rs1 + sext(imm12)]16 = rs2[15:0]Loads and stores |
| sh1add | rd, rs1, rs2 | 0010000 rs2 rs1 010 rd 01100110x20002033 / mask 0xFE00707F | Addition with a register shifted by 1 (Zba)rd = rs2 + (rs1 << 1)Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| sh2add | rd, rs1, rs2 | 0010000 rs2 rs1 100 rd 01100110x20004033 / mask 0xFE00707F | Addition with a register shifted by 2 (Zba)rd = rs2 + (rs1 << 2)Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| sh3add | rd, rs1, rs2 | 0010000 rs2 rs1 110 rd 01100110x20006033 / mask 0xFE00707F | Addition with a register shifted by 3 (Zba)rd = rs2 + (rs1 << 3)Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| sll | rd, rs1, rs2 | 0000000 rs2 rs1 001 rd 01100110x00001033 / mask 0xFE00707F | Shift left by a registerrd = rs1 << rs2[4:0]Shift and rotate |
| slli | rd, rs1, shamt | 0000000 shamt rs1 001 rd 00100110x00001013 / mask 0xFE00707F | Shift left by a constantrd = rs1 << shamtShift and rotate |
| slt | rd, rs1, rs2also shown as: sltz, sgtz | 0000000 rs2 rs1 010 rd 01100110x00002033 / mask 0xFE00707F | Signed comparison: 1 if lessrd = (rs1 <s rs2) ? 1 : 0Compare and exchange |
| slti | rd, rs1, imm12 | imm[11-0] rs1 010 rd 00100110x00002013 / mask 0x0000707F | Signed comparison with a constant: 1 if lessrd = (rs1 <s sext(imm12)) ? 1 : 0Compare and exchange |
| sltiu | rd, rs1, imm12also shown as: seqz | imm[11-0] rs1 011 rd 00100110x00003013 / mask 0x0000707F | Unsigned comparison with a constant: 1 if lessrd = (rs1 <u sext(imm12)) ? 1 : 0Compare and exchange |
| sltu | rd, rs1, rs2also shown as: snez | 0000000 rs2 rs1 011 rd 01100110x00003033 / mask 0xFE00707F | Unsigned comparison: 1 if lessrd = (rs1 <u rs2) ? 1 : 0Compare and exchange |
| sra | rd, rs1, rs2 | 0100000 rs2 rs1 101 rd 01100110x40005033 / mask 0xFE00707F | Shift right signed by a registerrd = rs1 >>s rs2[4:0]Shift and rotate |
| srai | rd, rs1, shamt | 0100000 shamt rs1 101 rd 00100110x40005013 / mask 0xFE00707F | Shift right signed by a constantrd = rs1 >>s shamtShift and rotate |
| sret | 0001000 00010 00000 000 00000 11100110x10200073 / mask 0xFFFFFFFF | Return from an exception in supervisor modepc = sepc; restore the mode from sstatusSystem and privileged | |
| srl | rd, rs1, rs2 | 0000000 rs2 rs1 101 rd 01100110x00005033 / mask 0xFE00707F | Shift right unsigned by a registerrd = rs1 >>u rs2[4:0]Shift and rotate |
| srli | rd, rs1, shamt | 0000000 shamt rs1 101 rd 00100110x00005013 / mask 0xFE00707F | Shift right unsigned by a constantrd = rs1 >>u shamtShift and rotate |
| sub | rd, rs1, rs2also shown as: neg | 0100000 rs2 rs1 000 rd 01100110x40000033 / mask 0xFE00707F | Subtraction of two registersrd = rs1 - rs2Arithmetic |
| sw | rs2, imm12(rs1) | imm[11-5] rs2 rs1 010 imm[4-0] 01000110x00002023 / mask 0x0000707F | Store of a word[rs1 + sext(imm12)]32 = rs2Loads and stores |
| unzip | rd, rs1 | 000010001111 rs1 101 rd 00100110x08F05013 / mask 0xFFF0707F | Deinterleaving into even and odd bits (Zbkb)rd[i] = rs1[2i]; rd[i+16] = rs1[2i+1]Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| wfi | 0001000 00101 00000 000 00000 11100110x10500073 / mask 0xFFFFFFFF | Wait for an interruptpause until an interrupt is pendingSystem and privileged | |
| xnor | rd, rs1, rs2 | 0100000 rs2 rs1 100 rd 01100110x40004033 / mask 0xFE00707F | Inverted exclusive OR (Zbb, Zbkb)rd = ~(rs1 ^ rs2)Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| xor | rd, rs1, rs2 | 0000000 rs2 rs1 100 rd 01100110x00004033 / mask 0xFE00707F | Exclusive ORrd = rs1 ^ rs2Logic and bits |
| xori | rd, rs1, imm12also shown as: not | imm[11-0] rs1 100 rd 00100110x00004013 / mask 0x0000707F | Exclusive OR with a constantrd = rs1 ^ sext(imm12)Logic and bits |
| zext.h | rd, rs1 | 0000100 00000 rs1 100 rd 01100110x08004033 / mask 0xFFF0707F | Zero extension of a half word (Zbb)rd = zext(rs1[15:0])Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |
| zip | rd, rs1 | 000010001111 rs1 001 rd 00100110x08F01013 / mask 0xFFF0707F | Interleaving of the bits of the two half words (Zbkb)rd[2i] = rs1[i]; rd[2i+1] = rs1[i+16]Bit manipulation (Zba, Zbb, Zbs, Zbc, Zbkb) |