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 | 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 */ | ... | ... |