Commit d219f7e7edf7874ae1572d9c6a8e9283c6f36bbc

Authored by bellard
1 parent 95cbfc64

output gen_op_xxx() in a separate file


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@234 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 34 additions and 20 deletions
dyngen.c
@@ -110,6 +110,12 @@ typedef uint64_t host_ulong; @@ -110,6 +110,12 @@ typedef uint64_t host_ulong;
110 110
111 #include "thunk.h" 111 #include "thunk.h"
112 112
  113 +enum {
  114 + OUT_GEN_OP,
  115 + OUT_CODE,
  116 + OUT_INDEX_OP,
  117 +};
  118 +
113 /* all dynamically generated functions begin with this code */ 119 /* all dynamically generated functions begin with this code */
114 #define OP_PREFIX "op_" 120 #define OP_PREFIX "op_"
115 121
@@ -1087,7 +1093,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, @@ -1087,7 +1093,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
1087 } 1093 }
1088 1094
1089 /* load an elf object file */ 1095 /* load an elf object file */
1090 -int load_elf(const char *filename, FILE *outfile, int do_print_enum) 1096 +int load_elf(const char *filename, FILE *outfile, int out_type)
1091 { 1097 {
1092 int fd; 1098 int fd;
1093 struct elf_shdr *sec, *symtab_sec, *strtab_sec, *text_sec; 1099 struct elf_shdr *sec, *symtab_sec, *strtab_sec, *text_sec;
@@ -1195,7 +1201,7 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum) @@ -1195,7 +1201,7 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum)
1195 } 1201 }
1196 } 1202 }
1197 1203
1198 - if (do_print_enum) { 1204 + if (out_type == OUT_INDEX_OP) {
1199 fprintf(outfile, "DEF(end, 0, 0)\n"); 1205 fprintf(outfile, "DEF(end, 0, 0)\n");
1200 for(i = 0, sym = symtab; i < nb_syms; i++, sym++) { 1206 for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
1201 const char *name, *p; 1207 const char *name, *p;
@@ -1205,6 +1211,20 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum) @@ -1205,6 +1211,20 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum)
1205 text, relocs, nb_relocs, 2); 1211 text, relocs, nb_relocs, 2);
1206 } 1212 }
1207 } 1213 }
  1214 + } else if (out_type == OUT_GEN_OP) {
  1215 + /* generate gen_xxx functions */
  1216 +
  1217 + for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
  1218 + const char *name;
  1219 + name = strtab + sym->st_name;
  1220 + if (strstart(name, OP_PREFIX, NULL)) {
  1221 + if (sym->st_shndx != (text_sec - shdr))
  1222 + error("invalid section for opcode (0x%x)", sym->st_shndx);
  1223 + gen_code(name, sym->st_value, sym->st_size, outfile,
  1224 + text, relocs, nb_relocs, 0);
  1225 + }
  1226 + }
  1227 +
1208 } else { 1228 } else {
1209 /* generate big code generation switch */ 1229 /* generate big code generation switch */
1210 fprintf(outfile, 1230 fprintf(outfile,
@@ -1305,22 +1325,12 @@ fprintf(outfile, @@ -1305,22 +1325,12 @@ fprintf(outfile,
1305 default: 1325 default:
1306 error("unknown ELF architecture"); 1326 error("unknown ELF architecture");
1307 } 1327 }
1308 - 1328 + /* flush instruction cache */
  1329 + fprintf(outfile, "flush_icache_range((unsigned long)gen_code_buf, (unsigned long)gen_code_ptr);\n");
  1330 +
1309 fprintf(outfile, "return gen_code_ptr - gen_code_buf;\n"); 1331 fprintf(outfile, "return gen_code_ptr - gen_code_buf;\n");
1310 fprintf(outfile, "}\n\n"); 1332 fprintf(outfile, "}\n\n");
1311 1333
1312 -/* generate gen_xxx functions */  
1313 -/* XXX: suppress the use of these functions to simplify code */  
1314 - for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {  
1315 - const char *name;  
1316 - name = strtab + sym->st_name;  
1317 - if (strstart(name, OP_PREFIX, NULL)) {  
1318 - if (sym->st_shndx != (text_sec - shdr))  
1319 - error("invalid section for opcode (0x%x)", sym->st_shndx);  
1320 - gen_code(name, sym->st_value, sym->st_size, outfile,  
1321 - text, relocs, nb_relocs, 0);  
1322 - }  
1323 - }  
1324 } 1334 }
1325 1335
1326 close(fd); 1336 close(fd);
@@ -1333,20 +1343,21 @@ void usage(void) @@ -1333,20 +1343,21 @@ void usage(void)
1333 "usage: dyngen [-o outfile] [-c] objfile\n" 1343 "usage: dyngen [-o outfile] [-c] objfile\n"
1334 "Generate a dynamic code generator from an object file\n" 1344 "Generate a dynamic code generator from an object file\n"
1335 "-c output enum of operations\n" 1345 "-c output enum of operations\n"
  1346 + "-g output gen_op_xx() functions\n"
1336 ); 1347 );
1337 exit(1); 1348 exit(1);
1338 } 1349 }
1339 1350
1340 int main(int argc, char **argv) 1351 int main(int argc, char **argv)
1341 { 1352 {
1342 - int c, do_print_enum; 1353 + int c, out_type;
1343 const char *filename, *outfilename; 1354 const char *filename, *outfilename;
1344 FILE *outfile; 1355 FILE *outfile;
1345 1356
1346 outfilename = "out.c"; 1357 outfilename = "out.c";
1347 - do_print_enum = 0; 1358 + out_type = OUT_CODE;
1348 for(;;) { 1359 for(;;) {
1349 - c = getopt(argc, argv, "ho:c"); 1360 + c = getopt(argc, argv, "ho:cg");
1350 if (c == -1) 1361 if (c == -1)
1351 break; 1362 break;
1352 switch(c) { 1363 switch(c) {
@@ -1357,7 +1368,10 @@ int main(int argc, char **argv) @@ -1357,7 +1368,10 @@ int main(int argc, char **argv)
1357 outfilename = optarg; 1368 outfilename = optarg;
1358 break; 1369 break;
1359 case 'c': 1370 case 'c':
1360 - do_print_enum = 1; 1371 + out_type = OUT_INDEX_OP;
  1372 + break;
  1373 + case 'g':
  1374 + out_type = OUT_GEN_OP;
1361 break; 1375 break;
1362 } 1376 }
1363 } 1377 }
@@ -1367,7 +1381,7 @@ int main(int argc, char **argv) @@ -1367,7 +1381,7 @@ int main(int argc, char **argv)
1367 outfile = fopen(outfilename, "w"); 1381 outfile = fopen(outfilename, "w");
1368 if (!outfile) 1382 if (!outfile)
1369 error("could not open '%s'", outfilename); 1383 error("could not open '%s'", outfilename);
1370 - load_elf(filename, outfile, do_print_enum); 1384 + load_elf(filename, outfile, out_type);
1371 fclose(outfile); 1385 fclose(outfile);
1372 return 0; 1386 return 0;
1373 } 1387 }