From: "J. Mayer" <l_indien@magic.fr>
To: qemu-devel@nongnu.org
Subject: [Fwd: Re: [Qemu-devel] RFC: Code fetch optimisation]
Date: Sat, 13 Oct 2007 01:00:23 +0200 [thread overview]
Message-ID: <1192230023.9976.291.camel@rapid> (raw)
[-- Attachment #1: Type: text/plain, Size: 2473 bytes --]
-------- Forwarded Message --------
> From: Jocelyn Mayer <l_indien@magic.fr>
> Reply-To: l_indien@magic.fr, qemu-devel@nongnu.org
> To: qemu-devel@nongnu.org
> Subject: Re: [Qemu-devel] RFC: Code fetch optimisation
> Date: Fri, 12 Oct 2007 20:24:44 +0200
>
> On Fri, 2007-10-12 at 18:21 +0300, Blue Swirl wrote:
> > On 10/12/07, J. Mayer <l_indien@magic.fr> wrote:
> > > Here's a small patch that allow an optimisation for code fetch, at least
> > > for RISC CPU targets, as suggested by Fabrice Bellard.
> > > The main idea is that a translated block is never to span over a page
> > > boundary. As the tb_find_slow routine already gets the physical address
> > > of the page of code to be translated, the code translator could then
> > > fetch the code using raw host memory accesses instead of doing it
> > > through the softmmu routines.
> > > This patch could also be adapted to RISC CPU targets, with care for the
> > > last instruction of a page. For now, I did implement it for alpha, arm,
> > > mips, PowerPC and SH4.
> > > I don't actually know if the optimsation would bring a sensible speed
> > > gain or if it will be absolutelly marginal.
> > >
> > > Please comment.
> >
> > This will not work correctly for execution of MMIO registers, but
> > maybe that won't work on real hardware either. Who cares.
>
> I wonder if this is important or not... But maybe, when retrieving the
> physical address we could check if it is inside ROM/RAM or an I/O area
> and in the last case do not give the phys_addr information to the
> translator. In that case, it would go on using the ldxx_code. I guess if
> we want to do that, a set of helpers would be appreciated to avoid
> adding code like:
> if (phys_pc == 0)
> opc = ldul_code(virt_pc)
> else
> opc = ldul_raw(phys_pc)
> everywhere... I could also add another check so this set of macro would
> automatically use ldxx_code if we reach a page boundary, which would
> then make easy to use this optimisation for CISC/VLE architectures too.
>
> I'm not sure of the proper solution to allow executing code from mmio
> devices. But adding specific accessors to handle the CISC/VLE case is to
> be done.
[...]
I did update my patch following this way and it's now able to run x86
and PowerPC targets.
PowerPC is the easy case, x86 is maybe the worst... Well, I'm not really
sure of what I've done for Sparc, but other targets should be safe.
Please comment.
--
J. Mayer <l_indien@magic.fr>
Never organized
[-- Attachment #2: code_raw_optim.diff --]
[-- Type: text/x-patch, Size: 55562 bytes --]
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)
next reply other threads:[~2007-10-12 23:00 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-10-12 23:00 J. Mayer [this message]
2007-10-13 7:11 ` [Fwd: Re: [Qemu-devel] RFC: Code fetch optimisation] Blue Swirl
2007-10-13 9:57 ` J. Mayer
2007-10-13 11:05 ` J. Mayer
2007-10-13 11:58 ` Blue Swirl
2007-10-13 19:07 ` Thiemo Seufer
2007-10-13 21:11 ` J. Mayer
2007-10-13 11:08 ` Blue Swirl
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1192230023.9976.291.camel@rapid \
--to=l_indien@magic.fr \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).