ARM init fix
[qemu] / dyngen.c
index de32756..c6c373b 100644 (file)
--- a/dyngen.c
+++ b/dyngen.c
@@ -108,8 +108,15 @@ typedef uint64_t host_ulong;
 #define SHT_RELOC SHT_REL
 #endif
 
+#define NO_THUNK_TYPE_SIZE
 #include "thunk.h"
 
+enum {
+    OUT_GEN_OP,
+    OUT_CODE,
+    OUT_INDEX_OP,
+};
+
 /* all dynamically generated functions begin with this code */
 #define OP_PREFIX "op_"
 
@@ -648,7 +655,6 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
                 sym_name = strtab + sym->st_name;
                 if (strstart(sym_name, "__op_label", &p)) {
                     uint8_t *ptr;
-                    int addend;
                     unsigned long offset;
                     
                     /* test if the variable refers to a label inside
@@ -657,7 +663,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
                     if (!ptr)
                         error("__op_labelN in invalid section");
                     offset = sym->st_value;
-                    addend = 0;
+                    val = *(target_ulong *)(ptr + offset);
 #ifdef ELF_USES_RELOCA
                     {
                         int reloc_shndx, nb_relocs1, j;
@@ -670,7 +676,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
                             rel = (ELF_RELOC *)sdata[reloc_shndx];
                             for(j = 0; j < nb_relocs1; j++) {
                                 if (rel->r_offset == offset) {
-                                    addend = rel->r_addend;
+                                   val = rel->r_addend;
                                     break;
                                 }
                                rel++;
@@ -678,8 +684,6 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
                         }
                     }
 #endif                    
-                    val = *(target_ulong *)(ptr + offset);
-                    val += addend;
 
                     if (val >= start_offset && val < start_offset + copy_size) {
                         n = strtol(p, NULL, 10);
@@ -1087,7 +1091,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,8 +1199,12 @@ 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");
+        fprintf(outfile, "DEF(nop, 0, 0)\n");
+        fprintf(outfile, "DEF(nop1, 1, 0)\n");
+        fprintf(outfile, "DEF(nop2, 2, 0)\n");
+        fprintf(outfile, "DEF(nop3, 3, 0)\n");
         for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
             const char *name, *p;
             name = strtab + sym->st_name;
@@ -1205,28 +1213,22 @@ 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 */
-#ifdef HOST_ALPHA
-fprintf(outfile,
-"register int gp asm(\"$29\");\n"
-"static inline void immediate_ldah(void *p, int val) {\n"
-"    uint32_t *dest = p;\n"
-"    long high = ((val >> 16) + ((val >> 15) & 1)) & 0xffff;\n"
-"\n"
-"    *dest &= ~0xffff;\n"
-"    *dest |= high;\n"
-"    *dest |= 31 << 16;\n"
-"}\n"
-"static inline void immediate_lda(void *dest, int val) {\n"
-"    *(uint16_t *) dest = val;\n"
-"}\n"
-"void fix_bsr(void *p, int offset) {\n"
-"    uint32_t *dest = p;\n"
-"    *dest &= ~((1 << 21) - 1);\n"
-"    *dest |= (offset >> 2) & ((1 << 21) - 1);\n"
-"}\n");
-#endif
 fprintf(outfile,
 "int dyngen_code(uint8_t *gen_code_buf,\n"
 "                uint16_t *label_offsets, uint16_t *jmp_offsets,\n"
@@ -1272,6 +1274,17 @@ fprintf(outfile,
         }
 
 fprintf(outfile,
+"        case INDEX_op_nop:\n"
+"            break;\n"
+"        case INDEX_op_nop1:\n"
+"            opparam_ptr++;\n"
+"            break;\n"
+"        case INDEX_op_nop2:\n"
+"            opparam_ptr += 2;\n"
+"            break;\n"
+"        case INDEX_op_nop3:\n"
+"            opparam_ptr += 3;\n"
+"            break;\n"
 "        default:\n"
 "            goto the_end;\n"
 "        }\n");
@@ -1325,22 +1338,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);
@@ -1353,20 +1356,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) {
@@ -1377,7 +1381,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;
         }
     }
@@ -1387,7 +1394,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;
 }