📄 issgen.cpp
字号:
}}void bin_ident::emit_codegenerator_content3(unsigned index, unsigned rmb, Symbol attr, ofstream& ofile){ assert(index<count); if (type==BIN_FIELD) { ofile << "((inst>>" << offset+rmb << ")&" << (1<<width)-1 <<")"; } else { oper->emit_codegenerator_content3(index, offset+rmb, attr, ofile); }}unsigned oper::get_field_index(Symbol field, unsigned index) const{ vector<class bin_code *>::reverse_iterator rbit; for (rbit=pat->rbegin(); rbit!=pat->rend(); rbit++) { if ((*rbit)->is_identifier()) { if ((*rbit)->get_name()==field) return index % (*rbit)->get_count(); index = index/(*rbit)->get_count(); } } assert(0); // should not be here return 0; // shut up gcc}void oper::emit_interpreter_content(unsigned index, Symbol attr, ofstream& ofile){ assert(index<count); assert(cont_table.find(attr)!=cont_table.end()); vector<class token> *tokens = cont_table[attr]; vector<class token>::iterator tit; for (tit=tokens->begin(); tit!=tokens->end(); tit++) { /* encountered a field */ if ((*tit).get_type()==token::FIELD) { /* get the name of the field */ Symbol fname = symbol_find_or_insert((*tit).get_data()); /* must exist in field table after type_check */ assert(field_table.find(fname)!=field_table.end()); /* if this is program counter */ if (fname==sym_pc) { ofile << "GET_PC()"; } else if (fname==sym_inst) { ofile << "inst"; } /* else emit its content */ else field_table[fname]->emit_interpreter_content (get_field_index(fname, index), attr, ofile); } else { ofile << (*tit).get_data(); } }}void group::emit_interpreter_content(unsigned index, Symbol attr, ofstream& ofile){ assert(index<count); vector<class oper_base *>::const_iterator op_it; for (op_it=opers->begin(); op_it!=opers->end(); op_it++) { if (index<(*op_it)->get_count()) return (*op_it)->emit_interpreter_content(index, attr, ofile); index -= (*op_it)->get_count(); } assert(0);}void group::emit_interpreter(unsigned index, ofstream& ofile){ assert(index<count); vector<class oper_base *>::const_iterator op_it; for (op_it=opers->begin(); op_it!=opers->end(); op_it++) { if (index<(*op_it)->get_count()) return (*op_it)->emit_interpreter(index, ofile); index -= (*op_it)->get_count(); } assert(0);}void group::emit_field_declarations(unsigned index, unsigned rmb, ofstream& ofile){ assert(index<count); vector<class oper_base *>::const_iterator op_it; for (op_it=opers->begin(); op_it!=opers->end(); op_it++) { if (index<(*op_it)->get_count()) return (*op_it)->emit_field_declarations(index, rmb, ofile); index -= (*op_it)->get_count(); } assert(0);}void group::emit_codegenerator(unsigned index, ofstream& ofile){ assert(index<count); vector<class oper_base *>::const_iterator op_it; for (op_it=opers->begin(); op_it!=opers->end(); op_it++) { if (index<(*op_it)->get_count()) { (*op_it)->emit_codegenerator(index, ofile); return; } index -= (*op_it)->get_count(); } assert(0);}void group::emit_codegenerator_content1(unsigned index, Symbol attr, ofstream& ofile){ assert(index<count); vector<class oper_base *>::const_iterator op_it; for (op_it=opers->begin(); op_it!=opers->end(); op_it++) { if (index<(*op_it)->get_count()) { (*op_it)->emit_codegenerator_content1(index, attr, ofile); return; } index -= (*op_it)->get_count(); } assert(0);}void group::emit_codegenerator_content2(unsigned index, unsigned rmb, Symbol attr, ofstream& ofile){ assert(index<count); vector<class oper_base *>::const_iterator op_it; for (op_it=opers->begin(); op_it!=opers->end(); op_it++) { if (index<(*op_it)->get_count()) { (*op_it)->emit_codegenerator_content2(index, rmb, attr, ofile); return; } index -= (*op_it)->get_count(); } assert(0);}void group::emit_codegenerator_content3(unsigned index, unsigned rmb, Symbol attr, ofstream& ofile){ assert(index<count); vector<class oper_base *>::const_iterator op_it; for (op_it=opers->begin(); op_it!=opers->end(); op_it++) { if (index<(*op_it)->get_count()) { (*op_it)->emit_codegenerator_content3(index, rmb, attr, ofile); return; } index -= (*op_it)->get_count(); } assert(0);}void oper::emit_field_declarations(unsigned index, unsigned rmb, ofstream& ofile){ assert(index<count); vector<class bin_code *>::reverse_iterator rbit; for (rbit=pat->rbegin(); rbit!=pat->rend(); rbit++) { if ((*rbit)->is_identifier()) { dynamic_cast<class bin_ident *>(*rbit)->emit_declaration (index%(*rbit)->get_count(), rmb, ofile); index = index/(*rbit)->get_count(); } }}void oper::emit_interpreter(unsigned index, ofstream& ofile){ // safety checking assert(index<count); // field variable declaration and initialization emit_field_declarations(index, 0, ofile); ofile << "\n"; // emit all the vars used VAR_ENV vtable; get_used_vars(index, &vtable); VAR_ENV::iterator vit; for (vit=vtable.begin(); vit!=vtable.end(); vit++) { ofile << "\t" << symbol_get_string((*vit).second) << " " << symbol_get_string((*vit).first) << ";\n"; } ofile << "\n"; // emit execution blocks if (cont_table.find(sym_execute)!=cont_table.end()) { emit_interpreter_content(index, sym_execute, ofile); ofile << "\n"; } if (cont_table.find(sym_condition)!=cont_table.end()) { ofile << "\tif ("; emit_interpreter_content(index, sym_condition, ofile); ofile << ") {\n"; } if (cont_table.find(sym_ctarget)!=cont_table.end()) { ofile << "\t\tSET_PC("; emit_interpreter_content(index, sym_ctarget, ofile); ofile << ");\n"; //ofile << "\t\tSET_DELAY();\n"; //delay slot } else if (cont_table.find(sym_vtarget)!=cont_table.end()) { ofile << "\t\tSET_PC("; emit_interpreter_content(index, sym_vtarget, ofile); ofile << ");\n"; //ofile << "\t\tSET_DELAY();\n"; //delay slot } if (cont_table.find(sym_condition)!=cont_table.end()) { ofile << "\t}\n"; }}void oper::emit_codegenerator_content1(unsigned index, Symbol attr, ofstream& ofile){ assert(index<count); assert(cont_table.find(attr)!=cont_table.end()); vector<class token> *tokens = cont_table[attr]; vector<class token>::iterator tit; for (tit=tokens->begin(); tit!=tokens->end(); tit++) { /* encountered a field */ if ((*tit).get_type()==token::FIELD) { /* get the name of the field */ Symbol fname = symbol_find_or_insert((*tit).get_data()); /* must exist in field table after type_check */ assert(field_table.find(fname)!=field_table.end()); /* if this is program counter */ // if (fname==sym_pc || fname==sym_inst) { // ofile << "%uU"; // } if (fname==sym_pc ) { ofile << "%s"; } else if (fname==sym_inst) { ofile << "%uU"; } else field_table[fname]->emit_codegenerator_content1 (get_field_index(fname, index), attr, ofile); } else { const char *data = (*tit).get_data(); int len = strlen(data); for (int i=0; i<len; i++) if (data[i]=='\n') ofile << "\\n\"\n\t\""; else ofile << data[i]; } }}void oper::emit_codegenerator_content2(unsigned index, unsigned rmb, Symbol attr, ofstream& ofile){ assert(index<count); assert(cont_table.find(attr)!=cont_table.end()); vector<class token> *tokens = cont_table[attr]; vector<class token>::iterator tit; for (tit=tokens->begin(); tit!=tokens->end(); tit++) { /* encountered a field */ if ((*tit).get_type()==token::FIELD) { /* get the name of the field */ Symbol fname = symbol_find_or_insert((*tit).get_data()); /* must exist in field table after type_check */ assert(field_table.find(fname)!=field_table.end()); // if (fname==sym_pc) // ofile << ", CURPC"; // else if (fname==sym_inst) // ofile << ", inst"; if (fname==sym_pc) ofile << ", \"PC\""; else if (fname==sym_inst) ofile << ", inst"; else field_table[fname]->emit_codegenerator_content2 (get_field_index(fname, index), rmb, attr, ofile); } }}void oper::emit_codegenerator_content3(unsigned index, unsigned rmb, Symbol attr, ofstream& ofile){ assert(index<count); assert(cont_table.find(attr)!=cont_table.end()); vector<class token> *tokens = cont_table[attr]; vector<class token>::iterator tit; for (tit=tokens->begin(); tit!=tokens->end(); tit++) { /* encountered a field */ if ((*tit).get_type()==token::FIELD) { /* get the name of the field */ Symbol fname = symbol_find_or_insert((*tit).get_data()); /* must exist in field table after type_check */ assert(field_table.find(fname)!=field_table.end()); // if (fname==sym_pc) // ofile << "CURPC"; // else if (fname==sym_inst) // ofile << ", inst"; if (fname==sym_pc) ofile << "CURPC"; else if (fname==sym_inst) ofile << ", inst"; else field_table[fname]->emit_codegenerator_content3 (get_field_index(fname, index), rmb, attr, ofile); } else { ofile << (*tit).get_data(); } }}void oper::emit_codegenerator(unsigned index, ofstream& ofile){// ofile << "\ttarget_inst_t inst = emu->mem->read_word_fast(curpc);\n";// ofile << "\ttarget_inst_t inst = emu->fetch_inst(curpc);\n";// ofile << "\tbuf += sprintf(buf,\"fprintf(stderr,\\\"%xX\\\\t\\\");\\n\",inst);\n";// ofile << "\tbuf += sprintf(buf,\"fprintf(stderr,\\\"%xX \\\\n\\\");\\n\",curpc);\n";// ofile << "\tbuf += sprintf(buf,\"CHECK_RETURN;\\n\");\n";// ofile << "\tbuf += sprintf(buf,\"IO_DO_CYCLE;\\n\");\n"; // emit all the vars used VAR_ENV vtable; get_used_vars(index, &vtable); VAR_ENV::iterator vit; for (vit=vtable.begin(); vit!=vtable.end(); vit++) { ofile << "\tbuf += sprintf(buf, \"\\t" << symbol_get_string((*vit).second) << " " << symbol_get_string((*vit).first) << ";\\n\");\n"; } ofile << "\n"; // emit execution blocks if (cont_table.find(sym_execute)!=cont_table.end()) { ofile << "\tbuf += sprintf(buf, \""; emit_codegenerator_content1(index, sym_execute, ofile); ofile << "\""; emit_codegenerator_content2(index, 0, sym_execute, ofile); ofile << ");\n"; } // emit conditionl execution block if (cont_table.find(sym_condition)!=cont_table.end()) { ofile << "\tbuf += sprintf(buf, \"\\tif ("; emit_codegenerator_content1(index, sym_condition, ofile); ofile << ") {\\n\""; emit_codegenerator_content2(index, 0, sym_condition, ofile); ofile << ");\n"; } if (cont_table.find(sym_ctarget)!=cont_table.end()) { // delay slot, define the macro to NULL if the processor has not ofile << "\tEMIT_DELAY_SLOT;\n"; ofile << "\ttarget_addr_t jpc = "; emit_codegenerator_content3(index, 0, sym_ctarget, ofile); ofile << ";\n"; ofile << "\tif (jpc >= size)\n"; ofile << "\t\tbuf += sprintf(buf, " "\"\\tLONG_JUMP(%uU, %uU);\\n\", " "curpc, jpc);\n"; ofile << "\telse\n"; ofile << "\t\tbuf += sprintf(buf, \"\\tJUMP(%uU, %uU, " "L%x);\\n\", " "curpc, jpc, jpc);\n"; } else if (cont_table.find(sym_vtarget)!=cont_table.end()) { assert(0); //not used for ARM // delay slot, define the macro to NULL if the processor has not ofile << "\tEMIT_DELAY_SLOT;\n"; ofile << "\tbuf += sprintf(buf, \"\\tjpc = "; emit_codegenerator_content1(index, sym_vtarget, ofile); ofile << ";\\n\""; emit_codegenerator_content2(index, 0, sym_vtarget, ofile); ofile << ");\n"; ofile << "\tbuf += sprintf(buf, " "\"\\tif (jpc<CISS_FSTART || jpc>=CISS_FEND ) {\\n\");\n"; ofile << "\tbuf += sprintf(buf, " "\"\\t\\tLONG_JUMP2(%uU, jpc);\\n\\t}\\n\", curpc);\n"; ofile << "\tbuf += sprintf(buf, " "\"\\telse\\n\");\n"; ofile << "\tbuf += sprintf(buf, " "\"\\t\\tJUMP(%uU, jpc, *labels[(jpc-CISS_FSTART)/4]);\\n\"," " curpc);\n"; } if (cont_table.find(sym_condition)!=cont_table.end()) { ofile << "\tbuf += sprintf(buf, \"\\t}\\n\");\n"; } ofile << "\treturn buf;\n";}void isa_prog::emit_interpreter_dec(ofstream& ofile){ unsigned count = grp_root->get_count(); for (unsigned ii=0; ii<count; ii++) { ofile << "void SIMIT_IMP(" << grp_root->get_qualified_name(ii) << ") (emulator_t *emu, target_inst_t inst);\n"; }}void isa_prog::emit_interpreter(ofstream& ofile){ ofile << "#include \"arch.hpp\"\n"; unsigned count = grp_root->get_count(); for (unsigned ii=0; ii<count; ii++) { ofile << "void SIMIT_IMP(" << grp_root->get_qualified_name(ii) << ") (emulator_t *emu, target_inst_t inst)\n{\n\n"; grp_root->emit_interpreter(ii, ofile); ofile << "\n}\n\n"; }}void isa_prog::emit_codegenerator(ofstream& ofile){ ofile << "#include \"arch_gen.hpp\"\n"; unsigned count = grp_root->get_count(); for (unsigned ii=0; ii<count; ii++) { ofile << "char *emitc_" << grp_root->get_qualified_name(ii) << "(char *buf, unsigned curpc, " << "target_inst_t inst, unsigned size)\n" << "{\n"; grp_root->emit_codegenerator(ii, ofile); ofile << "\n}\n\n"; }}void isa_prog::emit_codegenerator_dec(ofstream& ofile){ unsigned count = grp_root->get_count(); for (unsigned ii=0; ii<count; ii++) { ofile << "char *emitc_" << grp_root->get_qualified_name(ii) << "(char *, unsigned, target_inst_t, unsigned);\n"; }}void usage(char *cname) { fprintf(stderr, "Usage: %s [-p <prefix>] <isa file>\n", cname);}int main(int argc, char *argv[]){ char *bin_name; char *prog_name = NULL; char *prefix = NULL; /* initialize symboles */ sym_condition = symbol_find_or_insert("condition"); sym_vtarget = symbol_find_or_insert("vtarget"); sym_ctarget = symbol_find_or_insert("ctarget"); sym_execute = symbol_find_or_insert("execute"); sym_iswrite = symbol_find_or_insert("iswrite"); sym_root = symbol_find_or_insert("root"); // implicit variable sym_pc = symbol_find_or_insert("pc"); sym_inst = symbol_find_or_insert("inst"); for(int i = 1; i < argc; i++) { if (strcmp(argv[i], "-p") == 0) prefix = argv[++i]; else if (!prog_name) { prog_name = argv[i]; break; } } if ((bin_name = strrchr(argv[0], '/'))!=NULL) bin_name++; else bin_name = argv[0]; if (!prog_name) { usage(bin_name); exit(0); } if (!prefix) { prefix = prog_name; } ifstream infile; infile.open(prog_name); if (!infile.is_open()) { fprintf(stderr, "Cannot open file %s\n", argv[1]); exit(1); } isa_prog *isa = isa_parse_wrapper(&infile, argv[1]); infile.close(); if (!isa->type_check()) { fprintf(stderr, "Fix above error first\n"); } else { char *fname1 = new char[strlen(prefix)+10]; char *fname2 = new char[strlen(prefix)+10]; strcpy(fname1, prefix); strcat(fname1, "_inst.def"); ofstream decfile; decfile.open(fname1); isa->emit_decoder(decfile); decfile.close(); strcpy(fname1, prefix); strcat(fname1, "_iss.hpp"); ofstream isshdrfile; isshdrfile.open(fname1); isa->emit_interpreter_dec(isshdrfile); isshdrfile.close(); strcpy(fname2, prefix); strcat(fname2, "_iss.cpp"); ofstream issfile; issfile.open(fname2); isa->emit_interpreter(issfile); issfile.close(); strcpy(fname1, prefix); strcat(fname1, "_gen.hpp"); ofstream genhdrfile; genhdrfile.open(fname1); isa->emit_codegenerator_dec(genhdrfile); genhdrfile.close(); strcpy(fname2, prefix); strcat(fname2, "_gen.cpp"); ofstream genfile; genfile.open(fname2); isa->emit_codegenerator(genfile); genfile.close(); delete [] fname1; delete [] fname2; } delete isa;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -