From 1017ebe9cb38ae034b0e7c6c449abe2c9b5284fb Mon Sep 17 00:00:00 2001 From: bellard Date: Wed, 5 Mar 2003 23:26:16 +0000 Subject: [PATCH] convert several x86 instructions at the same time git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@24 c046a42c-6fe2-441c-8c8c-71466251a162 --- Makefile | 2 +- cpu-i386.h | 4 +-- op-i386.c | 3 +- translate-i386.c | 86 +++++++++++++++++++++++++++--------------------- 4 files changed, 53 insertions(+), 42 deletions(-) diff --git a/Makefile b/Makefile index c0a2915bed..57d2ba1ba7 100644 --- a/Makefile +++ b/Makefile @@ -86,7 +86,7 @@ i386.ld ppc.ld\ tests/Makefile\ tests/test-i386.c tests/test-i386-shift.h tests/test-i386.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) diff --git a/cpu-i386.h b/cpu-i386.h index ae49fffd04..4d06d92060 100644 --- a/cpu-i386.h +++ b/cpu-i386.h @@ -242,7 +242,7 @@ int cpu_x86_exec(CPUX86State *s); void cpu_x86_close(CPUX86State *s); /* internal functions */ -int cpu_x86_gen_code(uint8_t *gen_code_buf, int *gen_code_size_ptr, - uint8_t *pc_start); +int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, + int *gen_code_size_ptr, uint8_t *pc_start); #endif /* CPU_I386_H */ diff --git a/op-i386.c b/op-i386.c index 88bdb0a41f..2cca6a6722 100644 --- a/op-i386.c +++ b/op-i386.c @@ -1959,7 +1959,8 @@ int cpu_x86_exec(CPUX86State *env1) #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 */ gen_func = (void *)code_gen_buffer; gen_func(); diff --git a/translate-i386.c b/translate-i386.c index 5c1fc3dd7b..d13d5d7449 100644 --- a/translate-i386.c +++ b/translate-i386.c @@ -995,7 +995,7 @@ static void gen_jcc(DisasContext *s, int b, int val) default: slow_jcc: 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]; break; } @@ -1041,10 +1041,10 @@ static void gen_setcc(DisasContext *s, int b) case CC_OP_SHLL: switch(jcc_op) { 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; 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; default: goto slow_jcc; @@ -1053,7 +1053,7 @@ static void gen_setcc(DisasContext *s, int b) default: slow_jcc: 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]; break; } @@ -1891,7 +1891,7 @@ long disas_insn(DisasContext *s, uint8_t *pc_start, int *is_jmp_ptr) break; case 0x3c: /* fbld */ gen_op_fpush(); - op_fbld_ST0_A0(); + gen_op_fbld_ST0_A0(); break; case 0x3e: /* fbstp */ gen_op_fbst_ST0_A0(); @@ -2338,6 +2338,8 @@ long disas_insn(DisasContext *s, uint8_t *pc_start, int *is_jmp_ptr) /************************/ /* flags */ 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_pushl_T0(); break; @@ -2349,31 +2351,31 @@ long disas_insn(DisasContext *s, uint8_t *pc_start, int *is_jmp_ptr) case 0x9e: /* sahf */ gen_op_mov_TN_reg[OT_BYTE][0][R_AH](); 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(); s->cc_op = CC_OP_EFLAGS; break; case 0x9f: /* lahf */ 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_mov_reg_T0[OT_BYTE][R_AH](); break; case 0xf5: /* cmc */ 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(); s->cc_op = CC_OP_EFLAGS; break; case 0xf8: /* clc */ 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(); s->cc_op = CC_OP_EFLAGS; break; case 0xf9: /* stc */ 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(); s->cc_op = CC_OP_EFLAGS; break; @@ -2503,10 +2505,11 @@ long disas_insn(DisasContext *s, uint8_t *pc_start, int *is_jmp_ptr) } /* return the next pc */ -int cpu_x86_gen_code(uint8_t *gen_code_buf, int *gen_code_size_ptr, - uint8_t *pc_start) +int cpu_x86_gen_code(uint8_t *gen_code_buf, int max_code_size, + int *gen_code_size_ptr, uint8_t *pc_start) { DisasContext dc1, *dc = &dc1; + uint8_t *gen_code_end, *pc_ptr; int is_jmp; long ret; #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; gen_code_ptr = gen_code_buf; + gen_code_end = gen_code_buf + max_code_size - 4096; 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; - ret = disas_insn(dc, pc_start, &is_jmp); - if (ret == -1) - error("unknown instruction at PC=0x%x B=%02x %02x", - pc_start, pc_start[0], pc_start[1]); + pc_ptr = pc_start; + do { + ret = disas_insn(dc, pc_ptr, &is_jmp); + 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 */ if (dc->cc_op != CC_OP_DYNAMIC) 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; 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; disasm_info.buffer = pc; disasm_info.buffer_vma = (unsigned long)pc;