Skip to content

Commit c1bcd55

Browse files
committed
Merging updated upstream code
2 parents 0d28784 + 30b07b1 commit c1bcd55

24 files changed

+711
-32
lines changed

arch/ext/Zcd.yaml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# yaml-language-server: $schema=../../schemas/ext_schema.json
2+
3+
$schema: "ext_schema.json#"
4+
kind: extension
5+
name: Zcd
6+
long_name: Compressed instructions for double precision floating point
7+
description: |
8+
Zcd is the existing set of compressed double precision floating point loads and stores:
9+
`c.fld`, `c.fldsp`, `c.fsd`, `c.fsdsp`.
10+
11+
type: unprivileged
12+
company:
13+
name: RISC-V International
14+
url: https://riscv.org
15+
versions:
16+
- version: "1.0.0"
17+
state: ratified
18+
ratification_date: 2023-04
19+
repositories:
20+
- url: https://github.com/riscv/riscv-code-size-reduction
21+
branch: main
22+
contributors:
23+
- name: Tariq Kurd
24+
- name: Ibrahim Abu Kharmeh
25+
- name: Torbjørn Viem Ness
26+
- name: Matteo Perotti
27+
- name: Nidal Faour
28+
- name: Bill Traynor
29+
- name: Rafael Sene
30+
- name: Xinlong Wu
31+
- name: sinan
32+
- name: Jeremy Bennett
33+
- name: Heda Chen
34+
- name: Alasdair Armstrong
35+
- name: Graeme Smecher
36+
- name: Nicolas Brunie
37+
- name: Jiawei
38+
requires:
39+
allOf:
40+
- anyOf:
41+
- { name: Zca, version: "= 1.0.0" }
42+
- { name: C, version: "= 1.0.0" }
43+
- { name: D, version: "~> 2.2.0" }

arch/inst/Zbkb/brev8.yaml

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,10 @@
33
$schema: inst_schema.json#
44
kind: instruction
55
name: brev8
6-
long_name: No synopsis available.
6+
long_name: Reverse bits in bytes
77
description: |
8-
No description available.
9-
definedBy:
10-
anyOf: [B, Zbkb, Zk, Zkn, Zks]
8+
This instruction reverses the order of the bits in every byte of a register.
9+
definedBy: Zbkb
1110
assembly: xd, xs1
1211
encoding:
1312
match: 011010000111-----101-----0010011
@@ -23,3 +22,20 @@ access:
2322
vu: always
2423
data_independent_timing: false
2524
operation(): |
25+
XReg input = X[rs1];
26+
XReg output = 0;
27+
28+
for(U32 i=0; i<(xlen()-8); i = i+8) {
29+
for(U32 j=0; j<8; j = j+1) {
30+
output[(i*8)+(7-j)] = input[(i*8)+j];
31+
}
32+
}
33+
34+
X[rd] = output;
35+
36+
sail(): |
37+
result : xlenbits = EXTZ(0b0);
38+
foreach (i from 0 to sizeof(xlen) by 8) {
39+
result[i+7..i] = reverse_bits_in_byte(X(rs1)[i+7..i]);
40+
};
41+
X(rd) = result;

arch/inst/Zbkb/unzip.yaml

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
$schema: inst_schema.json#
44
kind: instruction
55
name: unzip
6-
long_name: No synopsis available.
6+
long_name: Bit deinterleave
77
description: |
8-
No description available.
9-
definedBy:
10-
anyOf: [B, Zbkb, Zk, Zkn, Zks]
8+
This instruction gathers bits from the high and low halves of the source word into odd/even bit
9+
positions in the destination word. It is the inverse of the zip instruction. This instruction is
10+
available only on RV32.
11+
definedBy: Zbkb
1112
assembly: xd, xs1
1213
encoding:
1314
match: 000010001111-----101-----0010011
@@ -24,3 +25,18 @@ access:
2425
data_independent_timing: false
2526
base: 32
2627
operation(): |
28+
XReg input = X[rs1];
29+
XReg output = 0;
30+
31+
for(U32 i=0; i<(xlen()/2-1); i = i+1) {
32+
output[i] = input[2*i];
33+
output[i+xlen()/2] = input[2*i+1];
34+
}
35+
36+
X[rd] = output;
37+
38+
sail(): |
39+
foreach (i from 0 to xlen/2-1) {
40+
X(rd)[i] = X(rs1)[2*i];
41+
X(rd)[i+xlen/2] = X(rs1)[2*i+1];
42+
}

arch/inst/Zbkb/zip.yaml

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
$schema: inst_schema.json#
44
kind: instruction
55
name: zip
6-
long_name: No synopsis available.
6+
long_name: Bit interleave
77
description: |
8-
No description available.
9-
definedBy:
10-
anyOf: [B, Zbkb, Zk, Zkn, Zks]
8+
This instruction scatters all of the odd and even bits of a source word into the high and low halves
9+
of a destination word. It is the inverse of the unzip instruction. This instruction is available only on
10+
RV32.
11+
definedBy: Zbkb
1112
assembly: xd, xs1
1213
encoding:
1314
match: 000010001111-----001-----0010011
@@ -24,3 +25,18 @@ access:
2425
data_independent_timing: false
2526
base: 32
2627
operation(): |
28+
XReg input = X[rs1];
29+
XReg output = 0;
30+
31+
for(U32 i=0; i<(xlen()/2-1); i = i+1){
32+
output[2*i] = input[i];
33+
output[2*i+1] = input[i+xlen()/2];
34+
}
35+
36+
X[rd] = output;
37+
38+
sail(): |
39+
foreach (i from 0 to xlen/2-1) {
40+
X(rd)[2*i] = X(rs1)[i];
41+
X(rd)[2*i+1] = X(rs1)[i+xlen/2];
42+
}

arch/inst/Zbkx/xperm4.yaml

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
$schema: inst_schema.json#
44
kind: instruction
55
name: xperm4
6-
long_name: No synopsis available.
6+
long_name: Crossbar permutation (nibbles)
77
description: |
8-
No description available.
9-
definedBy:
10-
anyOf: [B, Zbkx, Zk, Zkn, Zks]
8+
The xperm4 instruction operates on nibbles. The rs1 register contains a vector of XLEN/4 4-bit
9+
elements. The rs2 register contains a vector of XLEN/4 4-bit indexes. The result is each element in
10+
rs2 replaced by the indexed element in rs1, or zero if the index into rs2 is out of bounds.
11+
definedBy: Zbkx
1112
assembly: xd, xs1, xs2
1213
encoding:
1314
match: 0010100----------010-----0110011
@@ -25,3 +26,29 @@ access:
2526
vu: always
2627
data_independent_timing: false
2728
operation(): |
29+
XReg input1 = X[rs1];
30+
XReg input2 = X[rs2];
31+
XReg output = 0;
32+
33+
for(U32 i=0; i<(xlen()-4); i = i+4) {
34+
XReg index = input2[i+3:i];
35+
if(4*index < xlen()) {
36+
output[i+3:i] = input1[4*index+3:4*index];
37+
}
38+
}
39+
40+
X[rd] = output;
41+
42+
sail(): |
43+
val xperm4_lookup : (bits(4), xlenbits) -> bits(4)
44+
function xperm4_lookup (idx, lut) = {
45+
(lut >> (idx @ 0b00))[3..0]
46+
}
47+
function clause execute ( XPERM_4 (rs2,rs1,rd)) = {
48+
result : xlenbits = EXTZ(0b0);
49+
foreach(i from 0 to xlen by 4) {
50+
result[i+3..i] = xperm4_lookup(X(rs2)[i+3..i], X(rs1));
51+
};
52+
X(rd) = result;
53+
RETIRE_SUCCESS
54+
}

arch/inst/Zbkx/xperm8.yaml

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
$schema: inst_schema.json#
44
kind: instruction
55
name: xperm8
6-
long_name: No synopsis available.
6+
long_name: Crossbar permutation (bytes)
77
description: |
8-
No description available.
9-
definedBy:
10-
anyOf: [B, Zbkx, Zk, Zkn, Zks]
8+
The xperm8 instruction operates on bytes. The rs1 register contains a vector of XLEN/8 8-bit
9+
elements. The rs2 register contains a vector of XLEN/8 8-bit indexes. The result is each element in
10+
rs2 replaced by the indexed element in rs1, or zero if the index into rs2 is out of bounds.
11+
definedBy: Zbkx
1112
assembly: xd, xs1, xs2
1213
encoding:
1314
match: 0010100----------100-----0110011
@@ -25,3 +26,29 @@ access:
2526
vu: always
2627
data_independent_timing: false
2728
operation(): |
29+
XReg input1 = X[rs1];
30+
XReg input2 = X[rs2];
31+
XReg output = 0;
32+
33+
for(U32 i=0; i<(xlen()-8); i = i+8) {
34+
XReg index = input2[i+7:i];
35+
if(8*index < xlen()) {
36+
output[i+7:i] = input1[8*index+7:8*index];
37+
}
38+
}
39+
40+
X[rd] = output;
41+
42+
sail(): |
43+
val xperm8_lookup : (bits(8), xlenbits) -> bits(8)
44+
function xperm8_lookup (idx, lut) = {
45+
(lut >> (idx @ 0b00))[7..0]
46+
}
47+
function clause execute ( XPERM_8 (rs2,rs1,rd)) = {
48+
result : xlenbits = EXTZ(0b0);
49+
foreach(i from 0 to xlen by 8) {
50+
result[i+7..i] = xperm8_lookup(X(rs2)[i+7..i], X(rs1));
51+
};
52+
X(rd) = result;
53+
RETIRE_SUCCESS
54+
}

arch/inst/Zcmp/cm.mva01s.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+
$schema: "inst_schema.json#"
4+
kind: instruction
5+
name: cm.mva01s
6+
long_name: Move two s0-s7 registers into a0-a1
7+
description: |
8+
This instruction moves r1s' into a0 and r2s' into a1. The execution is atomic, so it is not possible to observe state where only one of a0 or a1 have been updated.
9+
The encoding uses sreg number specifiers instead of xreg number specifiers to save encoding space. The mapping between them is specified in the pseudo-code below.
10+
definedBy:
11+
anyOf:
12+
- Zcmp
13+
assembly: r1s, r2s
14+
encoding:
15+
match: 101011---11---10
16+
variables:
17+
- name: r1s
18+
location: 9-7
19+
- name: r2s
20+
location: 4-2
21+
access:
22+
s: always
23+
u: always
24+
vs: always
25+
vu: always
26+
operation(): |
27+
if (implemented?(ExtensionName::Zcmp) && (CSR[misa].C == 1'b0)) {
28+
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
29+
}
30+
XReg xreg1 = (r1s[2:1]>0) ? {1,0,r1s[2:0]} : {0,1,r1s[2:0]};
31+
XReg xreg2 = (r2s[2:1]>0) ? {1,0,r2s[2:0]} : {0,1,r2s[2:0]};
32+
X[10] = X[xreg1];
33+
X[11] = X[xreg2];

arch/inst/Zcmp/cm.mvsa01.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+
$schema: "inst_schema.json#"
4+
kind: instruction
5+
name: cm.mvsa01
6+
long_name: Move a0-a1 into two registers of s0-s7
7+
description: |
8+
This instruction moves a0 into r1s' and a1 into r2s'. r1s' and r2s' must be different.
9+
The execution is atomic, so it is not possible to observe state where only one of r1s' or r2s' has been updated.
10+
The encoding uses sreg number specifiers instead of xreg number specifiers to save encoding space.
11+
The mapping between them is specified in the pseudo-code below.
12+
definedBy:
13+
anyOf:
14+
- Zcmp
15+
assembly: r1s, r2s
16+
encoding:
17+
match: 101011---01---10
18+
variables:
19+
- name: r1s
20+
location: 9-7
21+
- name: r2s
22+
location: 4-2
23+
access:
24+
s: always
25+
u: always
26+
vs: always
27+
vu: always
28+
operation(): |
29+
if (implemented?(ExtensionName::Zcmp) && (CSR[misa].C == 1'b0)) {
30+
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
31+
}
32+
XReg xreg1 = (r1s[2:1]>0) ? {1,0,r1s[2:0]} : {0,1,r1s[2:0]};
33+
XReg xreg2 = (r2s[2:1]>0) ? {1,0,r2s[2:0]} : {0,1,r2s[2:0]};
34+
X[xreg1] = X[10];
35+
X[xreg2] = X[11];

arch/inst/Zcmp/cm.pop.yaml

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# yaml-language-server: $schema=../../../schemas/inst_schema.json
2+
3+
$schema: "inst_schema.json#"
4+
kind: instruction
5+
name: cm.pop
6+
long_name: Destroy function call stack frame
7+
description: |
8+
Destroy stack frame: load `ra` and 0 to 12 saved registers from the stack frame, deallocate the stack frame.
9+
This instruction pops (loads) the registers in `reg_list` from stack memory, and then adjusts the stack pointer by `stack_adj`.
10+
11+
Restrictions on stack_adj:
12+
13+
* it must be enough to store all of the listed registers
14+
* it must be a multiple of 16 (bytes):
15+
** for RV32 the allowed values are: 16, 32, 48, 64, 80, 96, 112
16+
** for RV64 the allowed values are: 16, 32, 48, 64, 80, 96, 112, 128, 144, 160
17+
definedBy:
18+
anyOf:
19+
- Zcmp
20+
assembly: reg_list, stack_adj
21+
encoding:
22+
match: 10111010------10
23+
variables:
24+
- name: rlist
25+
location: 7-4
26+
not: [0, 1, 2, 3]
27+
- name: spimm
28+
location: 3-2
29+
left_shift: 4
30+
access:
31+
s: always
32+
u: always
33+
vs: always
34+
vu: always
35+
operation(): |
36+
if (implemented?(ExtensionName::Zcmp) && (CSR[misa].C == 1'b0)) {
37+
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
38+
}
39+
40+
XReg size = xlen();
41+
XReg nreg = (rlist == 15) ? 13 : (rlist - 3);
42+
XReg stack_aligned_adj = (nreg * 4 + 15) & ~0xF;
43+
XReg virtual_address_sp = X[2];
44+
XReg virtual_address_new_sp = virtual_address_sp + stack_aligned_adj + spimm;
45+
XReg virtual_address_base = virtual_address_new_sp - (nreg * size);
46+
47+
X[ 1] = read_memory_xlen(virtual_address_base + 0*size, $encoding);
48+
if (nreg > 1) {
49+
X[ 8] = read_memory_xlen(virtual_address_base + 1*size, $encoding);
50+
}
51+
if (nreg > 2) {
52+
X[ 9] = read_memory_xlen(virtual_address_base + 2*size, $encoding);
53+
}
54+
if (nreg > 3) {
55+
X[18] = read_memory_xlen(virtual_address_base + 3*size, $encoding);
56+
}
57+
if (nreg > 4) {
58+
X[19] = read_memory_xlen(virtual_address_base + 4*size, $encoding);
59+
}
60+
if (nreg > 5) {
61+
X[20] = read_memory_xlen(virtual_address_base + 5*size, $encoding);
62+
}
63+
if (nreg > 6) {
64+
X[21] = read_memory_xlen(virtual_address_base + 6*size, $encoding);
65+
}
66+
if (nreg > 7) {
67+
X[22] = read_memory_xlen(virtual_address_base + 7*size, $encoding);
68+
}
69+
if (nreg > 8) {
70+
X[23] = read_memory_xlen(virtual_address_base + 8*size, $encoding);
71+
}
72+
if (nreg > 9) {
73+
X[24] = read_memory_xlen(virtual_address_base + 9*size, $encoding);
74+
}
75+
if (nreg > 10) {
76+
X[25] = read_memory_xlen(virtual_address_base + 10*size, $encoding);
77+
}
78+
if (nreg > 11) {
79+
X[26] = read_memory_xlen(virtual_address_base + 11*size, $encoding);
80+
X[27] = read_memory_xlen(virtual_address_base + 12*size, $encoding);
81+
}
82+
83+
X[2] = virtual_address_new_sp;

0 commit comments

Comments
 (0)