target/sparc: Move WRWIM, WRPR to decodetree
Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Acked-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
parent
25524734c6
commit
9422278ef8
@ -117,6 +117,27 @@ RDPR_gl 10 rd:5 101010 10000 0 0000000000000
|
||||
RDPR_strand_status 10 rd:5 101010 11010 0 0000000000000
|
||||
RDPR_ver 10 rd:5 101010 11111 0 0000000000000
|
||||
|
||||
{
|
||||
WRWIM 10 00000 110010 ..... . ............. @n_r_ri
|
||||
WRPR_tpc 10 00000 110010 ..... . ............. @n_r_ri
|
||||
}
|
||||
WRPR_tnpc 10 00001 110010 ..... . ............. @n_r_ri
|
||||
WRPR_tstate 10 00010 110010 ..... . ............. @n_r_ri
|
||||
WRPR_tt 10 00011 110010 ..... . ............. @n_r_ri
|
||||
WRPR_tick 10 00100 110010 ..... . ............. @n_r_ri
|
||||
WRPR_tba 10 00101 110010 ..... . ............. @n_r_ri
|
||||
WRPR_pstate 10 00110 110010 ..... . ............. @n_r_ri
|
||||
WRPR_tl 10 00111 110010 ..... . ............. @n_r_ri
|
||||
WRPR_pil 10 01000 110010 ..... . ............. @n_r_ri
|
||||
WRPR_cwp 10 01001 110010 ..... . ............. @n_r_ri
|
||||
WRPR_cansave 10 01010 110010 ..... . ............. @n_r_ri
|
||||
WRPR_canrestore 10 01011 110010 ..... . ............. @n_r_ri
|
||||
WRPR_cleanwin 10 01100 110010 ..... . ............. @n_r_ri
|
||||
WRPR_otherwin 10 01101 110010 ..... . ............. @n_r_ri
|
||||
WRPR_wstate 10 01110 110010 ..... . ............. @n_r_ri
|
||||
WRPR_gl 10 10000 110010 ..... . ............. @n_r_ri
|
||||
WRPR_strand_status 10 11010 110010 ..... . ............. @n_r_ri
|
||||
|
||||
{
|
||||
FLUSHW 10 00000 101011 00000 0 0000000000000
|
||||
RDTBR 10 rd:5 101011 00000 0 0000000000000
|
||||
|
@ -49,8 +49,13 @@
|
||||
# define gen_helper_saved(E) qemu_build_not_reached()
|
||||
# define gen_helper_set_softint(E, S) qemu_build_not_reached()
|
||||
# define gen_helper_tick_get_count(D, E, T, C) qemu_build_not_reached()
|
||||
# define gen_helper_tick_set_count(P, S) qemu_build_not_reached()
|
||||
# define gen_helper_wrccr(E, S) qemu_build_not_reached()
|
||||
# define gen_helper_wrcwp(E, S) qemu_build_not_reached()
|
||||
# define gen_helper_wrgl(E, S) qemu_build_not_reached()
|
||||
# define gen_helper_write_softint(E, S) qemu_build_not_reached()
|
||||
# define gen_helper_wrpil(E, S) qemu_build_not_reached()
|
||||
# define gen_helper_wrpstate(E, S) qemu_build_not_reached()
|
||||
# define MAXTL_MASK 0
|
||||
#endif
|
||||
|
||||
@ -3758,6 +3763,178 @@ static void do_wrpsr(DisasContext *dc, TCGv src)
|
||||
|
||||
TRANS(WRPSR, 32, do_wr_special, a, supervisor(dc), do_wrpsr)
|
||||
|
||||
static void do_wrwim(DisasContext *dc, TCGv src)
|
||||
{
|
||||
target_ulong mask = MAKE_64BIT_MASK(0, dc->def->nwindows);
|
||||
tcg_gen_andi_tl(cpu_wim, src, mask);
|
||||
}
|
||||
|
||||
TRANS(WRWIM, 32, do_wr_special, a, supervisor(dc), do_wrwim)
|
||||
|
||||
static void do_wrtpc(DisasContext *dc, TCGv src)
|
||||
{
|
||||
#ifdef TARGET_SPARC64
|
||||
TCGv_ptr r_tsptr = tcg_temp_new_ptr();
|
||||
|
||||
gen_load_trap_state_at_tl(r_tsptr);
|
||||
tcg_gen_st_tl(src, r_tsptr, offsetof(trap_state, tpc));
|
||||
#else
|
||||
qemu_build_not_reached();
|
||||
#endif
|
||||
}
|
||||
|
||||
TRANS(WRPR_tpc, 64, do_wr_special, a, supervisor(dc), do_wrtpc)
|
||||
|
||||
static void do_wrtnpc(DisasContext *dc, TCGv src)
|
||||
{
|
||||
#ifdef TARGET_SPARC64
|
||||
TCGv_ptr r_tsptr = tcg_temp_new_ptr();
|
||||
|
||||
gen_load_trap_state_at_tl(r_tsptr);
|
||||
tcg_gen_st_tl(src, r_tsptr, offsetof(trap_state, tnpc));
|
||||
#else
|
||||
qemu_build_not_reached();
|
||||
#endif
|
||||
}
|
||||
|
||||
TRANS(WRPR_tnpc, 64, do_wr_special, a, supervisor(dc), do_wrtnpc)
|
||||
|
||||
static void do_wrtstate(DisasContext *dc, TCGv src)
|
||||
{
|
||||
#ifdef TARGET_SPARC64
|
||||
TCGv_ptr r_tsptr = tcg_temp_new_ptr();
|
||||
|
||||
gen_load_trap_state_at_tl(r_tsptr);
|
||||
tcg_gen_st_tl(src, r_tsptr, offsetof(trap_state, tstate));
|
||||
#else
|
||||
qemu_build_not_reached();
|
||||
#endif
|
||||
}
|
||||
|
||||
TRANS(WRPR_tstate, 64, do_wr_special, a, supervisor(dc), do_wrtstate)
|
||||
|
||||
static void do_wrtt(DisasContext *dc, TCGv src)
|
||||
{
|
||||
#ifdef TARGET_SPARC64
|
||||
TCGv_ptr r_tsptr = tcg_temp_new_ptr();
|
||||
|
||||
gen_load_trap_state_at_tl(r_tsptr);
|
||||
tcg_gen_st32_tl(src, r_tsptr, offsetof(trap_state, tt));
|
||||
#else
|
||||
qemu_build_not_reached();
|
||||
#endif
|
||||
}
|
||||
|
||||
TRANS(WRPR_tt, 64, do_wr_special, a, supervisor(dc), do_wrtt)
|
||||
|
||||
static void do_wrtick(DisasContext *dc, TCGv src)
|
||||
{
|
||||
TCGv_ptr r_tickptr = tcg_temp_new_ptr();
|
||||
|
||||
tcg_gen_ld_ptr(r_tickptr, tcg_env, env64_field_offsetof(tick));
|
||||
translator_io_start(&dc->base);
|
||||
gen_helper_tick_set_count(r_tickptr, src);
|
||||
/* End TB to handle timer interrupt */
|
||||
dc->base.is_jmp = DISAS_EXIT;
|
||||
}
|
||||
|
||||
TRANS(WRPR_tick, 64, do_wr_special, a, supervisor(dc), do_wrtick)
|
||||
|
||||
static void do_wrtba(DisasContext *dc, TCGv src)
|
||||
{
|
||||
tcg_gen_mov_tl(cpu_tbr, src);
|
||||
}
|
||||
|
||||
TRANS(WRPR_tba, 64, do_wr_special, a, supervisor(dc), do_wrtba)
|
||||
|
||||
static void do_wrpstate(DisasContext *dc, TCGv src)
|
||||
{
|
||||
save_state(dc);
|
||||
if (translator_io_start(&dc->base)) {
|
||||
dc->base.is_jmp = DISAS_EXIT;
|
||||
}
|
||||
gen_helper_wrpstate(tcg_env, src);
|
||||
dc->npc = DYNAMIC_PC;
|
||||
}
|
||||
|
||||
TRANS(WRPR_pstate, 64, do_wr_special, a, supervisor(dc), do_wrpstate)
|
||||
|
||||
static void do_wrtl(DisasContext *dc, TCGv src)
|
||||
{
|
||||
save_state(dc);
|
||||
tcg_gen_st32_tl(src, tcg_env, env64_field_offsetof(tl));
|
||||
dc->npc = DYNAMIC_PC;
|
||||
}
|
||||
|
||||
TRANS(WRPR_tl, 64, do_wr_special, a, supervisor(dc), do_wrtl)
|
||||
|
||||
static void do_wrpil(DisasContext *dc, TCGv src)
|
||||
{
|
||||
if (translator_io_start(&dc->base)) {
|
||||
dc->base.is_jmp = DISAS_EXIT;
|
||||
}
|
||||
gen_helper_wrpil(tcg_env, src);
|
||||
}
|
||||
|
||||
TRANS(WRPR_pil, 64, do_wr_special, a, supervisor(dc), do_wrpil)
|
||||
|
||||
static void do_wrcwp(DisasContext *dc, TCGv src)
|
||||
{
|
||||
gen_helper_wrcwp(tcg_env, src);
|
||||
}
|
||||
|
||||
TRANS(WRPR_cwp, 64, do_wr_special, a, supervisor(dc), do_wrcwp)
|
||||
|
||||
static void do_wrcansave(DisasContext *dc, TCGv src)
|
||||
{
|
||||
tcg_gen_st32_tl(src, tcg_env, env64_field_offsetof(cansave));
|
||||
}
|
||||
|
||||
TRANS(WRPR_cansave, 64, do_wr_special, a, supervisor(dc), do_wrcansave)
|
||||
|
||||
static void do_wrcanrestore(DisasContext *dc, TCGv src)
|
||||
{
|
||||
tcg_gen_st32_tl(src, tcg_env, env64_field_offsetof(canrestore));
|
||||
}
|
||||
|
||||
TRANS(WRPR_canrestore, 64, do_wr_special, a, supervisor(dc), do_wrcanrestore)
|
||||
|
||||
static void do_wrcleanwin(DisasContext *dc, TCGv src)
|
||||
{
|
||||
tcg_gen_st32_tl(src, tcg_env, env64_field_offsetof(cleanwin));
|
||||
}
|
||||
|
||||
TRANS(WRPR_cleanwin, 64, do_wr_special, a, supervisor(dc), do_wrcleanwin)
|
||||
|
||||
static void do_wrotherwin(DisasContext *dc, TCGv src)
|
||||
{
|
||||
tcg_gen_st32_tl(src, tcg_env, env64_field_offsetof(otherwin));
|
||||
}
|
||||
|
||||
TRANS(WRPR_otherwin, 64, do_wr_special, a, supervisor(dc), do_wrotherwin)
|
||||
|
||||
static void do_wrwstate(DisasContext *dc, TCGv src)
|
||||
{
|
||||
tcg_gen_st32_tl(src, tcg_env, env64_field_offsetof(wstate));
|
||||
}
|
||||
|
||||
TRANS(WRPR_wstate, 64, do_wr_special, a, supervisor(dc), do_wrwstate)
|
||||
|
||||
static void do_wrgl(DisasContext *dc, TCGv src)
|
||||
{
|
||||
gen_helper_wrgl(tcg_env, src);
|
||||
}
|
||||
|
||||
TRANS(WRPR_gl, GL, do_wr_special, a, supervisor(dc), do_wrgl)
|
||||
|
||||
/* UA2005 strand status */
|
||||
static void do_wrssr(DisasContext *dc, TCGv src)
|
||||
{
|
||||
tcg_gen_mov_tl(cpu_ssr, src);
|
||||
}
|
||||
|
||||
TRANS(WRPR_strand_status, HYPV, do_wr_special, a, hypervisor(dc), do_wrssr)
|
||||
|
||||
static bool do_saved_restored(DisasContext *dc, bool saved)
|
||||
{
|
||||
if (!supervisor(dc)) {
|
||||
@ -4448,142 +4625,8 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
|
||||
case 0x30:
|
||||
goto illegal_insn; /* WRASR in decodetree */
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
case 0x32: /* wrwim, V9 wrpr */
|
||||
{
|
||||
if (!supervisor(dc))
|
||||
goto priv_insn;
|
||||
cpu_tmp0 = tcg_temp_new();
|
||||
tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
|
||||
#ifdef TARGET_SPARC64
|
||||
switch (rd) {
|
||||
case 0: // tpc
|
||||
{
|
||||
TCGv_ptr r_tsptr;
|
||||
|
||||
r_tsptr = tcg_temp_new_ptr();
|
||||
gen_load_trap_state_at_tl(r_tsptr);
|
||||
tcg_gen_st_tl(cpu_tmp0, r_tsptr,
|
||||
offsetof(trap_state, tpc));
|
||||
}
|
||||
break;
|
||||
case 1: // tnpc
|
||||
{
|
||||
TCGv_ptr r_tsptr;
|
||||
|
||||
r_tsptr = tcg_temp_new_ptr();
|
||||
gen_load_trap_state_at_tl(r_tsptr);
|
||||
tcg_gen_st_tl(cpu_tmp0, r_tsptr,
|
||||
offsetof(trap_state, tnpc));
|
||||
}
|
||||
break;
|
||||
case 2: // tstate
|
||||
{
|
||||
TCGv_ptr r_tsptr;
|
||||
|
||||
r_tsptr = tcg_temp_new_ptr();
|
||||
gen_load_trap_state_at_tl(r_tsptr);
|
||||
tcg_gen_st_tl(cpu_tmp0, r_tsptr,
|
||||
offsetof(trap_state,
|
||||
tstate));
|
||||
}
|
||||
break;
|
||||
case 3: // tt
|
||||
{
|
||||
TCGv_ptr r_tsptr;
|
||||
|
||||
r_tsptr = tcg_temp_new_ptr();
|
||||
gen_load_trap_state_at_tl(r_tsptr);
|
||||
tcg_gen_st32_tl(cpu_tmp0, r_tsptr,
|
||||
offsetof(trap_state, tt));
|
||||
}
|
||||
break;
|
||||
case 4: // tick
|
||||
{
|
||||
TCGv_ptr r_tickptr;
|
||||
|
||||
r_tickptr = tcg_temp_new_ptr();
|
||||
tcg_gen_ld_ptr(r_tickptr, tcg_env,
|
||||
offsetof(CPUSPARCState, tick));
|
||||
translator_io_start(&dc->base);
|
||||
gen_helper_tick_set_count(r_tickptr,
|
||||
cpu_tmp0);
|
||||
/* End TB to handle timer interrupt */
|
||||
dc->base.is_jmp = DISAS_EXIT;
|
||||
}
|
||||
break;
|
||||
case 5: // tba
|
||||
tcg_gen_mov_tl(cpu_tbr, cpu_tmp0);
|
||||
break;
|
||||
case 6: // pstate
|
||||
save_state(dc);
|
||||
if (translator_io_start(&dc->base)) {
|
||||
dc->base.is_jmp = DISAS_EXIT;
|
||||
}
|
||||
gen_helper_wrpstate(tcg_env, cpu_tmp0);
|
||||
dc->npc = DYNAMIC_PC;
|
||||
break;
|
||||
case 7: // tl
|
||||
save_state(dc);
|
||||
tcg_gen_st32_tl(cpu_tmp0, tcg_env,
|
||||
offsetof(CPUSPARCState, tl));
|
||||
dc->npc = DYNAMIC_PC;
|
||||
break;
|
||||
case 8: // pil
|
||||
if (translator_io_start(&dc->base)) {
|
||||
dc->base.is_jmp = DISAS_EXIT;
|
||||
}
|
||||
gen_helper_wrpil(tcg_env, cpu_tmp0);
|
||||
break;
|
||||
case 9: // cwp
|
||||
gen_helper_wrcwp(tcg_env, cpu_tmp0);
|
||||
break;
|
||||
case 10: // cansave
|
||||
tcg_gen_st32_tl(cpu_tmp0, tcg_env,
|
||||
offsetof(CPUSPARCState,
|
||||
cansave));
|
||||
break;
|
||||
case 11: // canrestore
|
||||
tcg_gen_st32_tl(cpu_tmp0, tcg_env,
|
||||
offsetof(CPUSPARCState,
|
||||
canrestore));
|
||||
break;
|
||||
case 12: // cleanwin
|
||||
tcg_gen_st32_tl(cpu_tmp0, tcg_env,
|
||||
offsetof(CPUSPARCState,
|
||||
cleanwin));
|
||||
break;
|
||||
case 13: // otherwin
|
||||
tcg_gen_st32_tl(cpu_tmp0, tcg_env,
|
||||
offsetof(CPUSPARCState,
|
||||
otherwin));
|
||||
break;
|
||||
case 14: // wstate
|
||||
tcg_gen_st32_tl(cpu_tmp0, tcg_env,
|
||||
offsetof(CPUSPARCState,
|
||||
wstate));
|
||||
break;
|
||||
case 16: // UA2005 gl
|
||||
CHECK_IU_FEATURE(dc, GL);
|
||||
gen_helper_wrgl(tcg_env, cpu_tmp0);
|
||||
break;
|
||||
case 26: // UA2005 strand status
|
||||
CHECK_IU_FEATURE(dc, HYPV);
|
||||
if (!hypervisor(dc))
|
||||
goto priv_insn;
|
||||
tcg_gen_mov_tl(cpu_ssr, cpu_tmp0);
|
||||
break;
|
||||
default:
|
||||
goto illegal_insn;
|
||||
}
|
||||
#else
|
||||
tcg_gen_trunc_tl_i32(cpu_wim, cpu_tmp0);
|
||||
if (dc->def->nwindows != 32) {
|
||||
tcg_gen_andi_tl(cpu_wim, cpu_wim,
|
||||
(1 << dc->def->nwindows) - 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case 0x32:
|
||||
goto illegal_insn; /* WRPR in decodetree */
|
||||
case 0x33: /* wrtbr, UA2005 wrhpr */
|
||||
{
|
||||
#ifndef TARGET_SPARC64
|
||||
|
Loading…
Reference in New Issue
Block a user