aboutsummaryrefslogtreecommitdiff
path: root/target/xtensa/op_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'target/xtensa/op_helper.c')
-rw-r--r--target/xtensa/op_helper.c24
1 files changed, 15 insertions, 9 deletions
diff --git a/target/xtensa/op_helper.c b/target/xtensa/op_helper.c
index 68052851af..e4b42ab3e5 100644
--- a/target/xtensa/op_helper.c
+++ b/target/xtensa/op_helper.c
@@ -310,19 +310,15 @@ void HELPER(test_ill_retw)(CPUXtensaState *env, uint32_t pc)
}
}
-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;
@@ -336,6 +332,16 @@ uint32_t HELPER(retw)(CPUXtensaState *env, uint32_t pc)
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;
}