target/arm: Factor out 'generate singlestep exception' function

Factor out code to 'generate a singlestep exception', which is
currently repeated in four places.

To do this we need to also pull the identical copies of the
gen-exception() function out of translate-a64.c and translate.c
into translate.h.

(There is a bug in the code: we're taking the exception to the wrong
target EL. This will be simpler to fix if there's only one place to
do it.)

Backports commit c1d5f50f094ab204accfacc2ee6aafc9601dd5c4 from qemu
This commit is contained in:
Peter Maydell 2019-11-18 16:47:00 -05:00 committed by Lioncash
parent 0d6ed39333
commit 3f531fac61
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
3 changed files with 28 additions and 37 deletions

View file

@ -394,20 +394,6 @@ static void gen_exception_internal(DisasContext *s, int excp)
tcg_temp_free_i32(tcg_ctx, tcg_excp);
}
static void gen_exception(DisasContext *s, int excp, uint32_t syndrome, uint32_t target_el)
{
TCGContext *tcg_ctx = s->uc->tcg_ctx;
TCGv_i32 tcg_excp = tcg_const_i32(tcg_ctx, excp);
TCGv_i32 tcg_syn = tcg_const_i32(tcg_ctx, syndrome);
TCGv_i32 tcg_el = tcg_const_i32(tcg_ctx, target_el);
gen_helper_exception_with_syndrome(tcg_ctx, tcg_ctx->cpu_env, tcg_excp,
tcg_syn, tcg_el);
tcg_temp_free_i32(tcg_ctx, tcg_el);
tcg_temp_free_i32(tcg_ctx, tcg_syn);
tcg_temp_free_i32(tcg_ctx, tcg_excp);
}
static void gen_exception_internal_insn(DisasContext *s, int offset, int excp)
{
gen_a64_set_pc_im(s, s->pc - offset);
@ -448,8 +434,7 @@ static void gen_step_complete_exception(DisasContext *s)
* of the exception, and our syndrome information is always correct.
*/
gen_ss_advance(s);
gen_exception(s, EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
default_exception_el(s));
gen_swstep_exception(s, 1, s->is_ldex);
s->base.is_jmp = DISAS_NORETURN;
}
@ -14607,8 +14592,7 @@ static void aarch64_tr_translate_insn(DisasContextBase *dcbase, CPUState *cpu)
* bits should be zero.
*/
assert(dc->base.num_insns == 1);
gen_exception(dc, EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
default_exception_el(dc));
gen_swstep_exception(dc, 0, 0);
dc->base.is_jmp = DISAS_NORETURN;
} else {
disas_a64_insn(env, dc);

View file

@ -286,21 +286,6 @@ static void gen_exception_internal(DisasContext *s, int excp)
tcg_temp_free_i32(tcg_ctx, tcg_excp);
}
static void gen_exception(DisasContext *s, int excp, uint32_t syndrome, uint32_t target_el)
{
TCGContext *tcg_ctx = s->uc->tcg_ctx;
TCGv_i32 tcg_excp = tcg_const_i32(tcg_ctx, excp);
TCGv_i32 tcg_syn = tcg_const_i32(tcg_ctx, syndrome);
TCGv_i32 tcg_el = tcg_const_i32(tcg_ctx, target_el);
gen_helper_exception_with_syndrome(tcg_ctx, tcg_ctx->cpu_env, tcg_excp,
tcg_syn, tcg_el);
tcg_temp_free_i32(tcg_ctx, tcg_el);
tcg_temp_free_i32(tcg_ctx, tcg_syn);
tcg_temp_free_i32(tcg_ctx, tcg_excp);
}
static void gen_step_complete_exception(DisasContext *s)
{
/* We just completed step of an insn. Move from Active-not-pending
@ -313,8 +298,7 @@ static void gen_step_complete_exception(DisasContext *s)
* of the exception, and our syndrome information is always correct.
*/
gen_ss_advance(s);
gen_exception(s, EXCP_UDEF, syn_swstep(s->ss_same_el, 1, s->is_ldex),
default_exception_el(s));
gen_swstep_exception(s, 1, s->is_ldex);
s->base.is_jmp = DISAS_NORETURN;
}
@ -12217,8 +12201,7 @@ static bool arm_pre_translate_insn(DisasContext *dc)
* bits should be zero.
*/
assert(dc->base.num_insns == 1);
gen_exception(dc, EXCP_UDEF, syn_swstep(dc->ss_same_el, 0, 0),
default_exception_el(dc));
gen_swstep_exception(dc, 0, 0);
dc->base.is_jmp = DISAS_NORETURN;
return true;
}

View file

@ -2,6 +2,7 @@
#define TARGET_ARM_TRANSLATE_H
#include "exec/translator.h"
#include "internals.h"
/* internal defines */
typedef struct DisasContext {
@ -238,6 +239,29 @@ static inline void gen_ss_advance(DisasContext *s)
}
}
static inline void gen_exception(DisasContext *s, int excp, uint32_t syndrome,
uint32_t target_el)
{
TCGContext *tcg_ctx = s->uc->tcg_ctx;
TCGv_i32 tcg_excp = tcg_const_i32(tcg_ctx, excp);
TCGv_i32 tcg_syn = tcg_const_i32(tcg_ctx, syndrome);
TCGv_i32 tcg_el = tcg_const_i32(tcg_ctx, target_el);
gen_helper_exception_with_syndrome(tcg_ctx, tcg_ctx->cpu_env, tcg_excp,
tcg_syn, tcg_el);
tcg_temp_free_i32(tcg_ctx, tcg_el);
tcg_temp_free_i32(tcg_ctx, tcg_syn);
tcg_temp_free_i32(tcg_ctx, tcg_excp);
}
/* Generate an architectural singlestep exception */
static inline void gen_swstep_exception(DisasContext *s, int isv, int ex)
{
gen_exception(s, EXCP_UDEF, syn_swstep(s->ss_same_el, isv, ex),
default_exception_el(s));
}
/*
* Given a VFP floating point constant encoded into an 8 bit immediate in an
* instruction, expand it to the actual constant value of the specified