summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2003-06-15 19:44:49 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2003-06-15 19:44:49 +0000
commitd219f7e7edf7874ae1572d9c6a8e9283c6f36bbc (patch)
tree0f3a9a95466272a5e71b3d491866b2a111155c86
parent95cbfc643dd8e0c4dd3690fbbbbc20f2a8af5998 (diff)
downloadqemu-d219f7e7edf7874ae1572d9c6a8e9283c6f36bbc.tar.gz
qemu-d219f7e7edf7874ae1572d9c6a8e9283c6f36bbc.tar.bz2
qemu-d219f7e7edf7874ae1572d9c6a8e9283c6f36bbc.zip
output gen_op_xxx() in a separate file
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@234 c046a42c-6fe2-441c-8c8c-71466251a162
-rw-r--r--dyngen.c54
1 files changed, 34 insertions, 20 deletions
diff --git a/dyngen.c b/dyngen.c
index c2f9d120ed..be790d7056 100644
--- a/dyngen.c
+++ b/dyngen.c
@@ -110,6 +110,12 @@ typedef uint64_t host_ulong;
#include "thunk.h"
+enum {
+ OUT_GEN_OP,
+ OUT_CODE,
+ OUT_INDEX_OP,
+};
+
/* all dynamically generated functions begin with this code */
#define OP_PREFIX "op_"
@@ -1087,7 +1093,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
}
/* load an elf object file */
-int load_elf(const char *filename, FILE *outfile, int do_print_enum)
+int load_elf(const char *filename, FILE *outfile, int out_type)
{
int fd;
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)
}
}
- if (do_print_enum) {
+ if (out_type == OUT_INDEX_OP) {
fprintf(outfile, "DEF(end, 0, 0)\n");
for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
const char *name, *p;
@@ -1205,6 +1211,20 @@ int load_elf(const char *filename, FILE *outfile, int do_print_enum)
text, relocs, nb_relocs, 2);
}
}
+ } else if (out_type == OUT_GEN_OP) {
+ /* generate gen_xxx functions */
+
+ for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
+ const char *name;
+ name = strtab + sym->st_name;
+ if (strstart(name, OP_PREFIX, NULL)) {
+ if (sym->st_shndx != (text_sec - shdr))
+ error("invalid section for opcode (0x%x)", sym->st_shndx);
+ gen_code(name, sym->st_value, sym->st_size, outfile,
+ text, relocs, nb_relocs, 0);
+ }
+ }
+
} else {
/* generate big code generation switch */
fprintf(outfile,
@@ -1305,22 +1325,12 @@ fprintf(outfile,
default:
error("unknown ELF architecture");
}
-
+ /* flush instruction cache */
+ fprintf(outfile, "flush_icache_range((unsigned long)gen_code_buf, (unsigned long)gen_code_ptr);\n");
+
fprintf(outfile, "return gen_code_ptr - gen_code_buf;\n");
fprintf(outfile, "}\n\n");
-/* generate gen_xxx functions */
-/* XXX: suppress the use of these functions to simplify code */
- for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
- const char *name;
- name = strtab + sym->st_name;
- if (strstart(name, OP_PREFIX, NULL)) {
- if (sym->st_shndx != (text_sec - shdr))
- error("invalid section for opcode (0x%x)", sym->st_shndx);
- gen_code(name, sym->st_value, sym->st_size, outfile,
- text, relocs, nb_relocs, 0);
- }
- }
}
close(fd);
@@ -1333,20 +1343,21 @@ void usage(void)
"usage: dyngen [-o outfile] [-c] objfile\n"
"Generate a dynamic code generator from an object file\n"
"-c output enum of operations\n"
+ "-g output gen_op_xx() functions\n"
);
exit(1);
}
int main(int argc, char **argv)
{
- int c, do_print_enum;
+ int c, out_type;
const char *filename, *outfilename;
FILE *outfile;
outfilename = "out.c";
- do_print_enum = 0;
+ out_type = OUT_CODE;
for(;;) {
- c = getopt(argc, argv, "ho:c");
+ c = getopt(argc, argv, "ho:cg");
if (c == -1)
break;
switch(c) {
@@ -1357,7 +1368,10 @@ int main(int argc, char **argv)
outfilename = optarg;
break;
case 'c':
- do_print_enum = 1;
+ out_type = OUT_INDEX_OP;
+ break;
+ case 'g':
+ out_type = OUT_GEN_OP;
break;
}
}
@@ -1367,7 +1381,7 @@ int main(int argc, char **argv)
outfile = fopen(outfilename, "w");
if (!outfile)
error("could not open '%s'", outfilename);
- load_elf(filename, outfile, do_print_enum);
+ load_elf(filename, outfile, out_type);
fclose(outfile);
return 0;
}