Commit c46878786af930f8f06695371ee80ffa8acf98ef

Authored by bellard
1 parent 0fa85d43

labels support in dyngen


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1196 c046a42c-6fe2-441c-8c8c-71466251a162
dyngen-exec.h
... ... @@ -211,12 +211,14 @@ extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
211 211  
212 212 #ifdef __i386__
213 213 #define EXIT_TB() asm volatile ("ret")
  214 +#define GOTO_LABEL_PARAM(n) asm volatile ("jmp __op_gen_label" #n)
214 215 #endif
215 216 #ifdef __x86_64__
216 217 #define EXIT_TB() asm volatile ("ret")
217 218 #endif
218 219 #ifdef __powerpc__
219 220 #define EXIT_TB() asm volatile ("blr")
  221 +#define GOTO_LABEL_PARAM(n) asm volatile ("b __op_gen_label" #n)
220 222 #endif
221 223 #ifdef __s390__
222 224 #define EXIT_TB() asm volatile ("br %r14")
... ...
dyngen-op.h 0 → 100644
  1 +static inline int gen_new_label(void)
  2 +{
  3 + return nb_gen_labels++;
  4 +}
  5 +
  6 +static inline void gen_set_label(int n)
  7 +{
  8 + gen_labels[n] = gen_opc_ptr - gen_opc_buf;
  9 +}
... ...
dyngen.c
... ... @@ -54,7 +54,7 @@
54 54 #define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
55 55 #undef ELF_USES_RELOCA
56 56  
57   -#elif defined(HOST_AMD64)
  57 +#elif defined(HOST_X86_64)
58 58  
59 59 #define ELF_CLASS ELFCLASS64
60 60 #define ELF_ARCH EM_X86_64
... ... @@ -1307,7 +1307,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
1307 1307 p_start = text + offset;
1308 1308 p_end = p_start + size;
1309 1309 start_offset = offset;
1310   -#if defined(HOST_I386) || defined(HOST_AMD64)
  1310 +#if defined(HOST_I386) || defined(HOST_X86_64)
1311 1311 #ifdef CONFIG_FORMAT_COFF
1312 1312 {
1313 1313 uint8_t *p;
... ... @@ -1482,7 +1482,8 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
1482 1482 sym_name = get_rel_sym_name(rel);
1483 1483 if(!sym_name)
1484 1484 continue;
1485   - if (strstart(sym_name, "__op_param", &p)) {
  1485 + if (strstart(sym_name, "__op_param", &p) ||
  1486 + strstart(sym_name, "__op_gen_label", &p)) {
1486 1487 n = strtoul(p, NULL, 10);
1487 1488 if (n > MAX_ARGS)
1488 1489 error("too many arguments in %s", name);
... ... @@ -1525,7 +1526,8 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
1525 1526 continue;
1526 1527 if (*sym_name &&
1527 1528 !strstart(sym_name, "__op_param", NULL) &&
1528   - !strstart(sym_name, "__op_jmp", NULL)) {
  1529 + !strstart(sym_name, "__op_jmp", NULL) &&
  1530 + !strstart(sym_name, "__op_gen_label", NULL)) {
1529 1531 #if defined(HOST_SPARC)
1530 1532 if (sym_name[0] == '.') {
1531 1533 fprintf(outfile,
... ... @@ -1604,8 +1606,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
1604 1606 }
1605 1607 }
1606 1608 #endif
1607   -
1608   - if (val >= start_offset && val < start_offset + copy_size) {
  1609 + if (val >= start_offset && val <= start_offset + copy_size) {
1609 1610 n = strtol(p, NULL, 10);
1610 1611 fprintf(outfile, " label_offsets[%d] = %ld + (gen_code_ptr - gen_code_buf);\n", n, val - start_offset);
1611 1612 }
... ... @@ -1642,6 +1643,8 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
1642 1643  
1643 1644 if (strstart(sym_name, "__op_param", &p)) {
1644 1645 snprintf(name, sizeof(name), "param%s", p);
  1646 + } else if (strstart(sym_name, "__op_gen_label", &p)) {
  1647 + snprintf(name, sizeof(name), "gen_labels[param%s]", p);
1645 1648 } else {
1646 1649 snprintf(name, sizeof(name), "(long)(&%s)", sym_name);
1647 1650 }
... ... @@ -1693,7 +1696,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
1693 1696 }
1694 1697 }
1695 1698 }
1696   -#elif defined(HOST_AMD64)
  1699 +#elif defined(HOST_X86_64)
1697 1700 {
1698 1701 char name[256];
1699 1702 int type;
... ... @@ -1723,7 +1726,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
1723 1726 rel->r_offset - start_offset, name, rel->r_offset - start_offset, addend);
1724 1727 break;
1725 1728 default:
1726   - error("unsupported AMD64 relocation (%d)", type);
  1729 + error("unsupported X86_64 relocation (%d)", type);
1727 1730 }
1728 1731 }
1729 1732 }
... ... @@ -2232,7 +2235,7 @@ int gen_file(FILE *outfile, int out_type)
2232 2235 }
2233 2236 } else if (out_type == OUT_GEN_OP) {
2234 2237 /* generate gen_xxx functions */
2235   -
  2238 + fprintf(outfile, "#include \"dyngen-op.h\"\n");
2236 2239 for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
2237 2240 const char *name;
2238 2241 name = get_sym_name(sym);
... ... @@ -2250,7 +2253,7 @@ int gen_file(FILE *outfile, int out_type)
2250 2253 fprintf(outfile,
2251 2254 "int dyngen_code(uint8_t *gen_code_buf,\n"
2252 2255 " uint16_t *label_offsets, uint16_t *jmp_offsets,\n"
2253   -" const uint16_t *opc_buf, const uint32_t *opparam_buf)\n"
  2256 +" const uint16_t *opc_buf, const uint32_t *opparam_buf, const long *gen_labels)\n"
2254 2257 "{\n"
2255 2258 " uint8_t *gen_code_ptr;\n"
2256 2259 " const uint16_t *opc_ptr;\n"
... ...
dyngen.h
... ... @@ -19,6 +19,7 @@
19 19 */
20 20  
21 21 int __op_param1, __op_param2, __op_param3;
  22 +int __op_gen_label1, __op_gen_label2, __op_gen_label3;
22 23 int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
23 24  
24 25 #ifdef __i386__
... ... @@ -203,6 +204,3 @@ static uint8_t *arm_flush_ldr(uint8_t *gen_code_ptr,
203 204 }
204 205  
205 206 #endif /* __arm__ */
206   -
207   -
208   -
... ...
translate-all.c
... ... @@ -42,12 +42,15 @@ enum {
42 42  
43 43 uint16_t gen_opc_buf[OPC_BUF_SIZE];
44 44 uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE];
45   -uint32_t gen_opc_pc[OPC_BUF_SIZE];
  45 +long gen_labels[OPC_BUF_SIZE];
  46 +int nb_gen_labels;
  47 +
  48 +target_ulong gen_opc_pc[OPC_BUF_SIZE];
46 49 uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
47 50 #if defined(TARGET_I386)
48 51 uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
49 52 #elif defined(TARGET_SPARC)
50   -uint32_t gen_opc_npc[OPC_BUF_SIZE];
  53 +target_ulong gen_opc_npc[OPC_BUF_SIZE];
51 54 #endif
52 55  
53 56 int code_copy_enabled = 1;
... ... @@ -65,6 +68,12 @@ static uint8_t op_nb_args[] = {
65 68 #undef DEF
66 69 };
67 70  
  71 +static const unsigned short opc_copy_size[] = {
  72 +#define DEF(s, n, copy_size) copy_size,
  73 +#include "opc.h"
  74 +#undef DEF
  75 +};
  76 +
68 77 void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf)
69 78 {
70 79 const uint16_t *opc_ptr;
... ... @@ -90,6 +99,35 @@ void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf)
90 99  
91 100 #endif
92 101  
  102 +/* compute label info */
  103 +static void dyngen_labels(long *gen_labels, int nb_gen_labels,
  104 + uint8_t *gen_code_buf, const uint16_t *opc_buf)
  105 +{
  106 + uint8_t *gen_code_ptr;
  107 + int c, i;
  108 + unsigned long gen_code_addr[OPC_BUF_SIZE];
  109 +
  110 + if (nb_gen_labels == 0)
  111 + return;
  112 + /* compute the address of each op code */
  113 +
  114 + gen_code_ptr = gen_code_buf;
  115 + i = 0;
  116 + for(;;) {
  117 + c = opc_buf[i];
  118 + gen_code_addr[i] =(unsigned long)gen_code_ptr;
  119 + if (c == INDEX_op_end)
  120 + break;
  121 + gen_code_ptr += opc_copy_size[c];
  122 + i++;
  123 + }
  124 +
  125 + /* compute the address of each label */
  126 + for(i = 0; i < nb_gen_labels; i++) {
  127 + gen_labels[i] = gen_code_addr[gen_labels[i]];
  128 + }
  129 +}
  130 +
93 131 /* return non zero if the very first instruction is invalid so that
94 132 the virtual CPU can trigger an exception.
95 133  
... ... @@ -121,19 +159,21 @@ int cpu_gen_code(CPUState *env, TranslationBlock *tb,
121 159 tb->tb_jmp_offset[2] = 0xffff;
122 160 tb->tb_jmp_offset[3] = 0xffff;
123 161 #endif
  162 + dyngen_labels(gen_labels, nb_gen_labels, gen_code_buf, gen_opc_buf);
  163 +
124 164 gen_code_size = dyngen_code(gen_code_buf, tb->tb_next_offset,
125 165 #ifdef USE_DIRECT_JUMP
126 166 tb->tb_jmp_offset,
127 167 #else
128 168 NULL,
129 169 #endif
130   - gen_opc_buf, gen_opparam_buf);
  170 + gen_opc_buf, gen_opparam_buf, gen_labels);
131 171 }
132 172 *gen_code_size_ptr = gen_code_size;
133 173 #ifdef DEBUG_DISAS
134 174 if (loglevel & CPU_LOG_TB_OUT_ASM) {
135 175 fprintf(logfile, "OUT: [size=%d]\n", *gen_code_size_ptr);
136   - disas(logfile, tb->tc_ptr, *gen_code_size_ptr, 1, 0);
  176 + disas(logfile, tb->tc_ptr, *gen_code_size_ptr);
137 177 fprintf(logfile, "\n");
138 178 fflush(logfile);
139 179 }
... ... @@ -141,12 +181,6 @@ int cpu_gen_code(CPUState *env, TranslationBlock *tb,
141 181 return 0;
142 182 }
143 183  
144   -static const unsigned short opc_copy_size[] = {
145   -#define DEF(s, n, copy_size) copy_size,
146   -#include "opc.h"
147   -#undef DEF
148   -};
149   -
150 184 /* The cpu state corresponding to 'searched_pc' is restored.
151 185 */
152 186 int cpu_restore_state(TranslationBlock *tb,
... ... @@ -193,11 +227,12 @@ int cpu_restore_state(TranslationBlock *tb,
193 227 fprintf(logfile, "RESTORE:\n");
194 228 for(i=0;i<=j; i++) {
195 229 if (gen_opc_instr_start[i]) {
196   - fprintf(logfile, "0x%04x: 0x%08x\n", i, gen_opc_pc[i]);
  230 + fprintf(logfile, "0x%04x: " TARGET_FMT_lx "\n", i, gen_opc_pc[i]);
197 231 }
198 232 }
199   - fprintf(logfile, "spc=0x%08lx j=0x%x eip=0x%x cs_base=%x\n",
200   - searched_pc, j, gen_opc_pc[j] - tb->cs_base, tb->cs_base);
  233 + fprintf(logfile, "spc=0x%08lx j=0x%x eip=" TARGET_FMT_lx " cs_base=%x\n",
  234 + searched_pc, j, gen_opc_pc[j] - tb->cs_base,
  235 + (uint32_t)tb->cs_base);
201 236 }
202 237 #endif
203 238 env->eip = gen_opc_pc[j] - tb->cs_base;
... ...