target/i386: Create eip_next_*
Create helpers for loading the address of the next insn. Use tcg_constant_* in adjacent code where convenient. Reviewed-by: Paolo Bonzini <pbonzini@redhat.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20221001140935.465607-16-richard.henderson@linaro.org> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
8c03ab9f74
commit
9e599bf707
@ -541,6 +541,27 @@ static TCGv_i32 cur_insn_len_i32(DisasContext *s)
|
|||||||
return tcg_constant_i32(cur_insn_len(s));
|
return tcg_constant_i32(cur_insn_len(s));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static TCGv_i32 eip_next_i32(DisasContext *s)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This function has two users: lcall_real (always 16-bit mode), and
|
||||||
|
* iret_protected (16, 32, or 64-bit mode). IRET only uses the value
|
||||||
|
* when EFLAGS.NT is set, which is illegal in 64-bit mode, which is
|
||||||
|
* why passing a 32-bit value isn't broken. To avoid using this where
|
||||||
|
* we shouldn't, return -1 in 64-bit mode so that execution goes into
|
||||||
|
* the weeds quickly.
|
||||||
|
*/
|
||||||
|
if (CODE64(s)) {
|
||||||
|
return tcg_constant_i32(-1);
|
||||||
|
}
|
||||||
|
return tcg_constant_i32(s->pc - s->cs_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TCGv eip_next_tl(DisasContext *s)
|
||||||
|
{
|
||||||
|
return tcg_constant_tl(s->pc - s->cs_base);
|
||||||
|
}
|
||||||
|
|
||||||
/* Compute SEG:REG into A0. SEG is selected from the override segment
|
/* Compute SEG:REG into A0. SEG is selected from the override segment
|
||||||
(OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
|
(OVR_SEG) and the default segment (DEF_SEG). OVR_SEG may be -1 to
|
||||||
indicate no override. */
|
indicate no override. */
|
||||||
@ -1213,12 +1234,9 @@ static void gen_bpt_io(DisasContext *s, TCGv_i32 t_port, int ot)
|
|||||||
/* user-mode cpu should not be in IOBPT mode */
|
/* user-mode cpu should not be in IOBPT mode */
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
#else
|
#else
|
||||||
TCGv_i32 t_size = tcg_const_i32(1 << ot);
|
TCGv_i32 t_size = tcg_constant_i32(1 << ot);
|
||||||
TCGv t_next = tcg_const_tl(s->pc - s->cs_base);
|
TCGv t_next = eip_next_tl(s);
|
||||||
|
|
||||||
gen_helper_bpt_io(cpu_env, t_port, t_size, t_next);
|
gen_helper_bpt_io(cpu_env, t_port, t_size, t_next);
|
||||||
tcg_temp_free_i32(t_size);
|
|
||||||
tcg_temp_free(t_next);
|
|
||||||
#endif /* CONFIG_USER_ONLY */
|
#endif /* CONFIG_USER_ONLY */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -5324,9 +5342,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
|
|||||||
if (dflag == MO_16) {
|
if (dflag == MO_16) {
|
||||||
tcg_gen_ext16u_tl(s->T0, s->T0);
|
tcg_gen_ext16u_tl(s->T0, s->T0);
|
||||||
}
|
}
|
||||||
next_eip = s->pc - s->cs_base;
|
gen_push_v(s, eip_next_tl(s));
|
||||||
tcg_gen_movi_tl(s->T1, next_eip);
|
|
||||||
gen_push_v(s, s->T1);
|
|
||||||
gen_op_jmp_v(s->T0);
|
gen_op_jmp_v(s->T0);
|
||||||
gen_bnd_jmp(s);
|
gen_bnd_jmp(s);
|
||||||
s->base.is_jmp = DISAS_JUMP;
|
s->base.is_jmp = DISAS_JUMP;
|
||||||
@ -5342,14 +5358,14 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
|
|||||||
if (PE(s) && !VM86(s)) {
|
if (PE(s) && !VM86(s)) {
|
||||||
tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
|
tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
|
||||||
gen_helper_lcall_protected(cpu_env, s->tmp2_i32, s->T1,
|
gen_helper_lcall_protected(cpu_env, s->tmp2_i32, s->T1,
|
||||||
tcg_const_i32(dflag - 1),
|
tcg_constant_i32(dflag - 1),
|
||||||
tcg_const_tl(s->pc - s->cs_base));
|
eip_next_tl(s));
|
||||||
} else {
|
} else {
|
||||||
tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
|
tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
|
||||||
tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
|
tcg_gen_trunc_tl_i32(s->tmp3_i32, s->T1);
|
||||||
gen_helper_lcall_real(cpu_env, s->tmp2_i32, s->tmp3_i32,
|
gen_helper_lcall_real(cpu_env, s->tmp2_i32, s->tmp3_i32,
|
||||||
tcg_const_i32(dflag - 1),
|
tcg_constant_i32(dflag - 1),
|
||||||
tcg_const_i32(s->pc - s->cs_base));
|
eip_next_i32(s));
|
||||||
}
|
}
|
||||||
s->base.is_jmp = DISAS_JUMP;
|
s->base.is_jmp = DISAS_JUMP;
|
||||||
break;
|
break;
|
||||||
@ -5372,7 +5388,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
|
|||||||
if (PE(s) && !VM86(s)) {
|
if (PE(s) && !VM86(s)) {
|
||||||
tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
|
tcg_gen_trunc_tl_i32(s->tmp2_i32, s->T0);
|
||||||
gen_helper_ljmp_protected(cpu_env, s->tmp2_i32, s->T1,
|
gen_helper_ljmp_protected(cpu_env, s->tmp2_i32, s->T1,
|
||||||
tcg_const_tl(s->pc - s->cs_base));
|
eip_next_tl(s));
|
||||||
} else {
|
} else {
|
||||||
gen_op_movl_seg_T0_vm(s, R_CS);
|
gen_op_movl_seg_T0_vm(s, R_CS);
|
||||||
gen_op_jmp_v(s->T1);
|
gen_op_jmp_v(s->T1);
|
||||||
@ -6854,8 +6870,8 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
|
|||||||
}
|
}
|
||||||
gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
|
gen_helper_iret_real(cpu_env, tcg_const_i32(dflag - 1));
|
||||||
} else {
|
} else {
|
||||||
gen_helper_iret_protected(cpu_env, tcg_const_i32(dflag - 1),
|
gen_helper_iret_protected(cpu_env, tcg_constant_i32(dflag - 1),
|
||||||
tcg_const_i32(s->pc - s->cs_base));
|
eip_next_i32(s));
|
||||||
}
|
}
|
||||||
set_cc_op(s, CC_OP_EFLAGS);
|
set_cc_op(s, CC_OP_EFLAGS);
|
||||||
s->base.is_jmp = DISAS_EOB_ONLY;
|
s->base.is_jmp = DISAS_EOB_ONLY;
|
||||||
@ -6867,15 +6883,13 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
|
|||||||
} else {
|
} else {
|
||||||
tval = (int16_t)insn_get(env, s, MO_16);
|
tval = (int16_t)insn_get(env, s, MO_16);
|
||||||
}
|
}
|
||||||
next_eip = s->pc - s->cs_base;
|
tval += s->pc - s->cs_base;
|
||||||
tval += next_eip;
|
|
||||||
if (dflag == MO_16) {
|
if (dflag == MO_16) {
|
||||||
tval &= 0xffff;
|
tval &= 0xffff;
|
||||||
} else if (!CODE64(s)) {
|
} else if (!CODE64(s)) {
|
||||||
tval &= 0xffffffff;
|
tval &= 0xffffffff;
|
||||||
}
|
}
|
||||||
tcg_gen_movi_tl(s->T0, next_eip);
|
gen_push_v(s, eip_next_tl(s));
|
||||||
gen_push_v(s, s->T0);
|
|
||||||
gen_bnd_jmp(s);
|
gen_bnd_jmp(s);
|
||||||
gen_jmp(s, tval);
|
gen_jmp(s, tval);
|
||||||
}
|
}
|
||||||
@ -7409,8 +7423,7 @@ static bool disas_insn(DisasContext *s, CPUState *cpu)
|
|||||||
TCGLabel *l1, *l2, *l3;
|
TCGLabel *l1, *l2, *l3;
|
||||||
|
|
||||||
tval = (int8_t)insn_get(env, s, MO_8);
|
tval = (int8_t)insn_get(env, s, MO_8);
|
||||||
next_eip = s->pc - s->cs_base;
|
tval += s->pc - s->cs_base;
|
||||||
tval += next_eip;
|
|
||||||
if (dflag == MO_16) {
|
if (dflag == MO_16) {
|
||||||
tval &= 0xffff;
|
tval &= 0xffff;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user