target/arm: Move do_coproc_insn() syndrome calculation earlier
Rearrange the code in do_coproc_insn() so that we calculate the syndrome value for a potential trap early; we're about to add a second check that wants this value earlier than where it is currently determined. (Specifically, a trap to EL2 because of HSTR_EL2 should take priority over an UNDEF to EL1, even when the UNDEF is because the register does not exist at all or because its ri->access bits non-configurably fail the access. So the check we put in for HSTR_EL2 trapping at EL1 (which needs the syndrome) is going to have to be done before the check "is the ARMCPRegInfo pointer NULL".) This commit is just code motion; the change to HSTR_EL2 handling that will use the 'syndrome' variable is in a subsequent commit. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Tested-by: Fuad Tabba <tabba@google.com> Message-id: 20230130182459.3309057-5-peter.maydell@linaro.org Message-id: 20230127175507.2895013-5-peter.maydell@linaro.org
This commit is contained in:
parent
80ea70f2e5
commit
9ada333982
@ -4718,6 +4718,47 @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
|
|||||||
const ARMCPRegInfo *ri = get_arm_cp_reginfo(s->cp_regs, key);
|
const ARMCPRegInfo *ri = get_arm_cp_reginfo(s->cp_regs, key);
|
||||||
TCGv_ptr tcg_ri = NULL;
|
TCGv_ptr tcg_ri = NULL;
|
||||||
bool need_exit_tb;
|
bool need_exit_tb;
|
||||||
|
uint32_t syndrome;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that since we are an implementation which takes an
|
||||||
|
* exception on a trapped conditional instruction only if the
|
||||||
|
* instruction passes its condition code check, we can take
|
||||||
|
* advantage of the clause in the ARM ARM that allows us to set
|
||||||
|
* the COND field in the instruction to 0xE in all cases.
|
||||||
|
* We could fish the actual condition out of the insn (ARM)
|
||||||
|
* or the condexec bits (Thumb) but it isn't necessary.
|
||||||
|
*/
|
||||||
|
switch (cpnum) {
|
||||||
|
case 14:
|
||||||
|
if (is64) {
|
||||||
|
syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
|
||||||
|
isread, false);
|
||||||
|
} else {
|
||||||
|
syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
|
||||||
|
rt, isread, false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
if (is64) {
|
||||||
|
syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
|
||||||
|
isread, false);
|
||||||
|
} else {
|
||||||
|
syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
|
||||||
|
rt, isread, false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
* ARMv8 defines that only coprocessors 14 and 15 exist,
|
||||||
|
* so this can only happen if this is an ARMv7 or earlier CPU,
|
||||||
|
* in which case the syndrome information won't actually be
|
||||||
|
* guest visible.
|
||||||
|
*/
|
||||||
|
assert(!arm_dc_feature(s, ARM_FEATURE_V8));
|
||||||
|
syndrome = syn_uncategorized();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (!ri) {
|
if (!ri) {
|
||||||
/*
|
/*
|
||||||
@ -4755,48 +4796,6 @@ static void do_coproc_insn(DisasContext *s, int cpnum, int is64,
|
|||||||
* Note that on XScale all cp0..c13 registers do an access check
|
* Note that on XScale all cp0..c13 registers do an access check
|
||||||
* call in order to handle c15_cpar.
|
* call in order to handle c15_cpar.
|
||||||
*/
|
*/
|
||||||
uint32_t syndrome;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Note that since we are an implementation which takes an
|
|
||||||
* exception on a trapped conditional instruction only if the
|
|
||||||
* instruction passes its condition code check, we can take
|
|
||||||
* advantage of the clause in the ARM ARM that allows us to set
|
|
||||||
* the COND field in the instruction to 0xE in all cases.
|
|
||||||
* We could fish the actual condition out of the insn (ARM)
|
|
||||||
* or the condexec bits (Thumb) but it isn't necessary.
|
|
||||||
*/
|
|
||||||
switch (cpnum) {
|
|
||||||
case 14:
|
|
||||||
if (is64) {
|
|
||||||
syndrome = syn_cp14_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
|
|
||||||
isread, false);
|
|
||||||
} else {
|
|
||||||
syndrome = syn_cp14_rt_trap(1, 0xe, opc1, opc2, crn, crm,
|
|
||||||
rt, isread, false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 15:
|
|
||||||
if (is64) {
|
|
||||||
syndrome = syn_cp15_rrt_trap(1, 0xe, opc1, crm, rt, rt2,
|
|
||||||
isread, false);
|
|
||||||
} else {
|
|
||||||
syndrome = syn_cp15_rt_trap(1, 0xe, opc1, opc2, crn, crm,
|
|
||||||
rt, isread, false);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
/*
|
|
||||||
* ARMv8 defines that only coprocessors 14 and 15 exist,
|
|
||||||
* so this can only happen if this is an ARMv7 or earlier CPU,
|
|
||||||
* in which case the syndrome information won't actually be
|
|
||||||
* guest visible.
|
|
||||||
*/
|
|
||||||
assert(!arm_dc_feature(s, ARM_FEATURE_V8));
|
|
||||||
syndrome = syn_uncategorized();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
gen_set_condexec(s);
|
gen_set_condexec(s);
|
||||||
gen_update_pc(s, 0);
|
gen_update_pc(s, 0);
|
||||||
tcg_ri = tcg_temp_new_ptr();
|
tcg_ri = tcg_temp_new_ptr();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user