diff mbox

[PULL,1/9] target-mips: move the test for enabled interrupts to a separate function

Message ID 1446217252-3637-2-git-send-email-leon.alrae@imgtec.com
State New
Headers show

Commit Message

Leon Alrae Oct. 30, 2015, 3 p.m. UTC
Signed-off-by: Leon Alrae <leon.alrae@imgtec.com>
---
 target-mips/cpu.c    |  4 +++-
 target-mips/cpu.h    | 29 +++++++++++++++--------------
 target-mips/helper.c |  3 ++-
 3 files changed, 20 insertions(+), 16 deletions(-)
diff mbox

Patch

diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index 37880d2..bbfee45 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -58,7 +58,9 @@  static bool mips_cpu_has_work(CPUState *cs)
        check for interrupts that can be taken. */
     if ((cs->interrupt_request & CPU_INTERRUPT_HARD) &&
         cpu_mips_hw_interrupts_pending(env)) {
-        has_work = true;
+        if (cpu_mips_hw_interrupts_enabled(env)) {
+            has_work = true;
+        }
     }
 
     /* MIPS-MT has the ability to halt the CPU.  */
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index f32a0fd..3799d26 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -637,23 +637,24 @@  static inline int cpu_mmu_index (CPUMIPSState *env, bool ifetch)
     return env->hflags & MIPS_HFLAG_KSU;
 }
 
-static inline int cpu_mips_hw_interrupts_pending(CPUMIPSState *env)
+static inline bool cpu_mips_hw_interrupts_enabled(CPUMIPSState *env)
 {
-    int32_t pending;
-    int32_t status;
-    int r;
-
-    if (!(env->CP0_Status & (1 << CP0St_IE)) ||
-        (env->CP0_Status & (1 << CP0St_EXL)) ||
-        (env->CP0_Status & (1 << CP0St_ERL)) ||
+    return (env->CP0_Status & (1 << CP0St_IE)) &&
+        !(env->CP0_Status & (1 << CP0St_EXL)) &&
+        !(env->CP0_Status & (1 << CP0St_ERL)) &&
+        !(env->hflags & MIPS_HFLAG_DM) &&
         /* Note that the TCStatus IXMT field is initialized to zero,
            and only MT capable cores can set it to one. So we don't
            need to check for MT capabilities here.  */
-        (env->active_tc.CP0_TCStatus & (1 << CP0TCSt_IXMT)) ||
-        (env->hflags & MIPS_HFLAG_DM)) {
-        /* Interrupts are disabled */
-        return 0;
-    }
+        !(env->active_tc.CP0_TCStatus & (1 << CP0TCSt_IXMT));
+}
+
+/* Check if there is pending and not masked out interrupt */
+static inline bool cpu_mips_hw_interrupts_pending(CPUMIPSState *env)
+{
+    int32_t pending;
+    int32_t status;
+    bool r;
 
     pending = env->CP0_Cause & CP0Ca_IP_mask;
     status = env->CP0_Status & CP0Ca_IP_mask;
@@ -667,7 +668,7 @@  static inline int cpu_mips_hw_interrupts_pending(CPUMIPSState *env)
         /* A MIPS configured with compatibility or VInt (Vectored Interrupts)
            treats the pending lines as individual interrupt lines, the status
            lines are individual masks.  */
-        r = pending & status;
+        r = (pending & status) != 0;
     }
     return r;
 }
diff --git a/target-mips/helper.c b/target-mips/helper.c
index 01c4461..2d86323 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -759,7 +759,8 @@  bool mips_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
         MIPSCPU *cpu = MIPS_CPU(cs);
         CPUMIPSState *env = &cpu->env;
 
-        if (cpu_mips_hw_interrupts_pending(env)) {
+        if (cpu_mips_hw_interrupts_enabled(env) &&
+            cpu_mips_hw_interrupts_pending(env)) {
             /* Raise it */
             cs->exception_index = EXCP_EXT_INTERRUPT;
             env->error_code = 0;