DEF_HELPER_2(wsr_windowbase, void, env, i32)
DEF_HELPER_4(entry, void, env, i32, i32, i32)
DEF_HELPER_2(test_ill_retw, void, env, i32)
+DEF_HELPER_2(test_underflow_retw, void, env, i32)
DEF_HELPER_2(retw, i32, env, i32)
DEF_HELPER_2(rotw, void, env, i32)
DEF_HELPER_3(window_check, noreturn, env, i32, i32)
}
}
-uint32_t HELPER(retw)(CPUXtensaState *env, uint32_t pc)
+void HELPER(test_underflow_retw)(CPUXtensaState *env, uint32_t pc)
{
int n = (env->regs[0] >> 30) & 0x3;
- uint32_t windowbase = windowbase_bound(env->sregs[WINDOW_BASE], env);
- uint32_t windowstart = env->sregs[WINDOW_START];
- uint32_t ret_pc = 0;
- ret_pc = (pc & 0xc0000000) | (env->regs[0] & 0x3fffffff);
+ if (!(env->sregs[WINDOW_START] &
+ windowstart_bit(env->sregs[WINDOW_BASE] - n, env))) {
+ uint32_t windowbase = windowbase_bound(env->sregs[WINDOW_BASE], env);
- xtensa_rotate_window(env, -n);
- if (windowstart & windowstart_bit(env->sregs[WINDOW_BASE], env)) {
- env->sregs[WINDOW_START] &= ~windowstart_bit(windowbase, env);
- } else {
+ xtensa_rotate_window(env, -n);
/* window underflow */
env->sregs[PS] = (env->sregs[PS] & ~PS_OWB) |
(windowbase << PS_OWB_SHIFT) | PS_EXCM;
HELPER(exception)(env, EXC_WINDOW_UNDERFLOW12);
}
}
+}
+
+uint32_t HELPER(retw)(CPUXtensaState *env, uint32_t pc)
+{
+ int n = (env->regs[0] >> 30) & 0x3;
+ uint32_t windowbase = windowbase_bound(env->sregs[WINDOW_BASE], env);
+ uint32_t ret_pc = (pc & 0xc0000000) | (env->regs[0] & 0x3fffffff);
+
+ xtensa_rotate_window(env, -n);
+ env->sregs[WINDOW_START] &= ~windowstart_bit(windowbase, env);
return ret_pc;
}
return;
}
+ if (op_flags & XTENSA_OP_UNDERFLOW) {
+ TCGv_i32 tmp = tcg_const_i32(dc->pc);
+
+ gen_helper_test_underflow_retw(cpu_env, tmp);
+ tcg_temp_free(tmp);
+ }
+
for (slot = 0; slot < slots; ++slot) {
XtensaOpcodeOps *ops = slot_prop[slot].ops;
.name = "retw",
.translate = translate_retw,
.test_ill = test_ill_retw,
+ .op_flags = XTENSA_OP_UNDERFLOW,
}, {
.name = "retw.n",
.translate = translate_retw,
.test_ill = test_ill_retw,
+ .op_flags = XTENSA_OP_UNDERFLOW,
}, {
.name = "rfdd",
.op_flags = XTENSA_OP_ILL,