Skip to content

Commit

Permalink
target/sparc: Move RDPSR, RDHPR to decodetree
Browse files Browse the repository at this point in the history
Implement htstate in the obvious way.

Resolves: https://gitlab.com/qemu-project/qemu/-/issues/847
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>
  • Loading branch information
rth7680 committed Oct 25, 2023
1 parent af25071 commit 668bb9b
Show file tree
Hide file tree
Showing 2 changed files with 83 additions and 43 deletions.
10 changes: 10 additions & 0 deletions target/sparc/insns.decode
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
116 changes: 73 additions & 43 deletions target/sparc/translate.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,12 @@
#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()
# define gen_helper_tick_get_count(D, E, T, C) qemu_build_not_reached()
# define MAXTL_MASK 0
#endif

/* Dynamic PC, must exit to main loop. */
Expand Down Expand Up @@ -71,8 +74,12 @@ static TCGv cpu_hintp, cpu_htba, cpu_hver, cpu_ssr, cpu_ver;
static TCGv cpu_wim;
# define cpu_fprs ({ qemu_build_not_reached(); (TCGv)NULL; })
# define cpu_gsr ({ qemu_build_not_reached(); (TCGv)NULL; })
# define cpu_tick_cmpr ({ qemu_build_not_reached(); (TCGv)NULL; })
# define cpu_hintp ({ qemu_build_not_reached(); (TCGv)NULL; })
# define cpu_hstick_cmpr ({ qemu_build_not_reached(); (TCGv)NULL; })
# define cpu_htba ({ qemu_build_not_reached(); (TCGv)NULL; })
# define cpu_hver ({ qemu_build_not_reached(); (TCGv)NULL; })
# define cpu_stick_cmpr ({ qemu_build_not_reached(); (TCGv)NULL; })
# define cpu_tick_cmpr ({ qemu_build_not_reached(); (TCGv)NULL; })
#endif
/* Floating point registers */
static TCGv_i64 cpu_fpr[TARGET_DPREGS];
Expand Down Expand Up @@ -272,15 +279,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

Expand Down Expand Up @@ -3320,6 +3326,69 @@ 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)
{
tcg_gen_ld_tl(dst, tcg_env, env64_field_offsetof(hpstate));
return dst;
}

TRANS(RDHPR_hpstate, HYPV, do_rd_special, hypervisor(dc), a->rd, do_rdhpstate)

static TCGv do_rdhtstate(DisasContext *dc, TCGv dst)
{
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_ld_tl(dst, tp, env64_field_offsetof(htstate));
return dst;
}

TRANS(RDHPR_htstate, HYPV, do_rd_special, hypervisor(dc), a->rd, do_rdhtstate)

static TCGv do_rdhintp(DisasContext *dc, TCGv dst)
{
return cpu_hintp;
}

TRANS(RDHPR_hintp, HYPV, do_rd_special, hypervisor(dc), a->rd, do_rdhintp)

static TCGv do_rdhtba(DisasContext *dc, TCGv dst)
{
return cpu_htba;
}

TRANS(RDHPR_htba, HYPV, do_rd_special, hypervisor(dc), a->rd, do_rdhtba)

static TCGv do_rdhver(DisasContext *dc, TCGv dst)
{
return cpu_hver;
}

TRANS(RDHPR_hver, HYPV, do_rd_special, hypervisor(dc), a->rd, do_rdhver)

static TCGv do_rdhstick_cmpr(DisasContext *dc, TCGv dst)
{
return cpu_hstick_cmpr;
}

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;
Expand Down Expand Up @@ -3351,45 +3420,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;
Expand Down

0 comments on commit 668bb9b

Please sign in to comment.