]> Git Repo - qemu.git/commitdiff
target/xtensa: extract test for window underflow exception
authorMax Filippov <[email protected]>
Fri, 31 Aug 2018 00:55:33 +0000 (17:55 -0700)
committerMax Filippov <[email protected]>
Mon, 1 Oct 2018 18:08:35 +0000 (11:08 -0700)
- 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 <[email protected]>
target/xtensa/helper.h
target/xtensa/op_helper.c
target/xtensa/translate.c

index c1b3bacb4cf256f23a38b11901f0da62c76c29a8..10153c2453605c09dc7079e8468a608e8b640654 100644 (file)
@@ -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)
index 68052851af329231ddfef8f85d24a8ba4504df54..e4b42ab3e56cfa82b04188f6d43905154c56c4c9 100644 (file)
@@ -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;
 }
 
index 83e107a2ac346fe843ee694846680f276384938a..187de7467f45035b392408a55b22307e096cc1b2 100644 (file)
@@ -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,
This page took 0.047751 seconds and 4 git commands to generate.