mirror of https://github.com/xemu-project/xemu.git
target/sparc: Move WRTBR, WRHPR to decodetree
Implement htstate in the obvious way. 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
9422278ef8
commit
bb97f2f5d7
|
@ -143,6 +143,15 @@ WRPR_strand_status 10 11010 110010 ..... . ............. @n_r_ri
|
|||
RDTBR 10 rd:5 101011 00000 0 0000000000000
|
||||
}
|
||||
|
||||
{
|
||||
WRTBR 10 00000 110011 ..... . ............. @n_r_ri
|
||||
WRHPR_hpstate 10 00000 110011 ..... . ............. @n_r_ri
|
||||
}
|
||||
WRHPR_htstate 10 00001 110011 ..... . ............. @n_r_ri
|
||||
WRHPR_hintp 10 00011 110011 ..... . ............. @n_r_ri
|
||||
WRHPR_htba 10 00101 110011 ..... . ............. @n_r_ri
|
||||
WRHPR_hstick_cmpr 10 11111 110011 ..... . ............. @n_r_ri
|
||||
|
||||
Tcc_r 10 0 cond:4 111010 rs1:5 0 cc:1 0000000 rs2:5
|
||||
{
|
||||
# For v7, the entire simm13 field is present, but masked to 7 bits.
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
# 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_tick_set_limit(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()
|
||||
|
@ -3935,6 +3936,61 @@ static void do_wrssr(DisasContext *dc, TCGv src)
|
|||
|
||||
TRANS(WRPR_strand_status, HYPV, do_wr_special, a, hypervisor(dc), do_wrssr)
|
||||
|
||||
TRANS(WRTBR, 32, do_wr_special, a, supervisor(dc), do_wrtba)
|
||||
|
||||
static void do_wrhpstate(DisasContext *dc, TCGv src)
|
||||
{
|
||||
tcg_gen_st_tl(src, tcg_env, env64_field_offsetof(hpstate));
|
||||
dc->base.is_jmp = DISAS_EXIT;
|
||||
}
|
||||
|
||||
TRANS(WRHPR_hpstate, HYPV, do_wr_special, a, hypervisor(dc), do_wrhpstate)
|
||||
|
||||
static void do_wrhtstate(DisasContext *dc, TCGv src)
|
||||
{
|
||||
TCGv_i32 tl = tcg_temp_new_i32();
|
||||
TCGv_ptr tp = tcg_temp_new_ptr();
|
||||
|
||||
tcg_gen_ld_i32(tl, tcg_env, env64_field_offsetof(tl));
|
||||
tcg_gen_andi_i32(tl, tl, MAXTL_MASK);
|
||||
tcg_gen_shli_i32(tl, tl, 3);
|
||||
tcg_gen_ext_i32_ptr(tp, tl);
|
||||
tcg_gen_add_ptr(tp, tp, tcg_env);
|
||||
|
||||
tcg_gen_st_tl(src, tp, env64_field_offsetof(htstate));
|
||||
}
|
||||
|
||||
TRANS(WRHPR_htstate, HYPV, do_wr_special, a, hypervisor(dc), do_wrhtstate)
|
||||
|
||||
static void do_wrhintp(DisasContext *dc, TCGv src)
|
||||
{
|
||||
tcg_gen_mov_tl(cpu_hintp, src);
|
||||
}
|
||||
|
||||
TRANS(WRHPR_hintp, HYPV, do_wr_special, a, hypervisor(dc), do_wrhintp)
|
||||
|
||||
static void do_wrhtba(DisasContext *dc, TCGv src)
|
||||
{
|
||||
tcg_gen_mov_tl(cpu_htba, src);
|
||||
}
|
||||
|
||||
TRANS(WRHPR_htba, HYPV, do_wr_special, a, hypervisor(dc), do_wrhtba)
|
||||
|
||||
static void do_wrhstick_cmpr(DisasContext *dc, TCGv src)
|
||||
{
|
||||
TCGv_ptr r_tickptr = tcg_temp_new_ptr();
|
||||
|
||||
tcg_gen_mov_tl(cpu_hstick_cmpr, src);
|
||||
tcg_gen_ld_ptr(r_tickptr, tcg_env, env64_field_offsetof(hstick));
|
||||
translator_io_start(&dc->base);
|
||||
gen_helper_tick_set_limit(r_tickptr, cpu_hstick_cmpr);
|
||||
/* End TB to handle timer interrupt */
|
||||
dc->base.is_jmp = DISAS_EXIT;
|
||||
}
|
||||
|
||||
TRANS(WRHPR_hstick_cmpr, HYPV, do_wr_special, a, hypervisor(dc),
|
||||
do_wrhstick_cmpr)
|
||||
|
||||
static bool do_saved_restored(DisasContext *dc, bool saved)
|
||||
{
|
||||
if (!supervisor(dc)) {
|
||||
|
@ -4624,63 +4680,10 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
|
|||
#endif
|
||||
case 0x30:
|
||||
goto illegal_insn; /* WRASR in decodetree */
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
case 0x32:
|
||||
goto illegal_insn; /* WRPR in decodetree */
|
||||
case 0x33: /* wrtbr, UA2005 wrhpr */
|
||||
{
|
||||
#ifndef TARGET_SPARC64
|
||||
if (!supervisor(dc))
|
||||
goto priv_insn;
|
||||
tcg_gen_xor_tl(cpu_tbr, cpu_src1, cpu_src2);
|
||||
#else
|
||||
CHECK_IU_FEATURE(dc, HYPV);
|
||||
if (!hypervisor(dc))
|
||||
goto priv_insn;
|
||||
cpu_tmp0 = tcg_temp_new();
|
||||
tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2);
|
||||
switch (rd) {
|
||||
case 0: // hpstate
|
||||
tcg_gen_st_i64(cpu_tmp0, tcg_env,
|
||||
offsetof(CPUSPARCState,
|
||||
hpstate));
|
||||
save_state(dc);
|
||||
gen_op_next_insn();
|
||||
tcg_gen_exit_tb(NULL, 0);
|
||||
dc->base.is_jmp = DISAS_NORETURN;
|
||||
break;
|
||||
case 1: // htstate
|
||||
// XXX gen_op_wrhtstate();
|
||||
break;
|
||||
case 3: // hintp
|
||||
tcg_gen_mov_tl(cpu_hintp, cpu_tmp0);
|
||||
break;
|
||||
case 5: // htba
|
||||
tcg_gen_mov_tl(cpu_htba, cpu_tmp0);
|
||||
break;
|
||||
case 31: // hstick_cmpr
|
||||
{
|
||||
TCGv_ptr r_tickptr;
|
||||
|
||||
tcg_gen_mov_tl(cpu_hstick_cmpr, cpu_tmp0);
|
||||
r_tickptr = tcg_temp_new_ptr();
|
||||
tcg_gen_ld_ptr(r_tickptr, tcg_env,
|
||||
offsetof(CPUSPARCState, hstick));
|
||||
translator_io_start(&dc->base);
|
||||
gen_helper_tick_set_limit(r_tickptr,
|
||||
cpu_hstick_cmpr);
|
||||
/* End TB to handle timer interrupt */
|
||||
dc->base.is_jmp = DISAS_EXIT;
|
||||
}
|
||||
break;
|
||||
case 6: // hver readonly
|
||||
default:
|
||||
goto illegal_insn;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
goto illegal_insn; /* WRTBR, WRHPR in decodetree */
|
||||
#ifdef TARGET_SPARC64
|
||||
case 0x2c: /* V9 movcc */
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue