mirror of https://gitee.com/openkylin/qemu.git
Fix BT zero flag for new Intel manuals
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQEcBAABAgAGBQJTcTxpAAoJEK0ScMxN0CebexYIAKAQdpfw8eamRMZqwwxllKrM VjdU3iR8ODpRmfEEvh+ZV80zF2OdiWNnGHAUEqk4Ur9G2r20kLrqtJanq/tX2FUZ S7GrcpQRWAXYIv872mrY7V2DyyLohIeUmTh6USgZXRC2saEYffOEsmos9uMVZjzD L3IP50OwpXCTRTwPQ8VyauwENf5ynOvIxkauFKq9PC48T60BOCfBUoNyHMzlMDTl UKPt/1f13YvAub68MyhpivMTQP8Z1E+ZbBgo6JZ8Wjx/8NaXBAqHSGVby9FTDhac a1NvjQxlgjpwkjxrygXy51R+5gfWDoJkaqdNbUUqc7FIAsW0BjY0/rX8eIM6m2Q= =70Dp -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/rth/tags/pull-tgt-i386-20140512' into staging Fix BT zero flag for new Intel manuals # gpg: Signature made Mon 12 May 2014 22:26:01 BST using RSA key ID 4DD0279B # gpg: Can't check signature: public key not found * remotes/rth/tags/pull-tgt-i386-20140512: target-i386: Preserve the Z bit for bt/bts/btr/btc Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
06e33c1c3c
|
@ -6708,41 +6708,63 @@ static target_ulong disas_insn(CPUX86State *env, DisasContext *s,
|
|||
}
|
||||
bt_op:
|
||||
tcg_gen_andi_tl(cpu_T[1], cpu_T[1], (1 << (3 + ot)) - 1);
|
||||
tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
|
||||
switch(op) {
|
||||
case 0:
|
||||
tcg_gen_shr_tl(cpu_cc_src, cpu_T[0], cpu_T[1]);
|
||||
tcg_gen_movi_tl(cpu_cc_dst, 0);
|
||||
break;
|
||||
case 1:
|
||||
tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
|
||||
tcg_gen_movi_tl(cpu_tmp0, 1);
|
||||
tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
|
||||
tcg_gen_or_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
|
||||
break;
|
||||
case 2:
|
||||
tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
|
||||
tcg_gen_movi_tl(cpu_tmp0, 1);
|
||||
tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
|
||||
tcg_gen_not_tl(cpu_tmp0, cpu_tmp0);
|
||||
tcg_gen_and_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
|
||||
tcg_gen_andc_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
|
||||
break;
|
||||
default:
|
||||
case 3:
|
||||
tcg_gen_shr_tl(cpu_tmp4, cpu_T[0], cpu_T[1]);
|
||||
tcg_gen_movi_tl(cpu_tmp0, 1);
|
||||
tcg_gen_shl_tl(cpu_tmp0, cpu_tmp0, cpu_T[1]);
|
||||
tcg_gen_xor_tl(cpu_T[0], cpu_T[0], cpu_tmp0);
|
||||
break;
|
||||
}
|
||||
set_cc_op(s, CC_OP_SARB + ot);
|
||||
if (op != 0) {
|
||||
if (mod != 3) {
|
||||
gen_op_st_v(s, ot, cpu_T[0], cpu_A0);
|
||||
} else {
|
||||
gen_op_mov_reg_v(ot, rm, cpu_T[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Delay all CC updates until after the store above. Note that
|
||||
C is the result of the test, Z is unchanged, and the others
|
||||
are all undefined. */
|
||||
switch (s->cc_op) {
|
||||
case CC_OP_MULB ... CC_OP_MULQ:
|
||||
case CC_OP_ADDB ... CC_OP_ADDQ:
|
||||
case CC_OP_ADCB ... CC_OP_ADCQ:
|
||||
case CC_OP_SUBB ... CC_OP_SUBQ:
|
||||
case CC_OP_SBBB ... CC_OP_SBBQ:
|
||||
case CC_OP_LOGICB ... CC_OP_LOGICQ:
|
||||
case CC_OP_INCB ... CC_OP_INCQ:
|
||||
case CC_OP_DECB ... CC_OP_DECQ:
|
||||
case CC_OP_SHLB ... CC_OP_SHLQ:
|
||||
case CC_OP_SARB ... CC_OP_SARQ:
|
||||
case CC_OP_BMILGB ... CC_OP_BMILGQ:
|
||||
/* Z was going to be computed from the non-zero status of CC_DST.
|
||||
We can get that same Z value (and the new C value) by leaving
|
||||
CC_DST alone, setting CC_SRC, and using a CC_OP_SAR of the
|
||||
same width. */
|
||||
tcg_gen_mov_tl(cpu_cc_src, cpu_tmp4);
|
||||
tcg_gen_movi_tl(cpu_cc_dst, 0);
|
||||
set_cc_op(s, ((s->cc_op - CC_OP_MULB) & 3) + CC_OP_SARB);
|
||||
break;
|
||||
default:
|
||||
/* Otherwise, generate EFLAGS and replace the C bit. */
|
||||
gen_compute_eflags(s);
|
||||
tcg_gen_deposit_tl(cpu_cc_src, cpu_cc_src, cpu_tmp4,
|
||||
ctz32(CC_C), 1);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0x1bc: /* bsf / tzcnt */
|
||||
|
|
Loading…
Reference in New Issue