target-sparc: Create gen_exception

This unifies quite a few duplicate code fragments.

Backports commit 4fbe00679000f9fd0c509c2d548d957b08ec6057 from qemu
This commit is contained in:
Richard Henderson 2018-02-25 04:55:12 -05:00 committed by Lioncash
parent 39d1657fc3
commit 847d65258b
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7

View file

@ -1120,6 +1120,18 @@ static inline void save_state(DisasContext *dc)
save_npc(dc); save_npc(dc);
} }
static void gen_exception(DisasContext *dc, int which)
{
TCGv_i32 t;
TCGContext *tcg_ctx = dc->uc->tcg_ctx;
save_state(dc);
t = tcg_const_i32(tcg_ctx, which);
gen_helper_raise_exception(tcg_ctx, tcg_ctx->cpu_env, t);
tcg_temp_free_i32(tcg_ctx, t);
dc->is_br = 1;
}
static inline void gen_mov_pc_npc(DisasContext *dc) static inline void gen_mov_pc_npc(DisasContext *dc)
{ {
TCGContext *tcg_ctx = dc->uc->tcg_ctx; TCGContext *tcg_ctx = dc->uc->tcg_ctx;
@ -1731,30 +1743,20 @@ static inline void gen_op_fcmpeq(DisasContext *dc, int fccno)
} }
#endif #endif
static inline void gen_op_fpexception_im(DisasContext *dc, int fsr_flags) static void gen_op_fpexception_im(DisasContext *dc, int fsr_flags)
{ {
TCGContext *tcg_ctx = dc->uc->tcg_ctx; TCGContext *tcg_ctx = dc->uc->tcg_ctx;
TCGv_i32 r_const;
tcg_gen_andi_tl(tcg_ctx, tcg_ctx->cpu_fsr, tcg_ctx->cpu_fsr, FSR_FTT_NMASK); tcg_gen_andi_tl(tcg_ctx, tcg_ctx->cpu_fsr, tcg_ctx->cpu_fsr, FSR_FTT_NMASK);
tcg_gen_ori_tl(tcg_ctx, tcg_ctx->cpu_fsr, tcg_ctx->cpu_fsr, fsr_flags); tcg_gen_ori_tl(tcg_ctx, tcg_ctx->cpu_fsr, tcg_ctx->cpu_fsr, fsr_flags);
r_const = tcg_const_i32(tcg_ctx, TT_FP_EXCP); gen_exception(dc, TT_FP_EXCP);
gen_helper_raise_exception(tcg_ctx, tcg_ctx->cpu_env, r_const);
tcg_temp_free_i32(tcg_ctx, r_const);
} }
static int gen_trap_ifnofpu(DisasContext *dc) static int gen_trap_ifnofpu(DisasContext *dc)
{ {
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
TCGContext *tcg_ctx = dc->uc->tcg_ctx;
if (!dc->fpu_enabled) { if (!dc->fpu_enabled) {
TCGv_i32 r_const; gen_exception(dc, TT_NFPU_INSN);
save_state(dc);
r_const = tcg_const_i32(tcg_ctx, TT_NFPU_INSN);
gen_helper_raise_exception(tcg_ctx, tcg_ctx->cpu_env, r_const);
tcg_temp_free_i32(tcg_ctx, r_const);
dc->is_br = 1;
return 1; return 1;
} }
#endif #endif
@ -5306,63 +5308,27 @@ static void disas_sparc_insn(DisasContext * dc, unsigned int insn, bool hook_ins
jmp_insn: jmp_insn:
goto egress; goto egress;
illegal_insn: illegal_insn:
{ gen_exception(dc, TT_ILL_INSN);
TCGv_i32 r_const;
save_state(dc);
r_const = tcg_const_i32(tcg_ctx, TT_ILL_INSN);
gen_helper_raise_exception(tcg_ctx, tcg_ctx->cpu_env, r_const);
tcg_temp_free_i32(tcg_ctx, r_const);
dc->is_br = 1;
}
goto egress; goto egress;
unimp_flush: unimp_flush:
{ gen_exception(dc, TT_UNIMP_FLUSH);
TCGv_i32 r_const;
save_state(dc);
r_const = tcg_const_i32(tcg_ctx, TT_UNIMP_FLUSH);
gen_helper_raise_exception(tcg_ctx, tcg_ctx->cpu_env, r_const);
tcg_temp_free_i32(tcg_ctx, r_const);
dc->is_br = 1;
}
goto egress; goto egress;
#if !defined(CONFIG_USER_ONLY) #if !defined(CONFIG_USER_ONLY)
priv_insn: priv_insn:
{ gen_exception(dc, TT_PRIV_INSN);
TCGv_i32 r_const;
save_state(dc);
r_const = tcg_const_i32(tcg_ctx, TT_PRIV_INSN);
gen_helper_raise_exception(tcg_ctx, tcg_ctx->cpu_env, r_const);
tcg_temp_free_i32(tcg_ctx, r_const);
dc->is_br = 1;
}
goto egress; goto egress;
#endif #endif
nfpu_insn: nfpu_insn:
save_state(dc);
gen_op_fpexception_im(dc, FSR_FTT_UNIMPFPOP); gen_op_fpexception_im(dc, FSR_FTT_UNIMPFPOP);
dc->is_br = 1;
goto egress; goto egress;
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64) #if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
nfq_insn: nfq_insn:
save_state(dc);
gen_op_fpexception_im(dc, FSR_FTT_SEQ_ERROR); gen_op_fpexception_im(dc, FSR_FTT_SEQ_ERROR);
dc->is_br = 1;
goto egress; goto egress;
#endif #endif
#ifndef TARGET_SPARC64 #ifndef TARGET_SPARC64
ncp_insn: ncp_insn:
{ gen_exception(dc, TT_NCP_INSN);
TCGv r_const;
save_state(dc);
r_const = tcg_const_i32(tcg_ctx, TT_NCP_INSN);
gen_helper_raise_exception(tcg_ctx, tcg_ctx->cpu_env, r_const);
tcg_temp_free(tcg_ctx, r_const);
dc->is_br = 1;
}
goto egress; goto egress;
#endif #endif
egress: egress: