]> Git Repo - qemu.git/blobdiff - dyngen.c
target-mips: gen_compute_branch1()
[qemu.git] / dyngen.c
index f3b9638982cc9edf63562fca0d29ce133c820089..68f23ad37663a6b2dd75652fcec9ca6919c68f8e 100644 (file)
--- a/dyngen.c
+++ b/dyngen.c
 #define elf_check_arch(x) ((x) == EM_PPC)
 #define ELF_USES_RELOCA
 
+#elif defined(HOST_PPC64)
+
+#define ELF_CLASS      ELFCLASS64
+#define ELF_ARCH       EM_PPC64
+#define elf_check_arch(x) ((x) == EM_PPC64)
+#define ELF_USES_RELOCA
+
 #elif defined(HOST_S390)
 
 #define ELF_CLASS      ELFCLASS32
@@ -265,7 +272,7 @@ static void *load_data(int fd, long offset, unsigned int size)
     return data;
 }
 
-int strstart(const char *str, const char *val, const char **ptr)
+static int strstart(const char *str, const char *val, const char **ptr)
 {
     const char *p, *q;
     p = str;
@@ -281,7 +288,7 @@ int strstart(const char *str, const char *val, const char **ptr)
     return 1;
 }
 
-void pstrcpy(char *buf, int buf_size, const char *str)
+static void pstrcpy(char *buf, int buf_size, const char *str)
 {
     int c;
     char *q = buf;
@@ -298,32 +305,32 @@ void pstrcpy(char *buf, int buf_size, const char *str)
     *q = '\0';
 }
 
-void swab16s(uint16_t *p)
+static void swab16s(uint16_t *p)
 {
     *p = bswap16(*p);
 }
 
-void swab32s(uint32_t *p)
+static void swab32s(uint32_t *p)
 {
     *p = bswap32(*p);
 }
 
-void swab32ss(int32_t *p)
+static void swab32ss(int32_t *p)
 {
     *p = bswap32(*p);
 }
 
-void swab64s(uint64_t *p)
+static void swab64s(uint64_t *p)
 {
     *p = bswap64(*p);
 }
 
-void swab64ss(int64_t *p)
+static void swab64ss(int64_t *p)
 {
     *p = bswap64(*p);
 }
 
-uint16_t get16(uint16_t *p)
+static uint16_t get16(uint16_t *p)
 {
     uint16_t val;
     val = *p;
@@ -332,7 +339,7 @@ uint16_t get16(uint16_t *p)
     return val;
 }
 
-uint32_t get32(uint32_t *p)
+static uint32_t get32(uint32_t *p)
 {
     uint32_t val;
     val = *p;
@@ -341,14 +348,14 @@ uint32_t get32(uint32_t *p)
     return val;
 }
 
-void put16(uint16_t *p, uint16_t val)
+static void put16(uint16_t *p, uint16_t val)
 {
     if (do_swap)
         val = bswap16(val);
     *p = val;
 }
 
-void put32(uint32_t *p, uint32_t val)
+static void put32(uint32_t *p, uint32_t val)
 {
     if (do_swap)
         val = bswap32(val);
@@ -371,7 +378,7 @@ uint8_t **sdata;
 struct elfhdr ehdr;
 char *strtab;
 
-int elf_must_swap(struct elfhdr *h)
+static int elf_must_swap(struct elfhdr *h)
 {
   union {
       uint32_t i;
@@ -383,7 +390,7 @@ int elf_must_swap(struct elfhdr *h)
       (swaptest.b[0] == 0);
 }
 
-void elf_swap_ehdr(struct elfhdr *h)
+static void elf_swap_ehdr(struct elfhdr *h)
 {
     swab16s(&h->e_type);                       /* Object file type */
     swab16s(&h->       e_machine);             /* Architecture */
@@ -400,7 +407,7 @@ void elf_swap_ehdr(struct elfhdr *h)
     swab16s(&h->       e_shstrndx);            /* Section header string table index */
 }
 
-void elf_swap_shdr(struct elf_shdr *h)
+static void elf_swap_shdr(struct elf_shdr *h)
 {
   swab32s(&h-> sh_name);               /* Section name (string tbl index) */
   swab32s(&h-> sh_type);               /* Section type */
@@ -414,7 +421,7 @@ void elf_swap_shdr(struct elf_shdr *h)
   swabls(&h->  sh_entsize);            /* Entry size if section holds table */
 }
 
-void elf_swap_phdr(struct elf_phdr *h)
+static void elf_swap_phdr(struct elf_phdr *h)
 {
     swab32s(&h->p_type);                       /* Segment type */
     swabls(&h->p_offset);              /* Segment file offset */
@@ -426,7 +433,7 @@ void elf_swap_phdr(struct elf_phdr *h)
     swabls(&h->p_align);               /* Segment alignment */
 }
 
-void elf_swap_rel(ELF_RELOC *rel)
+static void elf_swap_rel(ELF_RELOC *rel)
 {
     swabls(&rel->r_offset);
     swabls(&rel->r_info);
@@ -435,8 +442,8 @@ void elf_swap_rel(ELF_RELOC *rel)
 #endif
 }
 
-struct elf_shdr *find_elf_section(struct elf_shdr *shdr, int shnum, const char *shstr,
-                                  const char *name)
+static struct elf_shdr *find_elf_section(struct elf_shdr *shdr, int shnum,
+                                         const char *shstr, const char *name)
 {
     int i;
     const char *shname;
@@ -453,7 +460,7 @@ struct elf_shdr *find_elf_section(struct elf_shdr *shdr, int shnum, const char *
     return NULL;
 }
 
-int find_reloc(int sh_index)
+static int find_reloc(int sh_index)
 {
     struct elf_shdr *sec;
     int i;
@@ -482,7 +489,7 @@ static char *get_sym_name(EXE_SYM *sym)
 }
 
 /* load an elf object file */
-int load_object(const char *filename)
+static int load_object(const char *filename)
 {
     int fd;
     struct elf_shdr *sec, *symtab_sec, *strtab_sec, *text_sec;
@@ -1220,7 +1227,7 @@ int load_object(const char *filename)
 #endif /* CONFIG_FORMAT_MACH */
 
 /* return true if the expression is a label reference */
-int get_reloc_expr(char *name, int name_size, const char *sym_name)
+static int get_reloc_expr(char *name, int name_size, const char *sym_name)
 {
     const char *p;
 
@@ -1287,8 +1294,8 @@ get_plt_index (const char *name, unsigned long addend)
 #define MAX_ARGS 3
 
 /* generate op code */
-void gen_code(const char *name, host_ulong offset, host_ulong size,
-              FILE *outfile, int gen_switch)
+static void gen_code(const char *name, host_ulong offset, host_ulong size,
+                     FILE *outfile, int gen_switch)
 {
     int copy_size = 0;
     uint8_t *p_start, *p_end;
@@ -1551,6 +1558,8 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
     }
 #elif defined(HOST_ARM)
     error("dyngen targets not supported on ARM");
+#elif defined(HOST_PPC64)
+    error("dyngen targets not supported on PPC64");
 #else
 #error unsupported CPU
 #endif
@@ -1910,10 +1919,11 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
                 char relname[256];
                 int type;
                 int addend;
+                int is_label;
                 int reloc_offset;
                 for(i = 0, rel = relocs;i < nb_relocs; i++, rel++) {
                     if (rel->r_offset >= start_offset &&
-                       rel->r_offset < start_offset + copy_size) {
+                        rel->r_offset < start_offset + copy_size) {
                         sym_name = strtab + symtab[ELFW(R_SYM)(rel->r_info)].st_name;
                         reloc_offset = rel->r_offset - start_offset;
                         if (strstart(sym_name, "__op_jmp", &p)) {
@@ -1930,31 +1940,52 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
 
                         get_reloc_expr(relname, sizeof(relname), sym_name);
                         type = ELF32_R_TYPE(rel->r_info);
+                        is_label = get_reloc_expr(relname, sizeof(relname), sym_name);
                         addend = rel->r_addend;
-                        switch(type) {
-                        case R_PPC_ADDR32:
-                            fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
-                                    reloc_offset, relname, addend);
-                            break;
-                        case R_PPC_ADDR16_LO:
-                            fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d);\n",
-                                    reloc_offset, relname, addend);
-                            break;
-                        case R_PPC_ADDR16_HI:
-                            fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d) >> 16;\n",
-                                    reloc_offset, relname, addend);
-                            break;
-                        case R_PPC_ADDR16_HA:
-                            fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d + 0x8000) >> 16;\n",
-                                    reloc_offset, relname, addend);
-                            break;
-                        case R_PPC_REL24:
-                            /* warning: must be at 32 MB distancy */
-                            fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %d) + %d) & 0x03fffffc);\n",
-                                    reloc_offset, reloc_offset, relname, reloc_offset, addend);
-                            break;
-                        default:
-                            error("unsupported powerpc relocation (%d)", type);
+                        if (is_label) {
+                            switch (type) {
+                            case R_PPC_REL24:
+                                fprintf (outfile, "    tcg_out_reloc(s, gen_code_ptr + %d, %d, %s, %d);\n",
+                                         reloc_offset, type, relname, addend);
+                                break;
+                            default:
+                                error ("unsupported ppc relocation (%d)", type);
+                            }
+                        }
+                        else {
+                            switch(type) {
+                            case R_PPC_ADDR32:
+                                fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = %s + %d;\n",
+                                        reloc_offset, relname, addend);
+                                break;
+                            case R_PPC_ADDR16_LO:
+                                fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d);\n",
+                                        reloc_offset, relname, addend);
+                                break;
+                            case R_PPC_ADDR16_HI:
+                                fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d) >> 16;\n",
+                                        reloc_offset, relname, addend);
+                                break;
+                            case R_PPC_ADDR16_HA:
+                                fprintf(outfile, "    *(uint16_t *)(gen_code_ptr + %d) = (%s + %d + 0x8000) >> 16;\n",
+                                        reloc_offset, relname, addend);
+                                break;
+                            case R_PPC_REL24:
+                                /* warning: must be at 32 MB distancy */
+                                fprintf(outfile, "{\n"
+                                        "    long disp = (%s - (long)(gen_code_ptr + %d) + %d);\n"
+                                        "    if ((disp << 6) >> 6 != disp) {;\n"
+                                        "        fprintf(stderr, \"Branch target is too far away\\n\");"
+                                        "        abort();\n"
+                                        "    }\n"
+                                        "}\n",
+                                        relname, reloc_offset, addend);
+                                fprintf(outfile, "    *(uint32_t *)(gen_code_ptr + %d) = (*(uint32_t *)(gen_code_ptr + %d) & ~0x03fffffc) | ((%s - (long)(gen_code_ptr + %d) + %d) & 0x03fffffc);\n",
+                                        reloc_offset, reloc_offset, relname, reloc_offset, addend);
+                                break;
+                            default:
+                                error("unsupported powerpc relocation (%d)", type);
+                            }
                         }
                     }
                 }
@@ -2570,6 +2601,8 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
             }
 #elif defined(HOST_ARM)
     error("dyngen targets not supported on ARM");
+#elif defined(HOST_PPC64)
+    error("dyngen targets not supported on PPC64");
 #else
 #error unsupported CPU
 #endif
@@ -2597,7 +2630,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
     }
 }
 
-int gen_file(FILE *outfile, int out_type)
+static int gen_file(FILE *outfile, int out_type)
 {
     int i;
     EXE_SYM *sym;
@@ -2709,7 +2742,7 @@ int gen_file(FILE *outfile, int out_type)
     return 0;
 }
 
-void usage(void)
+static void usage(void)
 {
     printf("dyngen (c) 2003 Fabrice Bellard\n"
            "usage: dyngen [-o outfile] [-c] objfile\n"
This page took 0.033785 seconds and 4 git commands to generate.