aboutsummaryrefslogtreecommitdiff
path: root/target-i386
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2004-04-25 17:57:43 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2004-04-25 17:57:43 +0000
commitd720b93d0bcfe1beb729245b9ed1e5f071a24bd5 (patch)
tree4f9d65b82b9eb8bd65681cfde6bb18e7b6bd2eae /target-i386
parenteeab3a558f89e30ee93ef628bcbd6a3f64b9b8a6 (diff)
precise self modifying code support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@745 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'target-i386')
-rw-r--r--target-i386/cpu.h18
-rw-r--r--target-i386/translate-copy.c2
-rw-r--r--target-i386/translate.c6
3 files changed, 22 insertions, 4 deletions
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index daa2133f8e..6b2a89bb9a 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -22,6 +22,12 @@
#define TARGET_LONG_BITS 32
+/* target supports implicit self modifying code */
+#define TARGET_HAS_SMC
+/* support for self modifying code even if the modified instruction is
+ close to the modifying instruction */
+#define TARGET_HAS_PRECISE_SMC
+
#include "cpu-defs.h"
#if defined(__i386__) && !defined(CONFIG_SOFTMMU)
@@ -331,8 +337,16 @@ typedef struct CPUX86State {
int interrupt_request;
int user_mode_only; /* user mode only simulation */
- /* soft mmu support */
uint32_t a20_mask;
+
+ /* soft mmu support */
+ /* in order to avoid passing too many arguments to the memory
+ write helpers, we store some rarely used information in the CPU
+ context) */
+ unsigned long mem_write_pc; /* host pc at which the memory was
+ written */
+ unsigned long mem_write_vaddr; /* target virtual addr at which the
+ memory was written */
/* 0 = kernel, 1 = user */
CPUTLBEntry tlb_read[2][CPU_TLB_SIZE];
CPUTLBEntry tlb_write[2][CPU_TLB_SIZE];
@@ -358,7 +372,7 @@ int cpu_x86_inl(CPUX86State *env, int addr);
CPUX86State *cpu_x86_init(void);
int cpu_x86_exec(CPUX86State *s);
void cpu_x86_close(CPUX86State *s);
-int cpu_x86_get_pic_interrupt(CPUX86State *s);
+int cpu_get_pic_interrupt(CPUX86State *s);
/* this function must always be used to load data in the segment
cache: it synchronizes the hflags with the segment cache values */
diff --git a/target-i386/translate-copy.c b/target-i386/translate-copy.c
index 500475a74a..e6f9198abc 100644
--- a/target-i386/translate-copy.c
+++ b/target-i386/translate-copy.c
@@ -1189,6 +1189,8 @@ static inline int gen_intermediate_code_internal(CPUState *env,
return -1;
if (!(flags & HF_SS32_MASK))
return -1;
+ if (tb->cflags & CF_SINGLE_INSN)
+ return -1;
gen_code_end = gen_code_ptr +
GEN_CODE_MAX_SIZE - GEN_CODE_MAX_INSN_SIZE;
dc->gen_code_ptr = gen_code_ptr;
diff --git a/target-i386/translate.c b/target-i386/translate.c
index 4bddba56a3..a1a4c633dc 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -4491,7 +4491,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
DisasContext dc1, *dc = &dc1;
uint8_t *pc_ptr;
uint16_t *gen_opc_end;
- int flags, j, lj;
+ int flags, j, lj, cflags;
uint8_t *pc_start;
uint8_t *cs_base;
@@ -4499,6 +4499,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
pc_start = (uint8_t *)tb->pc;
cs_base = (uint8_t *)tb->cs_base;
flags = tb->flags;
+ cflags = tb->cflags;
dc->pe = (flags >> HF_PE_SHIFT) & 1;
dc->code32 = (flags >> HF_CS32_SHIFT) & 1;
@@ -4573,7 +4574,8 @@ static inline int gen_intermediate_code_internal(CPUState *env,
the flag and abort the translation to give the irqs a
change to be happen */
if (dc->tf || dc->singlestep_enabled ||
- (flags & HF_INHIBIT_IRQ_MASK)) {
+ (flags & HF_INHIBIT_IRQ_MASK) ||
+ (cflags & CF_SINGLE_INSN)) {
gen_op_jmp_im(pc_ptr - dc->cs_base);
gen_eob(dc);
break;