Signed-off-by: Richard Henderson <richard.hender...@linaro.org> --- target/sparc/insns.decode | 10 +++++++ target/sparc/translate.c | 61 ++++++++++++++++++--------------------- 2 files changed, 38 insertions(+), 33 deletions(-)
diff --git a/target/sparc/insns.decode b/target/sparc/insns.decode index d7e7f0c577..5ba71c3d84 100644 --- a/target/sparc/insns.decode +++ b/target/sparc/insns.decode @@ -85,6 +85,16 @@ RDHPR_htba 10 rd:5 101001 00101 0 0000000000000 RDHPR_hver 10 rd:5 101001 00110 0 0000000000000 RDHPR_hstick_cmpr 10 rd:5 101001 11111 0 0000000000000 +{ + WRPSR 10 00000 110001 ..... . ............. @n_r_ri + SAVED 10 00000 110001 00000 0 0000000000000 +} +RESTORED 10 00001 110001 00000 0 0000000000000 +# UA2005 ALLCLEAN +# UA2005 OTHERW +# UA2005 NORMALW +# UA2005 INVALW + { RDWIM 10 rd:5 101010 00000 0 0000000000000 RDPR_tpc 10 rd:5 101010 00000 0 0000000000000 diff --git a/target/sparc/translate.c b/target/sparc/translate.c index c34602df80..7358a59fda 100644 --- a/target/sparc/translate.c +++ b/target/sparc/translate.c @@ -38,6 +38,7 @@ #ifdef TARGET_SPARC64 #define gen_helper_rdpsr(D, E) qemu_build_not_reached() +#define gen_helper_wrpsr(E, S) qemu_build_not_reached() #define gen_helper_power_down(E) g_assert_not_reached() #else #define gen_helper_rdccr(D, E) qemu_build_not_reached() @@ -46,6 +47,8 @@ #define gen_helper_set_softint(E, S) qemu_build_not_reached() #define gen_helper_clear_softint(E, S) qemu_build_not_reached() #define gen_helper_write_softint(E, S) qemu_build_not_reached() +#define gen_helper_saved ({ qemu_build_not_reached(); NULL; }) +#define gen_helper_restored ({ qemu_build_not_reached(); NULL; }) #endif /* Dynamic PC, must exit to main loop. */ @@ -3803,6 +3806,31 @@ static void do_wrpowerdown(DisasContext *dc, TCGv src) TRANS(WRPOWERDOWN, POWERDOWN, do_wr_special, a, supervisor(dc), do_wrpowerdown) +static void do_wrpsr(DisasContext *dc, TCGv src) +{ + gen_helper_wrpsr(tcg_env, src); + tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS); + dc->cc_op = CC_OP_FLAGS; + save_state(dc); + gen_op_next_insn(); + tcg_gen_exit_tb(NULL, 0); + dc->base.is_jmp = DISAS_NORETURN; +} + +TRANS(WRPSR, 32, do_wr_special, a, supervisor(dc), do_wrpsr) + +static bool do_saved_restored(DisasContext *dc, void (*func)(TCGv_env)) +{ + if (!supervisor(dc)) { + return raise_priv(dc); + } + func(tcg_env); + return advance_pc(dc); +} + +TRANS(SAVED, 64, do_saved_restored, gen_helper_saved) +TRANS(RESTORED, 64, do_saved_restored, gen_helper_restored) + static bool trans_NOP_v7(DisasContext *dc, arg_NOP_v7 *a) { /* @@ -4477,39 +4505,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn) case 0x30: goto illegal_insn; /* WRASR in decodetree */ #if !defined(CONFIG_USER_ONLY) - case 0x31: /* wrpsr, V9 saved, restored */ - { - if (!supervisor(dc)) - goto priv_insn; -#ifdef TARGET_SPARC64 - switch (rd) { - case 0: - gen_helper_saved(tcg_env); - break; - case 1: - gen_helper_restored(tcg_env); - break; - case 2: /* UA2005 allclean */ - case 3: /* UA2005 otherw */ - case 4: /* UA2005 normalw */ - case 5: /* UA2005 invalw */ - // XXX - default: - goto illegal_insn; - } -#else - cpu_tmp0 = tcg_temp_new(); - tcg_gen_xor_tl(cpu_tmp0, cpu_src1, cpu_src2); - gen_helper_wrpsr(tcg_env, cpu_tmp0); - tcg_gen_movi_i32(cpu_cc_op, CC_OP_FLAGS); - dc->cc_op = CC_OP_FLAGS; - save_state(dc); - gen_op_next_insn(); - tcg_gen_exit_tb(NULL, 0); - dc->base.is_jmp = DISAS_NORETURN; -#endif - } - break; case 0x32: /* wrwim, V9 wrpr */ { if (!supervisor(dc)) -- 2.34.1