@@ -221,6 +221,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
@@ -54,6 +54,8 @@
#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; })
+#define gen_helper_done(E) qemu_build_not_reached()
+#define gen_helper_retry(E) qemu_build_not_reached()
#define gen_helper_udivx(D, E, A, B) qemu_build_not_reached()
#define gen_helper_sdivx(D, E, A, B) qemu_build_not_reached()
#endif
@@ -4549,6 +4551,36 @@ static bool do_restore(DisasContext *dc, int rd, TCGv src)
TRANS(RESTORE, ALL, do_add_special, a, do_restore)
+static bool trans_DONE(DisasContext *dc, arg_DONE *a)
+{
+ if (!avail_64(dc)) {
+ return false;
+ }
+ if (!supervisor(dc)) {
+ return raise_priv(dc);
+ }
+ dc->npc = DYNAMIC_PC;
+ dc->pc = DYNAMIC_PC;
+ translator_io_start(&dc->base);
+ gen_helper_done(tcg_env);
+ return true;
+}
+
+static bool trans_RETRY(DisasContext *dc, arg_RETRY *a)
+{
+ if (!avail_64(dc)) {
+ return false;
+ }
+ if (!supervisor(dc)) {
+ return raise_priv(dc);
+ }
+ dc->npc = DYNAMIC_PC;
+ dc->pc = DYNAMIC_PC;
+ translator_io_start(&dc->base);
+ gen_helper_retry(tcg_env);
+ return true;
+}
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
@@ -4560,7 +4592,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;
@@ -4575,9 +4608,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)) {
@@ -4897,8 +4929,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 */
@@ -5340,65 +5370,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 */
@@ -5795,7 +5770,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;
Signed-off-by: Richard Henderson <richard.henderson@linaro.org> --- target/sparc/insns.decode | 3 ++ target/sparc/translate.c | 99 +++++++++++++++------------------------ 2 files changed, 40 insertions(+), 62 deletions(-)