xref: /illumos-kvm-cmd/target-mips/exec.h (revision 68396ea9)
1 #if !defined(__QEMU_MIPS_EXEC_H__)
2 #define __QEMU_MIPS_EXEC_H__
3 
4 //#define DEBUG_OP
5 
6 #include "config.h"
7 #include "mips-defs.h"
8 #include "dyngen-exec.h"
9 #include "cpu-defs.h"
10 
11 register struct CPUMIPSState *env asm(AREG0);
12 
13 #include "cpu.h"
14 #include "exec-all.h"
15 
16 #if !defined(CONFIG_USER_ONLY)
17 #include "softmmu_exec.h"
18 #endif /* !defined(CONFIG_USER_ONLY) */
19 
cpu_has_work(CPUState * env)20 static inline int cpu_has_work(CPUState *env)
21 {
22     int has_work = 0;
23 
24     /* It is implementation dependent if non-enabled interrupts
25        wake-up the CPU, however most of the implementations only
26        check for interrupts that can be taken. */
27     if ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
28         cpu_mips_hw_interrupts_pending(env)) {
29         has_work = 1;
30     }
31 
32     if (env->interrupt_request & CPU_INTERRUPT_TIMER) {
33         has_work = 1;
34     }
35 
36     return has_work;
37 }
38 
cpu_halted(CPUState * env)39 static inline int cpu_halted(CPUState *env)
40 {
41     if (!env->halted)
42         return 0;
43     if (cpu_has_work(env)) {
44         env->halted = 0;
45         return 0;
46     }
47     return EXCP_HALTED;
48 }
49 
compute_hflags(CPUState * env)50 static inline void compute_hflags(CPUState *env)
51 {
52     env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
53                      MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU |
54                      MIPS_HFLAG_UX);
55     if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
56         !(env->CP0_Status & (1 << CP0St_ERL)) &&
57         !(env->hflags & MIPS_HFLAG_DM)) {
58         env->hflags |= (env->CP0_Status >> CP0St_KSU) & MIPS_HFLAG_KSU;
59     }
60 #if defined(TARGET_MIPS64)
61     if (((env->hflags & MIPS_HFLAG_KSU) != MIPS_HFLAG_UM) ||
62         (env->CP0_Status & (1 << CP0St_PX)) ||
63         (env->CP0_Status & (1 << CP0St_UX)))
64         env->hflags |= MIPS_HFLAG_64;
65     if (env->CP0_Status & (1 << CP0St_UX))
66         env->hflags |= MIPS_HFLAG_UX;
67 #endif
68     if ((env->CP0_Status & (1 << CP0St_CU0)) ||
69         !(env->hflags & MIPS_HFLAG_KSU))
70         env->hflags |= MIPS_HFLAG_CP0;
71     if (env->CP0_Status & (1 << CP0St_CU1))
72         env->hflags |= MIPS_HFLAG_FPU;
73     if (env->CP0_Status & (1 << CP0St_FR))
74         env->hflags |= MIPS_HFLAG_F64;
75     if (env->insn_flags & ISA_MIPS32R2) {
76         if (env->active_fpu.fcr0 & (1 << FCR0_F64))
77             env->hflags |= MIPS_HFLAG_COP1X;
78     } else if (env->insn_flags & ISA_MIPS32) {
79         if (env->hflags & MIPS_HFLAG_64)
80             env->hflags |= MIPS_HFLAG_COP1X;
81     } else if (env->insn_flags & ISA_MIPS4) {
82         /* All supported MIPS IV CPUs use the XX (CU3) to enable
83            and disable the MIPS IV extensions to the MIPS III ISA.
84            Some other MIPS IV CPUs ignore the bit, so the check here
85            would be too restrictive for them.  */
86         if (env->CP0_Status & (1 << CP0St_CU3))
87             env->hflags |= MIPS_HFLAG_COP1X;
88     }
89 }
90 
cpu_pc_from_tb(CPUState * env,TranslationBlock * tb)91 static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
92 {
93     env->active_tc.PC = tb->pc;
94     env->hflags &= ~MIPS_HFLAG_BMASK;
95     env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
96 }
97 
98 #endif /* !defined(__QEMU_MIPS_EXEC_H__) */
99