target/sparc: Move RDPSR, RDHPR to decodetree
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>
This commit is contained in:
parent
af25071c1d
commit
668bb9b755
@ -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,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. */
|
||||
@ -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];
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user