Skip to content

Commit 5f96554

Browse files
authored
Merge pull request #257 from riscv-software-src/c_ext
C extension support added
2 parents 6287ff9 + 7c108a7 commit 5f96554

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+1916
-0
lines changed

arch/ext/C.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
C:
44
type: unprivileged
55
long_name: Compressed instructions
6+
company:
7+
name: RISC-V International
8+
url: https://riscv.org
9+
doc_license:
10+
name: Creative Commons Attribution 4.0 International License
11+
url: https://creativecommons.org/licenses/by/4.0/
612
versions:
713
- version: "2.2.0"
814
state: ratified

arch/inst/C/c.add.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# yaml-language-server: $schema=../../../schemas/inst_schema.json
2+
3+
c.add:
4+
long_name: Add
5+
description: |
6+
Add the value in rs2 to rd, and store the result in rd.
7+
C.ADD expands into `add rd, rd, rs2`.
8+
definedBy:
9+
anyOf:
10+
- C
11+
- Zca
12+
assembly: xd, rs2
13+
encoding:
14+
match: 1001----------10
15+
variables:
16+
- name: rs2
17+
location: 6-2
18+
- name: rd
19+
location: 11-7
20+
access:
21+
s: always
22+
u: always
23+
vs: always
24+
vu: always
25+
operation(): |
26+
XReg t0 = X[rd];
27+
XReg t1 = X[rs2];
28+
X[rd] = t0 + t1;
29+
30+
sail(): |
31+
{
32+
let rs1_val = X(rd);
33+
let rs2_val = X(rs2);
34+
X(rd) = rs1_val + rs2_val;
35+
RETIRE_SUCCESS
36+
}

arch/inst/C/c.addi.yaml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# yaml-language-server: $schema=../../../schemas/inst_schema.json
2+
3+
c.addi:
4+
long_name: Add a sign-extended non-zero immediate
5+
description: |
6+
C.ADDI adds the non-zero sign-extended 6-bit immediate to the value in register rd then writes the result to rd.
7+
C.ADDI expands into `addi rd, rd, imm`.
8+
C.ADDI is only valid when rd≠x0 and imm≠0.
9+
The code points with rd=x0 encode the C.NOP instruction; the remaining code points with imm=0 encode HINTs.
10+
definedBy:
11+
anyOf:
12+
- C
13+
- Zca
14+
assembly: xd, imm
15+
encoding:
16+
match: 000-----------01
17+
variables:
18+
- name: imm
19+
location: 12|6-2
20+
not: 0
21+
- name: rd
22+
location: 11-7
23+
not: 0
24+
access:
25+
s: always
26+
u: always
27+
vs: always
28+
vu: always
29+
operation(): |
30+
if (implemented?(ExtensionName::C) && (CSR[misa].C == 1'b0)) {
31+
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
32+
}
33+
34+
X[rd] = X[rd] + imm;
35+

arch/inst/C/c.addi16sp.yaml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# yaml-language-server: $schema=../../../schemas/inst_schema.json
2+
3+
c.addi16sp:
4+
long_name: Add a sign-extended non-zero immediate
5+
description: |
6+
C.ADDI16SP 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).
7+
C.ADDI16SP is used to adjust the stack pointer in procedure prologues and epilogues.
8+
It expands into `addi x2, x2, nzimm[9:4]`.
9+
C.ADDI16SP is only valid when nzimm≠0; the code point with nzimm=0 is reserved.
10+
definedBy:
11+
anyOf:
12+
- C
13+
- Zca
14+
assembly: imm
15+
encoding:
16+
match: 011-00010-----01
17+
variables:
18+
- name: imm
19+
location: 12|4-3|5|2|6
20+
left_shift: 4
21+
not: 0
22+
access:
23+
s: always
24+
u: always
25+
vs: always
26+
vu: always
27+
operation(): |
28+
if (implemented?(ExtensionName::C) && (CSR[misa].C == 1'b0)) {
29+
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
30+
}
31+
32+
X[2] = X[2] + imm;
33+

arch/inst/C/c.addi4spn.yaml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# yaml-language-server: $schema=../../../schemas/inst_schema.json
2+
3+
c.addi4spn:
4+
long_name: Add a zero-extended non-zero immediate, scaled by 4, to the stack pointer
5+
description: |
6+
Adds a zero-extended non-zero immediate, scaled by 4, to the stack pointer, x2, and writes the result to rd′.
7+
This instruction is used to generate pointers to stack-allocated variables.
8+
It expands to `addi rd′, x2, nzuimm[9:2]`.
9+
C.ADDI4SPN is only valid when nzuimm≠0; the code points with nzuimm=0 are reserved.
10+
definedBy:
11+
anyOf:
12+
- C
13+
- Zca
14+
assembly: xd, imm
15+
encoding:
16+
match: 000-----------00
17+
variables:
18+
- name: imm
19+
location: 10-7|12-11|5|6
20+
left_shift: 2
21+
not: 0
22+
- name: rd
23+
location: 4-2
24+
access:
25+
s: always
26+
u: always
27+
vs: always
28+
vu: always
29+
operation(): |
30+
if (implemented?(ExtensionName::C) && (CSR[misa].C == 1'b0)) {
31+
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
32+
}
33+
34+
X[rd+8] = X[2] + imm;
35+

arch/inst/C/c.addiw.yaml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# yaml-language-server: $schema=../../../schemas/inst_schema.json
2+
3+
c.addiw:
4+
long_name: Add a sign-extended non-zero immediate
5+
description: |
6+
C.ADDIW is an RV64C/RV128C-only instruction that performs the same computation as C.ADDI but produces a 32-bit result, then sign-extends result to 64 bits.
7+
C.ADDIW expands into `addiw rd, rd, imm`.
8+
The immediate can be zero for C.ADDIW, where this corresponds to `sext.w rd`.
9+
C.ADDIW is only valid when rd≠x0; the code points with rd=x0 are reserved.
10+
definedBy:
11+
anyOf:
12+
- C
13+
- Zca
14+
base: 64
15+
assembly: xd, imm
16+
encoding:
17+
match: 001-----------01
18+
variables:
19+
- name: imm
20+
location: 12|6-2
21+
- name: rd
22+
location: 11-7
23+
not: 0
24+
access:
25+
s: always
26+
u: always
27+
vs: always
28+
vu: always
29+
operation(): |
30+
if (implemented?(ExtensionName::C) && (CSR[misa].C == 1'b0)) {
31+
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
32+
}
33+
34+
X[rd] = sext((X[rd] + imm), 32);
35+

arch/inst/C/c.addw.yaml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# yaml-language-server: $schema=../../../schemas/inst_schema.json
2+
3+
c.addw:
4+
long_name: Add word
5+
description: |
6+
Add the 32-bit values in rs2 from rd, and store the result in rd.
7+
The rd and rs2 register indexes should be used as rd+8 and rs2+8 (registers x8-x15).
8+
C.ADDW expands into `addw rd, rd, rs2`.
9+
definedBy:
10+
anyOf:
11+
- C
12+
- Zca
13+
base: 64
14+
assembly: xd, rs2
15+
encoding:
16+
match: 100111---01---01
17+
variables:
18+
- name: rs2
19+
location: 4-2
20+
- name: rd
21+
location: 9-7
22+
access:
23+
s: always
24+
u: always
25+
vs: always
26+
vu: always
27+
operation(): |
28+
Bits<32> t0 = X[rd+8][31:0];
29+
Bits<32> t1 = X[rs2+8][31:0];
30+
X[rd+8] = sext(t0 + t1, 31);
31+
32+
sail(): |
33+
{
34+
let rs1_val = (X(rd+8))[31..0];
35+
let rs2_val = (X(rs2+8))[31..0];
36+
let result : bits(32) = match op {
37+
RISCV_ADDW => rs1_val + rs2_val,
38+
RISCV_SUBW => rs1_val - rs2_val,
39+
RISCV_SLLW => rs1_val << (rs2_val[4..0]),
40+
RISCV_SRLW => rs1_val >> (rs2_val[4..0]),
41+
RISCV_SRAW => shift_right_arith32(rs1_val, rs2_val[4..0])
42+
};
43+
X(rd+8) = sign_extend(result);
44+
RETIRE_SUCCESS
45+
}

arch/inst/C/c.and.yaml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
# yaml-language-server: $schema=../../../schemas/inst_schema.json
2+
3+
c.and:
4+
long_name: And
5+
description: |
6+
And rd with rs2, and store the result in rd
7+
The rd and rs2 register indexes should be used as rd+8 and rs2+8 (registers x8-x15).
8+
C.AND expands into `and rd, rd, rs2`.
9+
definedBy:
10+
anyOf:
11+
- C
12+
- Zca
13+
assembly: xd, rs2
14+
encoding:
15+
match: 100011---11---01
16+
variables:
17+
- name: rs2
18+
location: 4-2
19+
- name: rd
20+
location: 9-7
21+
access:
22+
s: always
23+
u: always
24+
vs: always
25+
vu: always
26+
operation(): |
27+
XReg t0 = X[rd+8];
28+
XReg t1 = X[rs2+8];
29+
X[rd+8] = t0 & t1;
30+
31+
sail(): |
32+
{
33+
let rs1_val = X(rd+8);
34+
let rs2_val = X(rs2+8);
35+
let result : xlenbits = match op {
36+
RISCV_ADD => rs1_val + rs2_val,
37+
RISCV_SLT => zero_extend(bool_to_bits(rs1_val <_s rs2_val)),
38+
RISCV_SLTU => zero_extend(bool_to_bits(rs1_val <_u rs2_val)),
39+
RISCV_AND => rs1_val & rs2_val,
40+
RISCV_OR => rs1_val | rs2_val,
41+
RISCV_XOR => rs1_val ^ rs2_val,
42+
RISCV_SLL => if sizeof(xlen) == 32
43+
then rs1_val << (rs2_val[4..0])
44+
else rs1_val << (rs2_val[5..0]),
45+
RISCV_SRL => if sizeof(xlen) == 32
46+
then rs1_val >> (rs2_val[4..0])
47+
else rs1_val >> (rs2_val[5..0]),
48+
RISCV_SUB => rs1_val - rs2_val,
49+
RISCV_SRA => if sizeof(xlen) == 32
50+
then shift_right_arith32(rs1_val, rs2_val[4..0])
51+
else shift_right_arith64(rs1_val, rs2_val[5..0])
52+
};
53+
X(rd+8) = result;
54+
RETIRE_SUCCESS
55+
}

arch/inst/C/c.andi.yaml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
# yaml-language-server: $schema=../../../schemas/inst_schema.json
2+
3+
c.andi:
4+
long_name: And immediate
5+
description: |
6+
And an immediate to the value in rd, and store the result in rd.
7+
The rd register index should be used as rd+8 (registers x8-x15).
8+
C.ANDI expands into `andi rd, rd, imm`.
9+
definedBy:
10+
anyOf:
11+
- C
12+
- Zca
13+
assembly: xd, imm
14+
encoding:
15+
match: 100-10--------01
16+
variables:
17+
- name: imm
18+
location: 12|6-2
19+
- name: rd
20+
location: 9-7
21+
access:
22+
s: always
23+
u: always
24+
vs: always
25+
vu: always
26+
operation(): |
27+
# shamt is between 0-63
28+
X[rd+8] = X[rd+8] & imm;
29+
30+
sail(): |
31+
{
32+
let rd_val = X(rd+8);
33+
let immext : xlenbits = sign_extend(imm);
34+
let result : xlenbits = match op {
35+
RISCV_ADDI => rd_val + immext,
36+
RISCV_SLTI => zero_extend(bool_to_bits(rd_val <_s immext)),
37+
RISCV_SLTIU => zero_extend(bool_to_bits(rd_val <_u immext)),
38+
RISCV_ANDI => rd_val & immext,
39+
RISCV_ORI => rd_val | immext,
40+
RISCV_XORI => rd_val ^ immext
41+
};
42+
X(rd+8) = result;
43+
RETIRE_SUCCESS
44+
}

0 commit comments

Comments
 (0)