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,12 +211,14 @@ extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
211 211
212 #ifdef __i386__ 212 #ifdef __i386__
213 #define EXIT_TB() asm volatile ("ret") 213 #define EXIT_TB() asm volatile ("ret")
  214 +#define GOTO_LABEL_PARAM(n) asm volatile ("jmp __op_gen_label" #n)
214 #endif 215 #endif
215 #ifdef __x86_64__ 216 #ifdef __x86_64__
216 #define EXIT_TB() asm volatile ("ret") 217 #define EXIT_TB() asm volatile ("ret")
217 #endif 218 #endif
218 #ifdef __powerpc__ 219 #ifdef __powerpc__
219 #define EXIT_TB() asm volatile ("blr") 220 #define EXIT_TB() asm volatile ("blr")
  221 +#define GOTO_LABEL_PARAM(n) asm volatile ("b __op_gen_label" #n)
220 #endif 222 #endif
221 #ifdef __s390__ 223 #ifdef __s390__
222 #define EXIT_TB() asm volatile ("br %r14") 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,7 +54,7 @@
54 #define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) ) 54 #define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) )
55 #undef ELF_USES_RELOCA 55 #undef ELF_USES_RELOCA
56 56
57 -#elif defined(HOST_AMD64) 57 +#elif defined(HOST_X86_64)
58 58
59 #define ELF_CLASS ELFCLASS64 59 #define ELF_CLASS ELFCLASS64
60 #define ELF_ARCH EM_X86_64 60 #define ELF_ARCH EM_X86_64
@@ -1307,7 +1307,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, @@ -1307,7 +1307,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
1307 p_start = text + offset; 1307 p_start = text + offset;
1308 p_end = p_start + size; 1308 p_end = p_start + size;
1309 start_offset = offset; 1309 start_offset = offset;
1310 -#if defined(HOST_I386) || defined(HOST_AMD64) 1310 +#if defined(HOST_I386) || defined(HOST_X86_64)
1311 #ifdef CONFIG_FORMAT_COFF 1311 #ifdef CONFIG_FORMAT_COFF
1312 { 1312 {
1313 uint8_t *p; 1313 uint8_t *p;
@@ -1482,7 +1482,8 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, @@ -1482,7 +1482,8 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
1482 sym_name = get_rel_sym_name(rel); 1482 sym_name = get_rel_sym_name(rel);
1483 if(!sym_name) 1483 if(!sym_name)
1484 continue; 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 n = strtoul(p, NULL, 10); 1487 n = strtoul(p, NULL, 10);
1487 if (n > MAX_ARGS) 1488 if (n > MAX_ARGS)
1488 error("too many arguments in %s", name); 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,7 +1526,8 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
1525 continue; 1526 continue;
1526 if (*sym_name && 1527 if (*sym_name &&
1527 !strstart(sym_name, "__op_param", NULL) && 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 #if defined(HOST_SPARC) 1531 #if defined(HOST_SPARC)
1530 if (sym_name[0] == '.') { 1532 if (sym_name[0] == '.') {
1531 fprintf(outfile, 1533 fprintf(outfile,
@@ -1604,8 +1606,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, @@ -1604,8 +1606,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
1604 } 1606 }
1605 } 1607 }
1606 #endif 1608 #endif
1607 -  
1608 - if (val >= start_offset && val < start_offset + copy_size) { 1609 + if (val >= start_offset && val <= start_offset + copy_size) {
1609 n = strtol(p, NULL, 10); 1610 n = strtol(p, NULL, 10);
1610 fprintf(outfile, " label_offsets[%d] = %ld + (gen_code_ptr - gen_code_buf);\n", n, val - start_offset); 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,6 +1643,8 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
1642 1643
1643 if (strstart(sym_name, "__op_param", &p)) { 1644 if (strstart(sym_name, "__op_param", &p)) {
1644 snprintf(name, sizeof(name), "param%s", p); 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 } else { 1648 } else {
1646 snprintf(name, sizeof(name), "(long)(&%s)", sym_name); 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,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 char name[256]; 1701 char name[256];
1699 int type; 1702 int type;
@@ -1723,7 +1726,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size, @@ -1723,7 +1726,7 @@ void gen_code(const char *name, host_ulong offset, host_ulong size,
1723 rel->r_offset - start_offset, name, rel->r_offset - start_offset, addend); 1726 rel->r_offset - start_offset, name, rel->r_offset - start_offset, addend);
1724 break; 1727 break;
1725 default: 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,7 +2235,7 @@ int gen_file(FILE *outfile, int out_type)
2232 } 2235 }
2233 } else if (out_type == OUT_GEN_OP) { 2236 } else if (out_type == OUT_GEN_OP) {
2234 /* generate gen_xxx functions */ 2237 /* generate gen_xxx functions */
2235 - 2238 + fprintf(outfile, "#include \"dyngen-op.h\"\n");
2236 for(i = 0, sym = symtab; i < nb_syms; i++, sym++) { 2239 for(i = 0, sym = symtab; i < nb_syms; i++, sym++) {
2237 const char *name; 2240 const char *name;
2238 name = get_sym_name(sym); 2241 name = get_sym_name(sym);
@@ -2250,7 +2253,7 @@ int gen_file(FILE *outfile, int out_type) @@ -2250,7 +2253,7 @@ int gen_file(FILE *outfile, int out_type)
2250 fprintf(outfile, 2253 fprintf(outfile,
2251 "int dyngen_code(uint8_t *gen_code_buf,\n" 2254 "int dyngen_code(uint8_t *gen_code_buf,\n"
2252 " uint16_t *label_offsets, uint16_t *jmp_offsets,\n" 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 "{\n" 2257 "{\n"
2255 " uint8_t *gen_code_ptr;\n" 2258 " uint8_t *gen_code_ptr;\n"
2256 " const uint16_t *opc_ptr;\n" 2259 " const uint16_t *opc_ptr;\n"
dyngen.h
@@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
19 */ 19 */
20 20
21 int __op_param1, __op_param2, __op_param3; 21 int __op_param1, __op_param2, __op_param3;
  22 +int __op_gen_label1, __op_gen_label2, __op_gen_label3;
22 int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3; 23 int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
23 24
24 #ifdef __i386__ 25 #ifdef __i386__
@@ -203,6 +204,3 @@ static uint8_t *arm_flush_ldr(uint8_t *gen_code_ptr, @@ -203,6 +204,3 @@ static uint8_t *arm_flush_ldr(uint8_t *gen_code_ptr,
203 } 204 }
204 205
205 #endif /* __arm__ */ 206 #endif /* __arm__ */
206 -  
207 -  
208 -  
translate-all.c
@@ -42,12 +42,15 @@ enum { @@ -42,12 +42,15 @@ enum {
42 42
43 uint16_t gen_opc_buf[OPC_BUF_SIZE]; 43 uint16_t gen_opc_buf[OPC_BUF_SIZE];
44 uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE]; 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 uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; 49 uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
47 #if defined(TARGET_I386) 50 #if defined(TARGET_I386)
48 uint8_t gen_opc_cc_op[OPC_BUF_SIZE]; 51 uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
49 #elif defined(TARGET_SPARC) 52 #elif defined(TARGET_SPARC)
50 -uint32_t gen_opc_npc[OPC_BUF_SIZE]; 53 +target_ulong gen_opc_npc[OPC_BUF_SIZE];
51 #endif 54 #endif
52 55
53 int code_copy_enabled = 1; 56 int code_copy_enabled = 1;
@@ -65,6 +68,12 @@ static uint8_t op_nb_args[] = { @@ -65,6 +68,12 @@ static uint8_t op_nb_args[] = {
65 #undef DEF 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 void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf) 77 void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf)
69 { 78 {
70 const uint16_t *opc_ptr; 79 const uint16_t *opc_ptr;
@@ -90,6 +99,35 @@ void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf) @@ -90,6 +99,35 @@ void dump_ops(const uint16_t *opc_buf, const uint32_t *opparam_buf)
90 99
91 #endif 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 /* return non zero if the very first instruction is invalid so that 131 /* return non zero if the very first instruction is invalid so that
94 the virtual CPU can trigger an exception. 132 the virtual CPU can trigger an exception.
95 133
@@ -121,19 +159,21 @@ int cpu_gen_code(CPUState *env, TranslationBlock *tb, @@ -121,19 +159,21 @@ int cpu_gen_code(CPUState *env, TranslationBlock *tb,
121 tb->tb_jmp_offset[2] = 0xffff; 159 tb->tb_jmp_offset[2] = 0xffff;
122 tb->tb_jmp_offset[3] = 0xffff; 160 tb->tb_jmp_offset[3] = 0xffff;
123 #endif 161 #endif
  162 + dyngen_labels(gen_labels, nb_gen_labels, gen_code_buf, gen_opc_buf);
  163 +
124 gen_code_size = dyngen_code(gen_code_buf, tb->tb_next_offset, 164 gen_code_size = dyngen_code(gen_code_buf, tb->tb_next_offset,
125 #ifdef USE_DIRECT_JUMP 165 #ifdef USE_DIRECT_JUMP
126 tb->tb_jmp_offset, 166 tb->tb_jmp_offset,
127 #else 167 #else
128 NULL, 168 NULL,
129 #endif 169 #endif
130 - gen_opc_buf, gen_opparam_buf); 170 + gen_opc_buf, gen_opparam_buf, gen_labels);
131 } 171 }
132 *gen_code_size_ptr = gen_code_size; 172 *gen_code_size_ptr = gen_code_size;
133 #ifdef DEBUG_DISAS 173 #ifdef DEBUG_DISAS
134 if (loglevel & CPU_LOG_TB_OUT_ASM) { 174 if (loglevel & CPU_LOG_TB_OUT_ASM) {
135 fprintf(logfile, "OUT: [size=%d]\n", *gen_code_size_ptr); 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 fprintf(logfile, "\n"); 177 fprintf(logfile, "\n");
138 fflush(logfile); 178 fflush(logfile);
139 } 179 }
@@ -141,12 +181,6 @@ int cpu_gen_code(CPUState *env, TranslationBlock *tb, @@ -141,12 +181,6 @@ int cpu_gen_code(CPUState *env, TranslationBlock *tb,
141 return 0; 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 /* The cpu state corresponding to 'searched_pc' is restored. 184 /* The cpu state corresponding to 'searched_pc' is restored.
151 */ 185 */
152 int cpu_restore_state(TranslationBlock *tb, 186 int cpu_restore_state(TranslationBlock *tb,
@@ -193,11 +227,12 @@ int cpu_restore_state(TranslationBlock *tb, @@ -193,11 +227,12 @@ int cpu_restore_state(TranslationBlock *tb,
193 fprintf(logfile, "RESTORE:\n"); 227 fprintf(logfile, "RESTORE:\n");
194 for(i=0;i<=j; i++) { 228 for(i=0;i<=j; i++) {
195 if (gen_opc_instr_start[i]) { 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 #endif 237 #endif
203 env->eip = gen_opc_pc[j] - tb->cs_base; 238 env->eip = gen_opc_pc[j] - tb->cs_base;