Commit dc196a57e3e2e00e0c5f887390b1191787990193

Authored by bellard
1 parent 2a282056

fixed 16 bit segment optimisations


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@922 c046a42c-6fe2-441c-8c8c-71466251a162
target-i386/cpu.h
@@ -116,7 +116,7 @@ @@ -116,7 +116,7 @@
116 /* 16 or 32 segments */ 116 /* 16 or 32 segments */
117 #define HF_CS32_SHIFT 4 117 #define HF_CS32_SHIFT 4
118 #define HF_SS32_SHIFT 5 118 #define HF_SS32_SHIFT 5
119 -/* zero base for DS, ES and SS */ 119 +/* zero base for DS, ES and SS : can be '0' only in 32 bit CS segment */
120 #define HF_ADDSEG_SHIFT 6 120 #define HF_ADDSEG_SHIFT 6
121 /* copy of CR0.PE (protected mode) */ 121 /* copy of CR0.PE (protected mode) */
122 #define HF_PE_SHIFT 7 122 #define HF_PE_SHIFT 7
@@ -398,7 +398,9 @@ static inline void cpu_x86_load_seg_cache(CPUX86State *env, @@ -398,7 +398,9 @@ static inline void cpu_x86_load_seg_cache(CPUX86State *env,
398 >> (DESC_B_SHIFT - HF_CS32_SHIFT); 398 >> (DESC_B_SHIFT - HF_CS32_SHIFT);
399 new_hflags |= (env->segs[R_SS].flags & DESC_B_MASK) 399 new_hflags |= (env->segs[R_SS].flags & DESC_B_MASK)
400 >> (DESC_B_SHIFT - HF_SS32_SHIFT); 400 >> (DESC_B_SHIFT - HF_SS32_SHIFT);
401 - if (!(env->cr[0] & CR0_PE_MASK) || (env->eflags & VM_MASK)) { 401 + if (!(env->cr[0] & CR0_PE_MASK) ||
  402 + (env->eflags & VM_MASK) ||
  403 + !(new_hflags & HF_CS32_MASK)) {
402 /* XXX: try to avoid this test. The problem comes from the 404 /* XXX: try to avoid this test. The problem comes from the
403 fact that is real mode or vm86 mode we only modify the 405 fact that is real mode or vm86 mode we only modify the
404 'base' and 'selector' fields of the segment cache to go 406 'base' and 'selector' fields of the segment cache to go
target-i386/translate.c
@@ -1538,15 +1538,17 @@ static void gen_movl_seg_T0(DisasContext *s, int seg_reg, unsigned int cur_eip) @@ -1538,15 +1538,17 @@ static void gen_movl_seg_T0(DisasContext *s, int seg_reg, unsigned int cur_eip)
1538 gen_op_set_cc_op(s->cc_op); 1538 gen_op_set_cc_op(s->cc_op);
1539 gen_op_jmp_im(cur_eip); 1539 gen_op_jmp_im(cur_eip);
1540 gen_op_movl_seg_T0(seg_reg); 1540 gen_op_movl_seg_T0(seg_reg);
  1541 + /* abort translation because the addseg value may change or
  1542 + because ss32 may change. For R_SS, translation must always
  1543 + stop as a special handling must be done to disable hardware
  1544 + interrupts for the next instruction */
  1545 + if (seg_reg == R_SS || (s->code32 && seg_reg < R_FS))
  1546 + s->is_jmp = 3;
1541 } else { 1547 } else {
1542 gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[seg_reg])); 1548 gen_op_movl_seg_T0_vm(offsetof(CPUX86State,segs[seg_reg]));
  1549 + if (seg_reg == R_SS)
  1550 + s->is_jmp = 3;
1543 } 1551 }
1544 - /* abort translation because the register may have a non zero base  
1545 - or because ss32 may change. For R_SS, translation must always  
1546 - stop as a special handling must be done to disable hardware  
1547 - interrupts for the next instruction */  
1548 - if (seg_reg == R_SS || (!s->addseg && seg_reg < R_FS))  
1549 - s->is_jmp = 3;  
1550 } 1552 }
1551 1553
1552 static inline void gen_stack_update(DisasContext *s, int addend) 1554 static inline void gen_stack_update(DisasContext *s, int addend)
@@ -4572,7 +4574,7 @@ static inline int gen_intermediate_code_internal(CPUState *env, @@ -4572,7 +4574,7 @@ static inline int gen_intermediate_code_internal(CPUState *env,
4572 ); 4574 );
4573 #if 0 4575 #if 0
4574 /* check addseg logic */ 4576 /* check addseg logic */
4575 - if (!dc->addseg && (dc->vm86 || !dc->pe)) 4577 + if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))
4576 printf("ERROR addseg\n"); 4578 printf("ERROR addseg\n");
4577 #endif 4579 #endif
4578 4580