DEF_HELPER_4(exception_cause_vaddr, noreturn, env, i32, i32, i32)
DEF_HELPER_3(debug_exception, noreturn, env, i32, i32)
-DEF_HELPER_2(wsr_windowbase, void, env, i32)
+DEF_HELPER_1(sync_windowbase, void, env)
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)
DEF_HELPER_1(restore_owb, void, env)
DEF_HELPER_2(movsp, void, env, i32)
static TCGv_i32 cpu_FR[16];
static TCGv_i32 cpu_SR[256];
static TCGv_i32 cpu_UR[256];
+static TCGv_i32 cpu_windowbase_next;
#include "exec/gen-icount.h"
uregnames[i].name);
}
}
+
+ cpu_windowbase_next =
+ tcg_global_mem_new_i32(cpu_env,
+ offsetof(CPUXtensaState, windowbase_next),
+ "windowbase_next");
}
static inline bool option_enabled(DisasContext *dc, int opt)
#ifndef CONFIG_USER_ONLY
static void gen_wsr_windowbase(DisasContext *dc, uint32_t sr, TCGv_i32 v)
{
- gen_helper_wsr_windowbase(cpu_env, v);
+ tcg_gen_mov_i32(cpu_windowbase_next, v);
}
static void gen_wsr_windowstart(DisasContext *dc, uint32_t sr, TCGv_i32 v)
if (op_flags & XTENSA_OP_CHECK_INTERRUPTS) {
gen_check_interrupts(dc);
}
+ if (op_flags & XTENSA_OP_SYNC_REGISTER_WINDOW) {
+ gen_helper_sync_windowbase(cpu_env);
+ }
if (op_flags & XTENSA_OP_EXIT_TB_M1) {
slot = -1;
}
static void translate_rotw(DisasContext *dc, const uint32_t arg[],
const uint32_t par[])
{
- TCGv_i32 tmp = tcg_const_i32(arg[0]);
- gen_helper_rotw(cpu_env, tmp);
- tcg_temp_free(tmp);
+ tcg_gen_addi_i32(cpu_windowbase_next, cpu_SR[WINDOW_BASE], arg[0]);
}
static void translate_rsil(DisasContext *dc, const uint32_t arg[],
.translate = translate_entry,
.test_ill = test_ill_entry,
.test_overflow = test_overflow_entry,
- .op_flags = XTENSA_OP_EXIT_TB_M1,
+ .op_flags = XTENSA_OP_EXIT_TB_M1 |
+ XTENSA_OP_SYNC_REGISTER_WINDOW,
}, {
.name = "esync",
.translate = translate_nop,
}, {
.name = "rotw",
.translate = translate_rotw,
- .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
+ .op_flags = XTENSA_OP_PRIVILEGED |
+ XTENSA_OP_EXIT_TB_M1 |
+ XTENSA_OP_SYNC_REGISTER_WINDOW,
}, {
.name = "rsil",
.translate = translate_rsil,
.translate = translate_wsr,
.test_ill = test_ill_wsr,
.par = (const uint32_t[]){WINDOW_BASE},
- .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
+ .op_flags = XTENSA_OP_PRIVILEGED |
+ XTENSA_OP_EXIT_TB_M1 |
+ XTENSA_OP_SYNC_REGISTER_WINDOW,
}, {
.name = "wsr.windowstart",
.translate = translate_wsr,
.translate = translate_xsr,
.test_ill = test_ill_xsr,
.par = (const uint32_t[]){WINDOW_BASE},
- .op_flags = XTENSA_OP_PRIVILEGED | XTENSA_OP_EXIT_TB_M1,
+ .op_flags = XTENSA_OP_PRIVILEGED |
+ XTENSA_OP_EXIT_TB_M1 |
+ XTENSA_OP_SYNC_REGISTER_WINDOW,
}, {
.name = "xsr.windowstart",
.translate = translate_xsr,
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)
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)
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);