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; | ... | ... |