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:
commit
54600752a1
@ -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;
|
||||
|
@ -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))
|
||||
|
Loading…
Reference in New Issue
Block a user