Add instruction counter.

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4799 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
pbrook 2008-06-29 01:03:05 +00:00
parent f6e5889e7f
commit 2e70f6efa8
29 changed files with 830 additions and 117 deletions

View file

@ -753,6 +753,8 @@ static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
}
#endif
#define CPU_PC_FROM_TB(env, tb) env->eip = tb->pc - tb->cs_base
#include "cpu-all.h"
#include "svm.h"

View file

@ -65,6 +65,8 @@ static TCGv cpu_T[2], cpu_T3;
static TCGv cpu_tmp0, cpu_tmp1_i64, cpu_tmp2_i32, cpu_tmp3_i32, cpu_tmp4, cpu_ptr0, cpu_ptr1;
static TCGv cpu_tmp5, cpu_tmp6;
#include "gen-icount.h"
#ifdef TARGET_X86_64
static int x86_64_hregs;
#endif
@ -1203,6 +1205,8 @@ static inline void gen_cmps(DisasContext *s, int ot)
static inline void gen_ins(DisasContext *s, int ot)
{
if (use_icount)
gen_io_start();
gen_string_movl_A0_EDI(s);
/* Note: we must do this dummy write first to be restartable in
case of page fault. */
@ -1215,10 +1219,14 @@ static inline void gen_ins(DisasContext *s, int ot)
gen_op_st_T0_A0(ot + s->mem_index);
gen_op_movl_T0_Dshift(ot);
gen_op_add_reg_T0(s->aflag, R_EDI);
if (use_icount)
gen_io_end();
}
static inline void gen_outs(DisasContext *s, int ot)
{
if (use_icount)
gen_io_start();
gen_string_movl_A0_ESI(s);
gen_op_ld_T0_A0(ot + s->mem_index);
@ -1230,6 +1238,8 @@ static inline void gen_outs(DisasContext *s, int ot)
gen_op_movl_T0_Dshift(ot);
gen_op_add_reg_T0(s->aflag, R_ESI);
if (use_icount)
gen_io_end();
}
/* same method as Valgrind : we generate jumps to current or next
@ -5570,6 +5580,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_repz_ins(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
} else {
gen_ins(s, ot);
if (use_icount) {
gen_jmp(s, s->pc - s->cs_base);
}
}
break;
case 0x6e: /* outsS */
@ -5586,6 +5599,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_repz_outs(s, ot, pc_start - s->cs_base, s->pc - s->cs_base);
} else {
gen_outs(s, ot);
if (use_icount) {
gen_jmp(s, s->pc - s->cs_base);
}
}
break;
@ -5602,9 +5618,15 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_op_movl_T0_im(val);
gen_check_io(s, ot, pc_start - s->cs_base,
SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
if (use_icount)
gen_io_start();
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
tcg_gen_helper_1_1(helper_in_func[ot], cpu_T[1], cpu_tmp2_i32);
gen_op_mov_reg_T1(ot, R_EAX);
if (use_icount) {
gen_io_end();
gen_jmp(s, s->pc - s->cs_base);
}
break;
case 0xe6:
case 0xe7:
@ -5618,10 +5640,16 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
svm_is_rep(prefixes));
gen_op_mov_TN_reg(ot, 1, R_EAX);
if (use_icount)
gen_io_start();
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
tcg_gen_helper_0_2(helper_out_func[ot], cpu_tmp2_i32, cpu_tmp3_i32);
if (use_icount) {
gen_io_end();
gen_jmp(s, s->pc - s->cs_base);
}
break;
case 0xec:
case 0xed:
@ -5633,9 +5661,15 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
gen_op_andl_T0_ffff();
gen_check_io(s, ot, pc_start - s->cs_base,
SVM_IOIO_TYPE_MASK | svm_is_rep(prefixes));
if (use_icount)
gen_io_start();
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
tcg_gen_helper_1_1(helper_in_func[ot], cpu_T[1], cpu_tmp2_i32);
gen_op_mov_reg_T1(ot, R_EAX);
if (use_icount) {
gen_io_end();
gen_jmp(s, s->pc - s->cs_base);
}
break;
case 0xee:
case 0xef:
@ -5649,10 +5683,16 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
svm_is_rep(prefixes));
gen_op_mov_TN_reg(ot, 1, R_EAX);
if (use_icount)
gen_io_start();
tcg_gen_trunc_tl_i32(cpu_tmp2_i32, cpu_T[0]);
tcg_gen_andi_i32(cpu_tmp2_i32, cpu_tmp2_i32, 0xffff);
tcg_gen_trunc_tl_i32(cpu_tmp3_i32, cpu_T[1]);
tcg_gen_helper_0_2(helper_out_func[ot], cpu_tmp2_i32, cpu_tmp3_i32);
if (use_icount) {
gen_io_end();
gen_jmp(s, s->pc - s->cs_base);
}
break;
/************************/
@ -7109,6 +7149,8 @@ static inline int gen_intermediate_code_internal(CPUState *env,
uint64_t flags;
target_ulong pc_start;
target_ulong cs_base;
int num_insns;
int max_insns;
/* generate intermediate code */
pc_start = tb->pc;
@ -7179,7 +7221,12 @@ static inline int gen_intermediate_code_internal(CPUState *env,
dc->is_jmp = DISAS_NEXT;
pc_ptr = pc_start;
lj = -1;
num_insns = 0;
max_insns = tb->cflags & CF_COUNT_MASK;
if (max_insns == 0)
max_insns = CF_COUNT_MASK;
gen_icount_start();
for(;;) {
if (env->nb_breakpoints > 0) {
for(j = 0; j < env->nb_breakpoints; j++) {
@ -7199,8 +7246,13 @@ static inline int gen_intermediate_code_internal(CPUState *env,
gen_opc_pc[lj] = pc_ptr;
gen_opc_cc_op[lj] = dc->cc_op;
gen_opc_instr_start[lj] = 1;
gen_opc_icount[lj] = num_insns;
}
if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
gen_io_start();
pc_ptr = disas_insn(dc, pc_ptr);
num_insns++;
/* stop translation if indicated */
if (dc->is_jmp)
break;
@ -7210,20 +7262,23 @@ static inline int gen_intermediate_code_internal(CPUState *env,
the flag and abort the translation to give the irqs a
change to be happen */
if (dc->tf || dc->singlestep_enabled ||
(flags & HF_INHIBIT_IRQ_MASK) ||
(cflags & CF_SINGLE_INSN)) {
(flags & HF_INHIBIT_IRQ_MASK)) {
gen_jmp_im(pc_ptr - dc->cs_base);
gen_eob(dc);
break;
}
/* if too long translation, stop generation too */
if (gen_opc_ptr >= gen_opc_end ||
(pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32)) {
(pc_ptr - pc_start) >= (TARGET_PAGE_SIZE - 32) ||
num_insns >= max_insns) {
gen_jmp_im(pc_ptr - dc->cs_base);
gen_eob(dc);
break;
}
}
if (tb->cflags & CF_LAST_IO)
gen_io_end();
gen_icount_end(tb, num_insns);
*gen_opc_ptr = INDEX_op_end;
/* we don't forget to fill the last values */
if (search_pc) {
@ -7252,8 +7307,10 @@ static inline int gen_intermediate_code_internal(CPUState *env,
}
#endif
if (!search_pc)
if (!search_pc) {
tb->size = pc_ptr - pc_start;
tb->icount = num_insns;
}
return 0;
}