Skip to content

Commit 1e6e49f

Browse files
committed
fix inst_base split
1 parent 3aeae90 commit 1e6e49f

6 files changed

+342
-10
lines changed

src/machine/CMakeLists.txt

+8-1
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,13 @@ if(NOT ${WASM})
147147
PRIVATE ${QtLib}::Core ${QtLib}::Test)
148148
add_test(NAME cache COMMAND cache_test)
149149

150+
add_executable(instruction_test_gendata
151+
instruction.test.gendata.cpp
152+
)
153+
target_link_libraries(instruction_test_gendata
154+
PRIVATE machine ${QtLib}::Core
155+
)
156+
150157
add_executable(instruction_test
151158
csr/controlstate.cpp
152159
csr/controlstate.h
@@ -216,5 +223,5 @@ if(NOT ${WASM})
216223
add_test(NAME core COMMAND core_test)
217224

218225
add_custom_target(machine_unit_tests
219-
DEPENDS alu_test registers_test memory_test cache_test instruction_test program_loader_test core_test)
226+
DEPENDS alu_test registers_test memory_test cache_test instruction_test_gendata instruction_test program_loader_test core_test)
220227
endif()

src/machine/instruction.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1490,7 +1490,7 @@ TokenizedInstruction TokenizedInstruction::from_line(
14901490
}
14911491
end = start;
14921492
while (end < line_str.size()) {
1493-
if (!line_str.at(end).isLetterOrNumber()) { break; }
1493+
if (line_str.at(end).isSpace()) { break; }
14941494
end++;
14951495
}
14961496
QString inst_base = line_str.mid(start, end - start).toLower();

src/machine/instruction.test.cpp

+30-7
Original file line numberDiff line numberDiff line change
@@ -7,26 +7,49 @@ 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));
1310
}
1411

1512
// Test that we are correctly decoding instruction fields
1613
void TestInstruction::instruction_access() {
1714
Instruction i(0xffffffff);
1815

1916
QCOMPARE(i.data(), (uint32_t)0xffffffff);
20-
QCOMPARE(i.opcode(), (uint8_t)0x3f);
17+
QCOMPARE(i.opcode(), (uint8_t)0x7f);
2118
QCOMPARE(i.rs(), (uint8_t)0x1f);
2219
QCOMPARE(i.rt(), (uint8_t)0x1f);
2320
QCOMPARE(i.rd(), (uint8_t)0x1f);
2421
QCOMPARE(i.shamt(), (uint8_t)0x1f);
25-
QCOMPARE(i.funct(), (uint16_t)0x3f);
26-
QCOMPARE(i.immediate(), (int32_t)0xffff);
22+
QCOMPARE(i.funct(), (uint16_t)0x3ff);
23+
QCOMPARE(i.immediate(), (int32_t)0);
2724
QCOMPARE(i.address().get_raw(), (uint64_t)0x3ffffff);
2825
}
2926

30-
// TODO test to_str
27+
static struct { uint32_t code; QString str; } code_to_string[] = {
28+
{0xffffffff, "unknown"},
29+
{0x0, "unknown"},
30+
{0b00000000000000000000000000010011, "nop"},
31+
{0b00000000000000001000000010010011, "addi x1, x1, 0"},
32+
{0b01111111111111111000111110010011, "addi x31, x31, 2047"},
33+
{0b11111111111100001000000010010011, "addi x1, x1, -1"},
34+
{0b10000000000000001000000010010011, "addi x1, x1, -2048"},
35+
#include<./instruction.test.data.h>
36+
};
37+
38+
void TestInstruction::instruction_to_str() {
39+
size_t array_length = sizeof(code_to_string) / sizeof(code_to_string[0]);
40+
for (size_t i = 0; i < array_length; ++i) {
41+
QCOMPARE(Instruction(code_to_string[i].code).to_str(), code_to_string[i].str);
42+
}
43+
}
44+
45+
void TestInstruction::instruction_code_from_str() {
46+
size_t array_length = sizeof(code_to_string) / sizeof(code_to_string[0]);
47+
for (size_t i = 0; i < array_length; ++i) {
48+
if (code_to_string[i].str == "unknown") { continue; }
49+
uint32_t code = 0;
50+
Instruction::code_from_string(&code, code_to_string[i].str.length(), code_to_string[i].str, machine::Address(0x0));
51+
QCOMPARE(code, code_to_string[i].code);
52+
}
53+
}
3154

3255
QTEST_APPLESS_MAIN(TestInstruction)

src/machine/instruction.test.data.h

+162
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
{0x108083, "lb x1, 1(x1)"},
2+
{0x109083, "lh x1, 1(x1)"},
3+
{0x10a083, "lw x1, 1(x1)"},
4+
{0x10b083, "ld x1, 1(x1)"},
5+
{0x10c083, "lbu x1, 1(x1)"},
6+
{0x10d083, "lhu x1, 1(x1)"},
7+
{0x10e083, "lwu x1, 1(x1)"},
8+
{0xf, "fence"},
9+
{0x100f, "fence.i"},
10+
{0x108093, "addi x1, x1, 1"},
11+
{0x109093, "slli x1, x1, 0x1"},
12+
{0x10a093, "slti x1, x1, 1"},
13+
{0x10b093, "sltiu x1, x1, 1"},
14+
{0x10c093, "xori x1, x1, 1"},
15+
{0x10d093, "srli x1, x1, 0x1"},
16+
{0x4010d093, "srai x1, x1, 0x1"},
17+
{0x10e093, "ori x1, x1, 1"},
18+
{0x10f093, "andi x1, x1, 1"},
19+
{0x1097, "auipc x1, 0x1"},
20+
{0x10809b, "addiw x1, x1, 1"},
21+
{0x10909b, "slliw x1, x1, 0x1"},
22+
{0x10d09b, "srliw x1, x1, 0x1"},
23+
{0x4010d09b, "sraiw x1, x1, 0x1"},
24+
{0x1080a3, "sb x1, 1(x1)"},
25+
{0x1090a3, "sh x1, 1(x1)"},
26+
{0x10a0a3, "sw x1, 1(x1)"},
27+
{0x10b0a3, "sd x1, 1(x1)"},
28+
{0x10a0af, "amoadd.w x1, x1, (x1)"},
29+
{0x210a0af, "amoadd.w.rl x1, x1, (x1)"},
30+
{0x410a0af, "amoadd.w.aq x1, x1, (x1)"},
31+
{0x610a0af, "amoadd.w.aqrl x1, x1, (x1)"},
32+
{0x810a0af, "amoswap.w x1, x1, (x1)"},
33+
{0xa10a0af, "amoswap.w.rl x1, x1, (x1)"},
34+
{0xc10a0af, "amoswap.w.aq x1, x1, (x1)"},
35+
{0xe10a0af, "amoswap.w.aqrl x1, x1, (x1)"},
36+
{0x1000a0af, "lr.w x1, (x1)"},
37+
{0x1200a0af, "lr.w.rl x1, (x1)"},
38+
{0x1400a0af, "lr.w.aq x1, (x1)"},
39+
{0x1600a0af, "lr.w.aqrl x1, (x1)"},
40+
{0x1810a0af, "sc.w x1, x1, (x1)"},
41+
{0x1a10a0af, "sc.w.rl x1, x1, (x1)"},
42+
{0x1c10a0af, "sc.w.aq x1, x1, (x1)"},
43+
{0x1e10a0af, "sc.w.aqrl x1, x1, (x1)"},
44+
{0x2010a0af, "amoxor.w x1, x1, (x1)"},
45+
{0x2210a0af, "amoxor.w.rl x1, x1, (x1)"},
46+
{0x2410a0af, "amoxor.w.aq x1, x1, (x1)"},
47+
{0x2610a0af, "amoxor.w.aqrl x1, x1, (x1)"},
48+
{0x4010a0af, "amoor.w x1, x1, (x1)"},
49+
{0x4210a0af, "amoor.w.rl x1, x1, (x1)"},
50+
{0x4410a0af, "amoor.w.aq x1, x1, (x1)"},
51+
{0x4610a0af, "amoor.w.aqrl x1, x1, (x1)"},
52+
{0x6010a0af, "amoand.w x1, x1, (x1)"},
53+
{0x6210a0af, "amoand.w.rl x1, x1, (x1)"},
54+
{0x6410a0af, "amoand.w.aq x1, x1, (x1)"},
55+
{0x6610a0af, "amoand.w.aqrl x1, x1, (x1)"},
56+
{0x8010a0af, "amomin.w x1, x1, (x1)"},
57+
{0x8210a0af, "amomin.w.rl x1, x1, (x1)"},
58+
{0x8410a0af, "amomin.w.aq x1, x1, (x1)"},
59+
{0x8610a0af, "amomin.w.aqrl x1, x1, (x1)"},
60+
{0xa010a0af, "amomax.w x1, x1, (x1)"},
61+
{0xa210a0af, "amomax.w.rl x1, x1, (x1)"},
62+
{0xa410a0af, "amomax.w.aq x1, x1, (x1)"},
63+
{0xa610a0af, "amomax.w.aqrl x1, x1, (x1)"},
64+
{0xc010a0af, "amominu.w x1, x1, (x1)"},
65+
{0xc210a0af, "amominu.w.rl x1, x1, (x1)"},
66+
{0xc410a0af, "amominu.w.aq x1, x1, (x1)"},
67+
{0xc610a0af, "amominu.w.aqrl x1, x1, (x1)"},
68+
{0xe010a0af, "amomaxu.w x1, x1, (x1)"},
69+
{0xe210a0af, "amomaxu.w.rl x1, x1, (x1)"},
70+
{0xe410a0af, "amomaxu.w.aq x1, x1, (x1)"},
71+
{0xe610a0af, "amomaxu.w.aqrl x1, x1, (x1)"},
72+
{0x10b0af, "amoadd.d x1, x1, (x1)"},
73+
{0x210b0af, "amoadd.d.rl x1, x1, (x1)"},
74+
{0x410b0af, "amoadd.d.aq x1, x1, (x1)"},
75+
{0x610b0af, "amoadd.d.aqrl x1, x1, (x1)"},
76+
{0x810b0af, "amoswap.d x1, x1, (x1)"},
77+
{0xa10b0af, "amoswap.d.rl x1, x1, (x1)"},
78+
{0xc10b0af, "amoswap.d.aq x1, x1, (x1)"},
79+
{0xe10b0af, "amoswap.d.aqrl x1, x1, (x1)"},
80+
{0x1000b0af, "lr.d x1, (x1)"},
81+
{0x1200b0af, "lr.d.rl x1, (x1)"},
82+
{0x1400b0af, "lr.d.aq x1, (x1)"},
83+
{0x1600b0af, "lr.d.aqrl x1, (x1)"},
84+
{0x1810b0af, "sc.d x1, x1, (x1)"},
85+
{0x1a10b0af, "sc.d.rl x1, x1, (x1)"},
86+
{0x1c10b0af, "sc.d.aq x1, x1, (x1)"},
87+
{0x1e10b0af, "sc.d.aqrl x1, x1, (x1)"},
88+
{0x2010b0af, "amoxor.d x1, x1, (x1)"},
89+
{0x2210b0af, "amoxor.d.rl x1, x1, (x1)"},
90+
{0x2410b0af, "amoxor.d.aq x1, x1, (x1)"},
91+
{0x2610b0af, "amoxor.d.aqrl x1, x1, (x1)"},
92+
{0x4010b0af, "amoor.d x1, x1, (x1)"},
93+
{0x4210b0af, "amoor.d.rl x1, x1, (x1)"},
94+
{0x4410b0af, "amoor.d.aq x1, x1, (x1)"},
95+
{0x4610b0af, "amoor.d.aqrl x1, x1, (x1)"},
96+
{0x6010b0af, "amoand.d x1, x1, (x1)"},
97+
{0x6210b0af, "amoand.d.rl x1, x1, (x1)"},
98+
{0x6410b0af, "amoand.d.aq x1, x1, (x1)"},
99+
{0x6610b0af, "amoand.d.aqrl x1, x1, (x1)"},
100+
{0x8010b0af, "amomin.d x1, x1, (x1)"},
101+
{0x8210b0af, "amomin.d.rl x1, x1, (x1)"},
102+
{0x8410b0af, "amomin.d.aq x1, x1, (x1)"},
103+
{0x8610b0af, "amomin.d.aqrl x1, x1, (x1)"},
104+
{0xa010b0af, "amomax.d x1, x1, (x1)"},
105+
{0xa210b0af, "amomax.d.rl x1, x1, (x1)"},
106+
{0xa410b0af, "amomax.d.aq x1, x1, (x1)"},
107+
{0xa610b0af, "amomax.d.aqrl x1, x1, (x1)"},
108+
{0xc010b0af, "amominu.d x1, x1, (x1)"},
109+
{0xc210b0af, "amominu.d.rl x1, x1, (x1)"},
110+
{0xc410b0af, "amominu.d.aq x1, x1, (x1)"},
111+
{0xc610b0af, "amominu.d.aqrl x1, x1, (x1)"},
112+
{0xe010b0af, "amomaxu.d x1, x1, (x1)"},
113+
{0xe210b0af, "amomaxu.d.rl x1, x1, (x1)"},
114+
{0xe410b0af, "amomaxu.d.aq x1, x1, (x1)"},
115+
{0xe610b0af, "amomaxu.d.aqrl x1, x1, (x1)"},
116+
{0x1080b3, "add x1, x1, x1"},
117+
{0x401080b3, "sub x1, x1, x1"},
118+
{0x1090b3, "sll x1, x1, x1"},
119+
{0x10a0b3, "slt x1, x1, x1"},
120+
{0x10b0b3, "sltu x1, x1, x1"},
121+
{0x10c0b3, "xor x1, x1, x1"},
122+
{0x10d0b3, "srl x1, x1, x1"},
123+
{0x4010d0b3, "sra x1, x1, x1"},
124+
{0x10e0b3, "or x1, x1, x1"},
125+
{0x10f0b3, "and x1, x1, x1"},
126+
{0x21080b3, "mul x1, x1, x1"},
127+
{0x21090b3, "mulh x1, x1, x1"},
128+
{0x210a0b3, "mulhsu x1, x1, x1"},
129+
{0x210b0b3, "mulhu x1, x1, x1"},
130+
{0x210c0b3, "div x1, x1, x1"},
131+
{0x210d0b3, "divu x1, x1, x1"},
132+
{0x210e0b3, "rem x1, x1, x1"},
133+
{0x210f0b3, "remu x1, x1, x1"},
134+
{0x10b7, "lui x1, 0x1"},
135+
{0x1080bb, "addw x1, x1, x1"},
136+
{0x401080bb, "subw x1, x1, x1"},
137+
{0x1090bb, "sllw x1, x1, x1"},
138+
{0x10d0bb, "srlw x1, x1, x1"},
139+
{0x4010d0bb, "sraw x1, x1, x1"},
140+
{0x21080bb, "mulw x1, x1, x1"},
141+
{0x210c0bb, "divw x1, x1, x1"},
142+
{0x210d0bb, "divuw x1, x1, x1"},
143+
{0x210e0bb, "remw x1, x1, x1"},
144+
{0x210f0bb, "remuw x1, x1, x1"},
145+
{0x108163, "beq x1, x1, 0x2"},
146+
{0x109163, "bne x1, x1, 0x2"},
147+
{0x10c163, "blt x1, x1, 0x2"},
148+
{0x10d163, "bge x1, x1, 0x2"},
149+
{0x10e163, "bltu x1, x1, 0x2"},
150+
{0x10f163, "bgeu x1, x1, 0x2"},
151+
{0x1080e7, "jalr x1, 1(x1)"},
152+
{0x2000ef, "jal x1, 0x2"},
153+
{0x73, "ecall"},
154+
{0x100073, "ebreak"},
155+
{0x10200073, "sret"},
156+
{0x30200073, "mret"},
157+
{0x1090f3, "csrrw x1, 0x1, x1"},
158+
{0x10a0f3, "csrrs x1, 0x1, x1"},
159+
{0x10b0f3, "csrrc x1, 0x1, x1"},
160+
{0x10d0f3, "csrrwi x1, 0x1, 0x1"},
161+
{0x10e0f3, "csrrsi x1, 0x1, 0x1"},
162+
{0x10f0f3, "csrrci x1, 0x1, 0x1"},
+138
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
#include "common/logging.h"
2+
#include "machine/instruction.h"
3+
#include "machine/instruction.cpp"
4+
#include <QFile>
5+
#include <unordered_set>
6+
7+
using namespace machine;
8+
9+
static uint32_t MASK_AMO_RS2 = 0b1111100000000000000000000;
10+
11+
#define AMO_MAP_4ITEMS(NAME_BASE, MASK) \
12+
{ NAME_BASE, MASK}, \
13+
{ NAME_BASE ".rl", MASK }, \
14+
{ NAME_BASE ".aq", MASK }, \
15+
{ NAME_BASE ".aqrl", MASK },
16+
17+
static std::unordered_map<QString, uint32_t> mask_map = {
18+
AMO_MAP_4ITEMS("lr.w", MASK_AMO_RS2)
19+
AMO_MAP_4ITEMS("lr.d", MASK_AMO_RS2)
20+
};
21+
22+
void generate_code_and_string_data(QTextStream& out, const InstructionMap* im_iter, BitField subfield) {
23+
for (int i = 0; i < (1 << subfield.count); i++) {
24+
const InstructionMap* im = &im_iter[i];
25+
26+
if (im->name == "unknown") {
27+
continue;
28+
}
29+
30+
if (im->subclass != nullptr) {
31+
generate_code_and_string_data(out, im->subclass, im->subfield);
32+
continue;
33+
}
34+
35+
uint32_t code = im->code;
36+
QString string_data = im->name;
37+
38+
if (im->args.size()) {
39+
int val_mask;
40+
switch (im->type) {
41+
case Instruction::Type::R:
42+
case Instruction::Type::AMO: {
43+
val_mask = 0b00000000000100001000000010000000;
44+
break;
45+
}
46+
case Instruction::Type::I:
47+
val_mask = 0b00000000000100001000000010000000;
48+
break;
49+
case Instruction::Type::ZICSR: {
50+
val_mask = 0b00000000000100001000000010000000;
51+
break;
52+
}
53+
case Instruction::Type::S: {
54+
val_mask = 0b00000000000100001000000010000000;
55+
break;
56+
}
57+
case Instruction::Type::B: {
58+
val_mask = 0b00000000000100001000000100000000;
59+
break;
60+
}
61+
case Instruction::Type::U: {
62+
val_mask = 0b00000000000000000001000010000000;
63+
break;
64+
}
65+
case Instruction::Type::J: {
66+
val_mask = 0b00000000001000000000000010000000;
67+
break;
68+
}
69+
case Instruction::Type::UNKNOWN: {
70+
return;
71+
}
72+
}
73+
code |= val_mask & ~im->mask;
74+
if (mask_map.count(im->name)) {
75+
uint32_t old_code = code;
76+
code &= ~mask_map[im->name];
77+
}
78+
79+
QString next_delim = " ";
80+
for (const QString &arg_string : im->args) {
81+
string_data += next_delim;
82+
next_delim = ", ";
83+
for (int pos = 0; pos < arg_string.size(); pos += 1) {
84+
char arg_letter = arg_string[pos].toLatin1();
85+
const ArgumentDesc *arg_desc = arg_desc_by_code[(unsigned char)arg_letter];
86+
if (arg_desc == nullptr) {
87+
string_data += arg_letter;
88+
continue;
89+
}
90+
switch (arg_desc->kind) {
91+
case 'g': {
92+
string_data += "x1";
93+
break;
94+
}
95+
case 'p':
96+
case 'a':
97+
string_data += QString::asprintf("0x%d", Instruction(code).immediate());
98+
break;
99+
case 'o':
100+
case 'n': {
101+
if (arg_desc->min < 0) {
102+
string_data += "1";
103+
} else {
104+
string_data += "0x1";
105+
}
106+
break;
107+
}
108+
case 'E': {
109+
string_data += "0x1";
110+
break;
111+
}
112+
}
113+
}
114+
}
115+
}
116+
117+
QString enum_str = QString::asprintf("{0x%x, \"%s\"},", code, qPrintable(string_data));
118+
if (Instruction(code).to_str() != string_data) {
119+
enum_str += " // failed";
120+
}
121+
enum_str += "\n";
122+
out << enum_str;
123+
}
124+
}
125+
126+
int main(int argc, char *argv[]) {
127+
fill_argdesbycode();
128+
instruction_from_string_build_base();
129+
QFile outfile("instruction.test.data.h");
130+
if (outfile.open(QIODevice::WriteOnly | QIODevice::Text)) {
131+
QTextStream out(&outfile);
132+
generate_code_and_string_data(out, C_inst_map, instruction_map_opcode_field);
133+
outfile.close();
134+
} else {
135+
printf("open output file failed\n");
136+
exit(1);
137+
}
138+
}

0 commit comments

Comments
 (0)