mirror of https://github.com/proxmox/mirror_qemu
target/arm: Replace offset with pc in gen_exception_insn
The offset is variable depending on the instruction set, whereas we have stored values for the current pc and the next pc. Passing in the actual value is clearer in intent. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Reviewed-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Philippe Mathieu-Daudé <philmd@redhat.com> Message-id: 20190807045335.1361-8-richard.henderson@linaro.org Signed-off-by: Peter Maydell <peter.maydell@linaro.org>master
parent
a04159166b
commit
a767fac802
|
@ -260,10 +260,10 @@ static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
|
|||
s->base.is_jmp = DISAS_NORETURN;
|
||||
}
|
||||
|
||||
static void gen_exception_insn(DisasContext *s, int offset, int excp,
|
||||
static void gen_exception_insn(DisasContext *s, uint64_t pc, int excp,
|
||||
uint32_t syndrome, uint32_t target_el)
|
||||
{
|
||||
gen_a64_set_pc_im(s->base.pc_next - offset);
|
||||
gen_a64_set_pc_im(pc);
|
||||
gen_exception(excp, syndrome, target_el);
|
||||
s->base.is_jmp = DISAS_NORETURN;
|
||||
}
|
||||
|
@ -342,7 +342,7 @@ static inline void gen_goto_tb(DisasContext *s, int n, uint64_t dest)
|
|||
void unallocated_encoding(DisasContext *s)
|
||||
{
|
||||
/* Unallocated and reserved encodings are uncategorized */
|
||||
gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
|
||||
default_exception_el(s));
|
||||
}
|
||||
|
||||
|
@ -1114,8 +1114,8 @@ static inline bool fp_access_check(DisasContext *s)
|
|||
return true;
|
||||
}
|
||||
|
||||
gen_exception_insn(s, 4, EXCP_UDEF, syn_fp_access_trap(1, 0xe, false),
|
||||
s->fp_excp_el);
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
|
||||
syn_fp_access_trap(1, 0xe, false), s->fp_excp_el);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -1125,7 +1125,7 @@ static inline bool fp_access_check(DisasContext *s)
|
|||
bool sve_access_check(DisasContext *s)
|
||||
{
|
||||
if (s->sve_excp_el) {
|
||||
gen_exception_insn(s, 4, EXCP_UDEF, syn_sve_access_trap(),
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_sve_access_trap(),
|
||||
s->sve_excp_el);
|
||||
return false;
|
||||
}
|
||||
|
@ -1859,8 +1859,8 @@ static void disas_exc(DisasContext *s, uint32_t insn)
|
|||
switch (op2_ll) {
|
||||
case 1: /* SVC */
|
||||
gen_ss_advance(s);
|
||||
gen_exception_insn(s, 0, EXCP_SWI, syn_aa64_svc(imm16),
|
||||
default_exception_el(s));
|
||||
gen_exception_insn(s, s->base.pc_next, EXCP_SWI,
|
||||
syn_aa64_svc(imm16), default_exception_el(s));
|
||||
break;
|
||||
case 2: /* HVC */
|
||||
if (s->current_el == 0) {
|
||||
|
@ -1873,7 +1873,8 @@ static void disas_exc(DisasContext *s, uint32_t insn)
|
|||
gen_a64_set_pc_im(s->pc_curr);
|
||||
gen_helper_pre_hvc(cpu_env);
|
||||
gen_ss_advance(s);
|
||||
gen_exception_insn(s, 0, EXCP_HVC, syn_aa64_hvc(imm16), 2);
|
||||
gen_exception_insn(s, s->base.pc_next, EXCP_HVC,
|
||||
syn_aa64_hvc(imm16), 2);
|
||||
break;
|
||||
case 3: /* SMC */
|
||||
if (s->current_el == 0) {
|
||||
|
@ -1885,7 +1886,8 @@ static void disas_exc(DisasContext *s, uint32_t insn)
|
|||
gen_helper_pre_smc(cpu_env, tmp);
|
||||
tcg_temp_free_i32(tmp);
|
||||
gen_ss_advance(s);
|
||||
gen_exception_insn(s, 0, EXCP_SMC, syn_aa64_smc(imm16), 3);
|
||||
gen_exception_insn(s, s->base.pc_next, EXCP_SMC,
|
||||
syn_aa64_smc(imm16), 3);
|
||||
break;
|
||||
default:
|
||||
unallocated_encoding(s);
|
||||
|
@ -14064,7 +14066,8 @@ static void disas_a64_insn(CPUARMState *env, DisasContext *s)
|
|||
if (s->btype != 0
|
||||
&& s->guarded_page
|
||||
&& !btype_destination_ok(insn, s->bt, s->btype)) {
|
||||
gen_exception_insn(s, 4, EXCP_UDEF, syn_btitrap(s->btype),
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
|
||||
syn_btitrap(s->btype),
|
||||
default_exception_el(s));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -96,10 +96,10 @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
|
|||
{
|
||||
if (s->fp_excp_el) {
|
||||
if (arm_dc_feature(s, ARM_FEATURE_M)) {
|
||||
gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_NOCP, syn_uncategorized(),
|
||||
s->fp_excp_el);
|
||||
} else {
|
||||
gen_exception_insn(s, 4, EXCP_UDEF,
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
|
||||
syn_fp_access_trap(1, 0xe, false),
|
||||
s->fp_excp_el);
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ static bool full_vfp_access_check(DisasContext *s, bool ignore_vfp_enabled)
|
|||
|
||||
if (!s->vfp_enabled && !ignore_vfp_enabled) {
|
||||
assert(!arm_dc_feature(s, ARM_FEATURE_M));
|
||||
gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
|
||||
default_exception_el(s));
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1249,11 +1249,11 @@ static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
|
|||
s->base.is_jmp = DISAS_NORETURN;
|
||||
}
|
||||
|
||||
static void gen_exception_insn(DisasContext *s, int offset, int excp,
|
||||
static void gen_exception_insn(DisasContext *s, uint32_t pc, int excp,
|
||||
int syn, uint32_t target_el)
|
||||
{
|
||||
gen_set_condexec(s);
|
||||
gen_set_pc_im(s, s->base.pc_next - offset);
|
||||
gen_set_pc_im(s, pc);
|
||||
gen_exception(excp, syn, target_el);
|
||||
s->base.is_jmp = DISAS_NORETURN;
|
||||
}
|
||||
|
@ -1300,7 +1300,7 @@ static inline void gen_hlt(DisasContext *s, int imm)
|
|||
return;
|
||||
}
|
||||
|
||||
gen_exception_insn(s, s->thumb ? 2 : 4, EXCP_UDEF, syn_uncategorized(),
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
|
||||
default_exception_el(s));
|
||||
}
|
||||
|
||||
|
@ -3177,7 +3177,8 @@ static bool msr_banked_access_decode(DisasContext *s, int r, int sysm, int rn,
|
|||
|
||||
undef:
|
||||
/* If we get here then some access check did not pass */
|
||||
gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), exc_target);
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
|
||||
syn_uncategorized(), exc_target);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3571,7 +3572,7 @@ static int disas_neon_ls_insn(DisasContext *s, uint32_t insn)
|
|||
* for attempts to execute invalid vfp/neon encodings with FP disabled.
|
||||
*/
|
||||
if (s->fp_excp_el) {
|
||||
gen_exception_insn(s, 4, EXCP_UDEF,
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
|
||||
syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
|
||||
return 0;
|
||||
}
|
||||
|
@ -4842,7 +4843,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
|
|||
* for attempts to execute invalid vfp/neon encodings with FP disabled.
|
||||
*/
|
||||
if (s->fp_excp_el) {
|
||||
gen_exception_insn(s, 4, EXCP_UDEF,
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
|
||||
syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
|
||||
return 0;
|
||||
}
|
||||
|
@ -6970,7 +6971,7 @@ static int disas_neon_insn_3same_ext(DisasContext *s, uint32_t insn)
|
|||
}
|
||||
|
||||
if (s->fp_excp_el) {
|
||||
gen_exception_insn(s, 4, EXCP_UDEF,
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
|
||||
syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
|
||||
return 0;
|
||||
}
|
||||
|
@ -7093,7 +7094,7 @@ static int disas_neon_insn_2reg_scalar_ext(DisasContext *s, uint32_t insn)
|
|||
off_rm = vfp_reg_offset(0, rm);
|
||||
}
|
||||
if (s->fp_excp_el) {
|
||||
gen_exception_insn(s, 4, EXCP_UDEF,
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_UDEF,
|
||||
syn_simd_access_trap(1, 0xe, false), s->fp_excp_el);
|
||||
return 0;
|
||||
}
|
||||
|
@ -7586,7 +7587,7 @@ static void gen_srs(DisasContext *s,
|
|||
* For the UNPREDICTABLE cases we choose to UNDEF.
|
||||
*/
|
||||
if (s->current_el == 1 && !s->ns && mode == ARM_CPU_MODE_MON) {
|
||||
gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(), 3);
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(), 3);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -7622,7 +7623,7 @@ static void gen_srs(DisasContext *s,
|
|||
}
|
||||
|
||||
if (undef) {
|
||||
gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
|
||||
default_exception_el(s));
|
||||
return;
|
||||
}
|
||||
|
@ -7713,7 +7714,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
|
|||
* UsageFault exception.
|
||||
*/
|
||||
if (arm_dc_feature(s, ARM_FEATURE_M)) {
|
||||
gen_exception_insn(s, 4, EXCP_INVSTATE, syn_uncategorized(),
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_INVSTATE, syn_uncategorized(),
|
||||
default_exception_el(s));
|
||||
return;
|
||||
}
|
||||
|
@ -9250,7 +9251,7 @@ static void disas_arm_insn(DisasContext *s, unsigned int insn)
|
|||
break;
|
||||
default:
|
||||
illegal_op:
|
||||
gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
|
||||
default_exception_el(s));
|
||||
break;
|
||||
}
|
||||
|
@ -10275,7 +10276,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
|
|||
}
|
||||
|
||||
/* All other insns: NOCP */
|
||||
gen_exception_insn(s, 4, EXCP_NOCP, syn_uncategorized(),
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_NOCP, syn_uncategorized(),
|
||||
default_exception_el(s));
|
||||
break;
|
||||
}
|
||||
|
@ -10939,7 +10940,7 @@ static void disas_thumb2_insn(DisasContext *s, uint32_t insn)
|
|||
}
|
||||
return;
|
||||
illegal_op:
|
||||
gen_exception_insn(s, 4, EXCP_UDEF, syn_uncategorized(),
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
|
||||
default_exception_el(s));
|
||||
}
|
||||
|
||||
|
@ -11763,7 +11764,7 @@ static void disas_thumb_insn(DisasContext *s, uint32_t insn)
|
|||
return;
|
||||
illegal_op:
|
||||
undef:
|
||||
gen_exception_insn(s, 2, EXCP_UDEF, syn_uncategorized(),
|
||||
gen_exception_insn(s, s->pc_curr, EXCP_UDEF, syn_uncategorized(),
|
||||
default_exception_el(s));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue