void helper_done(void)
{
- env->pc = env->tsptr->tpc;
- env->npc = env->tsptr->tnpc + 4;
- PUT_CCR(env, env->tsptr->tstate >> 32);
- env->asi = (env->tsptr->tstate >> 24) & 0xff;
- change_pstate((env->tsptr->tstate >> 8) & 0xf3f);
- PUT_CWP64(env, env->tsptr->tstate & 0xff);
+ trap_state* tsptr = cpu_tsptr(env);
+
+ env->pc = tsptr->tpc;
+ env->npc = tsptr->tnpc + 4;
+ PUT_CCR(env, tsptr->tstate >> 32);
+ env->asi = (tsptr->tstate >> 24) & 0xff;
+ change_pstate((tsptr->tstate >> 8) & 0xf3f);
+ PUT_CWP64(env, tsptr->tstate & 0xff);
env->tl--;
- env->tsptr = &env->ts[env->tl & MAXTL_MASK];
}
void helper_retry(void)
{
- env->pc = env->tsptr->tpc;
- env->npc = env->tsptr->tnpc;
- PUT_CCR(env, env->tsptr->tstate >> 32);
- env->asi = (env->tsptr->tstate >> 24) & 0xff;
- change_pstate((env->tsptr->tstate >> 8) & 0xf3f);
- PUT_CWP64(env, env->tsptr->tstate & 0xff);
+ trap_state* tsptr = cpu_tsptr(env);
+
+ env->pc = tsptr->tpc;
+ env->npc = tsptr->tnpc;
+ PUT_CCR(env, tsptr->tstate >> 32);
+ env->asi = (tsptr->tstate >> 24) & 0xff;
+ change_pstate((tsptr->tstate >> 8) & 0xf3f);
+ PUT_CWP64(env, tsptr->tstate & 0xff);
env->tl--;
- env->tsptr = &env->ts[env->tl & MAXTL_MASK];
}
void helper_set_softint(uint64_t value)
};
#endif
+trap_state* cpu_tsptr(CPUState* env)
+{
+ return &env->ts[env->tl & MAXTL_MASK];
+}
+
void do_interrupt(CPUState *env)
{
int intno = env->exception_index;
+ trap_state* tsptr;
#ifdef DEBUG_PCALL
if (qemu_loglevel_mask(CPU_LOG_INT)) {
if (env->tl < env->maxtl)
env->tl++;
}
- env->tsptr = &env->ts[env->tl & MAXTL_MASK];
- env->tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) |
+ tsptr = cpu_tsptr(env);
+
+ tsptr->tstate = ((uint64_t)GET_CCR(env) << 32) |
((env->asi & 0xff) << 24) | ((env->pstate & 0xf3f) << 8) |
GET_CWP64(env);
- env->tsptr->tpc = env->pc;
- env->tsptr->tnpc = env->npc;
- env->tsptr->tt = intno;
+ tsptr->tpc = env->pc;
+ tsptr->tnpc = env->npc;
+ tsptr->tt = intno;
switch (intno) {
case TT_IVEC:
return r_rs2;
}
+#ifdef TARGET_SPARC64
+static inline void gen_load_trap_state_at_tl(TCGv_ptr r_tsptr, TCGv_ptr cpu_env)
+{
+ TCGv r_tl = tcg_temp_new();
+
+ /* load env->tl into r_tl */
+ {
+ TCGv_i32 r_tl_tmp = tcg_temp_new_i32();
+ tcg_gen_ld_i32(r_tl_tmp, cpu_env, offsetof(CPUSPARCState, tl));
+ tcg_gen_ext_i32_tl(r_tl, r_tl_tmp);
+ tcg_temp_free_i32(r_tl_tmp);
+ }
+
+ /* tl = [0 ... MAXTL_MASK] where MAXTL_MASK must be power of 2 */
+ tcg_gen_andi_tl(r_tl, r_tl, MAXTL_MASK);
+
+ /* calculate offset to current trap state from env->ts, reuse r_tl */
+ tcg_gen_muli_tl(r_tl, r_tl, sizeof (trap_state));
+ tcg_gen_addi_ptr(r_tsptr, cpu_env, offsetof(CPUState, ts));
+
+ /* tsptr = env->ts[env->tl & MAXTL_MASK] */
+ tcg_gen_add_ptr(r_tsptr, r_tsptr, r_tl);
+
+ tcg_temp_free(r_tl);
+}
+#endif
+
#define CHECK_IU_FEATURE(dc, FEATURE) \
if (!((dc)->def->features & CPU_FEATURE_ ## FEATURE)) \
goto illegal_insn;
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_load_trap_state_at_tl(r_tsptr, cpu_env);
tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
offsetof(trap_state, tpc));
tcg_temp_free_ptr(r_tsptr);
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_load_trap_state_at_tl(r_tsptr, cpu_env);
tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
offsetof(trap_state, tnpc));
tcg_temp_free_ptr(r_tsptr);
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_load_trap_state_at_tl(r_tsptr, cpu_env);
tcg_gen_ld_tl(cpu_tmp0, r_tsptr,
offsetof(trap_state, tstate));
tcg_temp_free_ptr(r_tsptr);
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_load_trap_state_at_tl(r_tsptr, cpu_env);
tcg_gen_ld_i32(cpu_tmp32, r_tsptr,
offsetof(trap_state, tt));
tcg_temp_free_ptr(r_tsptr);
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_load_trap_state_at_tl(r_tsptr, cpu_env);
tcg_gen_st_tl(cpu_tmp0, r_tsptr,
offsetof(trap_state, tpc));
tcg_temp_free_ptr(r_tsptr);
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_load_trap_state_at_tl(r_tsptr, cpu_env);
tcg_gen_st_tl(cpu_tmp0, r_tsptr,
offsetof(trap_state, tnpc));
tcg_temp_free_ptr(r_tsptr);
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_load_trap_state_at_tl(r_tsptr, cpu_env);
tcg_gen_st_tl(cpu_tmp0, r_tsptr,
offsetof(trap_state,
tstate));
TCGv_ptr r_tsptr;
r_tsptr = tcg_temp_new_ptr();
- tcg_gen_ld_ptr(r_tsptr, cpu_env,
- offsetof(CPUState, tsptr));
+ gen_load_trap_state_at_tl(r_tsptr, cpu_env);
tcg_gen_trunc_tl_i32(cpu_tmp32, cpu_tmp0);
tcg_gen_st_i32(cpu_tmp32, r_tsptr,
offsetof(trap_state, tt));