Skip to content

Commit

Permalink
fix inst_base split
Browse files Browse the repository at this point in the history
  • Loading branch information
trdthg committed Apr 25, 2024
1 parent 1989029 commit e77d427
Show file tree
Hide file tree
Showing 7 changed files with 334 additions and 280 deletions.
9 changes: 8 additions & 1 deletion src/machine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,13 @@ if(NOT ${WASM})
PRIVATE ${QtLib}::Core ${QtLib}::Test)
add_test(NAME cache COMMAND cache_test)

add_executable(instruction_test_gendata
instruction.test.gendata.cpp
)
target_link_libraries(instruction_test_gendata
PRIVATE machine ${QtLib}::Core
)

add_executable(instruction_test
csr/controlstate.cpp
csr/controlstate.h
Expand Down Expand Up @@ -216,5 +223,5 @@ if(NOT ${WASM})
add_test(NAME core COMMAND core_test)

add_custom_target(machine_unit_tests
DEPENDS alu_test registers_test memory_test cache_test instruction_test program_loader_test core_test)
DEPENDS alu_test registers_test memory_test cache_test instruction_test_gendata instruction_test program_loader_test core_test)
endif()
132 changes: 1 addition & 131 deletions src/machine/instruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1490,7 +1490,7 @@ TokenizedInstruction TokenizedInstruction::from_line(
}
end = start;
while (end < line_str.size()) {
if (!line_str.at(end).isLetterOrNumber()) { break; }
if (line_str.at(end).isSpace()) { break; }
end++;
}
QString inst_base = line_str.mid(start, end - start).toLower();
Expand All @@ -1514,133 +1514,3 @@ TokenizedInstruction::TokenizedInstruction(
, address(address)
, filename(std::move(filename))
, line(line) {}


void gen_instruction_code_and_expected_str(QTextStream& outfile, const InstructionMap* im, uint32_t code, int count, int offset, int subclass_i, int depth) {
if (im->name == "unknown") {
return;
}
code |= (((1 << count) - 1) & subclass_i) << offset;
// LOG("code: %d, count: %d, offset: %d, index: %d", code, count, offset, subclass_i);
if (im->subclass != nullptr) {
for (int j = 0; j < ((1 << im->subfield.count) - 1); j++) {
gen_instruction_code_and_expected_str(outfile, &im->subclass[j], code, im->subfield.count, im->subfield.offset, j, depth + 1);
}
return;
}

QString res = im->name;

std::unordered_map<std::string, uint32_t> direct_map = {
{ "ecall", 0b00000000000000000000000001110011 },
{ "mret", 0b00110000001000000000000001110011 },
{ "sret", 0b00010000001000000000000001110011 }
};
if (direct_map.count(im->name)) {
code = direct_map[im->name];
} else {


int val = 1;
switch (im->type) {
case Instruction::Type::R:
case Instruction::Type::AMO: {
code |= 0b00000000000100001000000010000000;
break;
}
case Instruction::Type::I:
code |= 0b00000000000100001000000010000000;
break;
case Instruction::Type::ZICSR: {
code |= 0b00000000000100001000000010000000;
break;
}
case Instruction::Type::S: {
code |= 0b00000000000100001000000010000000;
break;
}
case Instruction::Type::B: {
code |= 0b00000000000100001000000100000000;
val = 2;
break;
}
case Instruction::Type::U: {
code |= 0b00000000000000000001000010000000;
break;
}
case Instruction::Type::J: {
code |= 0b00000000001000000000000010000000;
val = 2;
break;
}
case Instruction::Type::UNKNOWN: {
return;
}
}

QString next_delim = " ";
for (const QString &arg_string : im->args) {
res += next_delim;
next_delim = ", ";
for (int pos = 0; pos < arg_string.size(); pos += 1) {
char arg_letter = arg_string[pos].toLatin1();
const ArgumentDesc *arg_desc = arg_desc_by_code[(unsigned char)arg_letter];
if (arg_desc == nullptr) {
res += arg_letter;
continue;
}
switch (arg_desc->kind) {
case 'g': {
res += "x1";
break;
}
case 'p':
case 'a':
res += QString::asprintf("0x%d", val);
break;
case 'o':
case 'n': {
if (arg_desc->min < 0) {
res += "1";
} else {
res += "0x1";
}
break;
}
case 'E': {
res += "0x1";
break;
}
}
}
}
}


QString test_code = QString::asprintf("QCOMPARE(Instruction(0x%x).to_str(), \"%s\");", code, qPrintable(res));
outfile << test_code;
if (Instruction(code).to_str() != res) {
outfile << QString::asprintf(" // failed");
}
outfile << "\n";
}

#include <iostream>
#include <fstream>
#include <qfile.h>
void gen() {
fill_argdesbycode();

QFile outfile("gen_instruction_test_case.txt");
if (outfile.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream out(&outfile);
const struct InstructionMap *im = &C_inst_map[0];
for (int i = 0; i < sizeof(C_inst_map) / sizeof(C_inst_map[0]); i++) {
im = &C_inst_map[i];
gen_instruction_code_and_expected_str(out, im, 0b0, 2, 0, i, 1);
}
outfile.close();
} else {
PANIC("gen_instruction_test_case failed");
}
}
2 changes: 0 additions & 2 deletions src/machine/instruction.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,8 +276,6 @@ struct RelocExpression {

} // namespace machine

void gen();

Q_DECLARE_METATYPE(machine::Instruction)

#endif // INSTRUCTION_H
171 changes: 25 additions & 146 deletions src/machine/instruction.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ using namespace machine;
// Test that we are correctly encoding instructions in constructor
void TestInstruction::instruction() {
QCOMPARE(Instruction(0x0), Instruction());
QCOMPARE(Instruction(0x0), Instruction(Instruction(0x0)));
}

// Test that we are correctly decoding instruction fields
Expand All @@ -25,152 +24,32 @@ void TestInstruction::instruction_access() {
QCOMPARE(i.address().get_raw(), (uint64_t)0x3ffffff);
}

static struct { uint32_t code; QString str; } code_to_string[] = {
{0xffffffff, "unknown"},
{0x0, "unknown"},
{0b00000000000000000000000000010011, "nop"},
{0b00000000000000001000000010010011, "addi x1, x1, 0"},
{0b01111111111111111000111110010011, "addi x31, x31, 2047"},
{0b11111111111100001000000010010011, "addi x1, x1, -1"},
{0b10000000000000001000000010010011, "addi x1, x1, -2048"},
#include<./instruction.test.data.h>
};

void TestInstruction::instruction_to_str() {
QCOMPARE(Instruction(0xffffffff).to_str(), "unknown");
QCOMPARE(Instruction(0x0).to_str(), "unknown");
QCOMPARE(Instruction(0b00000000000000000000000000010011).to_str(), "nop");
QCOMPARE(Instruction(0b00000000000000001000000010010011).to_str(), "addi x1, x1, 0");
QCOMPARE(Instruction(0b01111111111111111000111110010011).to_str(), "addi x31, x31, 2047");
QCOMPARE(Instruction(0b11111111111100001000000010010011).to_str(), "addi x1, x1, -1");
QCOMPARE(Instruction(0b10000000000000001000000010010011).to_str(), "addi x1, x1, -2048");
QCOMPARE(Instruction(0x108083).to_str(), "lb x1, 1(x1)");
QCOMPARE(Instruction(0x109083).to_str(), "lh x1, 1(x1)");
QCOMPARE(Instruction(0x10a083).to_str(), "lw x1, 1(x1)");
QCOMPARE(Instruction(0x10b083).to_str(), "ld x1, 1(x1)");
QCOMPARE(Instruction(0x10c083).to_str(), "lbu x1, 1(x1)");
QCOMPARE(Instruction(0x10d083).to_str(), "lhu x1, 1(x1)");
QCOMPARE(Instruction(0x10e083).to_str(), "lwu x1, 1(x1)");
QCOMPARE(Instruction(0x10808f).to_str(), "fence");
QCOMPARE(Instruction(0x10908f).to_str(), "fence.i");
QCOMPARE(Instruction(0x108093).to_str(), "addi x1, x1, 1");
QCOMPARE(Instruction(0x109093).to_str(), "slli x1, x1, 0x1");
QCOMPARE(Instruction(0x10a093).to_str(), "slti x1, x1, 1");
QCOMPARE(Instruction(0x10b093).to_str(), "sltiu x1, x1, 1");
QCOMPARE(Instruction(0x10c093).to_str(), "xori x1, x1, 1");
QCOMPARE(Instruction(0x10d093).to_str(), "srli x1, x1, 0x1");
QCOMPARE(Instruction(0x10e093).to_str(), "ori x1, x1, 1");
QCOMPARE(Instruction(0x1097).to_str(), "auipc x1, 0x1");
QCOMPARE(Instruction(0x10809b).to_str(), "addiw x1, x1, 1");
QCOMPARE(Instruction(0x10909b).to_str(), "slliw x1, x1, 0x1");
QCOMPARE(Instruction(0x10d09b).to_str(), "srliw x1, x1, 0x1");
QCOMPARE(Instruction(0x1080a3).to_str(), "sb x1, 1(x1)");
QCOMPARE(Instruction(0x1090a3).to_str(), "sh x1, 1(x1)");
QCOMPARE(Instruction(0x10a0a3).to_str(), "sw x1, 1(x1)");
QCOMPARE(Instruction(0x10b0a3).to_str(), "sd x1, 1(x1)");
QCOMPARE(Instruction(0x10a0af).to_str(), "amoadd.w x1, x1, (x1)");
QCOMPARE(Instruction(0x210a0af).to_str(), "amoadd.w.rl x1, x1, (x1)");
QCOMPARE(Instruction(0x410a0af).to_str(), "amoadd.w.aq x1, x1, (x1)");
QCOMPARE(Instruction(0x610a0af).to_str(), "amoadd.w.aqrl x1, x1, (x1)");
QCOMPARE(Instruction(0x810a0af).to_str(), "amoswap.w x1, x1, (x1)");
QCOMPARE(Instruction(0xa10a0af).to_str(), "amoswap.w.rl x1, x1, (x1)");
QCOMPARE(Instruction(0xc10a0af).to_str(), "amoswap.w.aq x1, x1, (x1)");
QCOMPARE(Instruction(0xe10a0af).to_str(), "amoswap.w.aqrl x1, x1, (x1)");
QCOMPARE(Instruction(0x1010a0af).to_str(), "lr.w x1, (x1)");
QCOMPARE(Instruction(0x1210a0af).to_str(), "lr.w.rl x1, (x1)");
QCOMPARE(Instruction(0x1410a0af).to_str(), "lr.w.aq x1, (x1)");
QCOMPARE(Instruction(0x1610a0af).to_str(), "lr.w.aqrl x1, (x1)");
QCOMPARE(Instruction(0x1810a0af).to_str(), "sc.w x1, x1, (x1)");
QCOMPARE(Instruction(0x1a10a0af).to_str(), "sc.w.rl x1, x1, (x1)");
QCOMPARE(Instruction(0x1c10a0af).to_str(), "sc.w.aq x1, x1, (x1)");
QCOMPARE(Instruction(0x1e10a0af).to_str(), "sc.w.aqrl x1, x1, (x1)");
QCOMPARE(Instruction(0x2010a0af).to_str(), "amoxor.w x1, x1, (x1)");
QCOMPARE(Instruction(0x2210a0af).to_str(), "amoxor.w.rl x1, x1, (x1)");
QCOMPARE(Instruction(0x2410a0af).to_str(), "amoxor.w.aq x1, x1, (x1)");
QCOMPARE(Instruction(0x2610a0af).to_str(), "amoxor.w.aqrl x1, x1, (x1)");
QCOMPARE(Instruction(0x4010a0af).to_str(), "amoor.w x1, x1, (x1)");
QCOMPARE(Instruction(0x4210a0af).to_str(), "amoor.w.rl x1, x1, (x1)");
QCOMPARE(Instruction(0x4410a0af).to_str(), "amoor.w.aq x1, x1, (x1)");
QCOMPARE(Instruction(0x4610a0af).to_str(), "amoor.w.aqrl x1, x1, (x1)");
QCOMPARE(Instruction(0x6010a0af).to_str(), "amoand.w x1, x1, (x1)");
QCOMPARE(Instruction(0x6210a0af).to_str(), "amoand.w.rl x1, x1, (x1)");
QCOMPARE(Instruction(0x6410a0af).to_str(), "amoand.w.aq x1, x1, (x1)");
QCOMPARE(Instruction(0x6610a0af).to_str(), "amoand.w.aqrl x1, x1, (x1)");
QCOMPARE(Instruction(0x8010a0af).to_str(), "amomin.w x1, x1, (x1)");
QCOMPARE(Instruction(0x8210a0af).to_str(), "amomin.w.rl x1, x1, (x1)");
QCOMPARE(Instruction(0x8410a0af).to_str(), "amomin.w.aq x1, x1, (x1)");
QCOMPARE(Instruction(0x8610a0af).to_str(), "amomin.w.aqrl x1, x1, (x1)");
QCOMPARE(Instruction(0xa010a0af).to_str(), "amomax.w x1, x1, (x1)");
QCOMPARE(Instruction(0xa210a0af).to_str(), "amomax.w.rl x1, x1, (x1)");
QCOMPARE(Instruction(0xa410a0af).to_str(), "amomax.w.aq x1, x1, (x1)");
QCOMPARE(Instruction(0xa610a0af).to_str(), "amomax.w.aqrl x1, x1, (x1)");
QCOMPARE(Instruction(0xc010a0af).to_str(), "amominu.w x1, x1, (x1)");
QCOMPARE(Instruction(0xc210a0af).to_str(), "amominu.w.rl x1, x1, (x1)");
QCOMPARE(Instruction(0xc410a0af).to_str(), "amominu.w.aq x1, x1, (x1)");
QCOMPARE(Instruction(0xc610a0af).to_str(), "amominu.w.aqrl x1, x1, (x1)");
QCOMPARE(Instruction(0xe010a0af).to_str(), "amomaxu.w x1, x1, (x1)");
QCOMPARE(Instruction(0xe210a0af).to_str(), "amomaxu.w.rl x1, x1, (x1)");
QCOMPARE(Instruction(0xe410a0af).to_str(), "amomaxu.w.aq x1, x1, (x1)");
QCOMPARE(Instruction(0xe610a0af).to_str(), "amomaxu.w.aqrl x1, x1, (x1)");
QCOMPARE(Instruction(0x10b0af).to_str(), "amoadd.d x1, x1, (x1)");
QCOMPARE(Instruction(0x210b0af).to_str(), "amoadd.d.rl x1, x1, (x1)");
QCOMPARE(Instruction(0x410b0af).to_str(), "amoadd.d.aq x1, x1, (x1)");
QCOMPARE(Instruction(0x610b0af).to_str(), "amoadd.d.aqrl x1, x1, (x1)");
QCOMPARE(Instruction(0x810b0af).to_str(), "amoswap.d x1, x1, (x1)");
QCOMPARE(Instruction(0xa10b0af).to_str(), "amoswap.d.rl x1, x1, (x1)");
QCOMPARE(Instruction(0xc10b0af).to_str(), "amoswap.d.aq x1, x1, (x1)");
QCOMPARE(Instruction(0xe10b0af).to_str(), "amoswap.d.aqrl x1, x1, (x1)");
QCOMPARE(Instruction(0x1010b0af).to_str(), "lr.d x1, (x1)");
QCOMPARE(Instruction(0x1210b0af).to_str(), "lr.d.rl x1, (x1)");
QCOMPARE(Instruction(0x1410b0af).to_str(), "lr.d.aq x1, (x1)");
QCOMPARE(Instruction(0x1610b0af).to_str(), "lr.d.aqrl x1, (x1)");
QCOMPARE(Instruction(0x1810b0af).to_str(), "sc.d x1, x1, (x1)");
QCOMPARE(Instruction(0x1a10b0af).to_str(), "sc.d.rl x1, x1, (x1)");
QCOMPARE(Instruction(0x1c10b0af).to_str(), "sc.d.aq x1, x1, (x1)");
QCOMPARE(Instruction(0x1e10b0af).to_str(), "sc.d.aqrl x1, x1, (x1)");
QCOMPARE(Instruction(0x2010b0af).to_str(), "amoxor.d x1, x1, (x1)");
QCOMPARE(Instruction(0x2210b0af).to_str(), "amoxor.d.rl x1, x1, (x1)");
QCOMPARE(Instruction(0x2410b0af).to_str(), "amoxor.d.aq x1, x1, (x1)");
QCOMPARE(Instruction(0x2610b0af).to_str(), "amoxor.d.aqrl x1, x1, (x1)");
QCOMPARE(Instruction(0x4010b0af).to_str(), "amoor.d x1, x1, (x1)");
QCOMPARE(Instruction(0x4210b0af).to_str(), "amoor.d.rl x1, x1, (x1)");
QCOMPARE(Instruction(0x4410b0af).to_str(), "amoor.d.aq x1, x1, (x1)");
QCOMPARE(Instruction(0x4610b0af).to_str(), "amoor.d.aqrl x1, x1, (x1)");
QCOMPARE(Instruction(0x6010b0af).to_str(), "amoand.d x1, x1, (x1)");
QCOMPARE(Instruction(0x6210b0af).to_str(), "amoand.d.rl x1, x1, (x1)");
QCOMPARE(Instruction(0x6410b0af).to_str(), "amoand.d.aq x1, x1, (x1)");
QCOMPARE(Instruction(0x6610b0af).to_str(), "amoand.d.aqrl x1, x1, (x1)");
QCOMPARE(Instruction(0x8010b0af).to_str(), "amomin.d x1, x1, (x1)");
QCOMPARE(Instruction(0x8210b0af).to_str(), "amomin.d.rl x1, x1, (x1)");
QCOMPARE(Instruction(0x8410b0af).to_str(), "amomin.d.aq x1, x1, (x1)");
QCOMPARE(Instruction(0x8610b0af).to_str(), "amomin.d.aqrl x1, x1, (x1)");
QCOMPARE(Instruction(0xa010b0af).to_str(), "amomax.d x1, x1, (x1)");
QCOMPARE(Instruction(0xa210b0af).to_str(), "amomax.d.rl x1, x1, (x1)");
QCOMPARE(Instruction(0xa410b0af).to_str(), "amomax.d.aq x1, x1, (x1)");
QCOMPARE(Instruction(0xa610b0af).to_str(), "amomax.d.aqrl x1, x1, (x1)");
QCOMPARE(Instruction(0xc010b0af).to_str(), "amominu.d x1, x1, (x1)");
QCOMPARE(Instruction(0xc210b0af).to_str(), "amominu.d.rl x1, x1, (x1)");
QCOMPARE(Instruction(0xc410b0af).to_str(), "amominu.d.aq x1, x1, (x1)");
QCOMPARE(Instruction(0xc610b0af).to_str(), "amominu.d.aqrl x1, x1, (x1)");
QCOMPARE(Instruction(0xe010b0af).to_str(), "amomaxu.d x1, x1, (x1)");
QCOMPARE(Instruction(0xe210b0af).to_str(), "amomaxu.d.rl x1, x1, (x1)");
QCOMPARE(Instruction(0xe410b0af).to_str(), "amomaxu.d.aq x1, x1, (x1)");
QCOMPARE(Instruction(0xe610b0af).to_str(), "amomaxu.d.aqrl x1, x1, (x1)");
QCOMPARE(Instruction(0x1080b3).to_str(), "add x1, x1, x1");
QCOMPARE(Instruction(0x1090b3).to_str(), "sll x1, x1, x1");
QCOMPARE(Instruction(0x10a0b3).to_str(), "slt x1, x1, x1");
QCOMPARE(Instruction(0x10b0b3).to_str(), "sltu x1, x1, x1");
QCOMPARE(Instruction(0x10c0b3).to_str(), "xor x1, x1, x1");
QCOMPARE(Instruction(0x10d0b3).to_str(), "srl x1, x1, x1");
QCOMPARE(Instruction(0x10e0b3).to_str(), "or x1, x1, x1");
QCOMPARE(Instruction(0x10b7).to_str(), "lui x1, 0x1");
QCOMPARE(Instruction(0x1080bb).to_str(), "addw x1, x1, x1");
QCOMPARE(Instruction(0x1090bb).to_str(), "sllw x1, x1, x1");
QCOMPARE(Instruction(0x10d0bb).to_str(), "srlw x1, x1, x1");
QCOMPARE(Instruction(0x108163).to_str(), "beq x1, x1, 0x2");
QCOMPARE(Instruction(0x109163).to_str(), "bne x1, x1, 0x2");
QCOMPARE(Instruction(0x10c163).to_str(), "blt x1, x1, 0x2");
QCOMPARE(Instruction(0x10d163).to_str(), "bge x1, x1, 0x2");
QCOMPARE(Instruction(0x10e163).to_str(), "bltu x1, x1, 0x2");
QCOMPARE(Instruction(0x1080e7).to_str(), "jalr x1, 1(x1)");
QCOMPARE(Instruction(0x2000ef).to_str(), "jal x1, 0x2");
QCOMPARE(Instruction(0x73).to_str(), "ecall");
QCOMPARE(Instruction(0x10200073).to_str(), "sret");
QCOMPARE(Instruction(0x30200073).to_str(), "mret");
QCOMPARE(Instruction(0x1090f3).to_str(), "csrrw x1, 0x1, x1");
QCOMPARE(Instruction(0x10a0f3).to_str(), "csrrs x1, 0x1, x1");
QCOMPARE(Instruction(0x10b0f3).to_str(), "csrrc x1, 0x1, x1");
QCOMPARE(Instruction(0x10d0f3).to_str(), "csrrwi x1, 0x1, 0x1");
QCOMPARE(Instruction(0x10e0f3).to_str(), "csrrsi x1, 0x1, 0x1");
size_t array_length = sizeof(code_to_string) / sizeof(code_to_string[0]);
for (size_t i = 0; i < array_length; ++i) {
QCOMPARE(Instruction(code_to_string[i].code).to_str(), code_to_string[i].str);
}
}

void TestInstruction::instruction_code_from_str() {
size_t array_length = sizeof(code_to_string) / sizeof(code_to_string[0]);
for (size_t i = 0; i < array_length; ++i) {
if (code_to_string[i].str == "unknown") { continue; }
uint32_t code = 0;
Instruction::code_from_string(&code, code_to_string[i].str.length(), code_to_string[i].str, machine::Address(0x0));
QCOMPARE(code, code_to_string[i].code);
}
}

QTEST_APPLESS_MAIN(TestInstruction)
Loading

0 comments on commit e77d427

Please sign in to comment.