fixed 16 bit segment optimisations
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@922 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
parent
2a2820560d
commit
dc196a57e3
@ -116,7 +116,7 @@
|
|||||||
/* 16 or 32 segments */
|
/* 16 or 32 segments */
|
||||||
#define HF_CS32_SHIFT 4
|
#define HF_CS32_SHIFT 4
|
||||||
#define HF_SS32_SHIFT 5
|
#define HF_SS32_SHIFT 5
|
||||||
/* zero base for DS, ES and SS */
|
/* zero base for DS, ES and SS : can be '0' only in 32 bit CS segment */
|
||||||
#define HF_ADDSEG_SHIFT 6
|
#define HF_ADDSEG_SHIFT 6
|
||||||
/* copy of CR0.PE (protected mode) */
|
/* copy of CR0.PE (protected mode) */
|
||||||
#define HF_PE_SHIFT 7
|
#define HF_PE_SHIFT 7
|
||||||
@ -398,7 +398,9 @@ static inline void cpu_x86_load_seg_cache(CPUX86State *env,
|
|||||||
>> (DESC_B_SHIFT - HF_CS32_SHIFT);
|
>> (DESC_B_SHIFT - HF_CS32_SHIFT);
|
||||||
new_hflags |= (env->segs[R_SS].flags & DESC_B_MASK)
|
new_hflags |= (env->segs[R_SS].flags & DESC_B_MASK)
|
||||||
>> (DESC_B_SHIFT - HF_SS32_SHIFT);
|
>> (DESC_B_SHIFT - HF_SS32_SHIFT);
|
||||||
if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) {
|
if (!(env->cr[0] & CR0_PE_MASK) ||
|
||||||
|
(env->eflags & VM_MASK) ||
|
||||||
|
!(new_hflags & HF_CS32_MASK)) {
|
||||||
/* XXX: try to avoid this test. The problem comes from the
|
/* XXX: try to avoid this test. The problem comes from the
|
||||||
fact that is real mode or vm86 mode we only modify the
|
fact that is real mode or vm86 mode we only modify the
|
||||||
'base' and 'selector' fields of the segment cache to go
|
'base' and 'selector' fields of the segment cache to go
|
||||||
|
@ -1538,15 +1538,17 @@ static void gen_movl_seg_T0(DisasContext *s, int seg_reg, unsigned int cur_eip)
|
|||||||
gen_op_set_cc_op(s->cc_op);
|
gen_op_set_cc_op(s->cc_op);
|
||||||
gen_op_jmp_im(cur_eip);
|
gen_op_jmp_im(cur_eip);
|
||||||
gen_op_movl_seg_T0(seg_reg);
|
gen_op_movl_seg_T0(seg_reg);
|
||||||
|
/* abort translation because the addseg value may change or
|
||||||
|
because ss32 may change. For R_SS, translation must always
|
||||||
|
stop as a special handling must be done to disable hardware
|
||||||
|
interrupts for the next instruction */
|
||||||
|
if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
|
||||||
|
s->is_jmp = 3;
|
||||||
} else {
|
} else {
|
||||||
gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[seg_reg]));
|
gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[seg_reg]));
|
||||||
|
if (seg_reg == R_SS)
|
||||||
|
s->is_jmp = 3;
|
||||||
}
|
}
|
||||||
/* abort translation because the register may have a non zero base
|
|
||||||
or because ss32 may change. For R_SS, translation must always
|
|
||||||
stop as a special handling must be done to disable hardware
|
|
||||||
interrupts for the next instruction */
|
|
||||||
if (seg_reg == R_SS || (!s->addseg && seg_reg < R_FS))
|
|
||||||
s->is_jmp = 3;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void gen_stack_update(DisasContext *s, int addend)
|
static inline void gen_stack_update(DisasContext *s, int addend)
|
||||||
@ -4572,7 +4574,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
|
|||||||
);
|
);
|
||||||
#if 0
|
#if 0
|
||||||
/* check addseg logic */
|
/* check addseg logic */
|
||||||
if (!dc->addseg && (dc->vm86 || !dc->pe))
|
if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
|
||||||
printf("ERROR addseg\n");
|
printf("ERROR addseg\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user