@@ -44,6 +44,16 @@ CALL 01 i:s30
RDY 10 rd:5 101000 rs1:5 0 0000000000000
}
+{
+ RDPSR 10 rd:5 101001 00000 0 0000000000000
+ RDHPR_hpstate 10 rd:5 101001 00000 0 0000000000000
+}
+RDHPR_htstate 10 rd:5 101001 00001 0 0000000000000
+RDHPR_hintp 10 rd:5 101001 00011 0 0000000000000
+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
+
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.
@@ -36,7 +36,9 @@
#include "exec/helper-info.c.inc"
#undef HELPER_H
-#ifndef TARGET_SPARC64
+#ifdef TARGET_SPARC64
+#define gen_helper_rdpsr(D, E) qemu_build_not_reached()
+#else
#define gen_helper_rdccr(D, E) qemu_build_not_reached()
#endif
@@ -260,15 +262,14 @@ static void gen_move_Q(DisasContext *dc, unsigned int rd, unsigned int rs)
/* moves */
#ifdef CONFIG_USER_ONLY
#define supervisor(dc) 0
-#ifdef TARGET_SPARC64
#define hypervisor(dc) 0
-#endif
#else
#ifdef TARGET_SPARC64
#define hypervisor(dc) (dc->hypervisor)
#define supervisor(dc) (dc->supervisor | dc->hypervisor)
#else
#define supervisor(dc) (dc->supervisor)
+#define hypervisor(dc) 0
#endif
#endif
@@ -3334,6 +3335,93 @@ static TCGv do_rdstrand_status(DisasContext *dc, TCGv dst)
TRANS(RDSTRAND_STATUS, HYPV, do_rd_special, true, a->rd, do_rdstrand_status)
+static TCGv do_rdpsr(DisasContext *dc, TCGv dst)
+{
+ update_psr(dc);
+ gen_helper_rdpsr(dst, tcg_env);
+ return dst;
+}
+
+TRANS(RDPSR, 32, do_rd_special, supervisor(dc), a->rd, do_rdpsr)
+
+static TCGv do_rdhpstate(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ tcg_gen_ld_i64(dst, tcg_env, offsetof(CPUSPARCState, hpstate));
+ return dst;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDHPR_hpstate, HYPV, do_rd_special, hypervisor(dc), a->rd, do_rdhpstate)
+
+static TCGv do_rdhtstate(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ TCGv_i32 tl = tcg_temp_new_i32();
+ TCGv_ptr tp = tcg_temp_new_ptr();
+
+ tcg_gen_ld_i32(tl, tcg_env, offsetof(CPUSPARCState, 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_ld_i64(dst, tp, offsetof(CPUSPARCState, htstate));
+ return dst;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDHPR_htstate, HYPV, do_rd_special, hypervisor(dc), a->rd, do_rdhtstate)
+
+static TCGv do_rdhintp(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ return cpu_hintp;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDHPR_hintp, HYPV, do_rd_special, hypervisor(dc), a->rd, do_rdhintp)
+
+static TCGv do_rdhtba(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ return cpu_htba;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDHPR_htba, HYPV, do_rd_special, hypervisor(dc), a->rd, do_rdhtba)
+
+static TCGv do_rdhver(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ return cpu_hver;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDHPR_hver, HYPV, do_rd_special, hypervisor(dc), a->rd, do_rdhver)
+
+static TCGv do_rdhstick_cmpr(DisasContext *dc, TCGv dst)
+{
+#ifdef TARGET_SPARC64
+ return cpu_hstick_cmpr;
+#else
+ qemu_build_not_reached();
+#endif
+}
+
+TRANS(RDHPR_hstick_cmpr, HYPV, do_rd_special, hypervisor(dc), a->rd,
+ do_rdhstick_cmpr)
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -3365,45 +3453,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
TCGv cpu_tmp0 __attribute__((unused));
#if !defined(CONFIG_USER_ONLY)
- if (xop == 0x29) { /* rdpsr / UA2005 rdhpr */
-#ifndef TARGET_SPARC64
- if (!supervisor(dc)) {
- goto priv_insn;
- }
- update_psr(dc);
- gen_helper_rdpsr(cpu_dst, tcg_env);
-#else
- CHECK_IU_FEATURE(dc, HYPV);
- if (!hypervisor(dc))
- goto priv_insn;
- rs1 = GET_FIELD(insn, 13, 17);
- switch (rs1) {
- case 0: // hpstate
- tcg_gen_ld_i64(cpu_dst, tcg_env,
- offsetof(CPUSPARCState, hpstate));
- break;
- case 1: // htstate
- // gen_op_rdhtstate();
- break;
- case 3: // hintp
- tcg_gen_mov_tl(cpu_dst, cpu_hintp);
- break;
- case 5: // htba
- tcg_gen_mov_tl(cpu_dst, cpu_htba);
- break;
- case 6: // hver
- tcg_gen_mov_tl(cpu_dst, cpu_hver);
- break;
- case 31: // hstick_cmpr
- tcg_gen_mov_tl(cpu_dst, cpu_hstick_cmpr);
- break;
- default:
- goto illegal_insn;
- }
-#endif
- gen_store_gpr(dc, rd, cpu_dst);
- break;
- }
if (xop == 0x2a) { /* rdwim / V9 rdpr */
if (!supervisor(dc)) {
goto priv_insn;
Implement htstate in the obvious way. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/sparc/insns.decode | 10 +++ target/sparc/translate.c | 133 ++++++++++++++++++++++++++------------ 2 files changed, 101 insertions(+), 42 deletions(-)