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