Commit d219f7e7edf7874ae1572d9c6a8e9283c6f36bbc
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 | 110 | |
| 111 | 111 | #include "thunk.h" |
| 112 | 112 | |
| 113 | +enum { | |
| 114 | + OUT_GEN_OP, | |
| 115 | + OUT_CODE, | |
| 116 | + OUT_INDEX_OP, | |
| 117 | +}; | |
| 118 | + | |
| 113 | 119 | /* all dynamically generated functions begin with this code */ |
| 114 | 120 | #define OP_PREFIX "op_" |
| 115 | 121 | |
| ... | ... | @@ -1087,7 +1093,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, |
| 1087 | 1093 | } |
| 1088 | 1094 | |
| 1089 | 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 | 1098 | int fd; |
| 1093 | 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 | 1201 | } |
| 1196 | 1202 | } |
| 1197 | 1203 | |
| 1198 | - if (do_print_enum) { | |
| 1204 | + if (out_type == OUT_INDEX_OP) { | |
| 1199 | 1205 | fprintf(outfile, "DEF(end, 0, 0)\n"); |
| 1200 | 1206 | for(i = 0, sym = symtab; i < nb_syms; i++, sym++) { |
| 1201 | 1207 | const char *name, *p; |
| ... | ... | @@ -1205,6 +1211,20 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum) |
| 1205 | 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 | 1228 | } else { |
| 1209 | 1229 | /* generate big code generation switch */ |
| 1210 | 1230 | fprintf(outfile, |
| ... | ... | @@ -1305,22 +1325,12 @@ fprintf(outfile, |
| 1305 | 1325 | default: |
| 1306 | 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 | 1331 | fprintf(outfile, "return gen_code_ptr - gen_code_buf;\n"); |
| 1310 | 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 | 1336 | close(fd); |
| ... | ... | @@ -1333,20 +1343,21 @@ void usage(void) |
| 1333 | 1343 | "usage: dyngen [-o outfile] [-c] objfile\n" |
| 1334 | 1344 | "Generate a dynamic code generator from an object file\n" |
| 1335 | 1345 | "-c output enum of operations\n" |
| 1346 | + "-g output gen_op_xx() functions\n" | |
| 1336 | 1347 | ); |
| 1337 | 1348 | exit(1); |
| 1338 | 1349 | } |
| 1339 | 1350 | |
| 1340 | 1351 | int main(int argc, char **argv) |
| 1341 | 1352 | { |
| 1342 | - int c, do_print_enum; | |
| 1353 | + int c, out_type; | |
| 1343 | 1354 | const char *filename, *outfilename; |
| 1344 | 1355 | FILE *outfile; |
| 1345 | 1356 | |
| 1346 | 1357 | outfilename = "out.c"; |
| 1347 | - do_print_enum = 0; | |
| 1358 | + out_type = OUT_CODE; | |
| 1348 | 1359 | for(;;) { |
| 1349 | - c = getopt(argc, argv, "ho:c"); | |
| 1360 | + c = getopt(argc, argv, "ho:cg"); | |
| 1350 | 1361 | if (c == -1) |
| 1351 | 1362 | break; |
| 1352 | 1363 | switch(c) { |
| ... | ... | @@ -1357,7 +1368,10 @@ int main(int argc, char **argv) |
| 1357 | 1368 | outfilename = optarg; |
| 1358 | 1369 | break; |
| 1359 | 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 | 1375 | break; |
| 1362 | 1376 | } |
| 1363 | 1377 | } |
| ... | ... | @@ -1367,7 +1381,7 @@ int main(int argc, char **argv) |
| 1367 | 1381 | outfile = fopen(outfilename, "w"); |
| 1368 | 1382 | if (!outfile) |
| 1369 | 1383 | error("could not open '%s'", outfilename); |
| 1370 | - load_elf(filename, outfile, do_print_enum); | |
| 1384 | + load_elf(filename, outfile, out_type); | |
| 1371 | 1385 | fclose(outfile); |
| 1372 | 1386 | return 0; |
| 1373 | 1387 | } | ... | ... |