Collected x86 patches

-----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1
 
 iQEcBAABAgAGBQJUjhUkAAoJEK0ScMxN0Cebe+IIAKTLD3oU9wLJ+PKIOcbRGoGq
 w+T9j16z/N5DlAT9WOJSPFqc4BYOjncm8CbV9OiTcqVkRYkX1B4Ne+Ao5oEiv3D3
 leABNxnM3h7ncvw89jb5C/ObWkmA6HmKZQDnUX5HwVaek3tTllmLzFqznDOnjGfr
 AajMEh4QkWdTufi+Vmn46MlhkJ5Z0GyhxYRKtjNcZ2sNh8o1gbcKA2uyUaQeUbi6
 WjYq66Gm7qWszKHSXmC0RTcF+uzlOVSaEAqDNvb1MvNyBvNQ3e6gHVazKQ1IVy3l
 +Smvc5pGbyS2qQSiLe2qEXhagzNARVPY7NNFhct++hpWW3O3it0z/aH4FqL2C/k=
 =32Pn
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/rth/tags/x86-next-20141214' into staging

Collected x86 patches

# gpg: Signature made Sun 14 Dec 2014 22:54:28 GMT using RSA key ID 4DD0279B
# gpg: Good signature from "Richard Henderson <rth7680@gmail.com>"
# gpg:                 aka "Richard Henderson <rth@redhat.com>"
# gpg:                 aka "Richard Henderson <rth@twiddle.net>"

* remotes/rth/tags/x86-next-20141214:
  target-i386: fix icount processing for repz instructions
  target-i386: fbld instruction doesn't set minus sign
  target-i386: Wrong conversion infinity from float80 to int32/int64

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2014-12-15 11:11:52 +00:00
commit 54600752a1
2 changed files with 34 additions and 4 deletions

View File

@ -251,16 +251,34 @@ int32_t helper_fist_ST0(CPUX86State *env)
int32_t helper_fistl_ST0(CPUX86State *env)
{
int32_t val;
signed char old_exp_flags;
old_exp_flags = get_float_exception_flags(&env->fp_status);
set_float_exception_flags(0, &env->fp_status);
val = floatx80_to_int32(ST0, &env->fp_status);
if (get_float_exception_flags(&env->fp_status) & float_flag_invalid) {
val = 0x80000000;
}
set_float_exception_flags(get_float_exception_flags(&env->fp_status)
| old_exp_flags, &env->fp_status);
return val;
}
int64_t helper_fistll_ST0(CPUX86State *env)
{
int64_t val;
signed char old_exp_flags;
val = floatx80_to_int64(ST0, &env->fp_status);
old_exp_flags = get_float_exception_flags(&env->fp_status);
set_float_exception_flags(0, &env->fp_status);
val = floatx80_to_int32(ST0, &env->fp_status);
if (get_float_exception_flags(&env->fp_status) & float_flag_invalid) {
val = 0x8000000000000000ULL;
}
set_float_exception_flags(get_float_exception_flags(&env->fp_status)
| old_exp_flags, &env->fp_status);
return val;
}
@ -621,7 +639,7 @@ void helper_fbld_ST0(CPUX86State *env, target_ulong ptr)
}
tmp = int64_to_floatx80(val, &env->fp_status);
if (cpu_ldub_data(env, ptr + 9) & 0x80) {
floatx80_chs(tmp);
tmp = floatx80_chs(tmp);
}
fpush(env);
ST0 = tmp;

View File

@ -115,6 +115,7 @@ typedef struct DisasContext {
int tf; /* TF cpu flag */
int singlestep_enabled; /* "hardware" single step enabled */
int jmp_opt; /* use direct block chaining for direct jumps */
int repz_opt; /* optimize jumps within repz instructions */
int mem_index; /* select memory access functions */
uint64_t flags; /* all execution flags */
struct TranslationBlock *tb;
@ -1215,7 +1216,7 @@ static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
gen_op_add_reg_im(s->aflag, R_ECX, -1); \
/* a loop would cause two single step exceptions if ECX = 1 \
before rep string_insn */ \
if (!s->jmp_opt) \
if (s->repz_opt) \
gen_op_jz_ecx(s->aflag, l2); \
gen_jmp(s, cur_eip); \
}
@ -1233,7 +1234,7 @@ static inline void gen_repz_ ## op(DisasContext *s, TCGMemOp ot, \
gen_op_add_reg_im(s->aflag, R_ECX, -1); \
gen_update_cc_op(s); \
gen_jcc1(s, (JCC_Z << 1) | (nz ^ 1), l2); \
if (!s->jmp_opt) \
if (s->repz_opt) \
gen_op_jz_ecx(s->aflag, l2); \
gen_jmp(s, cur_eip); \
}
@ -7951,6 +7952,17 @@ static inline void gen_intermediate_code_internal(X86CPU *cpu,
|| (flags & HF_SOFTMMU_MASK)
#endif
);
/* Do not optimize repz jumps at all in icount mode, because
rep movsS instructions are execured with different paths
in !repz_opt and repz_opt modes. The first one was used
always except single step mode. And this setting
disables jumps optimization and control paths become
equivalent in run and single step modes.
Now there will be no jump optimization for repz in
record/replay modes and there will always be an
additional step for ecx=0 when icount is enabled.
*/
dc->repz_opt = !dc->jmp_opt && !use_icount;
#if 0
/* check addseg logic */
if (!dc->addseg && (dc->vm86 || !dc->pe || !dc->code32))