"Bruno Larsen (billionai)" <bruno.lar...@eldorado.org.br> writes:
> Moved all SPR read/write callback, and some related functions, to a > new file specific for it. These callbacks are TCG only, so separating > them is required to support the flag disable-tcg. > > Making the spr_noaccess function not static, and moving the define to > internal.h is required, as spr_tcg.c.inc has to be included after > SPR_NOACCESS has been used. > > Signed-off-by: Bruno Larsen (billionai) <bruno.lar...@eldorado.org.br> > --- > target/ppc/internal.h | 3 + > target/ppc/spr_tcg.c.inc | 1033 +++++++++++++++++++++++++++++++ > target/ppc/translate.c | 49 +- > target/ppc/translate_init.c.inc | 981 ----------------------------- > 4 files changed, 1039 insertions(+), 1027 deletions(-) > create mode 100644 target/ppc/spr_tcg.c.inc > > diff --git a/target/ppc/internal.h b/target/ppc/internal.h > index 184ba6d6b3..1de15acfbd 100644 > --- a/target/ppc/internal.h > +++ b/target/ppc/internal.h > @@ -228,4 +228,7 @@ void destroy_ppc_opcodes(PowerPCCPU *cpu); > void ppc_gdb_init(CPUState *cs, PowerPCCPUClass *ppc); > gchar *ppc_gdb_arch_name(CPUState *cs); > > +void spr_noaccess(DisasContext *ctx, int gprn, int sprn); > +#define SPR_NOACCESS (&spr_noaccess) > + > #endif /* PPC_INTERNAL_H */ > diff --git a/target/ppc/spr_tcg.c.inc b/target/ppc/spr_tcg.c.inc > new file mode 100644 > index 0000000000..48274dd52b > --- /dev/null > +++ b/target/ppc/spr_tcg.c.inc > @@ -0,0 +1,1033 @@ > +#include "exec/translator.h" This is already in translate.c. > + > +/*****************************************************************************/ > +/* Reader and writer functions for SPRs */ > + > +/* I really see no reason to keep these gen_*_xer */ > +/* instead of just leaving the code in the spr_*_xer */ Ok, let's do this for the next version then. > +static void gen_read_xer(DisasContext *ctx, TCGv dst) > +{ > + TCGv t0 = tcg_temp_new(); > + TCGv t1 = tcg_temp_new(); > + TCGv t2 = tcg_temp_new(); > + tcg_gen_mov_tl(dst, cpu_xer); > + tcg_gen_shli_tl(t0, cpu_so, XER_SO); > + tcg_gen_shli_tl(t1, cpu_ov, XER_OV); > + tcg_gen_shli_tl(t2, cpu_ca, XER_CA); > + tcg_gen_or_tl(t0, t0, t1); > + tcg_gen_or_tl(dst, dst, t2); > + tcg_gen_or_tl(dst, dst, t0); > + if (is_isa300(ctx)) { > + tcg_gen_shli_tl(t0, cpu_ov32, XER_OV32); > + tcg_gen_or_tl(dst, dst, t0); > + tcg_gen_shli_tl(t0, cpu_ca32, XER_CA32); > + tcg_gen_or_tl(dst, dst, t0); > + } > + tcg_temp_free(t0); > + tcg_temp_free(t1); > + tcg_temp_free(t2); > +} > + > +static void gen_write_xer(TCGv src) > +{ > + /* Write all flags, while reading back check for isa300 */ > + tcg_gen_andi_tl(cpu_xer, src, > + ~((1u << XER_SO) | > + (1u << XER_OV) | (1u << XER_OV32) | > + (1u << XER_CA) | (1u << XER_CA32))); > + tcg_gen_extract_tl(cpu_ov32, src, XER_OV32, 1); > + tcg_gen_extract_tl(cpu_ca32, src, XER_CA32, 1); > + tcg_gen_extract_tl(cpu_so, src, XER_SO, 1); > + tcg_gen_extract_tl(cpu_ov, src, XER_OV, 1); > + tcg_gen_extract_tl(cpu_ca, src, XER_CA, 1); > +} <snip> > +/* User read access to SPR */ > +/* USPRx */ > +/* UMMCRx */ > +/* UPMCx */ > +/* USIA */ > +/* UDECR */ > +static void spr_read_ureg(DisasContext *ctx, int gprn, int sprn) > +{ > + gen_load_spr(cpu_gpr[gprn], sprn + 0x10); > +} > + > +#if defined(TARGET_PPC64) && !defined(CONFIG_USER_ONLY) > +static void spr_write_ureg(DisasContext *ctx, int sprn, int gprn) > +{ > + gen_store_spr(sprn + 0x10, cpu_gpr[gprn]); > +} > +#endif > + You missed this: /* SPR common to all non-embedded PowerPC */ > +#if !defined(CONFIG_USER_ONLY) > +static void spr_read_decr(DisasContext *ctx, int gprn, int sprn) > +{ > + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { > + gen_io_start(); > + } > + gen_helper_load_decr(cpu_gpr[gprn], cpu_env); > + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { > + gen_stop_exception(ctx); > + } > +} > + > +static void spr_write_decr(DisasContext *ctx, int sprn, int gprn) > +{ > + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { > + gen_io_start(); > + } > + gen_helper_store_decr(cpu_env, cpu_gpr[gprn]); > + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { > + gen_stop_exception(ctx); > + } > +} > +#endif > + > +/* SPR common to all non-embedded PowerPC, except 601 */ > +/* Time base */ > +static void spr_read_tbl(DisasContext *ctx, int gprn, int sprn) > +{ > + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { > + gen_io_start(); > + } > + gen_helper_load_tbl(cpu_gpr[gprn], cpu_env); > + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { > + gen_io_end(); > + gen_stop_exception(ctx); > + } > +} > + > +static void spr_read_tbu(DisasContext *ctx, int gprn, int sprn) > +{ > + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { > + gen_io_start(); > + } > + gen_helper_load_tbu(cpu_gpr[gprn], cpu_env); > + if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) { > + gen_io_end(); > + gen_stop_exception(ctx); > + } > +} <snip> > +static void spr_write_excp_vector(DisasContext *ctx, int sprn, int gprn) > +{ > + int sprn_offs; > + > + if (sprn >= SPR_BOOKE_IVOR0 && sprn <= SPR_BOOKE_IVOR15) { > + sprn_offs = sprn - SPR_BOOKE_IVOR0; > + } else if (sprn >= SPR_BOOKE_IVOR32 && sprn <= SPR_BOOKE_IVOR37) { > + sprn_offs = sprn - SPR_BOOKE_IVOR32 + 32; > + } else if (sprn >= SPR_BOOKE_IVOR38 && sprn <= SPR_BOOKE_IVOR42) { > + sprn_offs = sprn - SPR_BOOKE_IVOR38 + 38; > + } else { > + printf("Trying to write an unknown exception vector %d %03x\n", > + sprn, sprn); > + gen_inval_exception(ctx, POWERPC_EXCP_PRIV_REG); > + return; > + } > + > + TCGv t0 = tcg_temp_new(); > + tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUPPCState, ivor_mask)); > + tcg_gen_and_tl(t0, t0, cpu_gpr[gprn]); > + tcg_gen_st_tl(t0, cpu_env, offsetof(CPUPPCState, > excp_vectors[sprn_offs])); > + gen_store_spr(sprn, t0); > + tcg_temp_free(t0); > +} > +#endif > + > +#ifdef TARGET_PPC64 #ifndef CONFIG_USER_ONLY > +static void spr_write_amr(DisasContext *ctx, int sprn, int gprn) > +{ > + TCGv t0 = tcg_temp_new(); > + TCGv t1 = tcg_temp_new(); > + TCGv t2 = tcg_temp_new(); > + > + /* > + * Note, the HV=1 PR=0 case is handled earlier by simply using > + * spr_write_generic for HV mode in the SPR table > + */ > + > + /* Build insertion mask into t1 based on context */ > + if (ctx->pr) { > + gen_load_spr(t1, SPR_UAMOR); > + } else { > + gen_load_spr(t1, SPR_AMOR); > + } > + > + /* Mask new bits into t2 */ > + tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]); > + > + /* Load AMR and clear new bits in t0 */ > + gen_load_spr(t0, SPR_AMR); > + tcg_gen_andc_tl(t0, t0, t1); > + > + /* Or'in new bits and write it out */ > + tcg_gen_or_tl(t0, t0, t2); > + gen_store_spr(SPR_AMR, t0); > + spr_store_dump_spr(SPR_AMR); > + > + tcg_temp_free(t0); > + tcg_temp_free(t1); > + tcg_temp_free(t2); > +} > + > +static void spr_write_uamor(DisasContext *ctx, int sprn, int gprn) > +{ > + TCGv t0 = tcg_temp_new(); > + TCGv t1 = tcg_temp_new(); > + TCGv t2 = tcg_temp_new(); > + > + /* > + * Note, the HV=1 case is handled earlier by simply using > + * spr_write_generic for HV mode in the SPR table > + */ > + > + /* Build insertion mask into t1 based on context */ > + gen_load_spr(t1, SPR_AMOR); > + > + /* Mask new bits into t2 */ > + tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]); > + > + /* Load AMR and clear new bits in t0 */ > + gen_load_spr(t0, SPR_UAMOR); > + tcg_gen_andc_tl(t0, t0, t1); > + > + /* Or'in new bits and write it out */ > + tcg_gen_or_tl(t0, t0, t2); > + gen_store_spr(SPR_UAMOR, t0); > + spr_store_dump_spr(SPR_UAMOR); > + > + tcg_temp_free(t0); > + tcg_temp_free(t1); > + tcg_temp_free(t2); > +} > + > +static void spr_write_iamr(DisasContext *ctx, int sprn, int gprn) > +{ > + TCGv t0 = tcg_temp_new(); > + TCGv t1 = tcg_temp_new(); > + TCGv t2 = tcg_temp_new(); > + > + /* > + * Note, the HV=1 case is handled earlier by simply using > + * spr_write_generic for HV mode in the SPR table > + */ > + > + /* Build insertion mask into t1 based on context */ > + gen_load_spr(t1, SPR_AMOR); > + > + /* Mask new bits into t2 */ > + tcg_gen_and_tl(t2, t1, cpu_gpr[gprn]); > + > + /* Load AMR and clear new bits in t0 */ > + gen_load_spr(t0, SPR_IAMR); > + tcg_gen_andc_tl(t0, t0, t1); > + > + /* Or'in new bits and write it out */ > + tcg_gen_or_tl(t0, t0, t2); > + gen_store_spr(SPR_IAMR, t0); > + spr_store_dump_spr(SPR_IAMR); > + > + tcg_temp_free(t0); > + tcg_temp_free(t1); > + tcg_temp_free(t2); > +} #endif /* CONFIG_USER_ONLY */ > +#endif > + > +#if !defined(CONFIG_USER_ONLY) > +static void spr_read_thrm(DisasContext *ctx, int gprn, int sprn) > +{ > + gen_helper_fixup_thrm(cpu_env); > + gen_load_spr(cpu_gpr[gprn], sprn); > + spr_load_dump_spr(sprn); > +} <snip> > diff --git a/target/ppc/translate.c b/target/ppc/translate.c > index b319d409c6..a6e677fa6d 100644 > --- a/target/ppc/translate.c > +++ b/target/ppc/translate.c > @@ -36,6 +36,7 @@ > #include "exec/translator.h" > #include "exec/log.h" > #include "qemu/atomic128.h" > +#include "internal.h" This is already included.