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 3aeae90 commit 1e6e49f
Show file tree
Hide file tree
Showing 6 changed files with 342 additions and 10 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()
2 changes: 1 addition & 1 deletion 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 Down
37 changes: 30 additions & 7 deletions src/machine/instruction.test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,49 @@ using namespace machine;
// Test that we are correctly encoding instructions in constructor
void TestInstruction::instruction() {
QCOMPARE(Instruction(0x0), Instruction());
// QCOMPARE(Instruction(0x4432146), Instruction(1, 2, 3, 4, 5, 6));
// QCOMPARE(Instruction(0x4430004), Instruction(1, 2, 3, 4));
// QCOMPARE(Instruction(0x4000002), Instruction(1, 2_addr));
}

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

QCOMPARE(i.data(), (uint32_t)0xffffffff);
QCOMPARE(i.opcode(), (uint8_t)0x3f);
QCOMPARE(i.opcode(), (uint8_t)0x7f);
QCOMPARE(i.rs(), (uint8_t)0x1f);
QCOMPARE(i.rt(), (uint8_t)0x1f);
QCOMPARE(i.rd(), (uint8_t)0x1f);
QCOMPARE(i.shamt(), (uint8_t)0x1f);
QCOMPARE(i.funct(), (uint16_t)0x3f);
QCOMPARE(i.immediate(), (int32_t)0xffff);
QCOMPARE(i.funct(), (uint16_t)0x3ff);
QCOMPARE(i.immediate(), (int32_t)0);
QCOMPARE(i.address().get_raw(), (uint64_t)0x3ffffff);
}

// TODO test to_str
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() {
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)
162 changes: 162 additions & 0 deletions src/machine/instruction.test.data.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
{0x108083, "lb x1, 1(x1)"},
{0x109083, "lh x1, 1(x1)"},
{0x10a083, "lw x1, 1(x1)"},
{0x10b083, "ld x1, 1(x1)"},
{0x10c083, "lbu x1, 1(x1)"},
{0x10d083, "lhu x1, 1(x1)"},
{0x10e083, "lwu x1, 1(x1)"},
{0xf, "fence"},
{0x100f, "fence.i"},
{0x108093, "addi x1, x1, 1"},
{0x109093, "slli x1, x1, 0x1"},
{0x10a093, "slti x1, x1, 1"},
{0x10b093, "sltiu x1, x1, 1"},
{0x10c093, "xori x1, x1, 1"},
{0x10d093, "srli x1, x1, 0x1"},
{0x4010d093, "srai x1, x1, 0x1"},
{0x10e093, "ori x1, x1, 1"},
{0x10f093, "andi x1, x1, 1"},
{0x1097, "auipc x1, 0x1"},
{0x10809b, "addiw x1, x1, 1"},
{0x10909b, "slliw x1, x1, 0x1"},
{0x10d09b, "srliw x1, x1, 0x1"},
{0x4010d09b, "sraiw x1, x1, 0x1"},
{0x1080a3, "sb x1, 1(x1)"},
{0x1090a3, "sh x1, 1(x1)"},
{0x10a0a3, "sw x1, 1(x1)"},
{0x10b0a3, "sd x1, 1(x1)"},
{0x10a0af, "amoadd.w x1, x1, (x1)"},
{0x210a0af, "amoadd.w.rl x1, x1, (x1)"},
{0x410a0af, "amoadd.w.aq x1, x1, (x1)"},
{0x610a0af, "amoadd.w.aqrl x1, x1, (x1)"},
{0x810a0af, "amoswap.w x1, x1, (x1)"},
{0xa10a0af, "amoswap.w.rl x1, x1, (x1)"},
{0xc10a0af, "amoswap.w.aq x1, x1, (x1)"},
{0xe10a0af, "amoswap.w.aqrl x1, x1, (x1)"},
{0x1000a0af, "lr.w x1, (x1)"},
{0x1200a0af, "lr.w.rl x1, (x1)"},
{0x1400a0af, "lr.w.aq x1, (x1)"},
{0x1600a0af, "lr.w.aqrl x1, (x1)"},
{0x1810a0af, "sc.w x1, x1, (x1)"},
{0x1a10a0af, "sc.w.rl x1, x1, (x1)"},
{0x1c10a0af, "sc.w.aq x1, x1, (x1)"},
{0x1e10a0af, "sc.w.aqrl x1, x1, (x1)"},
{0x2010a0af, "amoxor.w x1, x1, (x1)"},
{0x2210a0af, "amoxor.w.rl x1, x1, (x1)"},
{0x2410a0af, "amoxor.w.aq x1, x1, (x1)"},
{0x2610a0af, "amoxor.w.aqrl x1, x1, (x1)"},
{0x4010a0af, "amoor.w x1, x1, (x1)"},
{0x4210a0af, "amoor.w.rl x1, x1, (x1)"},
{0x4410a0af, "amoor.w.aq x1, x1, (x1)"},
{0x4610a0af, "amoor.w.aqrl x1, x1, (x1)"},
{0x6010a0af, "amoand.w x1, x1, (x1)"},
{0x6210a0af, "amoand.w.rl x1, x1, (x1)"},
{0x6410a0af, "amoand.w.aq x1, x1, (x1)"},
{0x6610a0af, "amoand.w.aqrl x1, x1, (x1)"},
{0x8010a0af, "amomin.w x1, x1, (x1)"},
{0x8210a0af, "amomin.w.rl x1, x1, (x1)"},
{0x8410a0af, "amomin.w.aq x1, x1, (x1)"},
{0x8610a0af, "amomin.w.aqrl x1, x1, (x1)"},
{0xa010a0af, "amomax.w x1, x1, (x1)"},
{0xa210a0af, "amomax.w.rl x1, x1, (x1)"},
{0xa410a0af, "amomax.w.aq x1, x1, (x1)"},
{0xa610a0af, "amomax.w.aqrl x1, x1, (x1)"},
{0xc010a0af, "amominu.w x1, x1, (x1)"},
{0xc210a0af, "amominu.w.rl x1, x1, (x1)"},
{0xc410a0af, "amominu.w.aq x1, x1, (x1)"},
{0xc610a0af, "amominu.w.aqrl x1, x1, (x1)"},
{0xe010a0af, "amomaxu.w x1, x1, (x1)"},
{0xe210a0af, "amomaxu.w.rl x1, x1, (x1)"},
{0xe410a0af, "amomaxu.w.aq x1, x1, (x1)"},
{0xe610a0af, "amomaxu.w.aqrl x1, x1, (x1)"},
{0x10b0af, "amoadd.d x1, x1, (x1)"},
{0x210b0af, "amoadd.d.rl x1, x1, (x1)"},
{0x410b0af, "amoadd.d.aq x1, x1, (x1)"},
{0x610b0af, "amoadd.d.aqrl x1, x1, (x1)"},
{0x810b0af, "amoswap.d x1, x1, (x1)"},
{0xa10b0af, "amoswap.d.rl x1, x1, (x1)"},
{0xc10b0af, "amoswap.d.aq x1, x1, (x1)"},
{0xe10b0af, "amoswap.d.aqrl x1, x1, (x1)"},
{0x1000b0af, "lr.d x1, (x1)"},
{0x1200b0af, "lr.d.rl x1, (x1)"},
{0x1400b0af, "lr.d.aq x1, (x1)"},
{0x1600b0af, "lr.d.aqrl x1, (x1)"},
{0x1810b0af, "sc.d x1, x1, (x1)"},
{0x1a10b0af, "sc.d.rl x1, x1, (x1)"},
{0x1c10b0af, "sc.d.aq x1, x1, (x1)"},
{0x1e10b0af, "sc.d.aqrl x1, x1, (x1)"},
{0x2010b0af, "amoxor.d x1, x1, (x1)"},
{0x2210b0af, "amoxor.d.rl x1, x1, (x1)"},
{0x2410b0af, "amoxor.d.aq x1, x1, (x1)"},
{0x2610b0af, "amoxor.d.aqrl x1, x1, (x1)"},
{0x4010b0af, "amoor.d x1, x1, (x1)"},
{0x4210b0af, "amoor.d.rl x1, x1, (x1)"},
{0x4410b0af, "amoor.d.aq x1, x1, (x1)"},
{0x4610b0af, "amoor.d.aqrl x1, x1, (x1)"},
{0x6010b0af, "amoand.d x1, x1, (x1)"},
{0x6210b0af, "amoand.d.rl x1, x1, (x1)"},
{0x6410b0af, "amoand.d.aq x1, x1, (x1)"},
{0x6610b0af, "amoand.d.aqrl x1, x1, (x1)"},
{0x8010b0af, "amomin.d x1, x1, (x1)"},
{0x8210b0af, "amomin.d.rl x1, x1, (x1)"},
{0x8410b0af, "amomin.d.aq x1, x1, (x1)"},
{0x8610b0af, "amomin.d.aqrl x1, x1, (x1)"},
{0xa010b0af, "amomax.d x1, x1, (x1)"},
{0xa210b0af, "amomax.d.rl x1, x1, (x1)"},
{0xa410b0af, "amomax.d.aq x1, x1, (x1)"},
{0xa610b0af, "amomax.d.aqrl x1, x1, (x1)"},
{0xc010b0af, "amominu.d x1, x1, (x1)"},
{0xc210b0af, "amominu.d.rl x1, x1, (x1)"},
{0xc410b0af, "amominu.d.aq x1, x1, (x1)"},
{0xc610b0af, "amominu.d.aqrl x1, x1, (x1)"},
{0xe010b0af, "amomaxu.d x1, x1, (x1)"},
{0xe210b0af, "amomaxu.d.rl x1, x1, (x1)"},
{0xe410b0af, "amomaxu.d.aq x1, x1, (x1)"},
{0xe610b0af, "amomaxu.d.aqrl x1, x1, (x1)"},
{0x1080b3, "add x1, x1, x1"},
{0x401080b3, "sub x1, x1, x1"},
{0x1090b3, "sll x1, x1, x1"},
{0x10a0b3, "slt x1, x1, x1"},
{0x10b0b3, "sltu x1, x1, x1"},
{0x10c0b3, "xor x1, x1, x1"},
{0x10d0b3, "srl x1, x1, x1"},
{0x4010d0b3, "sra x1, x1, x1"},
{0x10e0b3, "or x1, x1, x1"},
{0x10f0b3, "and x1, x1, x1"},
{0x21080b3, "mul x1, x1, x1"},
{0x21090b3, "mulh x1, x1, x1"},
{0x210a0b3, "mulhsu x1, x1, x1"},
{0x210b0b3, "mulhu x1, x1, x1"},
{0x210c0b3, "div x1, x1, x1"},
{0x210d0b3, "divu x1, x1, x1"},
{0x210e0b3, "rem x1, x1, x1"},
{0x210f0b3, "remu x1, x1, x1"},
{0x10b7, "lui x1, 0x1"},
{0x1080bb, "addw x1, x1, x1"},
{0x401080bb, "subw x1, x1, x1"},
{0x1090bb, "sllw x1, x1, x1"},
{0x10d0bb, "srlw x1, x1, x1"},
{0x4010d0bb, "sraw x1, x1, x1"},
{0x21080bb, "mulw x1, x1, x1"},
{0x210c0bb, "divw x1, x1, x1"},
{0x210d0bb, "divuw x1, x1, x1"},
{0x210e0bb, "remw x1, x1, x1"},
{0x210f0bb, "remuw x1, x1, x1"},
{0x108163, "beq x1, x1, 0x2"},
{0x109163, "bne x1, x1, 0x2"},
{0x10c163, "blt x1, x1, 0x2"},
{0x10d163, "bge x1, x1, 0x2"},
{0x10e163, "bltu x1, x1, 0x2"},
{0x10f163, "bgeu x1, x1, 0x2"},
{0x1080e7, "jalr x1, 1(x1)"},
{0x2000ef, "jal x1, 0x2"},
{0x73, "ecall"},
{0x100073, "ebreak"},
{0x10200073, "sret"},
{0x30200073, "mret"},
{0x1090f3, "csrrw x1, 0x1, x1"},
{0x10a0f3, "csrrs x1, 0x1, x1"},
{0x10b0f3, "csrrc x1, 0x1, x1"},
{0x10d0f3, "csrrwi x1, 0x1, 0x1"},
{0x10e0f3, "csrrsi x1, 0x1, 0x1"},
{0x10f0f3, "csrrci x1, 0x1, 0x1"},
138 changes: 138 additions & 0 deletions src/machine/instruction.test.gendata.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
#include "common/logging.h"
#include "machine/instruction.h"
#include "machine/instruction.cpp"
#include <QFile>
#include <unordered_set>

using namespace machine;

static uint32_t MASK_AMO_RS2 = 0b1111100000000000000000000;

#define AMO_MAP_4ITEMS(NAME_BASE, MASK) \
{ NAME_BASE, MASK}, \
{ NAME_BASE ".rl", MASK }, \
{ NAME_BASE ".aq", MASK }, \
{ NAME_BASE ".aqrl", MASK },

static std::unordered_map<QString, uint32_t> mask_map = {
AMO_MAP_4ITEMS("lr.w", MASK_AMO_RS2)
AMO_MAP_4ITEMS("lr.d", MASK_AMO_RS2)
};

void generate_code_and_string_data(QTextStream& out, const InstructionMap* im_iter, BitField subfield) {
for (int i = 0; i < (1 << subfield.count); i++) {
const InstructionMap* im = &im_iter[i];

if (im->name == "unknown") {
continue;
}

if (im->subclass != nullptr) {
generate_code_and_string_data(out, im->subclass, im->subfield);
continue;
}

uint32_t code = im->code;
QString string_data = im->name;

if (im->args.size()) {
int val_mask;
switch (im->type) {
case Instruction::Type::R:
case Instruction::Type::AMO: {
val_mask = 0b00000000000100001000000010000000;
break;
}
case Instruction::Type::I:
val_mask = 0b00000000000100001000000010000000;
break;
case Instruction::Type::ZICSR: {
val_mask = 0b00000000000100001000000010000000;
break;
}
case Instruction::Type::S: {
val_mask = 0b00000000000100001000000010000000;
break;
}
case Instruction::Type::B: {
val_mask = 0b00000000000100001000000100000000;
break;
}
case Instruction::Type::U: {
val_mask = 0b00000000000000000001000010000000;
break;
}
case Instruction::Type::J: {
val_mask = 0b00000000001000000000000010000000;
break;
}
case Instruction::Type::UNKNOWN: {
return;
}
}
code |= val_mask & ~im->mask;
if (mask_map.count(im->name)) {
uint32_t old_code = code;
code &= ~mask_map[im->name];
}

QString next_delim = " ";
for (const QString &arg_string : im->args) {
string_data += 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) {
string_data += arg_letter;
continue;
}
switch (arg_desc->kind) {
case 'g': {
string_data += "x1";
break;
}
case 'p':
case 'a':
string_data += QString::asprintf("0x%d", Instruction(code).immediate());
break;
case 'o':
case 'n': {
if (arg_desc->min < 0) {
string_data += "1";
} else {
string_data += "0x1";
}
break;
}
case 'E': {
string_data += "0x1";
break;
}
}
}
}
}

QString enum_str = QString::asprintf("{0x%x, \"%s\"},", code, qPrintable(string_data));
if (Instruction(code).to_str() != string_data) {
enum_str += " // failed";
}
enum_str += "\n";
out << enum_str;
}
}

int main(int argc, char *argv[]) {
fill_argdesbycode();
instruction_from_string_build_base();
QFile outfile("instruction.test.data.h");
if (outfile.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream out(&outfile);
generate_code_and_string_data(out, C_inst_map, instruction_map_opcode_field);
outfile.close();
} else {
printf("open output file failed\n");
exit(1);
}
}
Loading

0 comments on commit 1e6e49f

Please sign in to comment.