summaryrefslogtreecommitdiff
path: root/target-sparc
diff options
context:
space:
mode:
Diffstat (limited to 'target-sparc')
-rw-r--r--target-sparc/op.c20
-rw-r--r--target-sparc/translate.c129
2 files changed, 111 insertions, 38 deletions
diff --git a/target-sparc/op.c b/target-sparc/op.c
index 96c8b2db72..2c21b5331d 100644
--- a/target-sparc/op.c
+++ b/target-sparc/op.c
@@ -1864,4 +1864,24 @@ void OPPROTO op_faligndata()
tmp |= (*((uint64_t *)&DT1)) >> (64 - (env->gsr & 7) * 8);
(*((uint64_t *)&DT0)) = tmp;
}
+
+void OPPROTO op_movl_FT0_0(void)
+{
+ (*((uint32_t *)&FT0)) = 0;
+}
+
+void OPPROTO op_movl_DT0_0(void)
+{
+ (*((uint64_t *)&DT0)) = 0;
+}
+
+void OPPROTO op_movl_FT0_1(void)
+{
+ (*((uint32_t *)&FT0)) = 0xffffffff;
+}
+
+void OPPROTO op_movl_DT0_1(void)
+{
+ (*((uint64_t *)&DT0)) = 0xffffffffffffffffULL;
+}
#endif
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index 19b10a200f..20dffe0d95 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -1931,7 +1931,13 @@ static void disas_sparc_insn(DisasContext * dc)
gen_op_movl_env_T0(offsetof(CPUSPARCState, asi));
break;
case 0x6: /* V9 wrfprs */
+ gen_op_xor_T1_T0();
gen_op_movl_env_T0(offsetof(CPUSPARCState, fprs));
+ save_state(dc);
+ gen_op_next_insn();
+ gen_op_movl_T0_0();
+ gen_op_exit_tb();
+ dc->is_br = 1;
break;
case 0xf: /* V9 sir, nop if user */
#if !defined(CONFIG_USER_ONLY)
@@ -2148,47 +2154,94 @@ static void disas_sparc_insn(DisasContext * dc)
gen_movl_T0_reg(rd);
break;
}
- case 0x36: /* UltraSparc shutdown, VIS */
- {
- int opf = GET_FIELD_SP(insn, 5, 13);
- rs1 = GET_FIELD(insn, 13, 17);
- rs2 = GET_FIELD(insn, 27, 31);
-
- switch (opf) {
- case 0x018: /* VIS I alignaddr */
- if (gen_trap_ifnofpu(dc))
- goto jmp_insn;
- gen_movl_reg_T0(rs1);
- gen_movl_reg_T1(rs2);
- gen_op_alignaddr();
- gen_movl_T0_reg(rd);
- break;
- case 0x01a: /* VIS I alignaddrl */
- if (gen_trap_ifnofpu(dc))
- goto jmp_insn;
- // XXX
- break;
- case 0x048: /* VIS I faligndata */
- if (gen_trap_ifnofpu(dc))
- goto jmp_insn;
- gen_op_load_fpr_DT0(rs1);
- gen_op_load_fpr_DT1(rs2);
- gen_op_faligndata();
- gen_op_store_DT0_fpr(rd);
- break;
- default:
- goto illegal_insn;
- }
- break;
- }
#endif
default:
goto illegal_insn;
}
}
- } else if (xop == 0x36 || xop == 0x37) { /* CPop1 & CPop2,
- V9 impdep1 &
- impdep2 */
+ } else if (xop == 0x36) { /* UltraSparc shutdown, VIS, V8 CPop1 */
+#ifdef TARGET_SPARC64
+ int opf = GET_FIELD_SP(insn, 5, 13);
+ rs1 = GET_FIELD(insn, 13, 17);
+ rs2 = GET_FIELD(insn, 27, 31);
+
+ switch (opf) {
+ case 0x018: /* VIS I alignaddr */
+ if (gen_trap_ifnofpu(dc))
+ goto jmp_insn;
+ gen_movl_reg_T0(rs1);
+ gen_movl_reg_T1(rs2);
+ gen_op_alignaddr();
+ gen_movl_T0_reg(rd);
+ break;
+ case 0x01a: /* VIS I alignaddrl */
+ if (gen_trap_ifnofpu(dc))
+ goto jmp_insn;
+ // XXX
+ break;
+ case 0x048: /* VIS I faligndata */
+ if (gen_trap_ifnofpu(dc))
+ goto jmp_insn;
+ gen_op_load_fpr_DT0(rs1);
+ gen_op_load_fpr_DT1(rs2);
+ gen_op_faligndata();
+ gen_op_store_DT0_fpr(rd);
+ break;
+ case 0x060: /* VIS I fzero */
+ if (gen_trap_ifnofpu(dc))
+ goto jmp_insn;
+ gen_op_movl_DT0_0();
+ gen_op_store_DT0_fpr(rd);
+ break;
+ case 0x061: /* VIS I fzeros */
+ if (gen_trap_ifnofpu(dc))
+ goto jmp_insn;
+ gen_op_movl_FT0_0();
+ gen_op_store_FT0_fpr(rd);
+ break;
+ case 0x074: /* VIS I fsrc1 */
+ if (gen_trap_ifnofpu(dc))
+ goto jmp_insn;
+ gen_op_load_fpr_DT0(rs1);
+ gen_op_store_DT0_fpr(rd);
+ break;
+ case 0x075: /* VIS I fsrc1s */
+ if (gen_trap_ifnofpu(dc))
+ goto jmp_insn;
+ gen_op_load_fpr_FT0(rs1);
+ gen_op_store_FT0_fpr(rd);
+ break;
+ case 0x078: /* VIS I fsrc2 */
+ if (gen_trap_ifnofpu(dc))
+ goto jmp_insn;
+ gen_op_load_fpr_DT0(rs2);
+ gen_op_store_DT0_fpr(rd);
+ break;
+ case 0x079: /* VIS I fsrc2s */
+ if (gen_trap_ifnofpu(dc))
+ goto jmp_insn;
+ gen_op_load_fpr_FT0(rs2);
+ gen_op_store_FT0_fpr(rd);
+ break;
+ case 0x07e: /* VIS I fone */
+ if (gen_trap_ifnofpu(dc))
+ goto jmp_insn;
+ gen_op_movl_DT0_1();
+ gen_op_store_DT0_fpr(rd);
+ break;
+ case 0x07f: /* VIS I fones */
+ if (gen_trap_ifnofpu(dc))
+ goto jmp_insn;
+ gen_op_movl_FT0_1();
+ gen_op_store_FT0_fpr(rd);
+ break;
+ default:
+ goto illegal_insn;
+ }
+#else
+ goto ncp_insn;
+#endif
+ } else if (xop == 0x37) { /* V8 CPop2, V9 impdep2 */
#ifdef TARGET_SPARC64
goto illegal_insn;
#else
@@ -2995,8 +3048,8 @@ void cpu_dump_state(CPUState *env, FILE *f,
cpu_fprintf(f, "\n");
}
#ifdef TARGET_SPARC64
- cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d\n",
- env->pstate, GET_CCR(env), env->asi, env->tl);
+ cpu_fprintf(f, "pstate: 0x%08x ccr: 0x%02x asi: 0x%02x tl: %d fprs: %d\n",
+ env->pstate, GET_CCR(env), env->asi, env->tl, env->fprs);
cpu_fprintf(f, "cansave: %d canrestore: %d otherwin: %d wstate %d cleanwin %d cwp %d\n",
env->cansave, env->canrestore, env->otherwin, env->wstate,
env->cleanwin, NWINDOWS - 1 - env->cwp);