Commit bd7a7b33df84cb053f9d2ac774d77372e4065d5f
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
Showing
5 changed files
with
46 additions
and
148 deletions
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 */ |