diff -ur qemu-0.9.1-stock/exec-all.h qemu-0.9.1/exec-all.h --- qemu-0.9.1-stock/exec-all.h 2008-01-06 14:38:42.000000000 -0500 +++ qemu-0.9.1/exec-all.h 2008-01-12 15:00:57.000000000 -0500 @@ -177,6 +177,7 @@ jmp_first */ struct TranslationBlock *jmp_next[2]; struct TranslationBlock *jmp_first; + int unique_id; } TranslationBlock; static inline unsigned int tb_jmp_cache_hash_page(target_ulong pc) diff -ur qemu-0.9.1-stock/exec.c qemu-0.9.1/exec.c --- qemu-0.9.1-stock/exec.c 2008-01-06 14:38:42.000000000 -0500 +++ qemu-0.9.1/exec.c 2008-01-12 15:04:47.000000000 -0500 @@ -927,6 +927,8 @@ #endif /* TARGET_HAS_SMC */ } +int tb_count=0; + /* Allocate a new translation block. Flush the translation buffer if too many translation blocks or too much generated code. */ TranslationBlock *tb_alloc(target_ulong pc) @@ -939,6 +941,8 @@ tb = &tbs[nb_tbs++]; tb->pc = pc; tb->cflags = 0; + tb->unique_id=tb_count; + tb_count++; return tb; } diff -ur qemu-0.9.1-stock/linux-user/mmap.c qemu-0.9.1/linux-user/mmap.c --- qemu-0.9.1-stock/linux-user/mmap.c 2008-01-06 14:38:42.000000000 -0500 +++ qemu-0.9.1/linux-user/mmap.c 2008-01-17 13:27:11.000000000 -0500 @@ -250,8 +250,8 @@ /* Note: we prefer to control the mapping address. It is especially important if qemu_host_page_size > qemu_real_host_page_size */ - p = mmap(g2h(mmap_start), - host_len, prot, flags | MAP_FIXED, fd, host_offset); + p = mmap(real_start ? g2h(real_start) : NULL, + host_len, prot, flags, fd, host_offset); if (p == MAP_FAILED) return -1; /* update start so that it points to the file position at 'offset' */ diff -ur qemu-0.9.1-stock/linux-user/signal.c qemu-0.9.1/linux-user/signal.c --- qemu-0.9.1-stock/linux-user/signal.c 2008-01-06 14:38:42.000000000 -0500 +++ qemu-0.9.1/linux-user/signal.c 2008-01-12 15:26:13.000000000 -0500 @@ -367,7 +367,9 @@ /* default handler : ignore some signal. The other are fatal */ if (sig != TARGET_SIGCHLD && sig != TARGET_SIGURG && - sig != TARGET_SIGWINCH) { + sig != TARGET_SIGWINCH && + sig != TARGET_SIGTSTP && + sig != TARGET_SIGCONT) { force_sig(sig); } else { return 0; /* indicate ignored */ diff -ur qemu-0.9.1-stock/target-i386/helper.c qemu-0.9.1/target-i386/helper.c --- qemu-0.9.1-stock/target-i386/helper.c 2008-01-06 14:38:45.000000000 -0500 +++ qemu-0.9.1/target-i386/helper.c 2008-01-16 23:41:49.000000000 -0500 @@ -97,6 +97,88 @@ spinlock_t global_cpu_lock = SPIN_LOCK_UNLOCKED; +#define MAX_BBS 60000 +#define INTERVAL_SIZE 100000000 /* 100 million */ + +void helper_dump_pc(unsigned long pc, unsigned long bb, + unsigned long rep) { + + /* debug */ +// static int interval=0; +// static FILE *vmw_debug=NULL; + /* debug */ + + static unsigned long total_count=0; + static int bbvs[MAX_BBS]; + int i; + static FILE *bbv_file=NULL; + static int rep_count=0; + + /* debug */ +// if (interval>59) { + // if (vmw_debug==NULL) { + // vmw_debug=fopen("/tmp/vmw.debug","w"); +// if (vmw_debug==NULL) { +// printf("Error!\n"); +// exit(-1); +// } +// } +// fprintf(vmw_debug,"%x\n",pc); +// fflush(vmw_debug); +// } + + /* debug */ + + if (bbv_file==NULL) { + bbv_file=fopen("qemusim.bbv","w"); + if (bbv_file==NULL) { + printf("Error! Could not open file %s\n","qemusim.bbv"); + exit(-1); + } + } + + if (bb>MAX_BBS) { + printf("Error! Not enough BBS %d\n",bb); + exit(-1); + } + + if (rep) { + rep_count++; + return; + } + + if ((rep_count) && (!rep)) { + rep_count=0; + /* count all reps as one instruction (as per docs) */ + /* this makes things match perf-ctr results */ + total_count++; + bbvs[bb]++; + } + + total_count++; + bbvs[bb]++; + if (total_count>=INTERVAL_SIZE) { + /* debug */ +// interval++; + /* debug */ + fprintf(bbv_file,"T"); + for(i=0;iis_jmp is set if the translation must be stopped. Return the next pc value */ -static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) +static target_ulong disas_insn(DisasContext *s, target_ulong pc_start,int unique_id) { int b, prefixes, aflag, dflag; int shift, ot; @@ -3369,6 +3369,9 @@ if (prefixes & PREFIX_LOCK) gen_op_lock(); + gen_op_dump_pc(s->pc,unique_id,prefixes &(PREFIX_REPZ | PREFIX_REPNZ)); + + /* now check op code */ reswitch: switch(b) { @@ -6775,7 +6778,7 @@ gen_opc_cc_op[lj] = dc->cc_op; gen_opc_instr_start[lj] = 1; } - pc_ptr = disas_insn(dc, pc_ptr); + pc_ptr = disas_insn(dc, pc_ptr,tb->unique_id); /* stop translation if indicated */ if (dc->is_jmp) break; diff -ur qemu-0.9.1-stock/target-mips/helper.c qemu-0.9.1/target-mips/helper.c --- qemu-0.9.1-stock/target-mips/helper.c 2008-01-06 14:38:45.000000000 -0500 +++ qemu-0.9.1/target-mips/helper.c 2008-01-12 17:55:08.000000000 -0500 @@ -36,6 +36,51 @@ TLBRET_MATCH = 0 }; +#define MAX_BBS 60000 +#define INTERVAL_SIZE 100000000 /* 100 million */ + +void helper_dump_pc(unsigned long pc, unsigned long bb) { + + static unsigned long total_count=0; + static int bbvs[MAX_BBS]; + int i; + static FILE *bbv_file=NULL; + + if (bbv_file==NULL) { + bbv_file=fopen("qemusim.bbv","w"); + if (bbv_file==NULL) { + printf("Error! Could not open file %s\n","qemusim.bbv"); + exit(-1); + } + } + + if (bb>MAX_BBS) { + printf("Error! Not enough BBS %ld\n",bb); + exit(-1); + } + total_count++; + bbvs[bb]++; + + if (total_count>=INTERVAL_SIZE) { + fprintf(bbv_file,"T"); + for(i=0;iunique_id); } int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb) { - return gen_intermediate_code_internal(env, tb, 1); + return gen_intermediate_code_internal(env, tb, 1, tb->unique_id); } void fpu_dump_state(CPUState *env, FILE *f,