summaryrefslogtreecommitdiff
path: root/target-xtensa/op_helper.c
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2014-10-30 18:07:47 +0300
committerMax Filippov <jcmvbkbc@gmail.com>2014-12-17 05:49:32 +0300
commit2db59a76c421cdd1039d10e32a9798952d3ff5ba (patch)
tree300de3cb63640349d027c6c26534dd3ff881ab0f /target-xtensa/op_helper.c
parent85d36377e4ff8b98119420099d445369bfd6b7bb (diff)
downloadqemu-2db59a76c421cdd1039d10e32a9798952d3ff5ba.tar.gz
target-xtensa: record available window in TB flags
Record last valid 4-register window pane number in TB flags so that a window overflow exception throw point is known at the translation time. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com> Reviewed-by: Richard Henderson <rth@twiddle.net>
Diffstat (limited to 'target-xtensa/op_helper.c')
-rw-r--r--target-xtensa/op_helper.c29
1 files changed, 11 insertions, 18 deletions
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index 872e5a823b..49e86343ed 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -251,34 +251,27 @@ void HELPER(entry)(CPUXtensaState *env, uint32_t pc, uint32_t s, uint32_t imm)
void HELPER(window_check)(CPUXtensaState *env, uint32_t pc, uint32_t w)
{
uint32_t windowbase = windowbase_bound(env->sregs[WINDOW_BASE], env);
- uint32_t windowstart = env->sregs[WINDOW_START];
- uint32_t m, n;
+ uint32_t windowstart = xtensa_replicate_windowstart(env) >>
+ (env->sregs[WINDOW_BASE] + 1);
+ uint32_t n = ctz32(windowstart) + 1;
- if ((env->sregs[PS] & (PS_WOE | PS_EXCM)) ^ PS_WOE) {
- return;
- }
+ assert(n <= w);
- for (n = 1; ; ++n) {
- if (n > w) {
- return;
- }
- if (windowstart & windowstart_bit(windowbase + n, env)) {
- break;
- }
- }
-
- m = windowbase_bound(windowbase + n, env);
rotate_window(env, n);
env->sregs[PS] = (env->sregs[PS] & ~PS_OWB) |
(windowbase << PS_OWB_SHIFT) | PS_EXCM;
env->sregs[EPC1] = env->pc = pc;
- if (windowstart & windowstart_bit(m + 1, env)) {
+ switch (ctz32(windowstart >> n)) {
+ case 0:
HELPER(exception)(env, EXC_WINDOW_OVERFLOW4);
- } else if (windowstart & windowstart_bit(m + 2, env)) {
+ break;
+ case 1:
HELPER(exception)(env, EXC_WINDOW_OVERFLOW8);
- } else {
+ break;
+ default:
HELPER(exception)(env, EXC_WINDOW_OVERFLOW12);
+ break;
}
}