Commit 1017ebe9cb38ae034b0e7c6c449abe2c9b5284fb
1 parent
77f8dd5a
convert several x86 instructions at the same time
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@24 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
53 additions
and
42 deletions
Makefile
... | ... | @@ -86,7 +86,7 @@ i386.ld ppc.ld\ |
86 | 86 | tests/Makefile\ |
87 | 87 | tests/test-i386.c tests/test-i386-shift.h tests/test-i386.h\ |
88 | 88 | tests/test-i386-muldiv.h\ |
89 | -tests/test2.c tests/hello.c tests/sha1.c tests/test1.c | |
89 | +tests/test2.c tests/hello.c tests/sha1.c | |
90 | 90 | |
91 | 91 | FILE=gemu-$(VERSION) |
92 | 92 | ... | ... |
cpu-i386.h
... | ... | @@ -242,7 +242,7 @@ int cpu_x86_exec(CPUX86State *s); |
242 | 242 | void cpu_x86_close(CPUX86State *s); |
243 | 243 | |
244 | 244 | /* internal functions */ |
245 | -int cpu_x86_gen_code(uint8_t *gen_code_buf, int *gen_code_size_ptr, | |
246 | - uint8_t *pc_start); | |
245 | +int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, | |
246 | + int *gen_code_size_ptr, uint8_t *pc_start); | |
247 | 247 | |
248 | 248 | #endif /* CPU_I386_H */ | ... | ... |
op-i386.c
... | ... | @@ -1959,7 +1959,8 @@ int cpu_x86_exec(CPUX86State *env1) |
1959 | 1959 | #endif |
1960 | 1960 | } |
1961 | 1961 | #endif |
1962 | - cpu_x86_gen_code(code_gen_buffer, &code_gen_size, (uint8_t *)env->pc); | |
1962 | + cpu_x86_gen_code(code_gen_buffer, sizeof(code_gen_buffer), | |
1963 | + &code_gen_size, (uint8_t *)env->pc); | |
1963 | 1964 | /* execute the generated code */ |
1964 | 1965 | gen_func = (void *)code_gen_buffer; |
1965 | 1966 | gen_func(); | ... | ... |
translate-i386.c
... | ... | @@ -995,7 +995,7 @@ static void gen_jcc(DisasContext *s, int b, int val) |
995 | 995 | default: |
996 | 996 | slow_jcc: |
997 | 997 | if (s->cc_op != CC_OP_DYNAMIC) |
998 | - op_set_cc_op(s->cc_op); | |
998 | + gen_op_set_cc_op(s->cc_op); | |
999 | 999 | func = gen_jcc_slow[jcc_op]; |
1000 | 1000 | break; |
1001 | 1001 | } |
... | ... | @@ -1041,10 +1041,10 @@ static void gen_setcc(DisasContext *s, int b) |
1041 | 1041 | case CC_OP_SHLL: |
1042 | 1042 | switch(jcc_op) { |
1043 | 1043 | case JCC_Z: |
1044 | - func = gen_setcc_sub[s->cc_op - CC_OP_ADDB][jcc_op]; | |
1044 | + func = gen_setcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op]; | |
1045 | 1045 | break; |
1046 | 1046 | case JCC_S: |
1047 | - func = gen_setcc_sub[s->cc_op - CC_OP_ADDB][jcc_op]; | |
1047 | + func = gen_setcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op]; | |
1048 | 1048 | break; |
1049 | 1049 | default: |
1050 | 1050 | goto slow_jcc; |
... | ... | @@ -1053,7 +1053,7 @@ static void gen_setcc(DisasContext *s, int b) |
1053 | 1053 | default: |
1054 | 1054 | slow_jcc: |
1055 | 1055 | if (s->cc_op != CC_OP_DYNAMIC) |
1056 | - op_set_cc_op(s->cc_op); | |
1056 | + gen_op_set_cc_op(s->cc_op); | |
1057 | 1057 | func = gen_setcc_slow[jcc_op]; |
1058 | 1058 | break; |
1059 | 1059 | } |
... | ... | @@ -1891,7 +1891,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start, int *is_jmp_ptr) |
1891 | 1891 | break; |
1892 | 1892 | case 0x3c: /* fbld */ |
1893 | 1893 | gen_op_fpush(); |
1894 | - op_fbld_ST0_A0(); | |
1894 | + gen_op_fbld_ST0_A0(); | |
1895 | 1895 | break; |
1896 | 1896 | case 0x3e: /* fbstp */ |
1897 | 1897 | gen_op_fbst_ST0_A0(); |
... | ... | @@ -2338,6 +2338,8 @@ long disas_insn(DisasContext *s, uint8_t *pc_start, int *is_jmp_ptr) |
2338 | 2338 | /************************/ |
2339 | 2339 | /* flags */ |
2340 | 2340 | case 0x9c: /* pushf */ |
2341 | + if (s->cc_op != CC_OP_DYNAMIC) | |
2342 | + gen_op_set_cc_op(s->cc_op); | |
2341 | 2343 | gen_op_movl_T0_eflags(); |
2342 | 2344 | gen_op_pushl_T0(); |
2343 | 2345 | break; |
... | ... | @@ -2349,31 +2351,31 @@ long disas_insn(DisasContext *s, uint8_t *pc_start, int *is_jmp_ptr) |
2349 | 2351 | case 0x9e: /* sahf */ |
2350 | 2352 | gen_op_mov_TN_reg[OT_BYTE][0][R_AH](); |
2351 | 2353 | if (s->cc_op != CC_OP_DYNAMIC) |
2352 | - op_set_cc_op(s->cc_op); | |
2354 | + gen_op_set_cc_op(s->cc_op); | |
2353 | 2355 | gen_op_movb_eflags_T0(); |
2354 | 2356 | s->cc_op = CC_OP_EFLAGS; |
2355 | 2357 | break; |
2356 | 2358 | case 0x9f: /* lahf */ |
2357 | 2359 | if (s->cc_op != CC_OP_DYNAMIC) |
2358 | - op_set_cc_op(s->cc_op); | |
2360 | + gen_op_set_cc_op(s->cc_op); | |
2359 | 2361 | gen_op_movl_T0_eflags(); |
2360 | 2362 | gen_op_mov_reg_T0[OT_BYTE][R_AH](); |
2361 | 2363 | break; |
2362 | 2364 | case 0xf5: /* cmc */ |
2363 | 2365 | if (s->cc_op != CC_OP_DYNAMIC) |
2364 | - op_set_cc_op(s->cc_op); | |
2366 | + gen_op_set_cc_op(s->cc_op); | |
2365 | 2367 | gen_op_cmc(); |
2366 | 2368 | s->cc_op = CC_OP_EFLAGS; |
2367 | 2369 | break; |
2368 | 2370 | case 0xf8: /* clc */ |
2369 | 2371 | if (s->cc_op != CC_OP_DYNAMIC) |
2370 | - op_set_cc_op(s->cc_op); | |
2372 | + gen_op_set_cc_op(s->cc_op); | |
2371 | 2373 | gen_op_clc(); |
2372 | 2374 | s->cc_op = CC_OP_EFLAGS; |
2373 | 2375 | break; |
2374 | 2376 | case 0xf9: /* stc */ |
2375 | 2377 | if (s->cc_op != CC_OP_DYNAMIC) |
2376 | - op_set_cc_op(s->cc_op); | |
2378 | + gen_op_set_cc_op(s->cc_op); | |
2377 | 2379 | gen_op_stc(); |
2378 | 2380 | s->cc_op = CC_OP_EFLAGS; |
2379 | 2381 | break; |
... | ... | @@ -2503,10 +2505,11 @@ long disas_insn(DisasContext *s, uint8_t *pc_start, int *is_jmp_ptr) |
2503 | 2505 | } |
2504 | 2506 | |
2505 | 2507 | /* return the next pc */ |
2506 | -int cpu_x86_gen_code(uint8_t *gen_code_buf, int *gen_code_size_ptr, | |
2507 | - uint8_t *pc_start) | |
2508 | +int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, | |
2509 | + int *gen_code_size_ptr, uint8_t *pc_start) | |
2508 | 2510 | { |
2509 | 2511 | DisasContext dc1, *dc = &dc1; |
2512 | + uint8_t *gen_code_end, *pc_ptr; | |
2510 | 2513 | int is_jmp; |
2511 | 2514 | long ret; |
2512 | 2515 | #ifdef DEBUG_DISAS |
... | ... | @@ -2515,35 +2518,18 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int *gen_code_size_ptr, |
2515 | 2518 | |
2516 | 2519 | dc->cc_op = CC_OP_DYNAMIC; |
2517 | 2520 | gen_code_ptr = gen_code_buf; |
2521 | + gen_code_end = gen_code_buf + max_code_size - 4096; | |
2518 | 2522 | gen_start(); |
2519 | 2523 | |
2520 | -#ifdef DEBUG_DISAS | |
2521 | - if (loglevel) { | |
2522 | - INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf); | |
2523 | - disasm_info.buffer = pc_start; | |
2524 | - disasm_info.buffer_vma = (unsigned long)pc_start; | |
2525 | - disasm_info.buffer_length = 15; | |
2526 | -#if 0 | |
2527 | - disasm_info.flavour = bfd_get_flavour (abfd); | |
2528 | - disasm_info.arch = bfd_get_arch (abfd); | |
2529 | - disasm_info.mach = bfd_get_mach (abfd); | |
2530 | -#endif | |
2531 | -#ifdef WORDS_BIGENDIAN | |
2532 | - disasm_info.endian = BFD_ENDIAN_BIG; | |
2533 | -#else | |
2534 | - disasm_info.endian = BFD_ENDIAN_LITTLE; | |
2535 | -#endif | |
2536 | - fprintf(logfile, "IN:\n"); | |
2537 | - fprintf(logfile, "0x%08lx: ", (long)pc_start); | |
2538 | - print_insn_i386((unsigned long)pc_start, &disasm_info); | |
2539 | - fprintf(logfile, "\n\n"); | |
2540 | - } | |
2541 | -#endif | |
2542 | 2524 | is_jmp = 0; |
2543 | - ret = disas_insn(dc, pc_start, &is_jmp); | |
2544 | - if (ret == -1) | |
2545 | - error("unknown instruction at PC=0x%x B=%02x %02x", | |
2546 | - pc_start, pc_start[0], pc_start[1]); | |
2525 | + pc_ptr = pc_start; | |
2526 | + do { | |
2527 | + ret = disas_insn(dc, pc_ptr, &is_jmp); | |
2528 | + if (ret == -1) | |
2529 | + error("unknown instruction at PC=0x%x B=%02x %02x", | |
2530 | + pc_ptr, pc_ptr[0], pc_ptr[1]); | |
2531 | + pc_ptr = (void *)ret; | |
2532 | + } while (!is_jmp && gen_code_ptr < gen_code_end); | |
2547 | 2533 | /* we must store the eflags state if it is not already done */ |
2548 | 2534 | if (dc->cc_op != CC_OP_DYNAMIC) |
2549 | 2535 | gen_op_set_cc_op(dc->cc_op); |
... | ... | @@ -2559,6 +2545,30 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int *gen_code_size_ptr, |
2559 | 2545 | uint8_t *pc; |
2560 | 2546 | int count; |
2561 | 2547 | |
2548 | + INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf); | |
2549 | +#if 0 | |
2550 | + disasm_info.flavour = bfd_get_flavour (abfd); | |
2551 | + disasm_info.arch = bfd_get_arch (abfd); | |
2552 | + disasm_info.mach = bfd_get_mach (abfd); | |
2553 | +#endif | |
2554 | +#ifdef WORDS_BIGENDIAN | |
2555 | + disasm_info.endian = BFD_ENDIAN_BIG; | |
2556 | +#else | |
2557 | + disasm_info.endian = BFD_ENDIAN_LITTLE; | |
2558 | +#endif | |
2559 | + fprintf(logfile, "IN:\n"); | |
2560 | + disasm_info.buffer = pc_start; | |
2561 | + disasm_info.buffer_vma = (unsigned long)pc_start; | |
2562 | + disasm_info.buffer_length = pc_ptr - pc_start; | |
2563 | + pc = pc_start; | |
2564 | + while (pc < pc_ptr) { | |
2565 | + fprintf(logfile, "0x%08lx: ", (long)pc); | |
2566 | + count = print_insn_i386((unsigned long)pc, &disasm_info); | |
2567 | + fprintf(logfile, "\n"); | |
2568 | + pc += count; | |
2569 | + } | |
2570 | + fprintf(logfile, "\n"); | |
2571 | + | |
2562 | 2572 | pc = gen_code_buf; |
2563 | 2573 | disasm_info.buffer = pc; |
2564 | 2574 | disasm_info.buffer_vma = (unsigned long)pc; | ... | ... |