diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2014-10-30 18:07:47 +0300 |
---|---|---|
committer | Max Filippov <jcmvbkbc@gmail.com> | 2014-12-17 05:49:32 +0300 |
commit | 2db59a76c421cdd1039d10e32a9798952d3ff5ba (patch) | |
tree | 300de3cb63640349d027c6c26534dd3ff881ab0f /target-xtensa/op_helper.c | |
parent | 85d36377e4ff8b98119420099d445369bfd6b7bb (diff) | |
download | qemu-2db59a76c421cdd1039d10e32a9798952d3ff5ba.zip |
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.c | 29 |
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; } } |