Skip to content

Commit 1989029

Browse files
committed
demo
1 parent 3aeae90 commit 1989029

File tree

4 files changed

+285
-8
lines changed

4 files changed

+285
-8
lines changed

src/machine/instruction.cpp

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1514,3 +1514,133 @@ TokenizedInstruction::TokenizedInstruction(
15141514
, address(address)
15151515
, filename(std::move(filename))
15161516
, line(line) {}
1517+
1518+
1519+
void gen_instruction_code_and_expected_str(QTextStream& outfile, const InstructionMap* im, uint32_t code, int count, int offset, int subclass_i, int depth) {
1520+
if (im->name == "unknown") {
1521+
return;
1522+
}
1523+
code |= (((1 << count) - 1) & subclass_i) << offset;
1524+
// LOG("code: %d, count: %d, offset: %d, index: %d", code, count, offset, subclass_i);
1525+
if (im->subclass != nullptr) {
1526+
for (int j = 0; j < ((1 << im->subfield.count) - 1); j++) {
1527+
gen_instruction_code_and_expected_str(outfile, &im->subclass[j], code, im->subfield.count, im->subfield.offset, j, depth + 1);
1528+
}
1529+
return;
1530+
}
1531+
1532+
QString res = im->name;
1533+
1534+
std::unordered_map<std::string, uint32_t> direct_map = {
1535+
{ "ecall", 0b00000000000000000000000001110011 },
1536+
{ "mret", 0b00110000001000000000000001110011 },
1537+
{ "sret", 0b00010000001000000000000001110011 }
1538+
};
1539+
if (direct_map.count(im->name)) {
1540+
code = direct_map[im->name];
1541+
} else {
1542+
1543+
1544+
int val = 1;
1545+
switch (im->type) {
1546+
case Instruction::Type::R:
1547+
case Instruction::Type::AMO: {
1548+
code |= 0b00000000000100001000000010000000;
1549+
break;
1550+
}
1551+
case Instruction::Type::I:
1552+
code |= 0b00000000000100001000000010000000;
1553+
break;
1554+
case Instruction::Type::ZICSR: {
1555+
code |= 0b00000000000100001000000010000000;
1556+
break;
1557+
}
1558+
case Instruction::Type::S: {
1559+
code |= 0b00000000000100001000000010000000;
1560+
break;
1561+
}
1562+
case Instruction::Type::B: {
1563+
code |= 0b00000000000100001000000100000000;
1564+
val = 2;
1565+
break;
1566+
}
1567+
case Instruction::Type::U: {
1568+
code |= 0b00000000000000000001000010000000;
1569+
break;
1570+
}
1571+
case Instruction::Type::J: {
1572+
code |= 0b00000000001000000000000010000000;
1573+
val = 2;
1574+
break;
1575+
}
1576+
case Instruction::Type::UNKNOWN: {
1577+
return;
1578+
}
1579+
}
1580+
1581+
QString next_delim = " ";
1582+
for (const QString &arg_string : im->args) {
1583+
res += next_delim;
1584+
next_delim = ", ";
1585+
for (int pos = 0; pos < arg_string.size(); pos += 1) {
1586+
char arg_letter = arg_string[pos].toLatin1();
1587+
const ArgumentDesc *arg_desc = arg_desc_by_code[(unsigned char)arg_letter];
1588+
if (arg_desc == nullptr) {
1589+
res += arg_letter;
1590+
continue;
1591+
}
1592+
switch (arg_desc->kind) {
1593+
case 'g': {
1594+
res += "x1";
1595+
break;
1596+
}
1597+
case 'p':
1598+
case 'a':
1599+
res += QString::asprintf("0x%d", val);
1600+
break;
1601+
case 'o':
1602+
case 'n': {
1603+
if (arg_desc->min < 0) {
1604+
res += "1";
1605+
} else {
1606+
res += "0x1";
1607+
}
1608+
break;
1609+
}
1610+
case 'E': {
1611+
res += "0x1";
1612+
break;
1613+
}
1614+
}
1615+
}
1616+
}
1617+
}
1618+
1619+
1620+
QString test_code = QString::asprintf("QCOMPARE(Instruction(0x%x).to_str(), \"%s\");", code, qPrintable(res));
1621+
outfile << test_code;
1622+
if (Instruction(code).to_str() != res) {
1623+
outfile << QString::asprintf(" // failed");
1624+
}
1625+
outfile << "\n";
1626+
}
1627+
1628+
#include <iostream>
1629+
#include <fstream>
1630+
#include <qfile.h>
1631+
void gen() {
1632+
fill_argdesbycode();
1633+
1634+
QFile outfile("gen_instruction_test_case.txt");
1635+
if (outfile.open(QIODevice::WriteOnly | QIODevice::Text)) {
1636+
QTextStream out(&outfile);
1637+
const struct InstructionMap *im = &C_inst_map[0];
1638+
for (int i = 0; i < sizeof(C_inst_map) / sizeof(C_inst_map[0]); i++) {
1639+
im = &C_inst_map[i];
1640+
gen_instruction_code_and_expected_str(out, im, 0b0, 2, 0, i, 1);
1641+
}
1642+
outfile.close();
1643+
} else {
1644+
PANIC("gen_instruction_test_case failed");
1645+
}
1646+
}

src/machine/instruction.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,8 @@ struct RelocExpression {
276276

277277
} // namespace machine
278278

279+
void gen();
280+
279281
Q_DECLARE_METATYPE(machine::Instruction)
280282

281283
#endif // INSTRUCTION_H

src/machine/instruction.test.cpp

Lines changed: 151 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,170 @@ using namespace machine;
77
// Test that we are correctly encoding instructions in constructor
88
void TestInstruction::instruction() {
99
QCOMPARE(Instruction(0x0), Instruction());
10-
// QCOMPARE(Instruction(0x4432146), Instruction(1, 2, 3, 4, 5, 6));
11-
// QCOMPARE(Instruction(0x4430004), Instruction(1, 2, 3, 4));
12-
// QCOMPARE(Instruction(0x4000002), Instruction(1, 2_addr));
10+
QCOMPARE(Instruction(0x0), Instruction(Instruction(0x0)));
1311
}
1412

1513
// Test that we are correctly decoding instruction fields
1614
void TestInstruction::instruction_access() {
1715
Instruction i(0xffffffff);
1816

1917
QCOMPARE(i.data(), (uint32_t)0xffffffff);
20-
QCOMPARE(i.opcode(), (uint8_t)0x3f);
18+
QCOMPARE(i.opcode(), (uint8_t)0x7f);
2119
QCOMPARE(i.rs(), (uint8_t)0x1f);
2220
QCOMPARE(i.rt(), (uint8_t)0x1f);
2321
QCOMPARE(i.rd(), (uint8_t)0x1f);
2422
QCOMPARE(i.shamt(), (uint8_t)0x1f);
25-
QCOMPARE(i.funct(), (uint16_t)0x3f);
26-
QCOMPARE(i.immediate(), (int32_t)0xffff);
23+
QCOMPARE(i.funct(), (uint16_t)0x3ff);
24+
QCOMPARE(i.immediate(), (int32_t)0);
2725
QCOMPARE(i.address().get_raw(), (uint64_t)0x3ffffff);
2826
}
2927

30-
// TODO test to_str
28+
void TestInstruction::instruction_to_str() {
29+
QCOMPARE(Instruction(0xffffffff).to_str(), "unknown");
30+
QCOMPARE(Instruction(0x0).to_str(), "unknown");
31+
QCOMPARE(Instruction(0b00000000000000000000000000010011).to_str(), "nop");
32+
QCOMPARE(Instruction(0b00000000000000001000000010010011).to_str(), "addi x1, x1, 0");
33+
QCOMPARE(Instruction(0b01111111111111111000111110010011).to_str(), "addi x31, x31, 2047");
34+
QCOMPARE(Instruction(0b11111111111100001000000010010011).to_str(), "addi x1, x1, -1");
35+
QCOMPARE(Instruction(0b10000000000000001000000010010011).to_str(), "addi x1, x1, -2048");
36+
QCOMPARE(Instruction(0x108083).to_str(), "lb x1, 1(x1)");
37+
QCOMPARE(Instruction(0x109083).to_str(), "lh x1, 1(x1)");
38+
QCOMPARE(Instruction(0x10a083).to_str(), "lw x1, 1(x1)");
39+
QCOMPARE(Instruction(0x10b083).to_str(), "ld x1, 1(x1)");
40+
QCOMPARE(Instruction(0x10c083).to_str(), "lbu x1, 1(x1)");
41+
QCOMPARE(Instruction(0x10d083).to_str(), "lhu x1, 1(x1)");
42+
QCOMPARE(Instruction(0x10e083).to_str(), "lwu x1, 1(x1)");
43+
QCOMPARE(Instruction(0x10808f).to_str(), "fence");
44+
QCOMPARE(Instruction(0x10908f).to_str(), "fence.i");
45+
QCOMPARE(Instruction(0x108093).to_str(), "addi x1, x1, 1");
46+
QCOMPARE(Instruction(0x109093).to_str(), "slli x1, x1, 0x1");
47+
QCOMPARE(Instruction(0x10a093).to_str(), "slti x1, x1, 1");
48+
QCOMPARE(Instruction(0x10b093).to_str(), "sltiu x1, x1, 1");
49+
QCOMPARE(Instruction(0x10c093).to_str(), "xori x1, x1, 1");
50+
QCOMPARE(Instruction(0x10d093).to_str(), "srli x1, x1, 0x1");
51+
QCOMPARE(Instruction(0x10e093).to_str(), "ori x1, x1, 1");
52+
QCOMPARE(Instruction(0x1097).to_str(), "auipc x1, 0x1");
53+
QCOMPARE(Instruction(0x10809b).to_str(), "addiw x1, x1, 1");
54+
QCOMPARE(Instruction(0x10909b).to_str(), "slliw x1, x1, 0x1");
55+
QCOMPARE(Instruction(0x10d09b).to_str(), "srliw x1, x1, 0x1");
56+
QCOMPARE(Instruction(0x1080a3).to_str(), "sb x1, 1(x1)");
57+
QCOMPARE(Instruction(0x1090a3).to_str(), "sh x1, 1(x1)");
58+
QCOMPARE(Instruction(0x10a0a3).to_str(), "sw x1, 1(x1)");
59+
QCOMPARE(Instruction(0x10b0a3).to_str(), "sd x1, 1(x1)");
60+
QCOMPARE(Instruction(0x10a0af).to_str(), "amoadd.w x1, x1, (x1)");
61+
QCOMPARE(Instruction(0x210a0af).to_str(), "amoadd.w.rl x1, x1, (x1)");
62+
QCOMPARE(Instruction(0x410a0af).to_str(), "amoadd.w.aq x1, x1, (x1)");
63+
QCOMPARE(Instruction(0x610a0af).to_str(), "amoadd.w.aqrl x1, x1, (x1)");
64+
QCOMPARE(Instruction(0x810a0af).to_str(), "amoswap.w x1, x1, (x1)");
65+
QCOMPARE(Instruction(0xa10a0af).to_str(), "amoswap.w.rl x1, x1, (x1)");
66+
QCOMPARE(Instruction(0xc10a0af).to_str(), "amoswap.w.aq x1, x1, (x1)");
67+
QCOMPARE(Instruction(0xe10a0af).to_str(), "amoswap.w.aqrl x1, x1, (x1)");
68+
QCOMPARE(Instruction(0x1010a0af).to_str(), "lr.w x1, (x1)");
69+
QCOMPARE(Instruction(0x1210a0af).to_str(), "lr.w.rl x1, (x1)");
70+
QCOMPARE(Instruction(0x1410a0af).to_str(), "lr.w.aq x1, (x1)");
71+
QCOMPARE(Instruction(0x1610a0af).to_str(), "lr.w.aqrl x1, (x1)");
72+
QCOMPARE(Instruction(0x1810a0af).to_str(), "sc.w x1, x1, (x1)");
73+
QCOMPARE(Instruction(0x1a10a0af).to_str(), "sc.w.rl x1, x1, (x1)");
74+
QCOMPARE(Instruction(0x1c10a0af).to_str(), "sc.w.aq x1, x1, (x1)");
75+
QCOMPARE(Instruction(0x1e10a0af).to_str(), "sc.w.aqrl x1, x1, (x1)");
76+
QCOMPARE(Instruction(0x2010a0af).to_str(), "amoxor.w x1, x1, (x1)");
77+
QCOMPARE(Instruction(0x2210a0af).to_str(), "amoxor.w.rl x1, x1, (x1)");
78+
QCOMPARE(Instruction(0x2410a0af).to_str(), "amoxor.w.aq x1, x1, (x1)");
79+
QCOMPARE(Instruction(0x2610a0af).to_str(), "amoxor.w.aqrl x1, x1, (x1)");
80+
QCOMPARE(Instruction(0x4010a0af).to_str(), "amoor.w x1, x1, (x1)");
81+
QCOMPARE(Instruction(0x4210a0af).to_str(), "amoor.w.rl x1, x1, (x1)");
82+
QCOMPARE(Instruction(0x4410a0af).to_str(), "amoor.w.aq x1, x1, (x1)");
83+
QCOMPARE(Instruction(0x4610a0af).to_str(), "amoor.w.aqrl x1, x1, (x1)");
84+
QCOMPARE(Instruction(0x6010a0af).to_str(), "amoand.w x1, x1, (x1)");
85+
QCOMPARE(Instruction(0x6210a0af).to_str(), "amoand.w.rl x1, x1, (x1)");
86+
QCOMPARE(Instruction(0x6410a0af).to_str(), "amoand.w.aq x1, x1, (x1)");
87+
QCOMPARE(Instruction(0x6610a0af).to_str(), "amoand.w.aqrl x1, x1, (x1)");
88+
QCOMPARE(Instruction(0x8010a0af).to_str(), "amomin.w x1, x1, (x1)");
89+
QCOMPARE(Instruction(0x8210a0af).to_str(), "amomin.w.rl x1, x1, (x1)");
90+
QCOMPARE(Instruction(0x8410a0af).to_str(), "amomin.w.aq x1, x1, (x1)");
91+
QCOMPARE(Instruction(0x8610a0af).to_str(), "amomin.w.aqrl x1, x1, (x1)");
92+
QCOMPARE(Instruction(0xa010a0af).to_str(), "amomax.w x1, x1, (x1)");
93+
QCOMPARE(Instruction(0xa210a0af).to_str(), "amomax.w.rl x1, x1, (x1)");
94+
QCOMPARE(Instruction(0xa410a0af).to_str(), "amomax.w.aq x1, x1, (x1)");
95+
QCOMPARE(Instruction(0xa610a0af).to_str(), "amomax.w.aqrl x1, x1, (x1)");
96+
QCOMPARE(Instruction(0xc010a0af).to_str(), "amominu.w x1, x1, (x1)");
97+
QCOMPARE(Instruction(0xc210a0af).to_str(), "amominu.w.rl x1, x1, (x1)");
98+
QCOMPARE(Instruction(0xc410a0af).to_str(), "amominu.w.aq x1, x1, (x1)");
99+
QCOMPARE(Instruction(0xc610a0af).to_str(), "amominu.w.aqrl x1, x1, (x1)");
100+
QCOMPARE(Instruction(0xe010a0af).to_str(), "amomaxu.w x1, x1, (x1)");
101+
QCOMPARE(Instruction(0xe210a0af).to_str(), "amomaxu.w.rl x1, x1, (x1)");
102+
QCOMPARE(Instruction(0xe410a0af).to_str(), "amomaxu.w.aq x1, x1, (x1)");
103+
QCOMPARE(Instruction(0xe610a0af).to_str(), "amomaxu.w.aqrl x1, x1, (x1)");
104+
QCOMPARE(Instruction(0x10b0af).to_str(), "amoadd.d x1, x1, (x1)");
105+
QCOMPARE(Instruction(0x210b0af).to_str(), "amoadd.d.rl x1, x1, (x1)");
106+
QCOMPARE(Instruction(0x410b0af).to_str(), "amoadd.d.aq x1, x1, (x1)");
107+
QCOMPARE(Instruction(0x610b0af).to_str(), "amoadd.d.aqrl x1, x1, (x1)");
108+
QCOMPARE(Instruction(0x810b0af).to_str(), "amoswap.d x1, x1, (x1)");
109+
QCOMPARE(Instruction(0xa10b0af).to_str(), "amoswap.d.rl x1, x1, (x1)");
110+
QCOMPARE(Instruction(0xc10b0af).to_str(), "amoswap.d.aq x1, x1, (x1)");
111+
QCOMPARE(Instruction(0xe10b0af).to_str(), "amoswap.d.aqrl x1, x1, (x1)");
112+
QCOMPARE(Instruction(0x1010b0af).to_str(), "lr.d x1, (x1)");
113+
QCOMPARE(Instruction(0x1210b0af).to_str(), "lr.d.rl x1, (x1)");
114+
QCOMPARE(Instruction(0x1410b0af).to_str(), "lr.d.aq x1, (x1)");
115+
QCOMPARE(Instruction(0x1610b0af).to_str(), "lr.d.aqrl x1, (x1)");
116+
QCOMPARE(Instruction(0x1810b0af).to_str(), "sc.d x1, x1, (x1)");
117+
QCOMPARE(Instruction(0x1a10b0af).to_str(), "sc.d.rl x1, x1, (x1)");
118+
QCOMPARE(Instruction(0x1c10b0af).to_str(), "sc.d.aq x1, x1, (x1)");
119+
QCOMPARE(Instruction(0x1e10b0af).to_str(), "sc.d.aqrl x1, x1, (x1)");
120+
QCOMPARE(Instruction(0x2010b0af).to_str(), "amoxor.d x1, x1, (x1)");
121+
QCOMPARE(Instruction(0x2210b0af).to_str(), "amoxor.d.rl x1, x1, (x1)");
122+
QCOMPARE(Instruction(0x2410b0af).to_str(), "amoxor.d.aq x1, x1, (x1)");
123+
QCOMPARE(Instruction(0x2610b0af).to_str(), "amoxor.d.aqrl x1, x1, (x1)");
124+
QCOMPARE(Instruction(0x4010b0af).to_str(), "amoor.d x1, x1, (x1)");
125+
QCOMPARE(Instruction(0x4210b0af).to_str(), "amoor.d.rl x1, x1, (x1)");
126+
QCOMPARE(Instruction(0x4410b0af).to_str(), "amoor.d.aq x1, x1, (x1)");
127+
QCOMPARE(Instruction(0x4610b0af).to_str(), "amoor.d.aqrl x1, x1, (x1)");
128+
QCOMPARE(Instruction(0x6010b0af).to_str(), "amoand.d x1, x1, (x1)");
129+
QCOMPARE(Instruction(0x6210b0af).to_str(), "amoand.d.rl x1, x1, (x1)");
130+
QCOMPARE(Instruction(0x6410b0af).to_str(), "amoand.d.aq x1, x1, (x1)");
131+
QCOMPARE(Instruction(0x6610b0af).to_str(), "amoand.d.aqrl x1, x1, (x1)");
132+
QCOMPARE(Instruction(0x8010b0af).to_str(), "amomin.d x1, x1, (x1)");
133+
QCOMPARE(Instruction(0x8210b0af).to_str(), "amomin.d.rl x1, x1, (x1)");
134+
QCOMPARE(Instruction(0x8410b0af).to_str(), "amomin.d.aq x1, x1, (x1)");
135+
QCOMPARE(Instruction(0x8610b0af).to_str(), "amomin.d.aqrl x1, x1, (x1)");
136+
QCOMPARE(Instruction(0xa010b0af).to_str(), "amomax.d x1, x1, (x1)");
137+
QCOMPARE(Instruction(0xa210b0af).to_str(), "amomax.d.rl x1, x1, (x1)");
138+
QCOMPARE(Instruction(0xa410b0af).to_str(), "amomax.d.aq x1, x1, (x1)");
139+
QCOMPARE(Instruction(0xa610b0af).to_str(), "amomax.d.aqrl x1, x1, (x1)");
140+
QCOMPARE(Instruction(0xc010b0af).to_str(), "amominu.d x1, x1, (x1)");
141+
QCOMPARE(Instruction(0xc210b0af).to_str(), "amominu.d.rl x1, x1, (x1)");
142+
QCOMPARE(Instruction(0xc410b0af).to_str(), "amominu.d.aq x1, x1, (x1)");
143+
QCOMPARE(Instruction(0xc610b0af).to_str(), "amominu.d.aqrl x1, x1, (x1)");
144+
QCOMPARE(Instruction(0xe010b0af).to_str(), "amomaxu.d x1, x1, (x1)");
145+
QCOMPARE(Instruction(0xe210b0af).to_str(), "amomaxu.d.rl x1, x1, (x1)");
146+
QCOMPARE(Instruction(0xe410b0af).to_str(), "amomaxu.d.aq x1, x1, (x1)");
147+
QCOMPARE(Instruction(0xe610b0af).to_str(), "amomaxu.d.aqrl x1, x1, (x1)");
148+
QCOMPARE(Instruction(0x1080b3).to_str(), "add x1, x1, x1");
149+
QCOMPARE(Instruction(0x1090b3).to_str(), "sll x1, x1, x1");
150+
QCOMPARE(Instruction(0x10a0b3).to_str(), "slt x1, x1, x1");
151+
QCOMPARE(Instruction(0x10b0b3).to_str(), "sltu x1, x1, x1");
152+
QCOMPARE(Instruction(0x10c0b3).to_str(), "xor x1, x1, x1");
153+
QCOMPARE(Instruction(0x10d0b3).to_str(), "srl x1, x1, x1");
154+
QCOMPARE(Instruction(0x10e0b3).to_str(), "or x1, x1, x1");
155+
QCOMPARE(Instruction(0x10b7).to_str(), "lui x1, 0x1");
156+
QCOMPARE(Instruction(0x1080bb).to_str(), "addw x1, x1, x1");
157+
QCOMPARE(Instruction(0x1090bb).to_str(), "sllw x1, x1, x1");
158+
QCOMPARE(Instruction(0x10d0bb).to_str(), "srlw x1, x1, x1");
159+
QCOMPARE(Instruction(0x108163).to_str(), "beq x1, x1, 0x2");
160+
QCOMPARE(Instruction(0x109163).to_str(), "bne x1, x1, 0x2");
161+
QCOMPARE(Instruction(0x10c163).to_str(), "blt x1, x1, 0x2");
162+
QCOMPARE(Instruction(0x10d163).to_str(), "bge x1, x1, 0x2");
163+
QCOMPARE(Instruction(0x10e163).to_str(), "bltu x1, x1, 0x2");
164+
QCOMPARE(Instruction(0x1080e7).to_str(), "jalr x1, 1(x1)");
165+
QCOMPARE(Instruction(0x2000ef).to_str(), "jal x1, 0x2");
166+
QCOMPARE(Instruction(0x73).to_str(), "ecall");
167+
QCOMPARE(Instruction(0x10200073).to_str(), "sret");
168+
QCOMPARE(Instruction(0x30200073).to_str(), "mret");
169+
QCOMPARE(Instruction(0x1090f3).to_str(), "csrrw x1, 0x1, x1");
170+
QCOMPARE(Instruction(0x10a0f3).to_str(), "csrrs x1, 0x1, x1");
171+
QCOMPARE(Instruction(0x10b0f3).to_str(), "csrrc x1, 0x1, x1");
172+
QCOMPARE(Instruction(0x10d0f3).to_str(), "csrrwi x1, 0x1, 0x1");
173+
QCOMPARE(Instruction(0x10e0f3).to_str(), "csrrsi x1, 0x1, 0x1");
174+
}
31175

32176
QTEST_APPLESS_MAIN(TestInstruction)

src/machine/instruction.test.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@
66
class TestInstruction : public QObject {
77
Q_OBJECT
88

9-
public slots:
9+
private slots:
1010
void instruction();
1111
void instruction_access();
12+
void instruction_to_str();
1213
};
1314

1415
#endif // INSTRUCTION_TEST_H

0 commit comments

Comments
 (0)