target/i386: set CC_OP in helpers if they want CC_OP_EFLAGS
Mark cc_op as clean and do not spill it at the end of the translation block. Technically this is a tiny bit less efficient, but: * it results in translations that are a tiny bit smaller * for most of these instructions, it is not unlikely that they are close to the end of the basic block, in which case cc_op would not be overwritten * anyway the cost is probably dwarfed by that of computing flags. Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
a0625efd4d
commit
abdcc5c8ef
@ -1111,6 +1111,7 @@ void helper_ucomiss(CPUX86State *env, Reg *d, Reg *s)
|
||||
s1 = s->ZMM_S(0);
|
||||
ret = float32_compare_quiet(s0, s1, &env->sse_status);
|
||||
CC_SRC = comis_eflags[ret + 1];
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
}
|
||||
|
||||
void helper_comiss(CPUX86State *env, Reg *d, Reg *s)
|
||||
@ -1122,6 +1123,7 @@ void helper_comiss(CPUX86State *env, Reg *d, Reg *s)
|
||||
s1 = s->ZMM_S(0);
|
||||
ret = float32_compare(s0, s1, &env->sse_status);
|
||||
CC_SRC = comis_eflags[ret + 1];
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
}
|
||||
|
||||
void helper_ucomisd(CPUX86State *env, Reg *d, Reg *s)
|
||||
@ -1133,6 +1135,7 @@ void helper_ucomisd(CPUX86State *env, Reg *d, Reg *s)
|
||||
d1 = s->ZMM_D(0);
|
||||
ret = float64_compare_quiet(d0, d1, &env->sse_status);
|
||||
CC_SRC = comis_eflags[ret + 1];
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
}
|
||||
|
||||
void helper_comisd(CPUX86State *env, Reg *d, Reg *s)
|
||||
@ -1144,6 +1147,7 @@ void helper_comisd(CPUX86State *env, Reg *d, Reg *s)
|
||||
d1 = s->ZMM_D(0);
|
||||
ret = float64_compare(d0, d1, &env->sse_status);
|
||||
CC_SRC = comis_eflags[ret + 1];
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1610,6 +1614,7 @@ void glue(helper_ptest, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
|
||||
cf |= (s->Q(i) & ~d->Q(i));
|
||||
}
|
||||
CC_SRC = (zf ? 0 : CC_Z) | (cf ? 0 : CC_C);
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
}
|
||||
|
||||
#define FMOVSLDUP(i) s->L((i) & ~1)
|
||||
@ -1966,6 +1971,7 @@ static inline unsigned pcmpxstrx(CPUX86State *env, Reg *d, Reg *s,
|
||||
validd--;
|
||||
|
||||
CC_SRC = (valids < upper ? CC_Z : 0) | (validd < upper ? CC_S : 0);
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
|
||||
switch ((ctrl >> 2) & 3) {
|
||||
case 0:
|
||||
@ -2297,6 +2303,7 @@ void glue(helper_vtestps, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
|
||||
cf |= (s->L(i) & ~d->L(i));
|
||||
}
|
||||
CC_SRC = ((zf >> 31) ? 0 : CC_Z) | ((cf >> 31) ? 0 : CC_C);
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
}
|
||||
|
||||
void glue(helper_vtestpd, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
|
||||
@ -2309,6 +2316,7 @@ void glue(helper_vtestpd, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
|
||||
cf |= (s->Q(i) & ~d->Q(i));
|
||||
}
|
||||
CC_SRC = ((zf >> 63) ? 0 : CC_Z) | ((cf >> 63) ? 0 : CC_C);
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
}
|
||||
|
||||
void glue(helper_vpmaskmovd_st, SUFFIX)(CPUX86State *env,
|
||||
|
@ -918,7 +918,7 @@ static void gen_##uname(DisasContext *s, CPUX86State *env, X86DecodedInsn *decod
|
||||
} else { \
|
||||
gen_helper_##lname##_ymm(tcg_env, OP_PTR1, OP_PTR2); \
|
||||
} \
|
||||
set_cc_op(s, CC_OP_EFLAGS); \
|
||||
assume_cc_op(s, CC_OP_EFLAGS); \
|
||||
}
|
||||
UNARY_CMP_SSE(VPTEST, ptest)
|
||||
UNARY_CMP_SSE(VTESTPS, vtestps)
|
||||
@ -1079,7 +1079,7 @@ static void gen_AAA(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
|
||||
{
|
||||
gen_update_cc_op(s);
|
||||
gen_helper_aaa(tcg_env);
|
||||
set_cc_op(s, CC_OP_EFLAGS);
|
||||
assume_cc_op(s, CC_OP_EFLAGS);
|
||||
}
|
||||
|
||||
static void gen_AAD(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
|
||||
@ -1102,7 +1102,7 @@ static void gen_AAS(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
|
||||
{
|
||||
gen_update_cc_op(s);
|
||||
gen_helper_aas(tcg_env);
|
||||
set_cc_op(s, CC_OP_EFLAGS);
|
||||
assume_cc_op(s, CC_OP_EFLAGS);
|
||||
}
|
||||
|
||||
static void gen_ADC(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
|
||||
@ -1566,14 +1566,14 @@ static void gen_DAA(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
|
||||
{
|
||||
gen_update_cc_op(s);
|
||||
gen_helper_daa(tcg_env);
|
||||
set_cc_op(s, CC_OP_EFLAGS);
|
||||
assume_cc_op(s, CC_OP_EFLAGS);
|
||||
}
|
||||
|
||||
static void gen_DAS(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
|
||||
{
|
||||
gen_update_cc_op(s);
|
||||
gen_helper_das(tcg_env);
|
||||
set_cc_op(s, CC_OP_EFLAGS);
|
||||
assume_cc_op(s, CC_OP_EFLAGS);
|
||||
}
|
||||
|
||||
static void gen_DEC(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
|
||||
@ -2353,14 +2353,14 @@ static void gen_PCMPESTRI(DisasContext *s, CPUX86State *env, X86DecodedInsn *dec
|
||||
{
|
||||
TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
|
||||
gen_helper_pcmpestri_xmm(tcg_env, OP_PTR1, OP_PTR2, imm);
|
||||
set_cc_op(s, CC_OP_EFLAGS);
|
||||
assume_cc_op(s, CC_OP_EFLAGS);
|
||||
}
|
||||
|
||||
static void gen_PCMPESTRM(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
|
||||
{
|
||||
TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
|
||||
gen_helper_pcmpestrm_xmm(tcg_env, OP_PTR1, OP_PTR2, imm);
|
||||
set_cc_op(s, CC_OP_EFLAGS);
|
||||
assume_cc_op(s, CC_OP_EFLAGS);
|
||||
if ((s->prefix & PREFIX_VEX) && !s->vex_l) {
|
||||
tcg_gen_gvec_dup_imm(MO_64, offsetof(CPUX86State, xmm_regs[0].ZMM_X(1)),
|
||||
16, 16, 0);
|
||||
@ -2371,14 +2371,14 @@ static void gen_PCMPISTRI(DisasContext *s, CPUX86State *env, X86DecodedInsn *dec
|
||||
{
|
||||
TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
|
||||
gen_helper_pcmpistri_xmm(tcg_env, OP_PTR1, OP_PTR2, imm);
|
||||
set_cc_op(s, CC_OP_EFLAGS);
|
||||
assume_cc_op(s, CC_OP_EFLAGS);
|
||||
}
|
||||
|
||||
static void gen_PCMPISTRM(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
|
||||
{
|
||||
TCGv_i32 imm = tcg_constant8u_i32(decode->immediate);
|
||||
gen_helper_pcmpistrm_xmm(tcg_env, OP_PTR1, OP_PTR2, imm);
|
||||
set_cc_op(s, CC_OP_EFLAGS);
|
||||
assume_cc_op(s, CC_OP_EFLAGS);
|
||||
if ((s->prefix & PREFIX_VEX) && !s->vex_l) {
|
||||
tcg_gen_gvec_dup_imm(MO_64, offsetof(CPUX86State, xmm_regs[0].ZMM_X(1)),
|
||||
16, 16, 0);
|
||||
@ -3595,7 +3595,7 @@ static void gen_VCOMI(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
|
||||
SSEFunc_0_epp fn;
|
||||
fn = s->prefix & PREFIX_DATA ? gen_helper_comisd : gen_helper_comiss;
|
||||
fn(tcg_env, OP_PTR1, OP_PTR2);
|
||||
set_cc_op(s, CC_OP_EFLAGS);
|
||||
assume_cc_op(s, CC_OP_EFLAGS);
|
||||
}
|
||||
|
||||
static void gen_VCVTPD2PS(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
|
||||
@ -3982,7 +3982,7 @@ static void gen_VUCOMI(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode
|
||||
SSEFunc_0_epp fn;
|
||||
fn = s->prefix & PREFIX_DATA ? gen_helper_ucomisd : gen_helper_ucomiss;
|
||||
fn(tcg_env, OP_PTR1, OP_PTR2);
|
||||
set_cc_op(s, CC_OP_EFLAGS);
|
||||
assume_cc_op(s, CC_OP_EFLAGS);
|
||||
}
|
||||
|
||||
static void gen_VZEROALL(DisasContext *s, CPUX86State *env, X86DecodedInsn *decode)
|
||||
|
@ -487,6 +487,7 @@ void helper_fcomi_ST0_FT0(CPUX86State *env)
|
||||
ret = floatx80_compare(ST0, FT0, &env->fp_status);
|
||||
eflags = cpu_cc_compute_all(env) & ~(CC_Z | CC_P | CC_C);
|
||||
CC_SRC = eflags | fcomi_ccval[ret + 1];
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
merge_exception_flags(env, old_flags);
|
||||
}
|
||||
|
||||
@ -499,6 +500,7 @@ void helper_fucomi_ST0_FT0(CPUX86State *env)
|
||||
ret = floatx80_compare_quiet(ST0, FT0, &env->fp_status);
|
||||
eflags = cpu_cc_compute_all(env) & ~(CC_Z | CC_P | CC_C);
|
||||
CC_SRC = eflags | fcomi_ccval[ret + 1];
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
merge_exception_flags(env, old_flags);
|
||||
}
|
||||
|
||||
|
@ -187,6 +187,7 @@ void helper_aaa(CPUX86State *env)
|
||||
}
|
||||
env->regs[R_EAX] = (env->regs[R_EAX] & ~0xffff) | al | (ah << 8);
|
||||
CC_SRC = eflags;
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
}
|
||||
|
||||
void helper_aas(CPUX86State *env)
|
||||
@ -211,6 +212,7 @@ void helper_aas(CPUX86State *env)
|
||||
}
|
||||
env->regs[R_EAX] = (env->regs[R_EAX] & ~0xffff) | al | (ah << 8);
|
||||
CC_SRC = eflags;
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
}
|
||||
|
||||
void helper_daa(CPUX86State *env)
|
||||
@ -238,6 +240,7 @@ void helper_daa(CPUX86State *env)
|
||||
eflags |= parity_table[al]; /* pf */
|
||||
eflags |= (al & 0x80); /* sf */
|
||||
CC_SRC = eflags;
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
}
|
||||
|
||||
void helper_das(CPUX86State *env)
|
||||
@ -269,6 +272,7 @@ void helper_das(CPUX86State *env)
|
||||
eflags |= parity_table[al]; /* pf */
|
||||
eflags |= (al & 0x80); /* sf */
|
||||
CC_SRC = eflags;
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
}
|
||||
|
||||
#ifdef TARGET_X86_64
|
||||
@ -449,10 +453,11 @@ target_ulong HELPER(rdrand)(CPUX86State *env)
|
||||
error_free(err);
|
||||
/* Failure clears CF and all other flags, and returns 0. */
|
||||
env->cc_src = 0;
|
||||
return 0;
|
||||
ret = 0;
|
||||
} else {
|
||||
/* Success sets CF and clears all others. */
|
||||
env->cc_src = CC_C;
|
||||
}
|
||||
|
||||
/* Success sets CF and clears all others. */
|
||||
env->cc_src = CC_C;
|
||||
env->cc_op = CC_OP_EFLAGS;
|
||||
return ret;
|
||||
}
|
||||
|
@ -2326,7 +2326,7 @@ void helper_verr(CPUX86State *env, target_ulong selector1)
|
||||
int rpl, dpl, cpl;
|
||||
|
||||
selector = selector1 & 0xffff;
|
||||
eflags = cpu_cc_compute_all(env);
|
||||
eflags = cpu_cc_compute_all(env) | CC_Z;
|
||||
if ((selector & 0xfffc) == 0) {
|
||||
goto fail;
|
||||
}
|
||||
@ -2351,11 +2351,11 @@ void helper_verr(CPUX86State *env, target_ulong selector1)
|
||||
} else {
|
||||
if (dpl < cpl || dpl < rpl) {
|
||||
fail:
|
||||
CC_SRC = eflags & ~CC_Z;
|
||||
return;
|
||||
eflags &= ~CC_Z;
|
||||
}
|
||||
}
|
||||
CC_SRC = eflags | CC_Z;
|
||||
CC_SRC = eflags;
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
}
|
||||
|
||||
void helper_verw(CPUX86State *env, target_ulong selector1)
|
||||
@ -2364,7 +2364,7 @@ void helper_verw(CPUX86State *env, target_ulong selector1)
|
||||
int rpl, dpl, cpl;
|
||||
|
||||
selector = selector1 & 0xffff;
|
||||
eflags = cpu_cc_compute_all(env);
|
||||
eflags = cpu_cc_compute_all(env) | CC_Z;
|
||||
if ((selector & 0xfffc) == 0) {
|
||||
goto fail;
|
||||
}
|
||||
@ -2385,9 +2385,9 @@ void helper_verw(CPUX86State *env, target_ulong selector1)
|
||||
}
|
||||
if (!(e2 & DESC_W_MASK)) {
|
||||
fail:
|
||||
CC_SRC = eflags & ~CC_Z;
|
||||
return;
|
||||
eflags &= ~CC_Z;
|
||||
}
|
||||
}
|
||||
CC_SRC = eflags | CC_Z;
|
||||
CC_SRC = eflags;
|
||||
CC_OP = CC_OP_EFLAGS;
|
||||
}
|
||||
|
@ -2984,7 +2984,7 @@ static bool disas_insn_x87(DisasContext *s, CPUState *cpu, int b)
|
||||
gen_update_cc_op(s);
|
||||
gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
|
||||
gen_helper_fucomi_ST0_FT0(tcg_env);
|
||||
set_cc_op(s, CC_OP_EFLAGS);
|
||||
assume_cc_op(s, CC_OP_EFLAGS);
|
||||
break;
|
||||
case 0x1e: /* fcomi */
|
||||
if (!(s->cpuid_features & CPUID_CMOV)) {
|
||||
@ -2993,7 +2993,7 @@ static bool disas_insn_x87(DisasContext *s, CPUState *cpu, int b)
|
||||
gen_update_cc_op(s);
|
||||
gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
|
||||
gen_helper_fcomi_ST0_FT0(tcg_env);
|
||||
set_cc_op(s, CC_OP_EFLAGS);
|
||||
assume_cc_op(s, CC_OP_EFLAGS);
|
||||
break;
|
||||
case 0x28: /* ffree sti */
|
||||
gen_helper_ffree_STN(tcg_env, tcg_constant_i32(opreg));
|
||||
@ -3052,7 +3052,7 @@ static bool disas_insn_x87(DisasContext *s, CPUState *cpu, int b)
|
||||
gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
|
||||
gen_helper_fucomi_ST0_FT0(tcg_env);
|
||||
gen_helper_fpop(tcg_env);
|
||||
set_cc_op(s, CC_OP_EFLAGS);
|
||||
assume_cc_op(s, CC_OP_EFLAGS);
|
||||
break;
|
||||
case 0x3e: /* fcomip */
|
||||
if (!(s->cpuid_features & CPUID_CMOV)) {
|
||||
@ -3062,7 +3062,7 @@ static bool disas_insn_x87(DisasContext *s, CPUState *cpu, int b)
|
||||
gen_helper_fmov_FT0_STN(tcg_env, tcg_constant_i32(opreg));
|
||||
gen_helper_fcomi_ST0_FT0(tcg_env);
|
||||
gen_helper_fpop(tcg_env);
|
||||
set_cc_op(s, CC_OP_EFLAGS);
|
||||
assume_cc_op(s, CC_OP_EFLAGS);
|
||||
break;
|
||||
case 0x10 ... 0x13: /* fcmovxx */
|
||||
case 0x18 ... 0x1b:
|
||||
@ -3268,7 +3268,7 @@ static void disas_insn_old(DisasContext *s, CPUState *cpu, int b)
|
||||
gen_helper_rdrand(s->T0, tcg_env);
|
||||
rm = (modrm & 7) | REX_B(s);
|
||||
gen_op_mov_reg_v(s, dflag, rm, s->T0);
|
||||
set_cc_op(s, CC_OP_EFLAGS);
|
||||
assume_cc_op(s, CC_OP_EFLAGS);
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -3655,7 +3655,7 @@ static void disas_insn_old(DisasContext *s, CPUState *cpu, int b)
|
||||
} else {
|
||||
gen_helper_verw(tcg_env, s->T0);
|
||||
}
|
||||
set_cc_op(s, CC_OP_EFLAGS);
|
||||
assume_cc_op(s, CC_OP_EFLAGS);
|
||||
break;
|
||||
default:
|
||||
goto unknown_op;
|
||||
|
Loading…
Reference in New Issue
Block a user