aboutsummaryrefslogtreecommitdiff
path: root/target/xtensa/win_helper.c
diff options
context:
space:
mode:
authorMax Filippov <jcmvbkbc@gmail.com>2019-01-30 14:56:29 -0800
committerMax Filippov <jcmvbkbc@gmail.com>2019-02-28 04:43:22 -0800
commit8df3fd359697d68095c5f1ba47e83e8e237a3055 (patch)
tree09dc8ab20422770cee30babaf7caa4c4b024db26 /target/xtensa/win_helper.c
parent45b71a795e5add347f0ba7aba526896132e9b986 (diff)
downloadqemu-8df3fd359697d68095c5f1ba47e83e8e237a3055.zip
qemu-8df3fd359697d68095c5f1ba47e83e8e237a3055.tar.gz
qemu-8df3fd359697d68095c5f1ba47e83e8e237a3055.tar.bz2
target/xtensa: move WINDOW_BASE SR update to postprocessing
Opcodes that modify WINDOW_BASE SR don't have dependency on opcodes that use windowed registers. If such opcodes are combined in a single instruction they may not be correctly ordered. Instead of adding said dependency use temporary register to store changed WINDOW_BASE value and do actual register window rotation as a postprocessing step. Not all opcodes that change WINDOW_BASE need this: retw, rfwo and rfwu are also jump opcodes, so they are guaranteed to be translated last and thus will not affect other opcodes in the same instruction. Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Diffstat (limited to 'target/xtensa/win_helper.c')
-rw-r--r--target/xtensa/win_helper.c14
1 files changed, 4 insertions, 10 deletions
diff --git a/target/xtensa/win_helper.c b/target/xtensa/win_helper.c
index 7d793d4..d7a4e27 100644
--- a/target/xtensa/win_helper.c
+++ b/target/xtensa/win_helper.c
@@ -96,9 +96,9 @@ void xtensa_rotate_window(CPUXtensaState *env, uint32_t delta)
xtensa_rotate_window_abs(env, env->sregs[WINDOW_BASE] + delta);
}
-void HELPER(wsr_windowbase)(CPUXtensaState *env, uint32_t v)
+void HELPER(sync_windowbase)(CPUXtensaState *env)
{
- xtensa_rotate_window_abs(env, v);
+ xtensa_rotate_window_abs(env, env->windowbase_next);
}
void HELPER(entry)(CPUXtensaState *env, uint32_t pc, uint32_t s, uint32_t imm)
@@ -106,9 +106,8 @@ void HELPER(entry)(CPUXtensaState *env, uint32_t pc, uint32_t s, uint32_t imm)
int callinc = (env->sregs[PS] & PS_CALLINC) >> PS_CALLINC_SHIFT;
env->regs[(callinc << 2) | (s & 3)] = env->regs[s] - imm;
- xtensa_rotate_window(env, callinc);
- env->sregs[WINDOW_START] |=
- windowstart_bit(env->sregs[WINDOW_BASE], env);
+ env->windowbase_next = env->sregs[WINDOW_BASE] + callinc;
+ env->sregs[WINDOW_START] |= windowstart_bit(env->windowbase_next, env);
}
void HELPER(window_check)(CPUXtensaState *env, uint32_t pc, uint32_t w)
@@ -196,11 +195,6 @@ uint32_t HELPER(retw)(CPUXtensaState *env, uint32_t pc)
return ret_pc;
}
-void HELPER(rotw)(CPUXtensaState *env, uint32_t imm4)
-{
- xtensa_rotate_window(env, imm4);
-}
-
void xtensa_restore_owb(CPUXtensaState *env)
{
xtensa_rotate_window_abs(env, (env->sregs[PS] & PS_OWB) >> PS_OWB_SHIFT);