Skip to content

Commit 2777e76

Browse files
committed
refactor
1 parent 7e3bd09 commit 2777e76

8 files changed

+524
-350
lines changed

src/machine/csr/controlstate.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,16 +255,16 @@ namespace machine { namespace CSR {
255255

256256
class RegisterMapByName {
257257
bool initialized = false;
258-
std::unordered_map<const char *, size_t> map;
258+
std::unordered_map<std::string, size_t> map;
259259

260260
void init() {
261261
for (size_t i = 0; i < REGISTERS.size(); i++) {
262-
map.emplace(REGISTERS[i].name, i);
262+
map.emplace(std::string(REGISTERS[i].name), i);
263263
}
264264
initialized = true;
265265
}
266266
public:
267-
size_t at(const char* name) {
267+
size_t at(std::string name) {
268268
if (!initialized) init();
269269
return map.at(name);
270270
}

src/machine/instruction.cpp

Lines changed: 56 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -765,6 +765,55 @@ Instruction &Instruction::operator=(const Instruction &c) {
765765
return *this;
766766
}
767767

768+
QString field_to_string(int32_t field, const ArgumentDesc* arg_desc, Address inst_addr, bool symbolic_registers_enabled) {
769+
QString res = "";
770+
if (arg_desc->min < 0) {
771+
field = extend(field, [&]() {
772+
int sum = (int)arg_desc->arg.shift;
773+
for (auto chunk : arg_desc->arg) {
774+
sum += chunk.count;
775+
}
776+
return sum;
777+
}());
778+
}
779+
switch (arg_desc->kind) {
780+
case 'g': {
781+
if (symbolic_registers_enabled) {
782+
res += QString(Rv_regnames[field]);
783+
} else {
784+
res += "x" + QString::number(field);
785+
}
786+
break;
787+
}
788+
case 'p':
789+
case 'a': {
790+
field += (int32_t)inst_addr.get_raw();
791+
res.append(str::asHex(field));
792+
break;
793+
}
794+
case 'o':
795+
case 'n': {
796+
if (arg_desc->min < 0) {
797+
res += QString::number((int32_t)field, 10);
798+
} else {
799+
res.append(str::asHex(uint32_t(field)));
800+
}
801+
break;
802+
}
803+
case 'E': {
804+
if (symbolic_registers_enabled) {
805+
try {
806+
res += CSR::REGISTERS[CSR::REGISTER_MAP.at(CSR::Address(field))].name;
807+
} catch (std::out_of_range &e) { res.append(str::asHex(field)); }
808+
} else {
809+
res.append(str::asHex(field));
810+
}
811+
break;
812+
}
813+
}
814+
return res;
815+
}
816+
768817
QString Instruction::to_str(Address inst_addr) const {
769818
const InstructionMap &im = InstructionMapFind(dt);
770819
// TODO there are exception where some fields are zero and such so we should
@@ -787,50 +836,7 @@ QString Instruction::to_str(Address inst_addr) const {
787836
continue;
788837
}
789838
auto field = (int32_t)arg_desc->arg.decode(this->dt);
790-
if (arg_desc->min < 0) {
791-
field = extend(field, [&]() {
792-
int sum = (int)arg_desc->arg.shift;
793-
for (auto chunk : arg_desc->arg) {
794-
sum += chunk.count;
795-
}
796-
return sum;
797-
}());
798-
}
799-
switch (arg_desc->kind) {
800-
case 'g': {
801-
if (symbolic_registers_enabled) {
802-
res += QString(Rv_regnames[field]);
803-
} else {
804-
res += "x" + QString::number(field);
805-
}
806-
break;
807-
}
808-
case 'p':
809-
case 'a': {
810-
field += (int32_t)inst_addr.get_raw();
811-
res.append(str::asHex(uint32_t(field)));
812-
break;
813-
}
814-
case 'o':
815-
case 'n': {
816-
if (arg_desc->min < 0) {
817-
res += QString::number((int32_t)field, 10);
818-
} else {
819-
res.append(str::asHex(uint32_t(field)));
820-
}
821-
break;
822-
}
823-
case 'E': {
824-
if (symbolic_registers_enabled) {
825-
try {
826-
res += CSR::REGISTERS[CSR::REGISTER_MAP.at(CSR::Address(field))].name;
827-
} catch (std::out_of_range &e) { res.append(str::asHex(field)); }
828-
} else {
829-
res.append(str::asHex(field));
830-
}
831-
break;
832-
}
833-
}
839+
res += field_to_string(field, arg_desc, inst_addr, symbolic_registers_enabled);
834840
}
835841
}
836842
return res;
@@ -1375,14 +1381,15 @@ bool parse_immediate_value(
13751381

13761382
uint16_t parse_csr_address(const QString &field_token, uint &chars_taken) {
13771383
if (field_token.at(0).isLetter()) {
1378-
size_t index = CSR::REGISTER_MAP_BY_NAME.at(qPrintable(field_token));
1379-
if (index < 0) {
1384+
try {
1385+
size_t index = CSR::REGISTER_MAP_BY_NAME.at(field_token.toStdString());
1386+
auto &reg = CSR::REGISTERS[index];
1387+
chars_taken = strlen(reg.name);
1388+
return reg.address.data;
1389+
} catch (std::out_of_range &e) {
13801390
chars_taken = 0;
13811391
return 0;
13821392
}
1383-
auto &reg = CSR::REGISTERS[index];
1384-
chars_taken = strlen(reg.name);
1385-
return reg.address.data;
13861393
} else {
13871394
char *r;
13881395
uint64_t val;
@@ -1449,9 +1456,6 @@ void Instruction::set_symbolic_registers(bool enable) {
14491456
symbolic_registers_enabled = enable;
14501457
}
14511458

1452-
inline int32_t Instruction::extend(uint32_t value, uint32_t used_bits) const {
1453-
return value | ~((value & (1 << (used_bits - 1))) - 1);
1454-
}
14551459

14561460
void Instruction::append_recognized_registers(QStringList &list) {
14571461
for (auto name : Rv_regnames) {

src/machine/instruction.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,10 @@ struct TokenizedInstruction {
9090
struct RelocExpression;
9191
typedef QVector<RelocExpression *> RelocExpressionList;
9292

93+
inline int32_t extend(uint32_t value, uint32_t used_bits) {
94+
return value | ~((value & (1 << (used_bits - 1))) - 1);
95+
}
96+
9397
class Instruction {
9498
public:
9599
Instruction();
@@ -208,7 +212,6 @@ class Instruction {
208212
RelocExpressionList *reloc,
209213
Modifier pseudo_mod = Modifier::NONE,
210214
uint64_t initial_immediate_value = 0);
211-
inline int32_t extend(uint32_t value, uint32_t used_bits) const;
212215
static uint32_t parse_field(
213216
QString &field_token,
214217
const QString &arg,

src/machine/instruction.test.cpp

Lines changed: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,31 +24,73 @@ void TestInstruction::instruction_access() {
2424
QCOMPARE(i.address().get_raw(), (uint64_t)0x3ffffff);
2525
}
2626

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>
27+
static const struct {
28+
uint32_t code;
29+
QString str;
30+
QString alias_str = nullptr;
31+
} code_to_string[] = {
32+
{ 0xffffffff, "unknown" },
33+
{ 0x0, "unknown" },
34+
{ 0b00000000000000000000000000010011, "nop" },
35+
{ 0b00000000000000001000000010010011, "addi x1, x1, 0" },
36+
{ 0b01111111111111111000111110010011, "addi x31, x31, 2047" },
37+
{ 0b11111111111100001000000010010011, "addi x1, x1, -1" },
38+
{ 0b10000000000000001000000010010011, "addi x1, x1, -2048" },
39+
#include <./instruction.test.data.def>
40+
};
41+
42+
struct Pair {
43+
uint32_t code;
44+
QString str;
45+
};
46+
static const struct {
47+
QString string_data;
48+
std::vector<Pair> pairs;
49+
} pesude_code_to_string[] = {
50+
{ "nop", { { 0b00000000000000000000000000010011, "nop" } } },
51+
{ "la x1, 0xffffefff",
52+
{ { 0xfffff097, "auipc x1, 0xfffff" }, { 0xfff08093, "addi x1, x1, -1" } } },
53+
{ "li x1, 0xffffefff",
54+
{ { 0xfffff0b7, "lui x1, 0xfffff" }, { 0xfff08093, "addi x1, x1, -1" } } },
55+
{ "call 0xfffeffff",
56+
{ { 0xffff0317, "auipc x6, 0xffff0" }, { 0xfff300e7, "jalr x1, -1(x6)" } } },
57+
{ "tail 0xfffeffff",
58+
{ { 0xffff0317, "auipc x6, 0xffff0" }, { 0xfff30067, "jalr x0, -1(x6)" } } },
59+
{ "sext.b x1, x2", { { 0x11093, "slli x1, x2, 0x0" }, { 0x4000d093, "srai x1, x1, 0x0" } } },
60+
{ "sext.h x1, x2", { { 0x11093, "slli x1, x2, 0x0" }, { 0x4000d093, "srai x1, x1, 0x0" } } },
61+
{ "zext.h x1, x2", { { 0x11093, "slli x1, x2, 0x0" }, { 0xd093, "srli x1, x1, 0x0" } } },
62+
{ "zext.w x1, x2", { { 0x11093, "slli x1, x2, 0x0" }, { 0xd093, "srli x1, x1, 0x0" } } },
3663
};
3764

3865
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) {
66+
for (size_t i = 0; i < sizeof(code_to_string) / sizeof(code_to_string[0]); i++) {
4167
QCOMPARE(Instruction(code_to_string[i].code).to_str(), code_to_string[i].str);
4268
}
69+
70+
for (size_t i = 0; i < sizeof(pesude_code_to_string) / sizeof(pesude_code_to_string[0]); i++) {
71+
for (size_t j = 0; j < pesude_code_to_string[i].pairs.size(); j++) {
72+
Pair pair = pesude_code_to_string[i].pairs[j];
73+
QCOMPARE(Instruction(pair.code).to_str(), pair.str);
74+
}
75+
}
4376
}
4477

4578
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) {
79+
for (size_t i = 0; i < sizeof(code_to_string) / sizeof(code_to_string[0]); i++) {
4880
if (code_to_string[i].str == "unknown") { continue; }
81+
QString test_string_data = code_to_string[i].alias_str == nullptr
82+
? code_to_string[i].str
83+
: code_to_string[i].alias_str;
4984
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);
85+
try {
86+
Instruction::code_from_string(
87+
&code, code_to_string[i].str.length(), test_string_data, Address(0x0));
88+
QCOMPARE(code, code_to_string[i].code);
89+
} catch (const Instruction::ParseError &e) {
90+
TokenizedInstruction inst
91+
= TokenizedInstruction::from_line(test_string_data, Address(0x0), nullptr, 0);
92+
QFAIL(qPrintable(e.message));
93+
} catch (...) { QFAIL("code_from_string throw unexpected exception"); }
5294
}
5395
}
5496

0 commit comments

Comments
 (0)