From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Jyrme-0000VJ-Rj for qemu-devel@nongnu.org; Wed, 21 May 2008 13:07:24 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1Jyrmc-0000UC-NB for qemu-devel@nongnu.org; Wed, 21 May 2008 13:07:23 -0400 Received: from [199.232.76.173] (port=55263 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Jyrmc-0000U9-Fv for qemu-devel@nongnu.org; Wed, 21 May 2008 13:07:22 -0400 Received: from savannah.gnu.org ([199.232.41.3]:38282 helo=sv.gnu.org) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1Jyrmc-0005jF-Ar for qemu-devel@nongnu.org; Wed, 21 May 2008 13:07:22 -0400 Received: from cvs.savannah.gnu.org ([199.232.41.69]) by sv.gnu.org with esmtp (Exim 4.63) (envelope-from ) id 1Jyrmb-0005eF-HJ for qemu-devel@nongnu.org; Wed, 21 May 2008 17:07:21 +0000 Received: from bellard by cvs.savannah.gnu.org with local (Exim 4.63) (envelope-from ) id 1Jyrmb-0005eB-7R for qemu-devel@nongnu.org; Wed, 21 May 2008 17:07:21 +0000 MIME-Version: 1.0 Errors-To: bellard Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Fabrice Bellard Message-Id: Date: Wed, 21 May 2008 17:07:21 +0000 Subject: [Qemu-devel] [4515] convert eflags manipulation insns to TCG Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Revision: 4515 http://svn.sv.gnu.org/viewvc/?view=rev&root=qemu&revision=4515 Author: bellard Date: 2008-05-21 17:07:20 +0000 (Wed, 21 May 2008) Log Message: ----------- convert eflags manipulation insns to TCG Modified Paths: -------------- trunk/target-i386/TODO trunk/target-i386/helper.c trunk/target-i386/helper.h trunk/target-i386/op.c trunk/target-i386/translate.c Modified: trunk/target-i386/TODO =================================================================== --- trunk/target-i386/TODO 2008-05-21 16:34:06 UTC (rev 4514) +++ trunk/target-i386/TODO 2008-05-21 17:07:20 UTC (rev 4515) @@ -1,5 +1,6 @@ Correctness issues: +- some eflags manipulation incorrectly reset the bit 0x2. - rework eflags optimization (will be a consequence of TCG port) - SVM: rework the implementation: simplify code, move most intercept tests as dynamic, correct segment access, verify exception safety, Modified: trunk/target-i386/helper.c =================================================================== --- trunk/target-i386/helper.c 2008-05-21 16:34:06 UTC (rev 4514) +++ trunk/target-i386/helper.c 2008-05-21 17:07:20 UTC (rev 4515) @@ -108,6 +108,20 @@ spin_unlock(&global_cpu_lock); } +void helper_write_eflags(target_ulong t0, uint32_t update_mask) +{ + load_eflags(t0, update_mask); +} + +target_ulong helper_read_eflags(void) +{ + uint32_t eflags; + eflags = cc_table[CC_OP].compute_all(); + eflags |= (DF & DF_MASK); + eflags |= env->eflags & ~(VM_MASK | RF_MASK); + return eflags; +} + /* return non zero if error */ static inline int load_segment(uint32_t *e1_ptr, uint32_t *e2_ptr, int selector) Modified: trunk/target-i386/helper.h =================================================================== --- trunk/target-i386/helper.h 2008-05-21 16:34:06 UTC (rev 4514) +++ trunk/target-i386/helper.h 2008-05-21 17:07:20 UTC (rev 4515) @@ -2,6 +2,8 @@ void helper_lock(void); void helper_unlock(void); +void helper_write_eflags(target_ulong t0, uint32_t update_mask); +target_ulong helper_read_eflags(void); void helper_divb_AL(target_ulong t0); void helper_idivb_AL(target_ulong t0); void helper_divw_AX(target_ulong t0); Modified: trunk/target-i386/op.c =================================================================== --- trunk/target-i386/op.c 2008-05-21 16:34:06 UTC (rev 4514) +++ trunk/target-i386/op.c 2008-05-21 17:07:20 UTC (rev 4515) @@ -255,138 +255,3 @@ { T0 ^= 1; } - -/* XXX: clear VIF/VIP in all ops ? */ - -void OPPROTO op_movl_eflags_T0(void) -{ - load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK)); -} - -void OPPROTO op_movw_eflags_T0(void) -{ - load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff); -} - -void OPPROTO op_movl_eflags_T0_io(void) -{ - load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK)); -} - -void OPPROTO op_movw_eflags_T0_io(void) -{ - load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK) & 0xffff); -} - -void OPPROTO op_movl_eflags_T0_cpl0(void) -{ - load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK)); -} - -void OPPROTO op_movw_eflags_T0_cpl0(void) -{ - load_eflags(T0, (TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK) & 0xffff); -} - -#if 0 -/* vm86plus version */ -void OPPROTO op_movw_eflags_T0_vm(void) -{ - int eflags; - eflags = T0; - CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); - DF = 1 - (2 * ((eflags >> 10) & 1)); - /* we also update some system flags as in user mode */ - env->eflags = (env->eflags & ~(FL_UPDATE_MASK16 | VIF_MASK)) | - (eflags & FL_UPDATE_MASK16); - if (eflags & IF_MASK) { - env->eflags |= VIF_MASK; - if (env->eflags & VIP_MASK) { - EIP = PARAM1; - raise_exception(EXCP0D_GPF); - } - } - FORCE_RET(); -} - -void OPPROTO op_movl_eflags_T0_vm(void) -{ - int eflags; - eflags = T0; - CC_SRC = eflags & (CC_O | CC_S | CC_Z | CC_A | CC_P | CC_C); - DF = 1 - (2 * ((eflags >> 10) & 1)); - /* we also update some system flags as in user mode */ - env->eflags = (env->eflags & ~(FL_UPDATE_MASK32 | VIF_MASK)) | - (eflags & FL_UPDATE_MASK32); - if (eflags & IF_MASK) { - env->eflags |= VIF_MASK; - if (env->eflags & VIP_MASK) { - EIP = PARAM1; - raise_exception(EXCP0D_GPF); - } - } - FORCE_RET(); -} -#endif - -/* XXX: compute only O flag */ -void OPPROTO op_movb_eflags_T0(void) -{ - int of; - of = cc_table[CC_OP].compute_all() & CC_O; - CC_SRC = (T0 & (CC_S | CC_Z | CC_A | CC_P | CC_C)) | of; -} - -void OPPROTO op_movl_T0_eflags(void) -{ - int eflags; - eflags = cc_table[CC_OP].compute_all(); - eflags |= (DF & DF_MASK); - eflags |= env->eflags & ~(VM_MASK | RF_MASK); - T0 = eflags; -} - -/* vm86plus version */ -#if 0 -void OPPROTO op_movl_T0_eflags_vm(void) -{ - int eflags; - eflags = cc_table[CC_OP].compute_all(); - eflags |= (DF & DF_MASK); - eflags |= env->eflags & ~(VM_MASK | RF_MASK | IF_MASK); - if (env->eflags & VIF_MASK) - eflags |= IF_MASK; - T0 = eflags; -} -#endif - -void OPPROTO op_clc(void) -{ - int eflags; - eflags = cc_table[CC_OP].compute_all(); - eflags &= ~CC_C; - CC_SRC = eflags; -} - -void OPPROTO op_stc(void) -{ - int eflags; - eflags = cc_table[CC_OP].compute_all(); - eflags |= CC_C; - CC_SRC = eflags; -} - -void OPPROTO op_cmc(void) -{ - int eflags; - eflags = cc_table[CC_OP].compute_all(); - eflags ^= CC_C; - CC_SRC = eflags; -} - -void OPPROTO op_salc(void) -{ - int cf; - cf = cc_table[CC_OP].compute_c(); - EAX = (EAX & ~0xff) | ((-cf) & 0xff); -} Modified: trunk/target-i386/translate.c =================================================================== --- trunk/target-i386/translate.c 2008-05-21 16:34:06 UTC (rev 4514) +++ trunk/target-i386/translate.c 2008-05-21 17:07:20 UTC (rev 4515) @@ -5733,7 +5733,7 @@ } else { if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); - gen_op_movl_T0_eflags(); + tcg_gen_helper_1_0(helper_read_eflags, cpu_T[0]); gen_push_T0(s); } break; @@ -5746,22 +5746,28 @@ gen_pop_T0(s); if (s->cpl == 0) { if (s->dflag) { - gen_op_movl_eflags_T0_cpl0(); + tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0], + tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK))); } else { - gen_op_movw_eflags_T0_cpl0(); + tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0], + tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK | IOPL_MASK) & 0xffff)); } } else { if (s->cpl <= s->iopl) { if (s->dflag) { - gen_op_movl_eflags_T0_io(); + tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0], + tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK))); } else { - gen_op_movw_eflags_T0_io(); + tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0], + tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK | IF_MASK) & 0xffff)); } } else { if (s->dflag) { - gen_op_movl_eflags_T0(); + tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0], + tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK))); } else { - gen_op_movw_eflags_T0(); + tcg_gen_helper_0_2(helper_write_eflags, cpu_T[0], + tcg_const_i32((TF_MASK | AC_MASK | ID_MASK | NT_MASK) & 0xffff)); } } } @@ -5778,7 +5784,10 @@ gen_op_mov_TN_reg(OT_BYTE, 0, R_AH); if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); - gen_op_movb_eflags_T0(); + gen_compute_eflags(cpu_cc_src); + tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, CC_O); + tcg_gen_andi_tl(cpu_T[0], cpu_T[0], CC_S | CC_Z | CC_A | CC_P | CC_C); + tcg_gen_or_tl(cpu_cc_src, cpu_cc_src, cpu_T[0]); s->cc_op = CC_OP_EFLAGS; break; case 0x9f: /* lahf */ @@ -5786,25 +5795,30 @@ goto illegal_op; if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); - gen_op_movl_T0_eflags(); + gen_compute_eflags(cpu_T[0]); + /* Note: gen_compute_eflags() only gives the condition codes */ + tcg_gen_ori_tl(cpu_T[0], cpu_T[0], 0x02); gen_op_mov_reg_T0(OT_BYTE, R_AH); break; case 0xf5: /* cmc */ if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); - gen_op_cmc(); + gen_compute_eflags(cpu_cc_src); + tcg_gen_xori_tl(cpu_cc_src, cpu_cc_src, CC_C); s->cc_op = CC_OP_EFLAGS; break; case 0xf8: /* clc */ if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); - gen_op_clc(); + gen_compute_eflags(cpu_cc_src); + tcg_gen_andi_tl(cpu_cc_src, cpu_cc_src, ~CC_C); s->cc_op = CC_OP_EFLAGS; break; case 0xf9: /* stc */ if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); - gen_op_stc(); + gen_compute_eflags(cpu_cc_src); + tcg_gen_ori_tl(cpu_cc_src, cpu_cc_src, CC_C); s->cc_op = CC_OP_EFLAGS; break; case 0xfc: /* cld */ @@ -6127,7 +6141,9 @@ goto illegal_op; if (s->cc_op != CC_OP_DYNAMIC) gen_op_set_cc_op(s->cc_op); - gen_op_salc(); + gen_compute_eflags_c(cpu_T[0]); + tcg_gen_neg_tl(cpu_T[0], cpu_T[0]); + gen_op_mov_reg_T0(OT_BYTE, R_EAX); break; case 0xe0: /* loopnz */ case 0xe1: /* loopz */