Index: cpu-all.h =================================================================== RCS file: /sources/qemu/qemu/cpu-all.h,v retrieving revision 1.76 diff -u -d -d -p -r1.76 cpu-all.h --- cpu-all.h 23 Sep 2007 15:28:03 -0000 1.76 +++ cpu-all.h 12 Oct 2007 22:53:37 -0000 @@ -646,6 +646,13 @@ static inline void stfq_be_p(void *ptr, #define ldl_code(p) ldl_raw(p) #define ldq_code(p) ldq_raw(p) +#define ldub_code_p(sp, pp, p) ldub_raw(p) +#define ldsb_code_p(sp, pp, p) ldsb_raw(p) +#define lduw_code_p(sp, pp, p) lduw_raw(p) +#define ldsw_code_p(sp, pp, p) ldsw_raw(p) +#define ldl_code_p(sp, pp, p) ldl_raw(p) +#define ldq_code_p(sp, pp, p) ldq_raw(p) + #define ldub_kernel(p) ldub_raw(p) #define ldsb_kernel(p) ldsb_raw(p) #define lduw_kernel(p) lduw_raw(p) Index: cpu-exec.c =================================================================== RCS file: /sources/qemu/qemu/cpu-exec.c,v retrieving revision 1.119 diff -u -d -d -p -r1.119 cpu-exec.c --- cpu-exec.c 8 Oct 2007 13:16:13 -0000 1.119 +++ cpu-exec.c 12 Oct 2007 22:53:37 -0000 @@ -133,6 +133,7 @@ static TranslationBlock *tb_find_slow(ta tb->tc_ptr = tc_ptr; tb->cs_base = cs_base; tb->flags = flags; + tb->page_addr[0] = phys_page1; cpu_gen_code(env, tb, CODE_GEN_MAX_SIZE, &code_gen_size); code_gen_ptr = (void *)(((unsigned long)code_gen_ptr + code_gen_size + CODE_GEN_ALIGN - 1) & ~(CODE_GEN_ALIGN - 1)); Index: softmmu_header.h =================================================================== RCS file: /sources/qemu/qemu/softmmu_header.h,v retrieving revision 1.17 diff -u -d -d -p -r1.17 softmmu_header.h --- softmmu_header.h 8 Oct 2007 13:16:14 -0000 1.17 +++ softmmu_header.h 12 Oct 2007 22:53:37 -0000 @@ -336,6 +336,60 @@ static inline void glue(glue(st, SUFFIX) } } +#else + +#if DATA_SIZE <= 2 +static inline RES_TYPE glue(glue(glue(lds,SUFFIX),MEMSUFFIX),_p)(unsigned long *start_pc, + unsigned long phys_pc, + target_ulong virt_pc) +{ + RES_TYPE opc; + + if (unlikely((*start_pc ^ + (phys_pc + sizeof(RES_TYPE) - 1)) >> TARGET_PAGE_BITS)) { + /* Slow path: phys_pc is not in the same page than start_pc + * or the insn is spanning two pages + */ + opc = glue(glue(lds,SUFFIX),MEMSUFFIX)(virt_pc); + /* Avoid softmmu access on next load */ + /* XXX: dont: phys PC is not correct anymore + * We chould call get_phys_addr_code(env, pc); and remove the else + * condition, here. + */ + //*start_pc = phys_pc; + } else { + opc = glue(glue(lds,SUFFIX),_raw)(phys_pc); + } + + return opc; +} +#endif + +static inline RES_TYPE glue(glue(glue(ld,USUFFIX),MEMSUFFIX),_p)(unsigned long *start_pc, + unsigned long phys_pc, + target_ulong virt_pc) +{ + RES_TYPE opc; + + if (unlikely((*start_pc ^ + (phys_pc + sizeof(RES_TYPE) - 1)) >> TARGET_PAGE_BITS)) { + /* Slow path: phys_pc is not in the same page than start_pc + * or the insn is spanning two pages + */ + opc = glue(glue(ld,USUFFIX),MEMSUFFIX)(virt_pc); + /* Avoid softmmu access on next load */ + /* XXX: dont: phys PC is not correct anymore + * We chould call get_phys_addr_code(env, pc); and remove the else + * condition, here. + */ + //*start_pc = phys_pc; + } else { + opc = glue(glue(ld,USUFFIX),_raw)(phys_pc); + } + + return opc; +} + #endif /* ACCESS_TYPE != 3 */ #endif /* !asm */ Index: target-alpha/translate.c =================================================================== RCS file: /sources/qemu/qemu/target-alpha/translate.c,v retrieving revision 1.5 diff -u -d -d -p -r1.5 translate.c --- target-alpha/translate.c 16 Sep 2007 21:08:01 -0000 1.5 +++ target-alpha/translate.c 12 Oct 2007 22:53:38 -0000 @@ -1965,6 +1965,7 @@ int gen_intermediate_code_internal (CPUS static int insn_count; #endif DisasContext ctx, *ctxp = &ctx; + unsigned long phys_pc, phys_pc_start; target_ulong pc_start; uint32_t insn; uint16_t *gen_opc_end; @@ -1972,6 +1973,9 @@ int gen_intermediate_code_internal (CPUS int ret; pc_start = tb->pc; + phys_pc_start = (unsigned long)phys_ram_base + tb->page_addr[0] + + (pc_start & ~TARGET_PAGE_MASK); + phys_pc = phys_pc_start; gen_opc_ptr = gen_opc_buf; gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; gen_opparam_ptr = gen_opparam_buf; @@ -2010,7 +2014,7 @@ int gen_intermediate_code_internal (CPUS ctx.pc, ctx.mem_idx); } #endif - insn = ldl_code(ctx.pc); + insn = ldl_code_p(&phys_pc_start, phys_pc, ctx.pc); #if defined ALPHA_DEBUG_DISAS insn_count++; if (logfile != NULL) { @@ -2018,6 +2022,7 @@ int gen_intermediate_code_internal (CPUS } #endif ctx.pc += 4; + phys_pc += 4; ret = translate_one(ctxp, insn); if (ret != 0) break; Index: target-arm/translate.c =================================================================== RCS file: /sources/qemu/qemu/target-arm/translate.c,v retrieving revision 1.57 diff -u -d -d -p -r1.57 translate.c --- target-arm/translate.c 17 Sep 2007 08:09:51 -0000 1.57 +++ target-arm/translate.c 12 Oct 2007 22:53:38 -0000 @@ -38,6 +38,8 @@ /* internal defines */ typedef struct DisasContext { target_ulong pc; + unsigned long phys_pc; + unsigned long phys_pc_start; int is_jmp; /* Nonzero if this instruction has been conditionally skipped. */ int condjmp; @@ -2206,8 +2208,9 @@ static void disas_arm_insn(CPUState * en { unsigned int cond, insn, val, op1, i, shift, rm, rs, rn, rd, sh; - insn = ldl_code(s->pc); + insn = ldl_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 4; + s->phys_pc += 4; cond = insn >> 28; if (cond == 0xf){ @@ -2971,8 +2974,9 @@ static void disas_thumb_insn(DisasContex int32_t offset; int i; - insn = lduw_code(s->pc); + insn = lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; switch (insn >> 12) { case 0: case 1: @@ -3494,7 +3498,7 @@ static void disas_thumb_insn(DisasContex break; } offset = ((int32_t)insn << 21) >> 10; - insn = lduw_code(s->pc); + insn = lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); offset |= insn & 0x7ff; val = (uint32_t)s->pc + 2; @@ -3544,6 +3548,9 @@ static inline int gen_intermediate_code_ dc->is_jmp = DISAS_NEXT; dc->pc = pc_start; + dc->phys_pc_start = (unsigned long)phys_ram_base + tb->page_addr[0] + + (pc_start & ~TARGET_PAGE_MASK); + dc->phys_pc = dc->phys_pc_start; dc->singlestep_enabled = env->singlestep_enabled; dc->condjmp = 0; dc->thumb = env->thumb; Index: target-cris/translate.c =================================================================== RCS file: /sources/qemu/qemu/target-cris/translate.c,v retrieving revision 1.1 diff -u -d -d -p -r1.1 translate.c --- target-cris/translate.c 8 Oct 2007 12:49:08 -0000 1.1 +++ target-cris/translate.c 12 Oct 2007 22:53:38 -0000 @@ -100,6 +100,7 @@ enum { typedef struct DisasContext { CPUState *env; target_ulong pc, insn_pc; + unsigned long phys_pc, phys_pc_start; /* Decoder. */ uint32_t ir; @@ -828,7 +829,8 @@ static int dec_prep_alu_m(DisasContext * if (memsize == 1) insn_len++; - imm = ldl_code(dc->pc + 2); + imm = ldl_code_p(&dc->phys_pc_start, dc->phys_pc + 2, + dc->pc + 2); if (memsize != 4) { if (s_ext) { imm = sign_extend(imm, (memsize * 8) - 1); @@ -1962,7 +1964,7 @@ static unsigned int dec_lapc_im(DisasCon rd = dc->op2; cris_cc_mask(dc, 0); - imm = ldl_code(dc->pc + 2); + imm = ldl_code_p(&dc->phys_pc_start, dc->phys_pc + 2, dc->pc + 2); DIS(fprintf (logfile, "lapc 0x%x, $r%u\n", imm + dc->pc, dc->op2)); gen_op_movl_T0_im (dc->pc + imm); gen_movl_reg_T0[rd] (); @@ -1999,7 +2001,7 @@ static unsigned int dec_jas_im(DisasCont { uint32_t imm; - imm = ldl_code(dc->pc + 2); + imm = ldl_code_p(&dc->phys_pc_start, dc->phys_pc + 2, dc->pc + 2); DIS(fprintf (logfile, "jas 0x%x\n", imm)); cris_cc_mask(dc, 0); @@ -2016,7 +2018,7 @@ static unsigned int dec_jasc_im(DisasCon { uint32_t imm; - imm = ldl_code(dc->pc + 2); + imm = ldl_code_p(&dc->phys_pc_start, dc->phys_pc + 2, dc->pc + 2); DIS(fprintf (logfile, "jasc 0x%x\n", imm)); cris_cc_mask(dc, 0); @@ -2047,7 +2049,7 @@ static unsigned int dec_bcc_im(DisasCont int32_t offset; uint32_t cond = dc->op2; - offset = ldl_code(dc->pc + 2); + offset = ldl_code_p(&dc->phys_pc_start, dc->phys_pc + 2, dc->pc + 2); offset = sign_extend(offset, 15); DIS(fprintf (logfile, "b%s %d pc=%x dst=%x\n", @@ -2065,7 +2067,7 @@ static unsigned int dec_bas_im(DisasCont int32_t simm; - simm = ldl_code(dc->pc + 2); + simm = ldl_code_p(&dc->phys_pc_start, dc->phys_pc + 2, dc->pc + 2); DIS(fprintf (logfile, "bas 0x%x, $p%u\n", dc->pc + simm, dc->op2)); cris_cc_mask(dc, 0); @@ -2081,7 +2083,7 @@ static unsigned int dec_bas_im(DisasCont static unsigned int dec_basc_im(DisasContext *dc) { int32_t simm; - simm = ldl_code(dc->pc + 2); + simm = ldl_code_p(&dc->phys_pc_start, dc->phys_pc + 2, dc->pc + 2); DIS(fprintf (logfile, "basc 0x%x, $p%u\n", dc->pc + simm, dc->op2)); cris_cc_mask(dc, 0); @@ -2259,7 +2261,7 @@ cris_decoder(DisasContext *dc) int i; /* Load a halfword onto the instruction register. */ - tmp = ldl_code(dc->pc); + tmp = ldl_code_p(&dc->phys_pc_start, dc->phys_pc, dc->pc); dc->ir = tmp & 0xffff; /* Now decode it. */ @@ -2313,6 +2315,9 @@ gen_intermediate_code_internal(CPUState uint32_t next_page_start; pc_start = tb->pc; + dc->phys_pc_start = (unsigned long)phys_ram_base + tb->page_addr[0] + + (pc_start & ~TARGET_PAGE_MASK); + dc->phys_pc = dc->phys_pc_start; dc->env = env; dc->tb = tb; @@ -2347,6 +2352,7 @@ gen_intermediate_code_internal(CPUState insn_len = cris_decoder(dc); STATS(gen_op_exec_insn()); dc->pc += insn_len; + dc->phys_pc += insn_len; if (!dc->flagx_live || (dc->flagx_live && !(dc->cc_op == CC_OP_FLAGS && dc->flags_x))) { Index: target-i386/translate.c =================================================================== RCS file: /sources/qemu/qemu/target-i386/translate.c,v retrieving revision 1.72 diff -u -d -d -p -r1.72 translate.c --- target-i386/translate.c 27 Sep 2007 01:52:00 -0000 1.72 +++ target-i386/translate.c 12 Oct 2007 22:53:39 -0000 @@ -73,6 +73,7 @@ typedef struct DisasContext { int prefix; int aflag, dflag; target_ulong pc; /* pc = eip + cs_base */ + unsigned long phys_pc,phys_pc_start; int is_jmp; /* 1 = means jump (stop translation), 2 means CPU static state change (stop translation) */ /* current block context */ @@ -1451,7 +1452,7 @@ static void gen_lea_modrm(DisasContext * if (base == 4) { havesib = 1; - code = ldub_code(s->pc++); + code = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); scale = (code >> 6) & 3; index = ((code >> 3) & 7) | REX_X(s); base = (code & 7); @@ -1462,8 +1463,10 @@ static void gen_lea_modrm(DisasContext * case 0: if ((base & 7) == 5) { base = -1; - disp = (int32_t)ldl_code(s->pc); + disp = (int32_t)ldl_code_p(&s->phys_pc_start, s->phys_pc, + s->pc); s->pc += 4; + s->phys_pc += 4; if (CODE64(s) && !havesib) { disp += s->pc + s->rip_offset; } @@ -1472,12 +1475,14 @@ static void gen_lea_modrm(DisasContext * } break; case 1: - disp = (int8_t)ldub_code(s->pc++); + disp = (int8_t)ldub_code_p(&s->phys_pc_start, s->phys_pc++, + s->pc++); break; default: case 2: - disp = ldl_code(s->pc); + disp = ldl_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 4; + s->phys_pc += 4; break; } @@ -1545,8 +1550,9 @@ static void gen_lea_modrm(DisasContext * switch (mod) { case 0: if (rm == 6) { - disp = lduw_code(s->pc); + disp = lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; gen_op_movl_A0_im(disp); rm = 0; /* avoid SS override */ goto no_rm; @@ -1555,12 +1561,14 @@ static void gen_lea_modrm(DisasContext * } break; case 1: - disp = (int8_t)ldub_code(s->pc++); + disp = (int8_t)ldub_code_p(&s->phys_pc_start, s->phys_pc++, + s->pc++); break; default: case 2: - disp = lduw_code(s->pc); + disp = lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; break; } switch(rm) { @@ -1629,7 +1637,7 @@ static void gen_nop_modrm(DisasContext * base = rm; if (base == 4) { - code = ldub_code(s->pc++); + code = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); base = (code & 7); } @@ -1637,14 +1645,17 @@ static void gen_nop_modrm(DisasContext * case 0: if (base == 5) { s->pc += 4; + s->phys_pc += 4; } break; case 1: s->pc++; + s->phys_pc++; break; default: case 2: s->pc += 4; + s->phys_pc += 4; break; } } else { @@ -1652,14 +1663,17 @@ static void gen_nop_modrm(DisasContext * case 0: if (rm == 6) { s->pc += 2; + s->phys_pc += 2; } break; case 1: s->pc++; + s->phys_pc++; break; default: case 2: s->pc += 2; + s->phys_pc += 2; break; } } @@ -1727,17 +1741,20 @@ static inline uint32_t insn_get(DisasCon switch(ot) { case OT_BYTE: - ret = ldub_code(s->pc); + ret = ldub_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc++; + s->phys_pc++; break; case OT_WORD: - ret = lduw_code(s->pc); + ret = lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; break; default: case OT_LONG: - ret = ldl_code(s->pc); + ret = ldl_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 4; + s->phys_pc += 4; break; } return ret; @@ -2689,7 +2706,7 @@ static void gen_sse(DisasContext *s, int gen_op_enter_mmx(); } - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); reg = ((modrm >> 3) & 7); if (is_xmm) reg |= rex_r; @@ -2962,7 +2979,7 @@ static void gen_sse(DisasContext *s, int case 0x171: /* shift xmm, im */ case 0x172: case 0x173: - val = ldub_code(s->pc++); + val = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); if (is_xmm) { gen_op_movl_T0_im(val); gen_op_movl_env_T0(offsetof(CPUX86State,xmm_t0.XMM_L(0))); @@ -3082,7 +3099,7 @@ static void gen_sse(DisasContext *s, int case 0x1c4: s->rip_offset = 1; gen_ldst_modrm(s, modrm, OT_WORD, OR_TMP0, 0); - val = ldub_code(s->pc++); + val = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); if (b1) { val &= 7; gen_op_pinsrw_xmm(offsetof(CPUX86State,xmm_regs[reg]), val); @@ -3095,7 +3112,7 @@ static void gen_sse(DisasContext *s, int case 0x1c5: if (mod != 3) goto illegal_op; - val = ldub_code(s->pc++); + val = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); if (b1) { val &= 7; rm = (modrm & 7) | REX_B(s); @@ -3213,13 +3230,13 @@ static void gen_sse(DisasContext *s, int switch(b) { case 0x70: /* pshufx insn */ case 0xc6: /* pshufx insn */ - val = ldub_code(s->pc++); + val = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); sse_op3 = (GenOpFunc3 *)sse_op2; sse_op3(op1_offset, op2_offset, val); break; case 0xc2: /* compare insns */ - val = ldub_code(s->pc++); + val = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); if (val >= 8) goto illegal_op; sse_op2 = sse_op_table4[val][b1]; @@ -3260,8 +3277,9 @@ static target_ulong disas_insn(DisasCont #endif s->rip_offset = 0; /* for relative ip address */ next_byte: - b = ldub_code(s->pc); + b = ldub_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc++; + s->phys_pc++; /* check prefixes */ #ifdef TARGET_X86_64 if (CODE64(s)) { @@ -3375,7 +3393,7 @@ static target_ulong disas_insn(DisasCont case 0x0f: /**************************/ /* extended op code */ - b = ldub_code(s->pc++) | 0x100; + b = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++) | 0x100; goto reswitch; /**************************/ @@ -3400,7 +3418,7 @@ static target_ulong disas_insn(DisasCont switch(f) { case 0: /* OP Ev, Gv */ - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; mod = (modrm >> 6) & 3; rm = (modrm & 7) | REX_B(s); @@ -3422,7 +3440,7 @@ static target_ulong disas_insn(DisasCont gen_op(s, op, ot, opreg); break; case 1: /* OP Gv, Ev */ - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); mod = (modrm >> 6) & 3; reg = ((modrm >> 3) & 7) | rex_r; rm = (modrm & 7) | REX_B(s); @@ -3457,7 +3475,7 @@ static target_ulong disas_insn(DisasCont else ot = dflag + OT_WORD; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); mod = (modrm >> 6) & 3; rm = (modrm & 7) | REX_B(s); op = (modrm >> 3) & 7; @@ -3506,7 +3524,7 @@ static target_ulong disas_insn(DisasCont else ot = dflag + OT_WORD; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); mod = (modrm >> 6) & 3; rm = (modrm & 7) | REX_B(s); op = (modrm >> 3) & 7; @@ -3648,7 +3666,7 @@ static target_ulong disas_insn(DisasCont else ot = dflag + OT_WORD; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); mod = (modrm >> 6) & 3; rm = (modrm & 7) | REX_B(s); op = (modrm >> 3) & 7; @@ -3754,7 +3772,7 @@ static target_ulong disas_insn(DisasCont else ot = dflag + OT_WORD; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); mod = (modrm >> 6) & 3; rm = (modrm & 7) | REX_B(s); reg = ((modrm >> 3) & 7) | rex_r; @@ -3805,7 +3823,7 @@ static target_ulong disas_insn(DisasCont case 0x69: /* imul Gv, Ev, I */ case 0x6b: ot = dflag + OT_WORD; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; if (b == 0x69) s->rip_offset = insn_const_size(ot); @@ -3841,7 +3859,7 @@ static target_ulong disas_insn(DisasCont ot = OT_BYTE; else ot = dflag + OT_WORD; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; mod = (modrm >> 6) & 3; if (mod == 3) { @@ -3868,7 +3886,7 @@ static target_ulong disas_insn(DisasCont ot = OT_BYTE; else ot = dflag + OT_WORD; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; mod = (modrm >> 6) & 3; gen_op_mov_TN_reg[ot][1][reg](); @@ -3885,7 +3903,7 @@ static target_ulong disas_insn(DisasCont s->cc_op = CC_OP_SUBB + ot; break; case 0x1c7: /* cmpxchg8b */ - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); mod = (modrm >> 6) & 3; if (mod == 3) goto illegal_op; @@ -3944,7 +3962,7 @@ static target_ulong disas_insn(DisasCont } else { ot = dflag + OT_WORD; } - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); mod = (modrm >> 6) & 3; gen_pop_T0(s); if (mod == 3) { @@ -3963,9 +3981,10 @@ static target_ulong disas_insn(DisasCont case 0xc8: /* enter */ { int level; - val = lduw_code(s->pc); + val = lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; - level = ldub_code(s->pc++); + s->phys_pc += 2; + level = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); gen_enter(s, val, level); } break; @@ -4045,7 +4064,7 @@ static target_ulong disas_insn(DisasCont ot = OT_BYTE; else ot = dflag + OT_WORD; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; /* generate a generic store */ @@ -4057,7 +4076,7 @@ static target_ulong disas_insn(DisasCont ot = OT_BYTE; else ot = dflag + OT_WORD; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); mod = (modrm >> 6) & 3; if (mod != 3) { s->rip_offset = insn_const_size(ot); @@ -4076,14 +4095,14 @@ static target_ulong disas_insn(DisasCont ot = OT_BYTE; else ot = OT_WORD + dflag; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); gen_op_mov_reg_T0[ot][reg](); break; case 0x8e: /* mov seg, Gv */ - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); reg = (modrm >> 3) & 7; if (reg >= 6 || reg == R_CS) goto illegal_op; @@ -4103,7 +4122,7 @@ static target_ulong disas_insn(DisasCont } break; case 0x8c: /* mov Gv, seg */ - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); reg = (modrm >> 3) & 7; mod = (modrm >> 6) & 3; if (reg >= 6) @@ -4126,7 +4145,7 @@ static target_ulong disas_insn(DisasCont d_ot = dflag + OT_WORD; /* ot is the size of source */ ot = (b & 1) + OT_BYTE; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; mod = (modrm >> 6) & 3; rm = (modrm & 7) | REX_B(s); @@ -4163,7 +4182,7 @@ static target_ulong disas_insn(DisasCont case 0x8d: /* lea */ ot = dflag + OT_WORD; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); mod = (modrm >> 6) & 3; if (mod == 3) goto illegal_op; @@ -4190,8 +4209,9 @@ static target_ulong disas_insn(DisasCont ot = dflag + OT_WORD; #ifdef TARGET_X86_64 if (s->aflag == 2) { - offset_addr = ldq_code(s->pc); + offset_addr = ldq_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 8; + s->phys_pc += 8; if (offset_addr == (int32_t)offset_addr) gen_op_movq_A0_im(offset_addr); else @@ -4243,8 +4263,9 @@ static target_ulong disas_insn(DisasCont if (dflag == 2) { uint64_t tmp; /* 64 bit case */ - tmp = ldq_code(s->pc); + tmp = ldq_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 8; + s->phys_pc += 8; reg = (b & 7) | REX_B(s); gen_movtl_T0_im(tmp); gen_op_mov_reg_T0[OT_QUAD][reg](); @@ -4270,7 +4291,7 @@ static target_ulong disas_insn(DisasCont ot = OT_BYTE; else ot = dflag + OT_WORD; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; mod = (modrm >> 6) & 3; if (mod == 3) { @@ -4313,7 +4334,7 @@ static target_ulong disas_insn(DisasCont op = R_GS; do_lxx: ot = dflag ? OT_LONG : OT_WORD; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; mod = (modrm >> 6) & 3; if (mod == 3) @@ -4345,7 +4366,7 @@ static target_ulong disas_insn(DisasCont else ot = dflag + OT_WORD; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); mod = (modrm >> 6) & 3; op = (modrm >> 3) & 7; @@ -4364,7 +4385,8 @@ static target_ulong disas_insn(DisasCont gen_shift(s, op, ot, opreg, OR_ECX); } else { if (shift == 2) { - shift = ldub_code(s->pc++); + shift = ldub_code_p(&s->phys_pc_start, s->phys_pc++, + s->pc++); } gen_shifti(s, op, ot, opreg, shift); } @@ -4398,7 +4420,7 @@ static target_ulong disas_insn(DisasCont shift = 0; do_shiftd: ot = dflag + OT_WORD; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); mod = (modrm >> 6) & 3; rm = (modrm & 7) | REX_B(s); reg = ((modrm >> 3) & 7) | rex_r; @@ -4412,7 +4434,7 @@ static target_ulong disas_insn(DisasCont gen_op_mov_TN_reg[ot][1][reg](); if (shift) { - val = ldub_code(s->pc++); + val = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); if (ot == OT_QUAD) val &= 0x3f; else @@ -4450,7 +4472,7 @@ static target_ulong disas_insn(DisasCont gen_exception(s, EXCP07_PREX, pc_start - s->cs_base); break; } - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); mod = (modrm >> 6) & 3; rm = modrm & 7; op = ((b & 7) << 3) | ((modrm >> 3) & 7); @@ -5013,7 +5035,7 @@ static target_ulong disas_insn(DisasCont ot = OT_BYTE; else ot = dflag ? OT_LONG : OT_WORD; - val = ldub_code(s->pc++); + val = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); gen_op_movl_T0_im(val); gen_check_io(s, ot, 0, pc_start - s->cs_base); if (gen_svm_check_io(s, pc_start, @@ -5029,7 +5051,7 @@ static target_ulong disas_insn(DisasCont ot = OT_BYTE; else ot = dflag ? OT_LONG : OT_WORD; - val = ldub_code(s->pc++); + val = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); gen_op_movl_T0_im(val); gen_check_io(s, ot, 0, pc_start - s->cs_base); if (gen_svm_check_io(s, pc_start, svm_is_rep(prefixes) | @@ -5073,8 +5095,9 @@ static target_ulong disas_insn(DisasCont /************************/ /* control */ case 0xc2: /* ret im */ - val = ldsw_code(s->pc); + val = ldsw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; gen_pop_T0(s); if (CODE64(s) && s->dflag) s->dflag = 2; @@ -5093,8 +5116,9 @@ static target_ulong disas_insn(DisasCont gen_eob(s); break; case 0xca: /* lret im */ - val = ldsw_code(s->pc); + val = ldsw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; do_lret: if (s->pe && !s->vm86) { if (s->cc_op != CC_OP_DYNAMIC) @@ -5223,13 +5247,13 @@ static target_ulong disas_insn(DisasCont break; case 0x190 ... 0x19f: /* setcc Gv */ - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); gen_setcc(s, b); gen_ldst_modrm(s, modrm, OT_BYTE, OR_TMP0, 1); break; case 0x140 ... 0x14f: /* cmov Gv, Ev */ ot = dflag + OT_WORD; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; mod = (modrm >> 6) & 3; gen_setcc(s, b); @@ -5338,7 +5362,7 @@ static target_ulong disas_insn(DisasCont /* bit operations */ case 0x1ba: /* bt/bts/btr/btc Gv, im */ ot = dflag + OT_WORD; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); op = (modrm >> 3) & 7; mod = (modrm >> 6) & 3; rm = (modrm & 7) | REX_B(s); @@ -5350,7 +5374,7 @@ static target_ulong disas_insn(DisasCont gen_op_mov_TN_reg[ot][0][rm](); } /* load shift */ - val = ldub_code(s->pc++); + val = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); gen_op_movl_T1_im(val); if (op < 4) goto illegal_op; @@ -5378,7 +5402,7 @@ static target_ulong disas_insn(DisasCont op = 3; do_btx: ot = dflag + OT_WORD; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; mod = (modrm >> 6) & 3; rm = (modrm & 7) | REX_B(s); @@ -5404,7 +5428,7 @@ static target_ulong disas_insn(DisasCont case 0x1bc: /* bsf */ case 0x1bd: /* bsr */ ot = dflag + OT_WORD; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); /* NOTE: in order to handle the 0 case, we must load the @@ -5451,7 +5475,7 @@ static target_ulong disas_insn(DisasCont case 0xd4: /* aam */ if (CODE64(s)) goto illegal_op; - val = ldub_code(s->pc++); + val = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); if (val == 0) { gen_exception(s, EXCP00_DIVZ, pc_start - s->cs_base); } else { @@ -5462,7 +5486,7 @@ static target_ulong disas_insn(DisasCont case 0xd5: /* aad */ if (CODE64(s)) goto illegal_op; - val = ldub_code(s->pc++); + val = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); gen_op_aad(val); s->cc_op = CC_OP_LOGICB; break; @@ -5494,7 +5518,7 @@ static target_ulong disas_insn(DisasCont gen_interrupt(s, EXCP03_INT3, pc_start - s->cs_base, s->pc - s->cs_base); break; case 0xcd: /* int N */ - val = ldub_code(s->pc++); + val = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); if (gen_svm_check_intercept(s, pc_start, SVM_EXIT_SWINT)) break; if (s->vm86 && s->iopl != 3) { @@ -5567,7 +5591,7 @@ static target_ulong disas_insn(DisasCont if (CODE64(s)) goto illegal_op; ot = dflag ? OT_LONG : OT_WORD; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); reg = (modrm >> 3) & 7; mod = (modrm >> 6) & 3; if (mod == 3) @@ -5738,7 +5762,7 @@ static target_ulong disas_insn(DisasCont } break; case 0x100: - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); mod = (modrm >> 6) & 3; op = (modrm >> 3) & 7; switch(op) { @@ -5808,7 +5832,7 @@ static target_ulong disas_insn(DisasCont } break; case 0x101: - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); mod = (modrm >> 6) & 3; op = (modrm >> 3) & 7; rm = modrm & 7; @@ -6022,7 +6046,7 @@ static target_ulong disas_insn(DisasCont /* d_ot is the size of destination */ d_ot = dflag + OT_WORD; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; mod = (modrm >> 6) & 3; rm = (modrm & 7) | REX_B(s); @@ -6048,7 +6072,7 @@ static target_ulong disas_insn(DisasCont if (!s->pe || s->vm86) goto illegal_op; ot = dflag ? OT_LONG : OT_WORD; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); reg = (modrm >> 3) & 7; mod = (modrm >> 6) & 3; rm = modrm & 7; @@ -6075,7 +6099,7 @@ static target_ulong disas_insn(DisasCont if (!s->pe || s->vm86) goto illegal_op; ot = dflag ? OT_LONG : OT_WORD; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); reg = ((modrm >> 3) & 7) | rex_r; gen_ldst_modrm(s, modrm, ot, OR_TMP0, 0); gen_op_mov_TN_reg[ot][1][reg](); @@ -6089,7 +6113,7 @@ static target_ulong disas_insn(DisasCont gen_op_mov_reg_T1[ot][reg](); break; case 0x118: - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); mod = (modrm >> 6) & 3; op = (modrm >> 3) & 7; switch(op) { @@ -6108,7 +6132,7 @@ static target_ulong disas_insn(DisasCont } break; case 0x119 ... 0x11f: /* nop (multi byte) */ - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); gen_nop_modrm(s, modrm); break; case 0x120: /* mov reg, crN */ @@ -6116,7 +6140,7 @@ static target_ulong disas_insn(DisasCont if (s->cpl != 0) { gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); if ((modrm & 0xc0) != 0xc0) goto illegal_op; rm = (modrm & 7) | REX_B(s); @@ -6158,7 +6182,7 @@ static target_ulong disas_insn(DisasCont if (s->cpl != 0) { gen_exception(s, EXCP0D_GPF, pc_start - s->cs_base); } else { - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); if ((modrm & 0xc0) != 0xc0) goto illegal_op; rm = (modrm & 7) | REX_B(s); @@ -6199,7 +6223,7 @@ static target_ulong disas_insn(DisasCont if (!(s->cpuid_features & CPUID_SSE2)) goto illegal_op; ot = s->dflag == 2 ? OT_QUAD : OT_LONG; - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); mod = (modrm >> 6) & 3; if (mod == 3) goto illegal_op; @@ -6208,7 +6232,7 @@ static target_ulong disas_insn(DisasCont gen_ldst_modrm(s, modrm, ot, reg, 1); break; case 0x1ae: - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); mod = (modrm >> 6) & 3; op = (modrm >> 3) & 7; switch(op) { @@ -6274,7 +6298,7 @@ static target_ulong disas_insn(DisasCont } break; case 0x10d: /* prefetch */ - modrm = ldub_code(s->pc++); + modrm = ldub_code_p(&s->phys_pc_start, s->phys_pc++, s->pc++); gen_lea_modrm(s, modrm, ®_addr, &offset_addr); /* ignore for now */ break; @@ -6752,6 +6776,9 @@ static inline int gen_intermediate_code_ dc->is_jmp = DISAS_NEXT; pc_ptr = pc_start; + dc->phys_pc_start = (unsigned long)phys_ram_base + tb->page_addr[0] + + (pc_start & ~TARGET_PAGE_MASK); + dc->phys_pc = dc->phys_pc_start; lj = -1; for(;;) { Index: target-m68k/translate.c =================================================================== RCS file: /sources/qemu/qemu/target-m68k/translate.c,v retrieving revision 1.20 diff -u -d -d -p -r1.20 translate.c --- target-m68k/translate.c 17 Sep 2007 08:09:53 -0000 1.20 +++ target-m68k/translate.c 12 Oct 2007 22:53:39 -0000 @@ -45,6 +45,8 @@ typedef struct DisasContext { CPUM68KState *env; target_ulong insn_pc; /* Start of the current instruction. */ target_ulong pc; + unsigned long phys_pc; + unsigned long phys_pc_start; int is_jmp; int cc_op; int user; @@ -207,10 +209,12 @@ static int gen_ldst(DisasContext *s, int static inline uint32_t read_im32(DisasContext *s) { uint32_t im; - im = ((uint32_t)lduw_code(s->pc)) << 16; + im = ((uint32_t)lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc)) << 16; s->pc += 2; - im |= lduw_code(s->pc); + s->phys_pc += 2; + im |= lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; return im; } @@ -244,8 +248,9 @@ static int gen_lea_indexed(DisasContext uint32_t bd, od; offset = s->pc; - ext = lduw_code(s->pc); + ext = lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; if ((ext & 0x800) == 0 && !m68k_feature(s->env, M68K_FEATURE_WORD_INDEX)) return -1; @@ -258,8 +263,10 @@ static int gen_lea_indexed(DisasContext if ((ext & 0x30) > 0x10) { /* base displacement */ if ((ext & 0x30) == 0x20) { - bd = (int16_t)lduw_code(s->pc); + bd = (int16_t)lduw_code_p(&s->phys_pc_start, s->phys_pc, + s->pc); s->pc += 2; + s->phys_pc += 2; } else { bd = read_im32(s); } @@ -307,8 +314,10 @@ static int gen_lea_indexed(DisasContext if ((ext & 3) > 1) { /* outer displacement */ if ((ext & 3) == 2) { - od = (int16_t)lduw_code(s->pc); + od = (int16_t)lduw_code_p(&s->phys_pc_start, s->phys_pc, + s->pc); s->pc += 2; + s->phys_pc += 2; } else { od = read_im32(s); } @@ -455,8 +464,9 @@ static int gen_lea(DisasContext *s, uint case 5: /* Indirect displacement. */ reg += QREG_A0; tmp = gen_new_qreg(QMODE_I32); - ext = lduw_code(s->pc); + ext = lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; gen_op_add32(tmp, reg, gen_im32((int16_t)ext)); return tmp; case 6: /* Indirect index + displacement. */ @@ -465,8 +475,9 @@ static int gen_lea(DisasContext *s, uint case 7: /* Other */ switch (reg) { case 0: /* Absolute short. */ - offset = ldsw_code(s->pc); + offset = ldsw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; return gen_im32(offset); case 1: /* Absolute long. */ offset = read_im32(s); @@ -474,8 +485,9 @@ static int gen_lea(DisasContext *s, uint case 2: /* pc displacement */ tmp = gen_new_qreg(QMODE_I32); offset = s->pc; - offset += ldsw_code(s->pc); + offset += ldsw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; return gen_im32(offset); case 3: /* pc index+displacement. */ return gen_lea_indexed(s, opsize, -1); @@ -581,18 +593,23 @@ static int gen_ea(DisasContext *s, uint1 /* Sign extend values for consistency. */ switch (opsize) { case OS_BYTE: - if (val) - offset = ldsb_code(s->pc + 1); - else - offset = ldub_code(s->pc + 1); + if (val) { + offset = ldsb_code_p(&s->phys_pc_start, s->phys_pc + 1, + s->pc + 1); + } else { + offset = ldub_code_p(&s->phys_pc_start, s->phys_pc + 1, + s->pc + 1); + } s->pc += 2; + s->phys_pc += 2; break; case OS_WORD: if (val) - offset = ldsw_code(s->pc); + offset = ldsw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); else - offset = lduw_code(s->pc); + offset = lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; break; case OS_LONG: offset = read_im32(s); @@ -879,8 +896,9 @@ DISAS_INSN(divl) int reg; uint16_t ext; - ext = lduw_code(s->pc); + ext = lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; if (ext & 0x87f8) { gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED); return; @@ -1066,8 +1084,9 @@ DISAS_INSN(movem) int tmp; int is_load; - mask = lduw_code(s->pc); + mask = lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; tmp = gen_lea(s, insn, OS_LONG); if (tmp == -1) { gen_addr_fault(s); @@ -1111,8 +1130,9 @@ DISAS_INSN(bitop_im) opsize = OS_LONG; op = (insn >> 6) & 3; - bitnum = lduw_code(s->pc); + bitnum = lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; if (bitnum & 0xff00) { disas_undef(s, insn); return; @@ -1375,8 +1395,9 @@ static void gen_set_sr(DisasContext *s, else if ((insn & 0x3f) == 0x3c) { uint16_t val; - val = lduw_code(s->pc); + val = lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; gen_set_sr_im(s, val, ccr_only); } else @@ -1502,8 +1523,9 @@ DISAS_INSN(mull) /* The upper 32 bits of the product are discarded, so muls.l and mulu.l are functionally equivalent. */ - ext = lduw_code(s->pc); + ext = lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; if (ext & 0x87ff) { gen_exception(s, s->pc - 4, EXCP_UNSUPPORTED); return; @@ -1523,8 +1545,9 @@ DISAS_INSN(link) int reg; int tmp; - offset = ldsw_code(s->pc); + offset = ldsw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; reg = AREG(insn, 0); tmp = gen_new_qreg(QMODE_I32); gen_op_sub32(tmp, QREG_SP, gen_im32(4)); @@ -1622,9 +1645,11 @@ DISAS_INSN(tpf) switch (insn & 7) { case 2: /* One extension word. */ s->pc += 2; + s->phys_pc += 2; break; case 3: /* Two extension words. */ s->pc += 4; + s->phys_pc += 4; break; case 4: /* No extension words. */ break; @@ -1644,8 +1669,9 @@ DISAS_INSN(branch) op = (insn >> 8) & 0xf; offset = (int8_t)insn; if (offset == 0) { - offset = ldsw_code(s->pc); + offset = ldsw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; } else if (offset == -1) { offset = read_im32(s); } @@ -1957,14 +1983,16 @@ DISAS_INSN(strldsr) uint32_t addr; addr = s->pc - 2; - ext = lduw_code(s->pc); + ext = lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; if (ext != 0x46FC) { gen_exception(s, addr, EXCP_UNSUPPORTED); return; } - ext = lduw_code(s->pc); + ext = lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; if (IS_USER(s) || (ext & SR_S) == 0) { gen_exception(s, addr, EXCP_PRIVILEGE); return; @@ -2032,8 +2060,9 @@ DISAS_INSN(stop) return; } - ext = lduw_code(s->pc); + ext = lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; gen_set_sr_im(s, ext, 0); gen_jmp(s, gen_im32(s->pc)); @@ -2059,8 +2088,9 @@ DISAS_INSN(movec) return; } - ext = lduw_code(s->pc); + ext = lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; if (ext & 0x8000) { reg = AREG(ext, 12); @@ -2121,8 +2151,9 @@ DISAS_INSN(fpu) int round; int opsize; - ext = lduw_code(s->pc); + ext = lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; opmode = ext & 0x7f; switch ((ext >> 13) & 7) { case 0: case 2: @@ -2331,6 +2362,7 @@ DISAS_INSN(fpu) return; undef: s->pc -= 2; + s->phys_pc -= 2; disas_undef_fpu(s, insn); } @@ -2343,11 +2375,14 @@ DISAS_INSN(fbcc) int l1; addr = s->pc; - offset = ldsw_code(s->pc); + offset = ldsw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; if (insn & (1 << 6)) { - offset = (offset << 16) | lduw_code(s->pc); + offset = (offset << 16) | + lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; } l1 = gen_new_label(); @@ -2473,8 +2508,9 @@ DISAS_INSN(mac) int dual; int saved_flags = -1; - ext = lduw_code(s->pc); + ext = lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; acc = ((insn >> 7) & 1) | ((ext >> 3) & 2); dual = ((insn & 0x30) != 0 && (ext & 3) != 0); @@ -2882,8 +2918,9 @@ static void disas_m68k_insn(CPUState * e { uint16_t insn; - insn = lduw_code(s->pc); + insn = lduw_code_p(&s->phys_pc_start, s->phys_pc, s->pc); s->pc += 2; + s->phys_pc += 2; opcode_table[insn](s, insn); } @@ -3169,6 +3206,9 @@ gen_intermediate_code_internal(CPUState dc->env = env; dc->is_jmp = DISAS_NEXT; dc->pc = pc_start; + dc->phys_pc_start = (unsigned long)phys_ram_base + tb->page_addr[0] + + (pc_start & ~TARGET_PAGE_MASK); + dc->phys_pc = dc->phys_pc_start; dc->cc_op = CC_OP_DYNAMIC; dc->singlestep_enabled = env->singlestep_enabled; dc->fpcr = env->fpcr; Index: target-mips/translate.c =================================================================== RCS file: /sources/qemu/qemu/target-mips/translate.c,v retrieving revision 1.106 diff -u -d -d -p -r1.106 translate.c --- target-mips/translate.c 9 Oct 2007 03:39:58 -0000 1.106 +++ target-mips/translate.c 12 Oct 2007 22:53:39 -0000 @@ -536,6 +536,7 @@ FOP_CONDS(abs, ps) typedef struct DisasContext { struct TranslationBlock *tb; target_ulong pc, saved_pc; + unsigned long phys_pc, phys_pc_start; uint32_t opcode; uint32_t fp_status; /* Routine used to access memory */ @@ -1764,6 +1765,7 @@ static void gen_compute_branch (DisasCon /* Skip the instruction in the delay slot */ MIPS_DEBUG("bnever, link and skip"); ctx->pc += 4; + ctx->phys_pc += 4; return; case OPC_BNEL: /* rx != rx likely */ case OPC_BGTZL: /* 0 > 0 likely */ @@ -1771,6 +1773,7 @@ static void gen_compute_branch (DisasCon /* Skip the instruction in the delay slot */ MIPS_DEBUG("bnever and skip"); ctx->pc += 4; + ctx->phys_pc += 4; return; case OPC_J: ctx->hflags |= MIPS_HFLAG_B; @@ -6495,6 +6498,9 @@ gen_intermediate_code_internal (CPUState gen_opparam_ptr = gen_opparam_buf; nb_gen_labels = 0; ctx.pc = pc_start; + ctx.phys_pc_start = (unsigned long)phys_ram_base + tb->page_addr[0] + + (pc_start & ~TARGET_PAGE_MASK); + ctx.phys_pc = ctx.phys_pc_start; ctx.saved_pc = -1; ctx.tb = tb; ctx.bstate = BS_NONE; @@ -6544,9 +6550,10 @@ gen_intermediate_code_internal (CPUState gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK; gen_opc_instr_start[lj] = 1; } - ctx.opcode = ldl_code(ctx.pc); + ctx.opcode = ldl_code_p(&ctx.phys_pc_start, ctx.phys_pc, ctx.pc); decode_opc(env, &ctx); ctx.pc += 4; + ctx.phys_pc += 4; if (env->singlestep_enabled) break; Index: target-ppc/translate.c =================================================================== RCS file: /sources/qemu/qemu/target-ppc/translate.c,v retrieving revision 1.92 diff -u -d -d -p -r1.92 translate.c --- target-ppc/translate.c 7 Oct 2007 23:10:08 -0000 1.92 +++ target-ppc/translate.c 12 Oct 2007 22:53:40 -0000 @@ -6678,6 +6678,7 @@ static always_inline int gen_intermediat { DisasContext ctx, *ctxp = &ctx; opc_handler_t **table, *handler; + unsigned long phys_pc, phys_pc_start; target_ulong pc_start; uint16_t *gen_opc_end; int supervisor; @@ -6685,6 +6686,9 @@ static always_inline int gen_intermediat int j, lj = -1; pc_start = tb->pc; + phys_pc_start = (unsigned long)phys_ram_base + tb->page_addr[0] + + (pc_start & ~TARGET_PAGE_MASK); + phys_pc = phys_pc_start; gen_opc_ptr = gen_opc_buf; gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; gen_opparam_ptr = gen_opparam_buf; @@ -6763,7 +6767,7 @@ static always_inline int gen_intermediat ctx.nip, 1 - msr_pr, msr_ir); } #endif - ctx.opcode = ldl_code(ctx.nip); + ctx.opcode = ldl_code_p(&phys_pc_start, phys_pc, env->nip); if (msr_le) { ctx.opcode = ((ctx.opcode & 0xFF000000) >> 24) | ((ctx.opcode & 0x00FF0000) >> 8) | @@ -6778,6 +6782,7 @@ static always_inline int gen_intermediat } #endif ctx.nip += 4; + phys_pc += 4; table = env->opcodes; handler = table[opc1(ctx.opcode)]; if (is_indirect_opcode(handler)) { Index: target-sh4/translate.c =================================================================== RCS file: /sources/qemu/qemu/target-sh4/translate.c,v retrieving revision 1.18 diff -u -d -d -p -r1.18 translate.c --- target-sh4/translate.c 29 Sep 2007 19:52:22 -0000 1.18 +++ target-sh4/translate.c 12 Oct 2007 22:53:40 -0000 @@ -1150,11 +1150,15 @@ gen_intermediate_code_internal(CPUState { DisasContext ctx; target_ulong pc_start; + unsigned long phys_pc, phys_pc_start; static uint16_t *gen_opc_end; uint32_t old_flags; int i, ii; pc_start = tb->pc; + phys_pc_start = (unsigned long)phys_ram_base + tb->page_addr[0] + + (pc_start & ~TARGET_PAGE_MASK); + phys_pc = phys_pc_start; gen_opc_ptr = gen_opc_buf; gen_opc_end = gen_opc_buf + OPC_MAX_SIZE; gen_opparam_ptr = gen_opparam_buf; @@ -1210,9 +1214,10 @@ gen_intermediate_code_internal(CPUState fprintf(stderr, "Loading opcode at address 0x%08x\n", ctx.pc); fflush(stderr); #endif - ctx.opcode = lduw_code(ctx.pc); + ctx.opcode = lduw_code_p(&phys_pc_start, phys_pc, ctx.pc); decode_opc(&ctx); ctx.pc += 2; + phys_pc += 2; if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0) break; if (env->singlestep_enabled) Index: target-sparc/translate.c =================================================================== RCS file: /sources/qemu/qemu/target-sparc/translate.c,v retrieving revision 1.74 diff -u -d -d -p -r1.74 translate.c --- target-sparc/translate.c 10 Oct 2007 19:11:54 -0000 1.74 +++ target-sparc/translate.c 12 Oct 2007 22:53:40 -0000 @@ -48,6 +48,8 @@ typedef struct DisasContext { target_ulong pc; /* current Program Counter: integer or DYNAMIC_PC */ target_ulong npc; /* next PC: integer or DYNAMIC_PC or JUMP_PC */ target_ulong jump_pc[2]; /* used when JUMP_PC pc value is used */ + unsigned long phys_pc; + unsigned long phys_pc_start; int is_br; int mem_idx; int fpu_enabled; @@ -1089,7 +1091,7 @@ static void disas_sparc_insn(DisasContex { unsigned int insn, opc, rs1, rs2, rd; - insn = ldl_code(dc->pc); + insn = ldl_code_p(&dc->phys_pc_start, dc->phys_pc, dc->pc); opc = GET_FIELD(insn, 0, 1); rd = GET_FIELD(insn, 2, 6); @@ -3319,6 +3321,7 @@ static void disas_sparc_insn(DisasContex } /* default case for non jump instructions */ if (dc->npc == DYNAMIC_PC) { + dc->phys_pc += DYNAMIC_PC - dc->pc; dc->pc = DYNAMIC_PC; gen_op_next_insn(); } else if (dc->npc == JUMP_PC) { @@ -3326,6 +3329,7 @@ static void disas_sparc_insn(DisasContex gen_branch2(dc, dc->jump_pc[0], dc->jump_pc[1]); dc->is_br = 1; } else { + dc->phys_pc += dc->npc - dc->pc; dc->pc = dc->npc; dc->npc = dc->npc + 4; } @@ -3376,6 +3380,9 @@ static inline int gen_intermediate_code_ dc->tb = tb; pc_start = tb->pc; dc->pc = pc_start; + dc->phys_pc_start = (unsigned long)phys_ram_base + tb->page_addr[0] + + (pc_start & ~TARGET_PAGE_MASK); + dc->phys_pc = dc->phys_pc_start; last_pc = dc->pc; dc->npc = (target_ulong) tb->cs_base; #if defined(CONFIG_USER_ONLY)