#endif
}
+static inline void gen_goto_tb(DisasContext *s, int tb_num,
+ target_ulong pc, target_ulong npc)
+{
+ TranslationBlock *tb;
+
+ tb = s->tb;
+ if ((pc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK) &&
+ (npc & TARGET_PAGE_MASK) == (tb->pc & TARGET_PAGE_MASK)) {
+ /* jump to same page: we can use a direct jump */
+ if (tb_num == 0)
+ gen_op_goto_tb0(TBPARAM(tb));
+ else
+ gen_op_goto_tb1(TBPARAM(tb));
+ gen_jmp_im(pc);
+ gen_movl_npc_im(npc);
+ gen_op_movl_T0_im((long)tb + tb_num);
+ gen_op_exit_tb();
+ } else {
+ /* jump to another page: currently not optimized */
+ gen_jmp_im(pc);
+ gen_movl_npc_im(npc);
+ gen_op_movl_T0_0();
+ gen_op_exit_tb();
+ }
+}
+
static inline void gen_branch2(DisasContext *dc, long tb, target_ulong pc1, target_ulong pc2)
{
int l1;
gen_op_jz_T2_label(l1);
- gen_op_goto_tb0(TBPARAM(tb));
- gen_jmp_im(pc1);
- gen_movl_npc_im(pc1 + 4);
- gen_op_movl_T0_im((long)tb + 0);
- gen_op_exit_tb();
+ gen_goto_tb(dc, 0, pc1, pc1 + 4);
gen_set_label(l1);
- gen_op_goto_tb1(TBPARAM(tb));
- gen_jmp_im(pc2);
- gen_movl_npc_im(pc2 + 4);
- gen_op_movl_T0_im((long)tb + 1);
- gen_op_exit_tb();
+ gen_goto_tb(dc, 1, pc2, pc2 + 4);
}
static inline void gen_branch_a(DisasContext *dc, long tb, target_ulong pc1, target_ulong pc2)
gen_op_jz_T2_label(l1);
- gen_op_goto_tb0(TBPARAM(tb));
- gen_jmp_im(pc2);
- gen_movl_npc_im(pc1);
- gen_op_movl_T0_im((long)tb + 0);
- gen_op_exit_tb();
+ gen_goto_tb(dc, 0, pc2, pc1);
gen_set_label(l1);
- gen_op_goto_tb1(TBPARAM(tb));
- gen_jmp_im(pc2 + 4);
- gen_movl_npc_im(pc2 + 8);
- gen_op_movl_T0_im((long)tb + 1);
- gen_op_exit_tb();
+ gen_goto_tb(dc, 1, pc2 + 4, pc2 + 8);
}
static inline void gen_branch(DisasContext *dc, long tb, target_ulong pc, target_ulong npc)
{
- gen_op_goto_tb0(TBPARAM(tb));
- gen_jmp_im(pc);
- gen_movl_npc_im(npc);
- gen_op_movl_T0_im((long)tb + 0);
- gen_op_exit_tb();
+ gen_goto_tb(dc, 0, pc, npc);
}
static inline void gen_generic_branch(DisasContext *dc, target_ulong npc1, target_ulong npc2)
int cc;
target = GET_FIELD_SP(insn, 0, 18);
- target <<= 2;
target = sign_extend(target, 18);
+ target <<= 2;
cc = GET_FIELD_SP(insn, 20, 21);
if (cc == 0)
do_branch(dc, target, insn, 0);
{
target = GET_FIELD_SP(insn, 0, 13) |
(GET_FIELD_SP(insn, 20, 21) >> 7);
- target <<= 2;
target = sign_extend(target, 16);
+ target <<= 2;
rs1 = GET_FIELD(insn, 13, 17);
gen_movl_reg_T0(rs1);
do_branch_reg(dc, target, insn);
{
int cc = GET_FIELD_SP(insn, 20, 21);
#if !defined(CONFIG_USER_ONLY)
+ save_state(dc);
gen_op_trap_ifnofpu();
#endif
target = GET_FIELD_SP(insn, 0, 18);
- target <<= 2;
target = sign_extend(target, 19);
+ target <<= 2;
do_fbranch(dc, target, insn, cc);
goto jmp_insn;
}
case 0x2: /* BN+x */
{
target = GET_FIELD(insn, 10, 31);
- target <<= 2;
target = sign_extend(target, 22);
+ target <<= 2;
do_branch(dc, target, insn, 0);
goto jmp_insn;
}
case 0x6: /* FBN+x */
{
#if !defined(CONFIG_USER_ONLY)
+ save_state(dc);
gen_op_trap_ifnofpu();
#endif
target = GET_FIELD(insn, 10, 31);
- target <<= 2;
target = sign_extend(target, 22);
+ target <<= 2;
do_fbranch(dc, target, insn, 0);
goto jmp_insn;
}
gen_movl_T0_reg(rd);
break;
case 0x5: /* V9 rdpc */
- gen_op_movl_T0_im(dc->pc);
+ if (dc->pc == (uint32_t)dc->pc) {
+ gen_op_movl_T0_im(dc->pc);
+ } else {
+ gen_op_movq_T0_im64(dc->pc >> 32, dc->pc);
+ }
gen_movl_T0_reg(rd);
break;
case 0x6: /* V9 rdfprs */
#endif
} else if (xop == 0x34) { /* FPU Operations */
#if !defined(CONFIG_USER_ONLY)
+ save_state(dc);
gen_op_trap_ifnofpu();
#endif
rs1 = GET_FIELD(insn, 13, 17);
int cond;
#endif
#if !defined(CONFIG_USER_ONLY)
+ save_state(dc);
gen_op_trap_ifnofpu();
#endif
rs1 = GET_FIELD(insn, 13, 17);
else
gen_op_addx_T1_T0();
break;
+#ifdef TARGET_SPARC64
+ case 0x9: /* V9 mulx */
+ gen_op_mulx_T1_T0();
+ break;
+#endif
case 0xa:
gen_op_umul_T1_T0();
if (xop & 0x10)
else
gen_op_subx_T1_T0();
break;
+#ifdef TARGET_SPARC64
+ case 0xd: /* V9 udivx */
+ gen_op_udivx_T1_T0();
+ break;
+#endif
case 0xe:
gen_op_udiv_T1_T0();
if (xop & 0x10)
gen_movl_T0_reg(rd);
} else {
switch (xop) {
-#ifdef TARGET_SPARC64
- case 0x9: /* V9 mulx */
- gen_op_mulx_T1_T0();
- gen_movl_T0_reg(rd);
- break;
- case 0xd: /* V9 udivx */
- gen_op_udivx_T1_T0();
- gen_movl_T0_reg(rd);
- break;
-#endif
case 0x20: /* taddcc */
case 0x21: /* tsubcc */
case 0x22: /* taddcctv */
#else
gen_op_xor_T1_T0();
gen_op_wrpsr();
+ save_state(dc);
+ gen_op_next_insn();
+ gen_op_movl_T0_0();
+ gen_op_exit_tb();
+ dc->is_br = 1;
#endif
}
break;
break;
case 6: // pstate
gen_op_wrpstate();
+ save_state(dc);
+ gen_op_next_insn();
+ gen_op_movl_T0_0();
+ gen_op_exit_tb();
+ dc->is_br = 1;
break;
case 7: // tl
gen_op_movl_env_T0(offsetof(CPUSPARCState, tl));
case 0x38: /* jmpl */
{
if (rd != 0) {
+#ifdef TARGET_SPARC64
+ if (dc->pc == (uint32_t)dc->pc) {
+ gen_op_movl_T1_im(dc->pc);
+ } else {
+ gen_op_movq_T1_im64(dc->pc >> 32, dc->pc);
+ }
+#else
gen_op_movl_T1_im(dc->pc);
+#endif
gen_movl_T1_reg(rd);
}
gen_mov_pc_npc(dc);
#endif
} else if (xop >= 0x20 && xop < 0x24) {
#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
+ save_state(dc);
gen_op_trap_ifnofpu();
#endif
switch (xop) {
gen_op_store_FT0_fpr(rd);
break;
case 0x21: /* load fsr */
+ gen_op_ldst(ldf);
gen_op_ldfsr();
- gen_op_store_FT0_fpr(rd);
break;
case 0x22: /* load quad fpreg */
goto nfpu_insn;
gen_op_ldst(stf);
break;
case 0x25: /* stfsr, V9 stxfsr */
- gen_op_load_fpr_FT0(rd);
- // XXX
gen_op_stfsr();
+ gen_op_ldst(stf);
break;
case 0x26: /* stdfq */
goto nfpu_insn;
{
CPUSPARCState *env;
- cpu_exec_init();
-
- if (!(env = malloc(sizeof(CPUSPARCState))))
- return (NULL);
- cpu_single_env = env;
+ env = qemu_mallocz(sizeof(CPUSPARCState));
+ if (!env)
+ return NULL;
+ cpu_exec_init(env);
cpu_reset(env);
return (env);
}
if ((i & 3) == 3)
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, "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);
+#else
cpu_fprintf(f, "psr: 0x%08x -> %c%c%c%c %c%c%c wim: 0x%08x\n", GET_PSR(env),
GET_FLAG(PSR_ZERO, 'Z'), GET_FLAG(PSR_OVF, 'V'),
GET_FLAG(PSR_NEG, 'N'), GET_FLAG(PSR_CARRY, 'C'),
env->psrs?'S':'-', env->psrps?'P':'-',
env->psret?'E':'-', env->wim);
+#endif
cpu_fprintf(f, "fsr: 0x%08x\n", GET_FSR32(env));
}