Applicability of this chapter to configurations:

Configuration

Implementation

CV32A60AX

Implemented extension

CV32A60X

Implemented extension

Note: This chapter is specific to CV32A6 configurations. CV64A6 configurations implement as an option RV64C, that includes a different list of instructions.

RV32C Compressed Instructions

RVC uses a simple compression scheme that offers shorter 16-bit versions of common 32-bit RISC-V instructions when:

  • the immediate or address offset is small;

  • one of the registers is the zero register (x0), the ABI link register (x1), or the ABI stack pointer (x2);

  • the destination register and the first source register are identical;

  • the registers used are the 8 most popular ones.

The C extension is compatible with all other standard instruction extensions. The C extension allows 16-bit instructions to be freely intermixed with 32-bit instructions, with the latter now able to start on any 16-bit boundary. With the addition of the C extension, JAL and JALR instructions will no longer raise an instruction misaligned exception.

Integer Computational Instructions

  • C.LI: Compressed Load Immediate

    Format: c.li rd, imm[5:0]

    Description: loads the sign-extended 6-bit immediate, imm, into register rd.

    Pseudocode: x[rd] = sext(imm[5:0])

    Invalid values: rd = x0

    Exception raised: NONE

  • C.LUI: Compressed Load Upper Immediate

    Format: c.lui rd, nzimm[17:12]

    Description: loads the non-zero 6-bit immediate field into bits 17–12 of the destination register, clears the bottom 12 bits, and sign-extends bit 17 into all higher bits of the destination.

    Pseudocode: x[rd] = sext(nzimm[17:12] << 12)

    Invalid values: rd = x0 & rd = x2 & nzimm = 0

    Exception raised: NONE

  • C.ADDI: Compressed Addition Immediate

    Format: c.addi rd, nzimm[5:0]

    Description: adds the non-zero sign-extended 6-bit immediate to the value in register rd then writes the result to rd.

    Pseudocode: x[rd] = x[rd] + sext(nzimm[5:0])

    Invalid values: rd = x0 & nzimm = 0

    Exception raised: NONE

  • C.ADDI16SP: Addition Immediate Scaled by 16, to Stack Pointer

    Format: c.addi16sp nzimm[9:4]

    Description: adds the non-zero sign-extended 6-bit immediate to the value in the stack pointer (sp=x2), where the immediate is scaled to represent multiples of 16 in the range (-512,496). C.ADDI16SP is used to adjust the stack pointer in procedure prologues and epilogues. C.ADDI16SP shares the opcode with C.LUI, but has a destination field of x2.

    Pseudocode: x[2] = x[2] + sext(nzimm[9:4])

    Invalid values: rd != x2 & nzimm = 0

    Exception raised: NONE

  • C.ADDI4SPN: Addition Immediate Scaled by 4, to Stack Pointer

    Format: c.addi4spn rd’, nzimm[9:2]

    Description: adds a zero-extended non-zero immediate, scaled by 4, to the stack pointer, x2, and writes the result to rd’. This instruction is used to generate pointers to stack-allocated variables.

    Pseudocode: x[8 + rd’] = x[2] + zext(nzimm[9:2])

    Invalid values: nzimm = 0

    Exception raised: NONE

  • C.SLLI: Compressed Shift Left Logic Immediate

    Format: c.slli rd, uimm[5:0]

    Description: performs a logical left shift (zeros are shifted into the lower bits).

    Pseudocode: x[rd] = x[rd] << uimm[5:0]

    Invalid values: rd = x0 & uimm[5] = 0

    Exception raised: NONE

  • C.SRLI: Compressed Shift Right Logic Immediate

    Format: c.srli rd’, uimm[5:0]

    Description: performs a logical right shift (zeros are shifted into the upper bits).

    Pseudocode: x[8 + rd’] = x[8 + rd’] >> uimm[5:0]

    Invalid values: uimm[5] = 0

    Exception raised: NONE

  • C.SRAI: Compressed Shift Right Arithmetic Immediate

    Format: c.srai rd’, uimm[5:0]

    Description: performs an arithmetic right shift (sign bits are shifted into the upper bits).

    Pseudocode: x[8 + rd’] = x[8 + rd’] >>s uimm[5:0]

    Invalid values: uimm[5] = 0

    Exception raised: NONE

  • C.ANDI: Compressed AND Immediate

    Format: c.andi rd’, imm[5:0]

    Description: computes the bitwise AND of the value in register rd’, and the sign-extended 6-bit immediate, then writes the result to rd’.

    Pseudocode: x[8 + rd’] = x[8 + rd’] & sext(imm[5:0])

    Invalid values: NONE

    Exception raised: NONE

  • C.ADD: Compressed Addition

    Format: c.add rd, rs2

    Description: adds the values in registers rd and rs2 and writes the result to register rd.

    Pseudocode: x[rd] = x[rd] + x[rs2]

    Invalid values: rd = x0 & rs2 = x0

    Exception raised: NONE

  • C.MV: Move

    Format: c.mv rd, rs2

    Description: copies the value in register rs2 into register rd.

    Pseudocode: x[rd] = x[rs2]

    Invalid values: rd = x0 & rs2 = x0

    Exception raised: NONE

  • C.AND: Compressed AND

    Format: c.and rd’, rs2’

    Description: computes the bitwise AND of of the value in register rd’, and register rs2’, then writes the result to rd’.

    Pseudocode: x[8 + rd’] = x[8 + rd’] & x[8 + rs2’]

    Invalid values: NONE

    Exception raised: NONE

  • C.OR: Compressed OR

    Format: c.or rd’, rs2’

    Description: computes the bitwise OR of of the value in register rd’, and register rs2’, then writes the result to rd’.

    Pseudocode: x[8 + rd’] = x[8 + rd’] | x[8 + rs2’]

    Invalid values: NONE

    Exception raised: NONE

  • C.XOR: Compressed XOR

    Format: c.and rd’, rs2’

    Description: computes the bitwise XOR of of the value in register rd’, and register rs2’, then writes the result to rd’.

    Pseudocode: x[8 + rd’] = x[8 + rd’] ^ x[8 + rs2’]

    Invalid values: NONE

    Exception raised: NONE

  • C.SUB: Compressed Subtraction

    Format: c.sub rd’, rs2’

    Description: subtracts the value in registers rs2’ from value in rd’ and writes the result to register rd’.

    Pseudocode: x[8 + rd’] = x[8 + rd’] - x[8 + rs2’]

    Invalid values: NONE

    Exception raised: NONE

  • C.EBREAK: Compressed Ebreak

    Format: c.ebreak

    Description: cause control to be transferred back to the debugging environment.

    Pseudocode: RaiseException(Breakpoint)

    Invalid values: NONE

    Exception raised: Raise a Breakpoint exception.

Control Transfer Instructions

  • C.J: Compressed Jump

    Format: c.j imm[11:1]

    Description: performs an unconditional control transfer. The offset is sign-extended and added to the pc to form the jump target address.

    Pseudocode: pc += sext(imm[11:1])

    Invalid values: NONE

    Exception raised: jumps to an unaligned address (4-byte or 2-byte boundary) will usually raise an exception.

  • C.JAL: Compressed Jump and Link

    Format: c.jal imm[11:1]

    Description: performs the same operation as C.J, but additionally writes the address of the instruction following the jump (pc+2) to the link register, x1.

    Pseudocode: x[1] = pc+2; pc += sext(imm[11:1])

    Invalid values: NONE

    Exception raised: jumps to an unaligned address (4-byte or 2-byte boundary) will usually raise an exception.

  • C.JR: Compressed Jump Register

    Format: c.jr rs1

    Description: performs an unconditional control transfer to the address in register rs1.

    Pseudocode: pc = x[rs1]

    Invalid values: rs1 = x0

    Exception raised: jumps to an unaligned address (4-byte or 2-byte boundary) will usually raise an exception.

  • C.JALR: Compressed Jump and Link Register

    Format: c.jalr rs1

    Description: performs the same operation as C.JR, but additionally writes the address of the instruction following the jump (pc+2) to the link register, x1.

    Pseudocode: t = pc+2; pc = x[rs1]; x[1] = t

    Invalid values: rs1 = x0

    Exception raised: jumps to an unaligned address (4-byte or 2-byte boundary) will usually raise an exception.

  • C.BEQZ: Branch if Equal Zero

    Format: c.beqz rs1’, imm[8:1]

    Description: performs conditional control transfers. The offset is sign-extended and added to the pc to form the branch target address. C.BEQZ takes the branch if the value in register rs1’ is zero.

    Pseudocode: if (x[8+rs1’] == 0) pc += sext(imm[8:1])

    Invalid values: NONE

    Exception raised: no instruction fetch misaligned exception is generated for a conditional branch that is not taken. An Instruction address misaligned exception is raised if the target address is not aligned on 4-byte or 2-byte boundary, because the core supports compressed instructions.

  • C.BNEZ: Branch if Not Equal Zero

    Format: c.bnez rs1’, imm[8:1]

    Description: performs conditional control transfers. The offset is sign-extended and added to the pc to form the branch target address. C.BEQZ takes the branch if the value in register rs1’ isn’t zero.

    Pseudocode: if (x[8+rs1’] != 0) pc += sext(imm[8:1])

    Invalid values: NONE

    Exception raised: no instruction fetch misaligned exception is generated for a conditional branch that is not taken. An Instruction address misaligned exception is raised if the target address is not aligned on 4-byte or 2-byte boundary, because the core supports compressed instructions.

Load and Store Instructions

  • C.LWSP: Load Word Stack-Pointer

    Format: c.lwsp rd, uimm(x2)

    Description: loads a 32-bit value from memory into register rd. It computes an effective address by adding the zero-extended offset, scaled by 4, to the stack pointer, x2.

    Pseudocode: x[rd] = M[x[2] + zext(uimm[7:2])][31:0]

    Invalid values: rd = x0

    Exception raised: loads with a destination of x0 must still raise any exceptions, also an exception if the memory address isn’t aligned (4-byte boundary).

  • C.SWSP: Store Word Stack-Pointer

    Format: c.swsp rd, uimm(x2)

    Description: stores a 32-bit value in register rs2 to memory. It computes an effective address by adding the zero-extended offset, scaled by 4, to the stack pointer, x2.

    Pseudocode: M[x[2] + zext(uimm[7:2])][31:0] = x[rs2]

    Invalid values: NONE

    Exception raised: an exception raised if the memory address isn’t aligned (4-byte boundary).

  • C.LW: Compressed Load Word

    Format: c.lw rd’, uimm(rs1’)

    Description: loads a 32-bit value from memory into register rd’. It computes an effective address by adding the zero-extended offset, scaled by 4, to the base address in register rs1’.

    Pseudocode: x[8+rd’] = M[x[8+rs1’] + zext(uimm[6:2])][31:0])

    Invalid values: NONE

    Exception raised: an exception raised if the memory address isn’t aligned (4-byte boundary).

  • C.SW: Compressed Store Word

    Format: c.sw rs2’, uimm(rs1’)

    Description: stores a 32-bit value from memory into register rd’. It computes an effective address by adding the zero-extended offset, scaled by 4, to the base address in register rs1’.

    Pseudocode: M[x[8+rs1’] + zext(uimm[6:2])][31:0] = x[8+rs2’]

    Invalid values: NONE

    Exception raised: an exception raised if the memory address isn’t aligned (4-byte boundary).