convert several x86 instructions at the same time

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@24 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
bellard 2003-03-05 23:26:16 +00:00
parent 77f8dd5add
commit 1017ebe9cb
4 changed files with 53 additions and 42 deletions

View File

@ -86,7 +86,7 @@ i386.ld ppc.ld\
tests/Makefile\ tests/Makefile\
tests/test-i386.c tests/test-i386-shift.h tests/test-i386.h\ tests/test-i386.c tests/test-i386-shift.h tests/test-i386.h\
tests/test-i386-muldiv.h\ tests/test-i386-muldiv.h\
tests/test2.c tests/hello.c tests/sha1.c tests/test1.c tests/test2.c tests/hello.c tests/sha1.c
FILE=gemu-$(VERSION) FILE=gemu-$(VERSION)

View File

@ -242,7 +242,7 @@ int cpu_x86_exec(CPUX86State *s);
void cpu_x86_close(CPUX86State *s); void cpu_x86_close(CPUX86State *s);
/* internal functions */ /* internal functions */
int cpu_x86_gen_code(uint8_t *gen_code_buf, int *gen_code_size_ptr, int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
uint8_t *pc_start); int *gen_code_size_ptr, uint8_t *pc_start);
#endif /* CPU_I386_H */ #endif /* CPU_I386_H */

View File

@ -1959,7 +1959,8 @@ int cpu_x86_exec(CPUX86State *env1)
#endif #endif
} }
#endif #endif
cpu_x86_gen_code(code_gen_buffer, &code_gen_size, (uint8_t *)env->pc); cpu_x86_gen_code(code_gen_buffer, sizeof(code_gen_buffer),
&code_gen_size, (uint8_t *)env->pc);
/* execute the generated code */ /* execute the generated code */
gen_func = (void *)code_gen_buffer; gen_func = (void *)code_gen_buffer;
gen_func(); gen_func();

View File

@ -995,7 +995,7 @@ static void gen_jcc(DisasContext *s, int b, int val)
default: default:
slow_jcc: slow_jcc:
if (s->cc_op != CC_OP_DYNAMIC) if (s->cc_op != CC_OP_DYNAMIC)
op_set_cc_op(s->cc_op); gen_op_set_cc_op(s->cc_op);
func = gen_jcc_slow[jcc_op]; func = gen_jcc_slow[jcc_op];
break; break;
} }
@ -1041,10 +1041,10 @@ static void gen_setcc(DisasContext *s, int b)
case CC_OP_SHLL: case CC_OP_SHLL:
switch(jcc_op) { switch(jcc_op) {
case JCC_Z: case JCC_Z:
func = gen_setcc_sub[s->cc_op - CC_OP_ADDB][jcc_op]; func = gen_setcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
break; break;
case JCC_S: case JCC_S:
func = gen_setcc_sub[s->cc_op - CC_OP_ADDB][jcc_op]; func = gen_setcc_sub[(s->cc_op - CC_OP_ADDB) % 3][jcc_op];
break; break;
default: default:
goto slow_jcc; goto slow_jcc;
@ -1053,7 +1053,7 @@ static void gen_setcc(DisasContext *s, int b)
default: default:
slow_jcc: slow_jcc:
if (s->cc_op != CC_OP_DYNAMIC) if (s->cc_op != CC_OP_DYNAMIC)
op_set_cc_op(s->cc_op); gen_op_set_cc_op(s->cc_op);
func = gen_setcc_slow[jcc_op]; func = gen_setcc_slow[jcc_op];
break; break;
} }
@ -1891,7 +1891,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start, int *is_jmp_ptr)
break; break;
case 0x3c: /* fbld */ case 0x3c: /* fbld */
gen_op_fpush(); gen_op_fpush();
op_fbld_ST0_A0(); gen_op_fbld_ST0_A0();
break; break;
case 0x3e: /* fbstp */ case 0x3e: /* fbstp */
gen_op_fbst_ST0_A0(); gen_op_fbst_ST0_A0();
@ -2338,6 +2338,8 @@ long disas_insn(DisasContext *s, uint8_t *pc_start, int *is_jmp_ptr)
/************************/ /************************/
/* flags */ /* flags */
case 0x9c: /* pushf */ case 0x9c: /* pushf */
if (s->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(s->cc_op);
gen_op_movl_T0_eflags(); gen_op_movl_T0_eflags();
gen_op_pushl_T0(); gen_op_pushl_T0();
break; break;
@ -2349,31 +2351,31 @@ long disas_insn(DisasContext *s, uint8_t *pc_start, int *is_jmp_ptr)
case 0x9e: /* sahf */ case 0x9e: /* sahf */
gen_op_mov_TN_reg[OT_BYTE][0][R_AH](); gen_op_mov_TN_reg[OT_BYTE][0][R_AH]();
if (s->cc_op != CC_OP_DYNAMIC) if (s->cc_op != CC_OP_DYNAMIC)
op_set_cc_op(s->cc_op); gen_op_set_cc_op(s->cc_op);
gen_op_movb_eflags_T0(); gen_op_movb_eflags_T0();
s->cc_op = CC_OP_EFLAGS; s->cc_op = CC_OP_EFLAGS;
break; break;
case 0x9f: /* lahf */ case 0x9f: /* lahf */
if (s->cc_op != CC_OP_DYNAMIC) if (s->cc_op != CC_OP_DYNAMIC)
op_set_cc_op(s->cc_op); gen_op_set_cc_op(s->cc_op);
gen_op_movl_T0_eflags(); gen_op_movl_T0_eflags();
gen_op_mov_reg_T0[OT_BYTE][R_AH](); gen_op_mov_reg_T0[OT_BYTE][R_AH]();
break; break;
case 0xf5: /* cmc */ case 0xf5: /* cmc */
if (s->cc_op != CC_OP_DYNAMIC) if (s->cc_op != CC_OP_DYNAMIC)
op_set_cc_op(s->cc_op); gen_op_set_cc_op(s->cc_op);
gen_op_cmc(); gen_op_cmc();
s->cc_op = CC_OP_EFLAGS; s->cc_op = CC_OP_EFLAGS;
break; break;
case 0xf8: /* clc */ case 0xf8: /* clc */
if (s->cc_op != CC_OP_DYNAMIC) if (s->cc_op != CC_OP_DYNAMIC)
op_set_cc_op(s->cc_op); gen_op_set_cc_op(s->cc_op);
gen_op_clc(); gen_op_clc();
s->cc_op = CC_OP_EFLAGS; s->cc_op = CC_OP_EFLAGS;
break; break;
case 0xf9: /* stc */ case 0xf9: /* stc */
if (s->cc_op != CC_OP_DYNAMIC) if (s->cc_op != CC_OP_DYNAMIC)
op_set_cc_op(s->cc_op); gen_op_set_cc_op(s->cc_op);
gen_op_stc(); gen_op_stc();
s->cc_op = CC_OP_EFLAGS; s->cc_op = CC_OP_EFLAGS;
break; break;
@ -2503,10 +2505,11 @@ long disas_insn(DisasContext *s, uint8_t *pc_start, int *is_jmp_ptr)
} }
/* return the next pc */ /* return the next pc */
int cpu_x86_gen_code(uint8_t *gen_code_buf, int *gen_code_size_ptr, int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size,
uint8_t *pc_start) int *gen_code_size_ptr, uint8_t *pc_start)
{ {
DisasContext dc1, *dc = &dc1; DisasContext dc1, *dc = &dc1;
uint8_t *gen_code_end, *pc_ptr;
int is_jmp; int is_jmp;
long ret; long ret;
#ifdef DEBUG_DISAS #ifdef DEBUG_DISAS
@ -2515,35 +2518,18 @@ int cpu_x86_gen_code(uint8_t *gen_code_buf, int *gen_code_size_ptr,
dc->cc_op = CC_OP_DYNAMIC; dc->cc_op = CC_OP_DYNAMIC;
gen_code_ptr = gen_code_buf; gen_code_ptr = gen_code_buf;
gen_code_end = gen_code_buf + max_code_size - 4096;
gen_start(); gen_start();
#ifdef DEBUG_DISAS
if (loglevel) {
INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf);
disasm_info.buffer = pc_start;
disasm_info.buffer_vma = (unsigned long)pc_start;
disasm_info.buffer_length = 15;
#if 0
disasm_info.flavour = bfd_get_flavour (abfd);
disasm_info.arch = bfd_get_arch (abfd);
disasm_info.mach = bfd_get_mach (abfd);
#endif
#ifdef WORDS_BIGENDIAN
disasm_info.endian = BFD_ENDIAN_BIG;
#else
disasm_info.endian = BFD_ENDIAN_LITTLE;
#endif
fprintf(logfile, "IN:\n");
fprintf(logfile, "0x%08lx: ", (long)pc_start);
print_insn_i386((unsigned long)pc_start, &disasm_info);
fprintf(logfile, "\n\n");
}
#endif
is_jmp = 0; is_jmp = 0;
ret = disas_insn(dc, pc_start, &is_jmp); pc_ptr = pc_start;
if (ret == -1) do {
error("unknown instruction at PC=0x%x B=%02x %02x", ret = disas_insn(dc, pc_ptr, &is_jmp);
pc_start, pc_start[0], pc_start[1]); if (ret == -1)
error("unknown instruction at PC=0x%x B=%02x %02x",
pc_ptr, pc_ptr[0], pc_ptr[1]);
pc_ptr = (void *)ret;
} while (!is_jmp && gen_code_ptr < gen_code_end);
/* we must store the eflags state if it is not already done */ /* we must store the eflags state if it is not already done */
if (dc->cc_op != CC_OP_DYNAMIC) if (dc->cc_op != CC_OP_DYNAMIC)
gen_op_set_cc_op(dc->cc_op); 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,
uint8_t *pc; uint8_t *pc;
int count; int count;
INIT_DISASSEMBLE_INFO(disasm_info, logfile, fprintf);
#if 0
disasm_info.flavour = bfd_get_flavour (abfd);
disasm_info.arch = bfd_get_arch (abfd);
disasm_info.mach = bfd_get_mach (abfd);
#endif
#ifdef WORDS_BIGENDIAN
disasm_info.endian = BFD_ENDIAN_BIG;
#else
disasm_info.endian = BFD_ENDIAN_LITTLE;
#endif
fprintf(logfile, "IN:\n");
disasm_info.buffer = pc_start;
disasm_info.buffer_vma = (unsigned long)pc_start;
disasm_info.buffer_length = pc_ptr - pc_start;
pc = pc_start;
while (pc < pc_ptr) {
fprintf(logfile, "0x%08lx: ", (long)pc);
count = print_insn_i386((unsigned long)pc, &disasm_info);
fprintf(logfile, "\n");
pc += count;
}
fprintf(logfile, "\n");
pc = gen_code_buf; pc = gen_code_buf;
disasm_info.buffer = pc; disasm_info.buffer = pc;
disasm_info.buffer_vma = (unsigned long)pc; disasm_info.buffer_vma = (unsigned long)pc;