target/sparc: Move DONE, RETRY to decodetree

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:
Richard Henderson 2023-10-04 19:05:45 -07:00
parent d382580031
commit 8f75b8a4eb
2 changed files with 29 additions and 62 deletions

View File

@ -228,6 +228,9 @@ NOP 10 00000 111011 ----- 1 ------------- # FLUSH reg+imm
SAVE 10 ..... 111100 ..... . ............. @r_r_ri
RESTORE 10 ..... 111101 ..... . ............. @r_r_ri
DONE 10 00000 111110 00000 0 0000000000000
RETRY 10 00001 111110 00000 0 0000000000000
NCP 10 ----- 110110 ----- --------- ----- # v8 CPop1
NCP 10 ----- 110111 ----- --------- ----- # v8 CPop2

View File

@ -43,10 +43,12 @@
# define gen_helper_wrpsr(E, S) qemu_build_not_reached()
#else
# define gen_helper_clear_softint(E, S) qemu_build_not_reached()
# define gen_helper_done(E) qemu_build_not_reached()
# define gen_helper_flushw(E) qemu_build_not_reached()
# define gen_helper_rdccr(D, E) qemu_build_not_reached()
# define gen_helper_rdcwp(D, E) qemu_build_not_reached()
# define gen_helper_restored(E) qemu_build_not_reached()
# define gen_helper_retry(E) qemu_build_not_reached()
# define gen_helper_saved(E) qemu_build_not_reached()
# define gen_helper_sdivx(D, E, A, B) qemu_build_not_reached()
# define gen_helper_set_softint(E, S) qemu_build_not_reached()
@ -4480,6 +4482,25 @@ static bool do_restore(DisasContext *dc, int rd, TCGv src)
TRANS(RESTORE, ALL, do_add_special, a, do_restore)
static bool do_done_retry(DisasContext *dc, bool done)
{
if (!supervisor(dc)) {
return raise_priv(dc);
}
dc->npc = DYNAMIC_PC;
dc->pc = DYNAMIC_PC;
translator_io_start(&dc->base);
if (done) {
gen_helper_done(tcg_env);
} else {
gen_helper_retry(tcg_env);
}
return true;
}
TRANS(DONE, 64, do_done_retry, true)
TRANS(RETRY, 64, do_done_retry, false)
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@ -4491,7 +4512,8 @@ TRANS(RESTORE, ALL, do_add_special, a, do_restore)
static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
{
unsigned int opc, rs1, rs2, rd;
TCGv cpu_src1, cpu_src2;
TCGv cpu_src1;
TCGv cpu_src2 __attribute__((unused));
TCGv_i32 cpu_src1_32, cpu_src2_32, cpu_dst_32;
TCGv_i64 cpu_src1_64, cpu_src2_64, cpu_dst_64;
target_long simm;
@ -4506,9 +4528,8 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
g_assert_not_reached(); /* in decodetree */
case 2: /* FPU & Logical Operations */
{
unsigned int xop __attribute__((unused)) = GET_FIELD(insn, 7, 12);
unsigned int xop = GET_FIELD(insn, 7, 12);
TCGv cpu_dst __attribute__((unused)) = tcg_temp_new();
TCGv cpu_tmp0 __attribute__((unused));
if (xop == 0x34) { /* FPU Operations */
if (gen_trap_ifnofpu(dc)) {
@ -4828,8 +4849,6 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
default:
goto illegal_insn;
}
} else if (xop < 0x36) {
goto illegal_insn; /* in decodetree */
} else if (xop == 0x36) {
#ifdef TARGET_SPARC64
/* VIS */
@ -5271,65 +5290,10 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
default:
goto illegal_insn;
}
#else
g_assert_not_reached(); /* in decodetree */
#endif
} else if (xop == 0x37) {
/* V8 CPop2, V9 impdep2 */
goto illegal_insn; /* in decodetree */
} else {
cpu_src1 = get_src1(dc, insn);
cpu_tmp0 = tcg_temp_new();
if (IS_IMM) { /* immediate */
simm = GET_FIELDs(insn, 19, 31);
tcg_gen_addi_tl(cpu_tmp0, cpu_src1, simm);
} else { /* register */
rs2 = GET_FIELD(insn, 27, 31);
if (rs2) {
cpu_src2 = gen_load_gpr(dc, rs2);
tcg_gen_add_tl(cpu_tmp0, cpu_src1, cpu_src2);
} else {
tcg_gen_mov_tl(cpu_tmp0, cpu_src1);
}
}
switch (xop) {
case 0x38: /* jmpl */
case 0x39: /* rett, V9 return */
case 0x3b: /* flush */
case 0x3c: /* save */
case 0x3d: /* restore */
g_assert_not_reached(); /* in decode tree */
#if !defined(CONFIG_USER_ONLY) && defined(TARGET_SPARC64)
case 0x3e: /* V9 done/retry */
{
switch (rd) {
case 0:
if (!supervisor(dc))
goto priv_insn;
dc->npc = DYNAMIC_PC;
dc->pc = DYNAMIC_PC;
translator_io_start(&dc->base);
gen_helper_done(tcg_env);
goto jmp_insn;
case 1:
if (!supervisor(dc))
goto priv_insn;
dc->npc = DYNAMIC_PC;
dc->pc = DYNAMIC_PC;
translator_io_start(&dc->base);
gen_helper_retry(tcg_env);
goto jmp_insn;
default:
goto illegal_insn;
}
}
break;
#endif
default:
goto illegal_insn;
}
goto illegal_insn; /* in decodetree */
}
break;
}
break;
case 3: /* load/store instructions */
@ -5726,7 +5690,7 @@ static void disas_sparc_legacy(DisasContext *dc, unsigned int insn)
illegal_insn:
gen_exception(dc, TT_ILL_INSN);
return;
#if !defined(CONFIG_USER_ONLY)
#if !defined(CONFIG_USER_ONLY) && !defined(TARGET_SPARC64)
priv_insn:
gen_exception(dc, TT_PRIV_INSN);
return;