target/xtensa: extract test for window underflow exception
- mark retw and retw.n instructions; - extract window inderflow test from retw helper; - put underflow exception check generation right after the overflow check; Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
This commit is contained in:
parent
6416d16f75
commit
f473019a97
@ -6,6 +6,7 @@ DEF_HELPER_3(debug_exception, noreturn, env, i32, i32)
|
||||
DEF_HELPER_2(wsr_windowbase, void, env, i32)
|
||||
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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -1071,6 +1071,13 @@ static void disas_xtensa_insn(CPUXtensaState *env, DisasContext *dc)
|
||||
return;
|
||||
}
|
||||
|
||||
if (op_flags & XTENSA_OP_UNDERFLOW) {
|
||||
TCGv_i32 tmp = tcg_const_i32(dc->pc);
|
||||
|
||||
gen_helper_test_underflow_retw(cpu_env, tmp);
|
||||
tcg_temp_free(tmp);
|
||||
}
|
||||
|
||||
for (slot = 0; slot < slots; ++slot) {
|
||||
XtensaOpcodeOps *ops = slot_prop[slot].ops;
|
||||
|
||||
@ -3485,10 +3492,12 @@ static const XtensaOpcodeOps core_ops[] = {
|
||||
.name = "retw",
|
||||
.translate = translate_retw,
|
||||
.test_ill = test_ill_retw,
|
||||
.op_flags = XTENSA_OP_UNDERFLOW,
|
||||
}, {
|
||||
.name = "retw.n",
|
||||
.translate = translate_retw,
|
||||
.test_ill = test_ill_retw,
|
||||
.op_flags = XTENSA_OP_UNDERFLOW,
|
||||
}, {
|
||||
.name = "rfdd",
|
||||
.op_flags = XTENSA_OP_ILL,
|
||||
|
Loading…
Reference in New Issue
Block a user