RV32C, RV64C Instructions

c.addi4spn

15-13

12-5

4-2

1-0

000

nzuimm[5:4|9:6|2|3]

rd'

00

Format
c.addi4spn rd',uimm
Description
Add 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, and expands to addi rd', x2, nzuimm[9:2].
Implementation
x[8+rd'] = x[2] + nzuimm
Expansion
addi rd',x2,nzuimm

c.fld

15-13

12-10

9-7

6-5

4-2

1-0

001

uimm[5:3]

rs1'

uimm[7:6]

rd'

00

Format
c.fld rd',uimm(rs1')
Description
Load a double-precision floating-point value from memory into floating-point register rd'.
It computes an effective address by adding the zero-extended offset, scaled by 8, to the base address in register rs1'.
Implementation
f[8+rd'] = M[x[8+rs1'] + uimm][63:0]
Expansion
fld rd',offset[7:3](rs1')

c.lw

15-13

12-10

9-7

6-5

4-2

1-0

010

uimm[5:3]

rs1'

uimm[2|6]

rd'

00

Format
c.lw rd',uimm(rs1')
Description
Load 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'.
Implementation
x[8+rd'] = sext(M[x[8+rs1'] + uimm][31:0])
Expansion
lw rd',offset[6:2](rs1')

c.flw

15-13

12-10

9-7

6-5

4-2

1-0

011

uimm[5:3]

rs1'

uimm[2|6]

rd'

00

Format
c.flw rd',uimm(rs1')
Description
Load a single-precision floating-point value from memory into floating-point register rd'.
It computes an effective address by adding the zero-extended offset, scaled by 4, to the base address in register rs1'.
Implementation
f[8+rd'] = M[x[8+rs1'] + uimm][31:0]
Expansion
lw rd',offset[6:2](rs1')

c.ld

15-13

12-10

9-7

6-5

4-2

1-0

011

uimm[5:3]

rs1'

uimm[7:6]

rd'

00

Format
c.ld rd',uimm(rs1')
Description
Load a 64-bit value from memory into register rd'.
It computes an effective address by adding the zero-extended offset, scaled by 8, to the base address in register rs1'.
Implementation
x[8+rd'] = M[x[8+rs1'] + uimm][63:0]
Expansion
ld rd', offset[7:3](rs1')

c.fsd

15-13

12-10

9-7

6-5

4-2

1-0

101

uimm[5:3]

rs1'

uimm[7:6]

rd'

00

Format
c.fsd rd',uimm(rs1')
Description
Store a double-precision floating-point value in floating-point register rs2' to memory.
It computes an effective address by adding the zeroextended offset, scaled by 8, to the base address in register rs1'.
Implementation
M[x[8+rs1'] + uimm][63:0] = f[8+rs2']
Expansion
fsd rs2',offset[7:3](rs1')

c.sw

15-13

12-10

9-7

6-5

4-2

1-0

110

uimm[5:3]

rs1'

uimm[2|6]

rs2'

00

Format
c.sw rd',uimm(rs1')
Description
Store 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 base address in register rs1'.
Implementation
M[x[8+rs1'] + uimm][31:0] = x[8+rs2']
Expansion
sw rs2',offset[6:2](rs1')

c.fsw

15-13

12-10

9-7

6-5

4-2

1-0

111

uimm[5:3]

rs1'

uimm[2|6]

rs2'

00

Format
c.fsw rd',uimm(rs1')
Description
Store a single-precision floating-point value in floatingpoint register rs2' to memory.
It computes an effective address by adding the zero-extended offset, scaled by 4, to the base address in register rs1'.
Implementation
M[x[8+rs1'] + uimm][31:0] = f[8+rs2']
Expansion
fsw rs2', offset[6:2](rs1')

c.sd

15-13

12-10

9-7

6-5

4-2

1-0

111

uimm[5:3]

rs1'

uimm[7:6]

rs2'

00

Format
c.sd rd',uimm(rs1')
Description
Store a 64-bit value in register rs2' to memory.
It computes an effective address by adding the zero-extended offset, scaled by 8, to the base address in register rs1'.
Implementation
M[x[8+rs1'] + uimm][63:0] = x[8+rs2']
Expansion
sd rs2', offset[7:3](rs1')

c.nop

15-13

12-10

9-7

6-5

4-2

1-0

000

0

0

0

0

01

Format
c.nop
Description
Does not change any user-visible state, except for advancing the pc.
Implementation
None
Expansion
addi x0, x0, 0

c.addi

15-13

12

11-7

6-2

1-0

000

nzimm[5]

rs1/rd!=0

nzimm[4:0]

01

Format
c.addi rd,u[12:12]|u[6:2]
Description
Add the non-zero sign-extended 6-bit immediate to the value in register rd then writes the result to rd.
Implementation
x[rd] = x[rd] + sext(imm)
Expansion
addi rd, rd, nzimm[5:0]

c.jal

15-13

12-2

1-0

001

imm[11|4|9:8|10|6|7|3:1|5]

01

Format
c.jal offset
Description
Jump to address and place return address in rd.
Implementation
x[1] = pc+2; pc += sext(offset)
Expansion
jal x1, offset[11:1]

c.addiw

15-13

12

11-7

6-2

1-0

001

imm[5]

rd

imm[4:0]

01

Format
c.addiw rd,imm
Description
Add the non-zero sign-extended 6-bit immediate to the value in register rd then produce 32-bit result, then sign-extends result to 64 bits.
Implementation
x[rd] = sext((x[rd] + sext(imm))[31:0])
Expansion
addiw rd,rd,imm[5:0]

c.li

15-13

12

11-7

6-2

1-0

010

imm[5]

rd

imm[4:0]

01

Format
c.li rd,imm
Description
Load the sign-extended 6-bit immediate, imm, into register rd.
C.LI is only valid when rd!=x0.
Implementation
x[rd] = sext(imm)
Expansion
addi rd,x0,imm[5:0]

c.addi16sp

15-13

12

11-7

6-2

1-0

011

imm[9]

00010

imm[4|6|8:7|5]

01

Format
c.addi16sp imm
Description
Add 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).
Implementation
x[2] = x[2] + sext(imm)
Expansion
addi x2,x2, nzimm[9:4]

c.lui

15-13

12

11-7

6-2

1-0

011

imm[17]

rd

imm[16:12]

01

Format
c.lui rd,imm
Description

Implementation
x[rd] = sext(imm[17:12] << 12)
Expansion
lui rd,nzuimm[17:12]

c.srli

15-13

12

11-10

9-7

6-2

1-0

100

uimm[5]

00

rd'

uimm[4:0]

01

Format
c.srli rd',uimm
Description
Perform a logical right shift of the value in register rd' then writes the result to rd'.
The shift amount is encoded in the shamt field, where shamt[5] must be zero for RV32C.
Implementation
x[8+rd'] = x[8+rd'] >>u uimm
Expansion
srli rd',rd',shamt[5:0]

c.srai

15-13

12

11-10

9-7

6-2

1-0

100

uimm[5]

01

rd'

uimm[4:0]

01

Format
c.srai rd',uimm
Description
Perform a arithmetic right shift of the value in register rd' then writes the result to rd'.
The shift amount is encoded in the shamt field, where shamt[5] must be zero for RV32C.
Implementation
x[8+rd'] = x[8+rd'] >>s uimm
Expansion
srai rd',rd',shamt[5:0]

c.andi

15-13

12

11-10

9-7

6-2

1-0

100

imm[5]

10

rd'

imm[4:0]

01

Format
c.andi rd',imm
Description
Compute the bitwise AND of of the value in register rd' and the sign-extended 6-bit immediate, then writes the result to rd'.
Implementation
x[8+rd'] = x[8+rd'] & sext(imm)
Expansion
andi rd',rd',imm[5:0]

c.sub

15-10

9-7

6-5

4-2

1-0

100011

rd'

00

rs2'

01

Format
c.sub rd',rs2'
Description
Subtract the value in register rs2' from the value in register rd', then writes the result to register rd'.
Implementation
x[8+rd'] = x[8+rd'] - x[8+rs2']
Expansion
sub rd',rd',rs2'

c.xor

15-10

9-7

6-5

4-2

1-0

100011

rd'

01

rs2'

01

Format
c.xor rd',rs2'
Description
Compute the bitwise XOR of the values in registers rd' and rs2', then writes the result to register rd'.
Implementation
x[8+rd'] = x[8+rd'] ^ x[8+rs2']
Expansion
xor rd',rd',rs2'

c.or

15-10

9-7

6-5

4-2

1-0

100011

rd'

10

rs2'

01

Format
c.or rd',rs2'
Description
Compute the bitwise OR of the values in registers rd' and rs2', then writes the result to register rd'.
Implementation
x[8+rd'] = x[8+rd'] | x[8+rs2']
Expansion
or rd',rd',rs2

c.and

15-10

9-7

6-5

4-2

1-0

100011

rd'

11

rs2'

01

Format
c.and rd',rs2'
Description
Compute the bitwise AND of the values in registers rd' and rs2', then writes the result to register rd'.
Implementation
x[8+rd'] = x[8+rd'] & x[8+rs2']
Expansion
and rd',rd',rs2'

c.subw

15-10

9-7

6-5

4-2

1-0

100111

rd'

00

rs2'

01

Format
c.subw rd',rs2'
Description
Subtract the value in register rs2' from the value in register rd', then sign-extends the lower 32 bits of the difference before writing the result to register rd'.
Implementation
x[8+rd'] = sext((x[8+rd'] - x[8+rs2'])[31:0])
Expansion
subw rd',rd',rs2'

c.addw

15-10

9-7

6-5

4-2

1-0

100111

rd'

01

rs2'

01

Format
c.addw rd',rs2'
Description
Add the value in register rs2' from the value in register rd', then sign-extends the lower 32 bits of the difference before writing the result to register rd'.
Implementation
x[8+rd'] = sext((x[8+rd'] + x[8+rs2'])[31:0])
Expansion
addw rd',rd',rs2'

c.j

15-13

12-2

1-0

101

imm[11|4|9:8|10|6|7|3:1|5]

01

Format
c.j offset
Description
Unconditional control transfer.
Implementation
pc += sext(offset)
Expansion
jal x0,offset[11:1]

c.beqz

15-13

12-10

9-7

6-2

1-0

110

offset[8|4:3]

rs1'

offset[7:6|2:1|5]

01

Format
c.beqz rs1',offset
Description
Take the branch if the value in register rs1' is zero.
Implementation
if (x[8+rs1'] == 0) pc += sext(offset)
Expansion
beq rs1',x0,offset[8:1]

c.bnez

15-13

12-10

9-7

6-2

1-0

111

offset[8|4:3]

rs1'

offset[7:6|2:1|5]

01

Format
c.bnez rs1',offset
Description
Take the branch if the value in register rs1' is not zero.
Implementation
if (x[8+rs1'] != 0) pc += sext(offset)
Expansion
bne rs1',x0,offset[8:1]

c.slli

15-13

12

11-7

6-2

1-0

010

uimm[5]

rd

uimm[4:0]

10

Format
c.slli rd,uimm
Description
Perform a logical left shift of the value in register rd then writes the result to rd.
The shift amount is encoded in the shamt field, where shamt[5] must be zero for RV32C.
Implementation
x[rd] = x[rd] << uimm
Expansion
slli rd,rd,shamt[5:0]

c.fldsp

15-13

12

11-7

6-2

1-0

001

uimm[5]

rd

uimm[4:3|8:6]

10

Format
c.fldsp rd,uimm(x2)
Description
Load a double-precision floating-point value from memory into floating-point register rd.
It computes its effective address by adding the zero-extended offset, scaled by 8, to the stack pointer, x2.
Implementation
f[rd] = M[x[2] + uimm][63:0]
Expansion
fld rd,offset[8:3](x2)

c.lwsp

15-13

12

11-7

6-2

1-0

010

uimm[5]

rd

uimm[4:2|7:6]

10

Format
c.lwsp rd,uimm(x2)
Description
Load 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.
Implementation
x[rd] = sext(M[x[2] + uimm][31:0])
Expansion
lw rd,offset[7:2](x2)

c.flwsp

15-13

12

11-7

6-2

1-0

011

uimm[5]

rd

uimm[4:2|7:6]

10

Format
c.flwsp rd,uimm(x2)
Description
Load a single-precision floating-point value from memory into floating-point register rd.
It computes its effective address by adding the zero-extended offset, scaled by 4, to the stack pointer, x2.
Implementation
f[rd] = M[x[2] + uimm][31:0]
Expansion
flw rd,offset[7:2](x2)

c.ldsp

15-13

12

11-7

6-2

1-0

011

uimm[5]

rd

uimm[4:3|8:6]

10

Format
c.ldsp rd,uimm(x2)
Description
Load a 64-bit value from memory into register rd.
It computes its effective address by adding the zero-extended offset, scaled by 8, to the stack pointer, x2.
Implementation
x[rd] = M[x[2] + uimm][63:0]
Expansion
ld rd,offset[8:3](x2)

c.jr

15-13

12

11-7

6-2

1-0

100

0

rs1

00000

10

Format
c.jr rs1
Description
Performs an unconditional control transfer to the address in register rs1.
Implementation
pc = x[rs1]
Expansion
jalr x0,rs1,0

c.mv

15-13

12

11-7

6-2

1-0

100

0

rd

rs2

10

Format
c.mv rd,rs2
Description
Copy the value in register rs2 into register rd.
Implementation
x[rd] = x[rs2]
Expansion
add rd, x0, rs2

c.ebreak

15-13

12

11-7

6-2

1-0

100

1

00000

00000

10

Format
c.ebreak
Description
Cause control to be transferred back to the debugging environment.
Implementation
RaiseException(Breakpoint)
Expansion
ebreak

c.jalr

15-13

12

11-7

6-2

1-0

100

1

rs1

00000

10

Format
c.jalr rd
Description
Jump to address and place return address in rd.
Implementation
t = pc+2; pc = x[rs1]; x[1] = t
Expansion
jalr x1,rs1,0

c.add

15-13

12

11-7

6-2

1-0

100

1

rd

rs2

10

Format
c.add rd,rs2
Description
Add the values in registers rd and rs2 and writes the result to register rd.
Implementation
x[rd] = x[rd] + x[rs2]
Expansion
add rd,rd,rs2

c.fsdsp

15-13

12-7

6-2

1-0

101

uimm[5:3|8:6]

rs2

10

Format
c.fsdsp rs2,uimm(x2)
Description
Store a double-precision floating-point value in floating-point register rs2 to memory.
It computes an effective address by adding the zeroextended offset, scaled by 8, to the stack pointer, x2.
Implementation
M[x[2] + uimm][63:0] = f[rs2]
Expansion
fsd rs2,offset[8:3](x2)

c.swsp

15-13

12-7

6-2

1-0

110

uimm[5:2|7:6]

rs2

10

Format
c.swsp rs2,uimm(x2)
Description
Store 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.
Implementation
M[x[2] + uimm][31:0] = x[rs2]
Expansion
sw rs2,offset[7:2](x2)

c.fswsp

15-13

12-7

6-2

1-0

111

uimm[5:2|7:6]

rs2

10

Format
c.fswsp rs2,uimm(rs2)
Description
Store a single-precision floating-point value in floating-point register rs2 to memory.
It computes an effective address by adding the zero-extended offset, scaled by 4, to the stack pointer, x2.
Implementation
M[x[2] + uimm][31:0] = f[rs2]
Expansion
fsw rs2,offset[7:2](x2)

c.sdsp

15-13

12-7

6-2

1-0

111

uimm[5:3|8:6]

rs2

10

Format
c.sdsp rs2,uimm(x2)
Description
Store a 64-bit value in register rs2 to memory.
It computes an effective address by adding the zero-extended offset, scaled by 8, to the stack pointer, x2.
Implementation
M[x[2] + uimm][63:0] = x[rs2]
Expansion
sd rs2,offset[8:3](x2)