diff options
Diffstat (limited to 'target/i386/tcg')
| -rw-r--r-- | target/i386/tcg/emit.c.inc | 59 | ||||
| -rw-r--r-- | target/i386/tcg/system/misc_helper.c | 3 | ||||
| -rw-r--r-- | target/i386/tcg/translate.c | 2 |
3 files changed, 42 insertions, 22 deletions
diff --git a/target/i386/tcg/emit.c.inc b/target/i386/tcg/emit.c.inc index 785ff63f2a..c4cc5f48d8 100644 --- a/target/i386/tcg/emit.c.inc +++ b/target/i386/tcg/emit.c.inc @@ -286,24 +286,25 @@ static void gen_load(DisasContext *s, X86DecodedInsn *decode, int opn, TCGv v) gen_op_ld_v(s, op->ot, v, s->A0); } - } else if (op->ot == MO_8 && byte_reg_is_xH(s, op->n)) { - if (v == s->T0 && decode->e.special == X86_SPECIAL_SExtT0) { - tcg_gen_sextract_tl(v, cpu_regs[op->n - 4], 8, 8); - } else { - tcg_gen_extract_tl(v, cpu_regs[op->n - 4], 8, 8); - } - } else if (op->ot < MO_TL && v == s->T0 && (decode->e.special == X86_SPECIAL_SExtT0 || decode->e.special == X86_SPECIAL_ZExtT0)) { - if (decode->e.special == X86_SPECIAL_SExtT0) { - tcg_gen_ext_tl(v, cpu_regs[op->n], op->ot | MO_SIGN); + if (op->ot == MO_8 && byte_reg_is_xH(s, op->n)) { + if (decode->e.special == X86_SPECIAL_SExtT0) { + tcg_gen_sextract_tl(v, cpu_regs[op->n - 4], 8, 8); + } else { + tcg_gen_extract_tl(v, cpu_regs[op->n - 4], 8, 8); + } } else { - tcg_gen_ext_tl(v, cpu_regs[op->n], op->ot); + if (decode->e.special == X86_SPECIAL_SExtT0) { + tcg_gen_ext_tl(v, cpu_regs[op->n], op->ot | MO_SIGN); + } else { + tcg_gen_ext_tl(v, cpu_regs[op->n], op->ot); + } } } else { - tcg_gen_mov_tl(v, cpu_regs[op->n]); + gen_op_mov_v_reg(s, op->ot, v, op->n); } break; case X86_OP_IMM: @@ -1443,8 +1444,9 @@ static TCGv gen_bt_mask(DisasContext *s, X86DecodedInsn *decode) return mask; } -/* Expects truncated bit index in s->T1, 1 << s->T1 in MASK. */ -static void gen_bt_flags(DisasContext *s, X86DecodedInsn *decode, TCGv src, TCGv mask) +/* Expects truncated bit index in COUNT, 1 << COUNT in MASK. */ +static void gen_bt_flags(DisasContext *s, X86DecodedInsn *decode, TCGv src, + TCGv count, TCGv mask) { TCGv cf; @@ -1467,15 +1469,34 @@ static void gen_bt_flags(DisasContext *s, X86DecodedInsn *decode, TCGv src, TCGv decode->cc_src = tcg_temp_new(); decode->cc_dst = cpu_cc_dst; decode->cc_op = CC_OP_SARB + cc_op_size(s->cc_op); - tcg_gen_shr_tl(decode->cc_src, src, s->T1); + tcg_gen_shr_tl(decode->cc_src, src, count); } } static void gen_BT(DisasContext *s, X86DecodedInsn *decode) { - TCGv mask = gen_bt_mask(s, decode); + TCGv count = s->T1; + TCGv mask; + + /* + * Try to ensure that the rhs of the TSTNE condition is a constant (and a + * power of two), as that is more readily available on most TCG backends. + * + * For immediate bit number gen_bt_mask()'s output is already a constant; + * for register bit number, shift the source right and check bit 0. + */ + if (decode->e.op2 == X86_TYPE_I) { + mask = gen_bt_mask(s, decode); + } else { + MemOp ot = decode->op[1].ot; + + tcg_gen_andi_tl(s->T1, s->T1, (8 << ot) - 1); + tcg_gen_shr_tl(s->T0, s->T0, s->T1); - gen_bt_flags(s, decode, s->T0, mask); + count = tcg_constant_tl(0); + mask = tcg_constant_tl(1); + } + gen_bt_flags(s, decode, s->T0, count, mask); } static void gen_BTC(DisasContext *s, X86DecodedInsn *decode) @@ -1491,7 +1512,7 @@ static void gen_BTC(DisasContext *s, X86DecodedInsn *decode) tcg_gen_xor_tl(s->T0, s->T0, mask); } - gen_bt_flags(s, decode, old, mask); + gen_bt_flags(s, decode, old, s->T1, mask); } static void gen_BTR(DisasContext *s, X86DecodedInsn *decode) @@ -1509,7 +1530,7 @@ static void gen_BTR(DisasContext *s, X86DecodedInsn *decode) tcg_gen_andc_tl(s->T0, s->T0, mask); } - gen_bt_flags(s, decode, old, mask); + gen_bt_flags(s, decode, old, s->T1, mask); } static void gen_BTS(DisasContext *s, X86DecodedInsn *decode) @@ -1525,7 +1546,7 @@ static void gen_BTS(DisasContext *s, X86DecodedInsn *decode) tcg_gen_or_tl(s->T0, s->T0, mask); } - gen_bt_flags(s, decode, old, mask); + gen_bt_flags(s, decode, old, s->T1, mask); } static void gen_BZHI(DisasContext *s, X86DecodedInsn *decode) diff --git a/target/i386/tcg/system/misc_helper.c b/target/i386/tcg/system/misc_helper.c index ffed8a3215..c9c4d42f84 100644 --- a/target/i386/tcg/system/misc_helper.c +++ b/target/i386/tcg/system/misc_helper.c @@ -468,8 +468,7 @@ void helper_rdmsr(CPUX86State *env) val = x86_cpu->ucode_rev; break; case MSR_CORE_THREAD_COUNT: { - CPUState *cs = CPU(x86_cpu); - val = (cs->nr_threads * cs->nr_cores) | (cs->nr_cores << 16); + val = cpu_x86_get_msr_core_thread_count(x86_cpu); break; } case MSR_APIC_START ... MSR_APIC_END: { diff --git a/target/i386/tcg/translate.c b/target/i386/tcg/translate.c index 834aea1e59..dbc9d637c4 100644 --- a/target/i386/tcg/translate.c +++ b/target/i386/tcg/translate.c @@ -486,7 +486,7 @@ static inline void gen_op_mov_v_reg(DisasContext *s, MemOp ot, TCGv t0, int reg) { if (ot == MO_8 && byte_reg_is_xH(s, reg)) { - tcg_gen_extract_tl(t0, cpu_regs[reg - 4], 8, 8); + tcg_gen_shri_tl(t0, cpu_regs[reg - 4], 8); } else { tcg_gen_mov_tl(t0, cpu_regs[reg]); } |