Skip to content

Commit 9e6253f

Browse files
authored
Merge pull request #1687 from riscv-software-src/flw-overlap
Separate RV32 and RV64 C instructions into separate files
2 parents 9bcda41 + 40b660a commit 9e6253f

File tree

13 files changed

+179
-124
lines changed

13 files changed

+179
-124
lines changed

riscv/check-opcode-overlap.t.cc

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "decode.h"
22
#include "common.h"
3-
#include <unordered_set>
3+
#include <unordered_map>
44
#include <vector>
55
#include <string>
66
#include <cstdio>
@@ -11,13 +11,9 @@ struct opcode {
1111
std::string name;
1212
};
1313

14-
static void check_overlap(const opcode& a, const opcode& b)
14+
static bool overlaps(const opcode& a, const opcode& b)
1515
{
16-
if ((a.match & b.mask) == b.match) {
17-
fprintf(stderr, "Instruction %s (%" PRIx64 ") overlaps instruction %s (%" PRIx64 ", mask %" PRIx64 ")\n",
18-
a.name.c_str(), a.match, b.name.c_str(), b.match, b.mask);
19-
exit(-1);
20-
}
16+
return (a.mask & b.mask & (a.match ^ b.match)) == 0;
2117
}
2218

2319
int main()
@@ -34,24 +30,47 @@ int main()
3430
#undef DEFINE_INSN
3531
};
3632

37-
std::unordered_set<std::string> overlap_list;
33+
std::unordered_map<std::string, bool> overlap_list;
3834
#define DECLARE_OVERLAP_INSN(name, ext) \
39-
overlap_list.insert(std::string(#name));
35+
overlap_list[std::string(#name)] = false;
4036
#include "overlap_list.h"
4137
#undef DECLARE_OVERLAP_INSN
4238

4339
std::vector<const opcode*> list;
44-
for (size_t i = 0; i < sizeof(static_list) / sizeof(static_list[0]); i++) {
40+
for (size_t i = 0; i < std::size(static_list); i++) {
4541
if (!overlap_list.count(static_list[i].name))
4642
list.push_back(&static_list[i]);
4743
}
4844

45+
bool ok = true;
46+
4947
for (size_t i = 1; i < list.size(); i++) {
5048
for (size_t j = 0; j < i; j++) {
51-
check_overlap(*list[i], *list[j]);
52-
check_overlap(*list[j], *list[i]);
49+
if (overlaps(*list[i], *list[j])) {
50+
fprintf(stderr, "Instruction %s (%" PRIx64 ") overlaps instruction %s (%" PRIx64 ", mask %" PRIx64 ")\n",
51+
list[i]->name.c_str(), list[i]->match, list[j]->name.c_str(), list[j]->match, list[j]->mask);
52+
ok = false;
53+
}
54+
}
55+
}
56+
57+
// make sure nothing in the overlap list is unused
58+
for (size_t i = 1; i < std::size(static_list); i++) {
59+
for (size_t j = 0; j < i; j++) {
60+
if (overlaps(static_list[i], static_list[j])) {
61+
overlap_list[static_list[i].name] = true;
62+
overlap_list[static_list[j].name] = true;
63+
}
64+
}
65+
}
66+
67+
for (auto const& [name, used] : overlap_list) {
68+
if (!used) {
69+
fprintf(stderr, "Instruction %s overlaps nothing, so overlap list entry has no effect\n",
70+
name.c_str());
71+
ok = false;
5372
}
5473
}
5574

56-
return 0;
75+
return ok ? 0 : -1;
5776
}

riscv/insns/c_flw.h

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
if (xlen == 32) {
2-
require_extension(EXT_ZCF);
3-
require_fp;
4-
WRITE_RVC_FRS2S(f32(MMU.load<uint32_t>(RVC_RS1S + insn.rvc_lw_imm())));
5-
} else { // c.ld
6-
require_extension(EXT_ZCA);
7-
WRITE_RVC_RS2S(MMU.load<int64_t>(RVC_RS1S + insn.rvc_ld_imm()));
8-
}
1+
require_extension(EXT_ZCF);
2+
require_fp;
3+
WRITE_RVC_FRS2S(f32(MMU.load<uint32_t>(RVC_RS1S + insn.rvc_lw_imm())));

riscv/insns/c_flwsp.h

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,3 @@
1-
if (xlen == 32) {
2-
require_extension(EXT_ZCF);
3-
require_fp;
4-
WRITE_FRD(f32(MMU.load<uint32_t>(RVC_SP + insn.rvc_lwsp_imm())));
5-
} else { // c.ldsp
6-
require_extension(EXT_ZCA);
7-
require(insn.rvc_rd() != 0);
8-
WRITE_RD(MMU.load<int64_t>(RVC_SP + insn.rvc_ldsp_imm()));
9-
}
1+
require_extension(EXT_ZCF);
2+
require_fp;
3+
WRITE_FRD(f32(MMU.load<uint32_t>(RVC_SP + insn.rvc_lwsp_imm())));

riscv/insns/c_fsw.h

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
if (xlen == 32) {
2-
require_extension(EXT_ZCF);
3-
require_fp;
4-
MMU.store<uint32_t>(RVC_RS1S + insn.rvc_lw_imm(), RVC_FRS2S.v[0]);
5-
} else { // c.sd
6-
require_extension(EXT_ZCA);
7-
MMU.store<uint64_t>(RVC_RS1S + insn.rvc_ld_imm(), RVC_RS2S);
8-
}
1+
require_extension(EXT_ZCF);
2+
require_fp;
3+
MMU.store<uint32_t>(RVC_RS1S + insn.rvc_lw_imm(), RVC_FRS2S.v[0]);

riscv/insns/c_fswsp.h

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,3 @@
1-
if (xlen == 32) {
2-
require_extension(EXT_ZCF);
3-
require_fp;
4-
MMU.store<uint32_t>(RVC_SP + insn.rvc_swsp_imm(), RVC_FRS2.v[0]);
5-
} else { // c.sdsp
6-
require_extension(EXT_ZCA);
7-
MMU.store<uint64_t>(RVC_SP + insn.rvc_sdsp_imm(), RVC_RS2);
8-
}
1+
require_extension(EXT_ZCF);
2+
require_fp;
3+
MMU.store<uint32_t>(RVC_SP + insn.rvc_swsp_imm(), RVC_FRS2.v[0]);

riscv/insns/c_ld.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
require_extension(EXT_ZCA);
2+
WRITE_RVC_RS2S(MMU.load<int64_t>(RVC_RS1S + insn.rvc_ld_imm()));

riscv/insns/c_ldsp.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
require_extension(EXT_ZCA);
2+
require(insn.rvc_rd() != 0);
3+
WRITE_RD(MMU.load<int64_t>(RVC_SP + insn.rvc_ldsp_imm()));

riscv/insns/c_sd.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
require_extension(EXT_ZCA);
2+
MMU.store<uint64_t>(RVC_RS1S + insn.rvc_ld_imm(), RVC_RS2S);

riscv/insns/c_sdsp.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
require_extension(EXT_ZCA);
2+
MMU.store<uint64_t>(RVC_SP + insn.rvc_sdsp_imm(), RVC_RS2);

riscv/overlap_list.h

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,34 @@
1-
DECLARE_OVERLAP_INSN(c_fsdsp, EXT_ZCD)
2-
DECLARE_OVERLAP_INSN(c_fld, EXT_ZCD)
3-
DECLARE_OVERLAP_INSN(c_fldsp, EXT_ZCD)
1+
// these overlap c.ld[sp]/c.sd[sp]
2+
DECLARE_OVERLAP_INSN(c_flw, EXT_ZCF)
3+
DECLARE_OVERLAP_INSN(c_flwsp, EXT_ZCF)
4+
DECLARE_OVERLAP_INSN(c_fsw, EXT_ZCF)
5+
DECLARE_OVERLAP_INSN(c_fswsp, EXT_ZCF)
6+
7+
// these overlap c.fsdsp
48
DECLARE_OVERLAP_INSN(cm_push, EXT_ZCMP)
59
DECLARE_OVERLAP_INSN(cm_pop, EXT_ZCMP)
610
DECLARE_OVERLAP_INSN(cm_popret, EXT_ZCMP)
711
DECLARE_OVERLAP_INSN(cm_popretz, EXT_ZCMP)
812
DECLARE_OVERLAP_INSN(cm_mva01s, EXT_ZCMP)
913
DECLARE_OVERLAP_INSN(cm_mvsa01, EXT_ZCMP)
1014
DECLARE_OVERLAP_INSN(cm_jalt, EXT_ZCMT)
11-
DECLARE_OVERLAP_INSN(c_fsd, EXT_ZCD)
15+
16+
// c.ebreak and c.jalr overlap c.add
1217
DECLARE_OVERLAP_INSN(c_ebreak, EXT_ZCA)
1318
DECLARE_OVERLAP_INSN(c_jalr, EXT_ZCA)
19+
20+
// c.jr overlaps c.mv
1421
DECLARE_OVERLAP_INSN(c_jr, EXT_ZCA)
15-
DECLARE_OVERLAP_INSN(vaesdf_vv, EXT_ZVKNED)
16-
DECLARE_OVERLAP_INSN(vghsh_vv, EXT_ZVKG)
17-
DECLARE_OVERLAP_INSN(vsha2ms_vv, EXT_ZVKNHA)
18-
DECLARE_OVERLAP_INSN(vsha2ms_vv, EXT_ZVKNHB)
19-
DECLARE_OVERLAP_INSN(vsm3me_vv, EXT_ZVKSH)
22+
23+
// lpad overlaps auipc
2024
DECLARE_OVERLAP_INSN(lpad, EXT_ZICFILP)
21-
DECLARE_OVERLAP_INSN(mop_r_28, EXT_ZIMOP)
22-
DECLARE_OVERLAP_INSN(mop_r_N, EXT_ZIMOP)
23-
DECLARE_OVERLAP_INSN(mop_rr_7, EXT_ZIMOP)
24-
DECLARE_OVERLAP_INSN(mop_rr_N, EXT_ZIMOP)
25+
26+
// these overlap Zimop/Zcmop
27+
DECLARE_OVERLAP_INSN(ssrdp, EXT_ZICFISS)
28+
DECLARE_OVERLAP_INSN(sspush_x1, EXT_ZICFISS)
29+
DECLARE_OVERLAP_INSN(sspush_x5, EXT_ZICFISS)
30+
DECLARE_OVERLAP_INSN(sspopchk_x1, EXT_ZICFISS)
31+
DECLARE_OVERLAP_INSN(sspopchk_x5, EXT_ZICFISS)
2532
DECLARE_OVERLAP_INSN(c_sspush_x1, EXT_ZICFISS)
2633
DECLARE_OVERLAP_INSN(c_sspopchk_x5, EXT_ZICFISS)
2734
DECLARE_OVERLAP_INSN(c_mop_N, EXT_ZCMOP)

0 commit comments

Comments
 (0)