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 1 Correctness issues:
2 2  
  3 +- some eflags manipulation incorrectly reset the bit 0x2.
3 4 - rework eflags optimization (will be a consequence of TCG port)
4 5 - SVM: rework the implementation: simplify code, move most intercept
5 6 tests as dynamic, correct segment access, verify exception safety,
... ...
target-i386/helper.c
... ... @@ -108,6 +108,20 @@ void helper_unlock(void)
108 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 125 /* return non zero if error */
112 126 static inline int load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr,
113 127 int selector)
... ...
target-i386/helper.h
... ... @@ -2,6 +2,8 @@
2 2  
3 3 void helper_lock(void);
4 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 7 void helper_divb_AL(target_ulong t0);
6 8 void helper_idivb_AL(target_ulong t0);
7 9 void helper_divw_AX(target_ulong t0);
... ...
target-i386/op.c
... ... @@ -255,138 +255,3 @@ void OPPROTO op_xor_T0_1(void)
255 255 {
256 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 5733 } else {
5734 5734 if (s->cc_op != CC_OP_DYNAMIC)
5735 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 5737 gen_push_T0(s);
5738 5738 }
5739 5739 break;
... ... @@ -5746,22 +5746,28 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5746 5746 gen_pop_T0(s);
5747 5747 if (s->cpl == 0) {
5748 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 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 5755 } else {
5754 5756 if (s->cpl <= s->iopl) {
5755 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 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 5764 } else {
5761 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 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 5784 gen_op_mov_TN_reg(OT_BYTE, 0, R_AH);
5779 5785 if (s->cc_op != CC_OP_DYNAMIC)
5780 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 5791 s->cc_op = CC_OP_EFLAGS;
5783 5792 break;
5784 5793 case 0x9f: /* lahf */
... ... @@ -5786,25 +5795,30 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
5786 5795 goto illegal_op;
5787 5796 if (s->cc_op != CC_OP_DYNAMIC)
5788 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 5801 gen_op_mov_reg_T0(OT_BYTE, R_AH);
5791 5802 break;
5792 5803 case 0xf5: /* cmc */
5793 5804 if (s->cc_op != CC_OP_DYNAMIC)
5794 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 5808 s->cc_op = CC_OP_EFLAGS;
5797 5809 break;
5798 5810 case 0xf8: /* clc */
5799 5811 if (s->cc_op != CC_OP_DYNAMIC)
5800 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 5815 s->cc_op = CC_OP_EFLAGS;
5803 5816 break;
5804 5817 case 0xf9: /* stc */
5805 5818 if (s->cc_op != CC_OP_DYNAMIC)
5806 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 5822 s->cc_op = CC_OP_EFLAGS;
5809 5823 break;
5810 5824 case 0xfc: /* cld */
... ... @@ -6127,7 +6141,9 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
6127 6141 goto illegal_op;
6128 6142 if (s->cc_op != CC_OP_DYNAMIC)
6129 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 6147 break;
6132 6148 case 0xe0: /* loopnz */
6133 6149 case 0xe1: /* loopz */
... ...