3
3
#include " machine/instruction.cpp"
4
4
5
5
#include < QFile>
6
-
6
+ # include < QMap >
7
7
using namespace machine ;
8
8
9
- static uint32_t MASK_AMO_RS2 = 0b1111100000000000000000000 ;
9
+ static const uint32_t MASK_AMO_RS2 = 0b1111100000000000000000000 ;
10
+ static const uint32_t MASK_I_RS1 = 0b11111000000000000000 ;
10
11
11
- #define AMO_MAP_4ITEMS (NAME_BASE, MASK ) \
12
- { NAME_BASE, MASK }, { NAME_BASE " .rl" , MASK }, { NAME_BASE " .aq" , MASK }, \
13
- { NAME_BASE " .aqrl" , MASK },
12
+ #define AMO_MAP_4ITEMS (NAME, MASK ) \
13
+ { NAME, MASK }, { NAME " .aq" , MASK }, { NAME " .rl" , MASK }, { \
14
+ NAME " .aqrl" , MASK \
15
+ }
14
16
15
- static std::unordered_map<QString, uint32_t > mask_map
16
- = { AMO_MAP_4ITEMS (" lr.w" , MASK_AMO_RS2) AMO_MAP_4ITEMS (" lr.d" , MASK_AMO_RS2) };
17
+ static const QMap<QString, uint32_t > zero_mask_tb = {
18
+ // lr.w/d rs2 = 0
19
+ AMO_MAP_4ITEMS (" lr.w" , ~MASK_AMO_RS2), AMO_MAP_4ITEMS (" lr.d" , ~MASK_AMO_RS2),
20
+ // csrw(alias of csrrs) rs1 = 0
21
+ // { "csrrs", MASK_I_RS1 }
22
+ };
17
23
18
24
void generate_code_and_string_data (
19
25
QTextStream &out,
@@ -22,15 +28,15 @@ void generate_code_and_string_data(
22
28
const InstructionMap *alias_parent) {
23
29
for (int i = 0 ;; i++) {
24
30
if (alias_parent == nullptr ) {
25
- // end of bits
31
+ // end of subclass table
26
32
if (i >= (1 << subfield.count )) { break ; }
27
33
} else {
28
34
// end of alias
29
35
if (im_iter[i].name == nullptr ) { break ; }
30
36
}
31
37
const InstructionMap *im = &im_iter[i];
32
38
33
- if (im->name == " unknown" ) { continue ; }
39
+ if (QString ( im->name ) == " unknown" ) { continue ; }
34
40
35
41
if (im->subclass != nullptr ) {
36
42
generate_code_and_string_data (out, im->subclass , im->subfield , nullptr );
@@ -41,7 +47,7 @@ void generate_code_and_string_data(
41
47
QString string_data = im->name ;
42
48
43
49
if (im->args .size ()) {
44
- int val_mask;
50
+ uint32_t val_mask = 0 ;
45
51
Instruction::Type t = im->type ;
46
52
if (alias_parent != nullptr ) { t = alias_parent->type ; }
47
53
switch (t) {
@@ -52,7 +58,8 @@ void generate_code_and_string_data(
52
58
}
53
59
case Instruction::Type::I: val_mask = 0b00000000000100001000000010000000 ; break ;
54
60
case Instruction::Type::ZICSR: {
55
- val_mask = 0b00000000000100001000000010000000 ;
61
+ // dest is not set here
62
+ val_mask = 0b00000000000000001000000010000000 ;
56
63
break ;
57
64
}
58
65
case Instruction::Type::S: {
@@ -76,7 +83,7 @@ void generate_code_and_string_data(
76
83
}
77
84
}
78
85
code |= val_mask & ~im->mask ;
79
- if (mask_map .count (im->name )) { code &= ~mask_map [im->name ]; }
86
+ if (zero_mask_tb .count (im->name )) { code &= zero_mask_tb [im->name ]; }
80
87
81
88
QString next_delim = " " ;
82
89
for (const QString &arg_string : im->args ) {
@@ -108,7 +115,17 @@ void generate_code_and_string_data(
108
115
break ;
109
116
}
110
117
case ' E' : {
111
- string_data += " 0x1" ;
118
+ int i = 0 ;
119
+ for (auto ® : CSR::REGISTERS) {
120
+ if (i < 2 ) {
121
+ i++;
122
+ continue ;
123
+ }
124
+ string_data += QString::asprintf (" 0x%x" , reg.address .data );
125
+ code |= reg.address .data << 20 ;
126
+ if (zero_mask_tb.count (im->name )) { code &= zero_mask_tb[im->name ]; }
127
+ break ;
128
+ }
112
129
break ;
113
130
}
114
131
}
@@ -120,32 +137,34 @@ void generate_code_and_string_data(
120
137
generate_code_and_string_data (out, im->aliases , im->subfield , im);
121
138
}
122
139
123
- QString enum_str ;
140
+ QString elem_str ;
124
141
bool check_failed = false ;
125
142
QString parsed_string_data = Instruction (code).to_str ();
143
+ uint32_t parsed_code;
144
+ Instruction::code_from_string (
145
+ &parsed_code, parsed_string_data.length (), string_data, Address (0x0 ));
126
146
if (alias_parent == nullptr ) {
127
- enum_str = QString::asprintf (" {0x%x, \" %s\" }," , code, qPrintable (string_data));
147
+ // base inst
148
+ elem_str = QString::asprintf (" {0x%x, \" %s\" }," , code, qPrintable (string_data));
128
149
if (parsed_string_data != string_data) { check_failed = true ; }
129
150
} else {
130
- enum_str = QString::asprintf (
151
+ // alias inst
152
+ elem_str = QString::asprintf (
131
153
" {0x%x, \" %s\" , \" %s\" }," , code, qPrintable (parsed_string_data),
132
154
qPrintable (string_data));
155
+ if (parsed_code != code) { check_failed = true ; }
133
156
}
134
- uint32_t parsed_code;
135
- Instruction::code_from_string (
136
- &parsed_code, parsed_string_data.length (), string_data, Address (0x0 ));
137
- if (parsed_code != code) { check_failed = true ; }
138
- if (check_failed) { enum_str += " // failed" ; }
157
+ if (check_failed) { elem_str += " // failed" ; }
139
158
140
- enum_str += " \n " ;
141
- out << enum_str ;
159
+ elem_str += " \n " ;
160
+ out << elem_str ;
142
161
}
143
162
}
144
163
145
- int main (int argc, char *argv[] ) {
164
+ int main () {
146
165
fill_argdesbycode ();
147
166
instruction_from_string_build_base ();
148
- QFile outfile (" instruction.test.data.h " );
167
+ QFile outfile (" instruction.test.data.def " );
149
168
if (outfile.open (QIODevice::WriteOnly | QIODevice::Text)) {
150
169
QTextStream out (&outfile);
151
170
generate_code_and_string_data (out, C_inst_map, instruction_map_opcode_field, nullptr );
0 commit comments