33#include " machine/instruction.cpp"
44
55#include < QFile>
6-
6+ # include < QMap >
77using namespace machine ;
88
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 ;
1011
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+ }
1416
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+ };
1723
1824void generate_code_and_string_data (
1925 QTextStream &out,
@@ -22,15 +28,15 @@ void generate_code_and_string_data(
2228 const InstructionMap *alias_parent) {
2329 for (int i = 0 ;; i++) {
2430 if (alias_parent == nullptr ) {
25- // end of bits
31+ // end of subclass table
2632 if (i >= (1 << subfield.count )) { break ; }
2733 } else {
2834 // end of alias
2935 if (im_iter[i].name == nullptr ) { break ; }
3036 }
3137 const InstructionMap *im = &im_iter[i];
3238
33- if (im->name == " unknown" ) { continue ; }
39+ if (QString ( im->name ) == " unknown" ) { continue ; }
3440
3541 if (im->subclass != nullptr ) {
3642 generate_code_and_string_data (out, im->subclass , im->subfield , nullptr );
@@ -41,7 +47,7 @@ void generate_code_and_string_data(
4147 QString string_data = im->name ;
4248
4349 if (im->args .size ()) {
44- int val_mask;
50+ uint32_t val_mask = 0 ;
4551 Instruction::Type t = im->type ;
4652 if (alias_parent != nullptr ) { t = alias_parent->type ; }
4753 switch (t) {
@@ -52,7 +58,8 @@ void generate_code_and_string_data(
5258 }
5359 case Instruction::Type::I: val_mask = 0b00000000000100001000000010000000 ; break ;
5460 case Instruction::Type::ZICSR: {
55- val_mask = 0b00000000000100001000000010000000 ;
61+ // dest is not set here
62+ val_mask = 0b00000000000000001000000010000000 ;
5663 break ;
5764 }
5865 case Instruction::Type::S: {
@@ -76,7 +83,7 @@ void generate_code_and_string_data(
7683 }
7784 }
7885 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 ]; }
8087
8188 QString next_delim = " " ;
8289 for (const QString &arg_string : im->args ) {
@@ -108,7 +115,17 @@ void generate_code_and_string_data(
108115 break ;
109116 }
110117 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+ }
112129 break ;
113130 }
114131 }
@@ -120,32 +137,34 @@ void generate_code_and_string_data(
120137 generate_code_and_string_data (out, im->aliases , im->subfield , im);
121138 }
122139
123- QString enum_str ;
140+ QString elem_str ;
124141 bool check_failed = false ;
125142 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 ));
126146 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));
128149 if (parsed_string_data != string_data) { check_failed = true ; }
129150 } else {
130- enum_str = QString::asprintf (
151+ // alias inst
152+ elem_str = QString::asprintf (
131153 " {0x%x, \" %s\" , \" %s\" }," , code, qPrintable (parsed_string_data),
132154 qPrintable (string_data));
155+ if (parsed_code != code) { check_failed = true ; }
133156 }
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" ; }
139158
140- enum_str += " \n " ;
141- out << enum_str ;
159+ elem_str += " \n " ;
160+ out << elem_str ;
142161 }
143162}
144163
145- int main (int argc, char *argv[] ) {
164+ int main () {
146165 fill_argdesbycode ();
147166 instruction_from_string_build_base ();
148- QFile outfile (" instruction.test.data.h " );
167+ QFile outfile (" instruction.test.data.def " );
149168 if (outfile.open (QIODevice::WriteOnly | QIODevice::Text)) {
150169 QTextStream out (&outfile);
151170 generate_code_and_string_data (out, C_inst_map, instruction_map_opcode_field, nullptr );
0 commit comments