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 | } | ... | ... |