Commit bd7a7b33df84cb053f9d2ac774d77372e4065d5f

Authored by bellard
1 parent 3bd7da9e

convert eflags manipulation insns to TCG

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4515 c046a42c-6fe2-441c-8c8c-71466251a162
target-i386/TODO
1 Correctness issues: 1 Correctness issues:
2 2
  3 +- some eflags manipulation incorrectly reset the bit 0x2.
3 - rework eflags optimization (will be a consequence of TCG port) 4 - rework eflags optimization (will be a consequence of TCG port)
4 - SVM: rework the implementation: simplify code, move most intercept 5 - SVM: rework the implementation: simplify code, move most intercept
5 tests as dynamic, correct segment access, verify exception safety, 6 tests as dynamic, correct segment access, verify exception safety,
target-i386/helper.c
@@ -108,6 +108,20 @@ void helper_unlock(void) @@ -108,6 +108,20 @@ void helper_unlock(void)
108 spin_unlock(&global_cpu_lock); 108 spin_unlock(&global_cpu_lock);
109 } 109 }
110 110
  111 +void helper_write_eflags(target_ulong t0, uint32_t update_mask)
  112 +{
  113 + load_eflags(t0, update_mask);
  114 +}
  115 +
  116 +target_ulong helper_read_eflags(void)
  117 +{
  118 + uint32_t eflags;
  119 + eflags = cc_table[CC_OP].compute_all();
  120 + eflags |= (DF & DF_MASK);
  121 + eflags |= env->eflags & ~(VM_MASK | RF_MASK);
  122 + return eflags;
  123 +}
  124 +
111 /* return non zero if error */ 125 /* return non zero if error */
112 static inline int load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr, 126 static inline int load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr,
113 int selector) 127 int selector)
target-i386/helper.h
@@ -2,6 +2,8 @@ @@ -2,6 +2,8 @@
2 2
3 void helper_lock(void); 3 void helper_lock(void);
4 void helper_unlock(void); 4 void helper_unlock(void);
  5 +void helper_write_eflags(target_ulong t0, uint32_t update_mask);
  6 +target_ulong helper_read_eflags(void);
5 void helper_divb_AL(target_ulong t0); 7 void helper_divb_AL(target_ulong t0);
6 void helper_idivb_AL(target_ulong t0); 8 void helper_idivb_AL(target_ulong t0);
7 void helper_divw_AX(target_ulong t0); 9 void helper_divw_AX(target_ulong t0);
target-i386/op.c
@@ -255,138 +255,3 @@ void OPPROTO op_xor_T0_1(void) @@ -255,138 +255,3 @@ void OPPROTO op_xor_T0_1(void)
255 { 255 {
256 T0 ^= 1; 256 T0 ^= 1;
257 } 257 }
258 -  
259 -/* XXX: clear VIF/VIP in all ops ? */  
260 -  
261 -void OPPROTO op_movl_eflags_T0(void)  
262 -{  
263 - load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK));  
264 -}  
265 -  
266 -void OPPROTO op_movw_eflags_T0(void)  
267 -{  
268 - load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff);  
269 -}  
270 -  
271 -void OPPROTO op_movl_eflags_T0_io(void)  
272 -{  
273 - load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK));  
274 -}  
275 -  
276 -void OPPROTO op_movw_eflags_T0_io(void)  
277 -{  
278 - load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK) & 0xffff);  
279 -}  
280 -  
281 -void OPPROTO op_movl_eflags_T0_cpl0(void)  
282 -{  
283 - load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK));  
284 -}  
285 -  
286 -void OPPROTO op_movw_eflags_T0_cpl0(void)  
287 -{  
288 - load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK) & 0xffff);  
289 -}  
290 -  
291 -#if 0  
292 -/* vm86plus version */  
293 -void OPPROTO op_movw_eflags_T0_vm(void)  
294 -{  
295 - int eflags;  
296 - eflags = T0;  
297 - CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);  
298 - DF = 1 - (2 * ((eflags >> 10) & 1));  
299 - /* we also update some system flags as in user mode */  
300 - env->eflags = (env->eflags & ~(FL_UPDATE_MASK16 | VIF_MASK)) |  
301 - (eflags & FL_UPDATE_MASK16);  
302 - if (eflags & IF_MASK) {  
303 - env->eflags |= VIF_MASK;  
304 - if (env->eflags & VIP_MASK) {  
305 - EIP = PARAM1;  
306 - raise_exception(EXCP0D_GPF);  
307 - }  
308 - }  
309 - FORCE_RET();  
310 -}  
311 -  
312 -void OPPROTO op_movl_eflags_T0_vm(void)  
313 -{  
314 - int eflags;  
315 - eflags = T0;  
316 - CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C);  
317 - DF = 1 - (2 * ((eflags >> 10) & 1));  
318 - /* we also update some system flags as in user mode */  
319 - env->eflags = (env->eflags & ~(FL_UPDATE_MASK32 | VIF_MASK)) |  
320 - (eflags & FL_UPDATE_MASK32);  
321 - if (eflags & IF_MASK) {  
322 - env->eflags |= VIF_MASK;  
323 - if (env->eflags & VIP_MASK) {  
324 - EIP = PARAM1;  
325 - raise_exception(EXCP0D_GPF);  
326 - }  
327 - }  
328 - FORCE_RET();  
329 -}  
330 -#endif  
331 -  
332 -/* XXX: compute only O flag */  
333 -void OPPROTO op_movb_eflags_T0(void)  
334 -{  
335 - int of;  
336 - of = cc_table[CC_OP].compute_all() & CC_O;  
337 - CC_SRC = (T0 & (CC_S | CC_Z | CC_A | CC_P | CC_C)) | of;  
338 -}  
339 -  
340 -void OPPROTO op_movl_T0_eflags(void)  
341 -{  
342 - int eflags;  
343 - eflags = cc_table[CC_OP].compute_all();  
344 - eflags |= (DF & DF_MASK);  
345 - eflags |= env->eflags & ~(VM_MASK | RF_MASK);  
346 - T0 = eflags;  
347 -}  
348 -  
349 -/* vm86plus version */  
350 -#if 0  
351 -void OPPROTO op_movl_T0_eflags_vm(void)  
352 -{  
353 - int eflags;  
354 - eflags = cc_table[CC_OP].compute_all();  
355 - eflags |= (DF & DF_MASK);  
356 - eflags |= env->eflags & ~(VM_MASK | RF_MASK | IF_MASK);  
357 - if (env->eflags & VIF_MASK)  
358 - eflags |= IF_MASK;  
359 - T0 = eflags;  
360 -}  
361 -#endif  
362 -  
363 -void OPPROTO op_clc(void)  
364 -{  
365 - int eflags;  
366 - eflags = cc_table[CC_OP].compute_all();  
367 - eflags &= ~CC_C;  
368 - CC_SRC = eflags;  
369 -}  
370 -  
371 -void OPPROTO op_stc(void)  
372 -{  
373 - int eflags;  
374 - eflags = cc_table[CC_OP].compute_all();  
375 - eflags |= CC_C;  
376 - CC_SRC = eflags;  
377 -}  
378 -  
379 -void OPPROTO op_cmc(void)  
380 -{  
381 - int eflags;  
382 - eflags = cc_table[CC_OP].compute_all();  
383 - eflags ^= CC_C;  
384 - CC_SRC = eflags;  
385 -}  
386 -  
387 -void OPPROTO op_salc(void)  
388 -{  
389 - int cf;  
390 - cf = cc_table[CC_OP].compute_c();  
391 - EAX = (EAX & ~0xff) | ((-cf) & 0xff);  
392 -}  
target-i386/translate.c
@@ -5733,7 +5733,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -5733,7 +5733,7 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5733 } else { 5733 } else {
5734 if (s->cc_op != CC_OP_DYNAMIC) 5734 if (s->cc_op != CC_OP_DYNAMIC)
5735 gen_op_set_cc_op(s->cc_op); 5735 gen_op_set_cc_op(s->cc_op);
5736 - gen_op_movl_T0_eflags(); 5736 + tcg_gen_helper_1_0(helper_read_eflags, cpu_T[0]);
5737 gen_push_T0(s); 5737 gen_push_T0(s);
5738 } 5738 }
5739 break; 5739 break;
@@ -5746,22 +5746,28 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -5746,22 +5746,28 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5746 gen_pop_T0(s); 5746 gen_pop_T0(s);
5747 if (s->cpl == 0) { 5747 if (s->cpl == 0) {
5748 if (s->dflag) { 5748 if (s->dflag) {
5749 - gen_op_movl_eflags_T0_cpl0(); 5749 + tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
  5750 + tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK)));
5750 } else { 5751 } else {
5751 - gen_op_movw_eflags_T0_cpl0(); 5752 + tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
  5753 + tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK) & 0xffff));
5752 } 5754 }
5753 } else { 5755 } else {
5754 if (s->cpl <= s->iopl) { 5756 if (s->cpl <= s->iopl) {
5755 if (s->dflag) { 5757 if (s->dflag) {
5756 - gen_op_movl_eflags_T0_io(); 5758 + tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
  5759 + tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK)));
5757 } else { 5760 } else {
5758 - gen_op_movw_eflags_T0_io(); 5761 + tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
  5762 + tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK) & 0xffff));
5759 } 5763 }
5760 } else { 5764 } else {
5761 if (s->dflag) { 5765 if (s->dflag) {
5762 - gen_op_movl_eflags_T0(); 5766 + tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
  5767 + tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK)));
5763 } else { 5768 } else {
5764 - gen_op_movw_eflags_T0(); 5769 + tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0],
  5770 + tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff));
5765 } 5771 }
5766 } 5772 }
5767 } 5773 }
@@ -5778,7 +5784,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -5778,7 +5784,10 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5778 gen_op_mov_TN_reg(OT_BYTE, 0, R_AH); 5784 gen_op_mov_TN_reg(OT_BYTE, 0, R_AH);
5779 if (s->cc_op != CC_OP_DYNAMIC) 5785 if (s->cc_op != CC_OP_DYNAMIC)
5780 gen_op_set_cc_op(s->cc_op); 5786 gen_op_set_cc_op(s->cc_op);
5781 - gen_op_movb_eflags_T0(); 5787 + gen_compute_eflags(cpu_cc_src);
  5788 + tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O);
  5789 + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], CC_S | CC_Z | CC_A | CC_P | CC_C);
  5790 + tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T[0]);
5782 s->cc_op = CC_OP_EFLAGS; 5791 s->cc_op = CC_OP_EFLAGS;
5783 break; 5792 break;
5784 case 0x9f: /* lahf */ 5793 case 0x9f: /* lahf */
@@ -5786,25 +5795,30 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -5786,25 +5795,30 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5786 goto illegal_op; 5795 goto illegal_op;
5787 if (s->cc_op != CC_OP_DYNAMIC) 5796 if (s->cc_op != CC_OP_DYNAMIC)
5788 gen_op_set_cc_op(s->cc_op); 5797 gen_op_set_cc_op(s->cc_op);
5789 - gen_op_movl_T0_eflags(); 5798 + gen_compute_eflags(cpu_T[0]);
  5799 + /* Note: gen_compute_eflags() only gives the condition codes */
  5800 + tcg_gen_ori_tl(cpu_T[0], cpu_T[0], 0x02);
5790 gen_op_mov_reg_T0(OT_BYTE, R_AH); 5801 gen_op_mov_reg_T0(OT_BYTE, R_AH);
5791 break; 5802 break;
5792 case 0xf5: /* cmc */ 5803 case 0xf5: /* cmc */
5793 if (s->cc_op != CC_OP_DYNAMIC) 5804 if (s->cc_op != CC_OP_DYNAMIC)
5794 gen_op_set_cc_op(s->cc_op); 5805 gen_op_set_cc_op(s->cc_op);
5795 - gen_op_cmc(); 5806 + gen_compute_eflags(cpu_cc_src);
  5807 + tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C);
5796 s->cc_op = CC_OP_EFLAGS; 5808 s->cc_op = CC_OP_EFLAGS;
5797 break; 5809 break;
5798 case 0xf8: /* clc */ 5810 case 0xf8: /* clc */
5799 if (s->cc_op != CC_OP_DYNAMIC) 5811 if (s->cc_op != CC_OP_DYNAMIC)
5800 gen_op_set_cc_op(s->cc_op); 5812 gen_op_set_cc_op(s->cc_op);
5801 - gen_op_clc(); 5813 + gen_compute_eflags(cpu_cc_src);
  5814 + tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C);
5802 s->cc_op = CC_OP_EFLAGS; 5815 s->cc_op = CC_OP_EFLAGS;
5803 break; 5816 break;
5804 case 0xf9: /* stc */ 5817 case 0xf9: /* stc */
5805 if (s->cc_op != CC_OP_DYNAMIC) 5818 if (s->cc_op != CC_OP_DYNAMIC)
5806 gen_op_set_cc_op(s->cc_op); 5819 gen_op_set_cc_op(s->cc_op);
5807 - gen_op_stc(); 5820 + gen_compute_eflags(cpu_cc_src);
  5821 + tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C);
5808 s->cc_op = CC_OP_EFLAGS; 5822 s->cc_op = CC_OP_EFLAGS;
5809 break; 5823 break;
5810 case 0xfc: /* cld */ 5824 case 0xfc: /* cld */
@@ -6127,7 +6141,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start) @@ -6127,7 +6141,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
6127 goto illegal_op; 6141 goto illegal_op;
6128 if (s->cc_op != CC_OP_DYNAMIC) 6142 if (s->cc_op != CC_OP_DYNAMIC)
6129 gen_op_set_cc_op(s->cc_op); 6143 gen_op_set_cc_op(s->cc_op);
6130 - gen_op_salc(); 6144 + gen_compute_eflags_c(cpu_T[0]);
  6145 + tcg_gen_neg_tl(cpu_T[0], cpu_T[0]);
  6146 + gen_op_mov_reg_T0(OT_BYTE, R_EAX);
6131 break; 6147 break;
6132 case 0xe0: /* loopnz */ 6148 case 0xe0: /* loopnz */
6133 case 0xe1: /* loopz */ 6149 case 0xe1: /* loopz */