From patchwork Thu Jan 24 04:03:17 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [33/57] target-i386: introduce gen_cmovcc1 Date: Wed, 23 Jan 2013 18:03:17 -0000 From: Richard Henderson X-Patchwork-Id: 215198 Message-Id: <1359000221-19834-34-git-send-email-rth@twiddle.net> To: qemu-devel@nongnu.org Cc: Blue Swirl , Paolo Bonzini From: Paolo Bonzini Signed-off-by: Richard Henderson --- target-i386/translate.c | 70 +++++++++++++++++++++++++------------------------ 1 file changed, 36 insertions(+), 34 deletions(-) diff --git a/target-i386/translate.c b/target-i386/translate.c index 9b57fb4..2a220c1 100644 --- a/target-i386/translate.c +++ b/target-i386/translate.c @@ -2407,6 +2407,38 @@ static inline void gen_jcc(DisasContext *s, int b, } } +static void gen_cmovcc1(CPUX86State *env, DisasContext *s, int ot, int b, + int modrm, int reg) +{ + int l1, mod = (modrm >> 6) & 3; + TCGv t0 = tcg_temp_local_new(); + + if (mod != 3) { + int reg_addr, offset_addr; + gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); + gen_op_ld_v(ot + s->mem_index, t0, cpu_A0); + } else { + int rm = (modrm & 7) | REX_B(s); + gen_op_mov_v_reg(ot, t0, rm); + } + + l1 = gen_new_label(); + gen_jcc1(s, b ^ 1, l1); +#ifdef TARGET_X86_64 + if (ot == OT_LONG) { + tcg_gen_mov_tl(cpu_regs[reg], t0); + gen_set_label(l1); + tcg_gen_ext32u_tl(cpu_regs[reg], cpu_regs[reg]); + } else +#endif + { + gen_op_mov_reg_v(ot, reg, t0); + gen_set_label(l1); + } + + tcg_temp_free(t0); +} + static inline void gen_op_movl_T0_seg(int seg_reg) { tcg_gen_ld32u_tl(cpu_T[0], cpu_env, @@ -6420,40 +6452,10 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s, gen_ldst_modrm(env, s, modrm, OT_BYTE, OR_TMP0, 1); break; case 0x140 ... 0x14f: /* cmov Gv, Ev */ - { - int l1; - TCGv t0; - - ot = dflag + OT_WORD; - modrm = cpu_ldub_code(env, s->pc++); - reg = ((modrm >> 3) & 7) | rex_r; - mod = (modrm >> 6) & 3; - t0 = tcg_temp_local_new(); - if (mod != 3) { - gen_lea_modrm(env, s, modrm, ®_addr, &offset_addr); - gen_op_ld_v(ot + s->mem_index, t0, cpu_A0); - } else { - rm = (modrm & 7) | REX_B(s); - gen_op_mov_v_reg(ot, t0, rm); - } -#ifdef TARGET_X86_64 - if (ot == OT_LONG) { - /* XXX: specific Intel behaviour ? */ - l1 = gen_new_label(); - gen_jcc1(s, b ^ 1, l1); - tcg_gen_mov_tl(cpu_regs[reg], t0); - gen_set_label(l1); - tcg_gen_ext32u_tl(cpu_regs[reg], cpu_regs[reg]); - } else -#endif - { - l1 = gen_new_label(); - gen_jcc1(s, b ^ 1, l1); - gen_op_mov_reg_v(ot, reg, t0); - gen_set_label(l1); - } - tcg_temp_free(t0); - } + ot = dflag + OT_WORD; + modrm = cpu_ldub_code(env, s->pc++); + reg = ((modrm >> 3) & 7) | rex_r; + gen_cmovcc1(env, s, ot, b, modrm, reg); break; /************************/