1#if !defined (__MIPS_CPU_H__)
2#define __MIPS_CPU_H__
3
4
5
6#define TARGET_HAS_ICE 1
7
8#define ELF_MACHINE EM_MIPS
9
10#define CPUArchState struct CPUMIPSState
11
12#include "config.h"
13#include "qemu-common.h"
14#include "mips-defs.h"
15#include "exec/cpu-defs.h"
16#include "fpu/softfloat.h"
17
18struct CPUMIPSState;
19
20typedef struct r4k_tlb_t r4k_tlb_t;
21struct r4k_tlb_t {
22 target_ulong VPN;
23 uint32_t PageMask;
24 uint_fast8_t ASID;
25 uint_fast16_t G:1;
26 uint_fast16_t C0:3;
27 uint_fast16_t C1:3;
28 uint_fast16_t V0:1;
29 uint_fast16_t V1:1;
30 uint_fast16_t D0:1;
31 uint_fast16_t D1:1;
32 target_ulong PFN[2];
33};
34
35#if !defined(CONFIG_USER_ONLY)
36typedef struct CPUMIPSTLBContext CPUMIPSTLBContext;
37struct CPUMIPSTLBContext {
38 uint32_t nb_tlb;
39 uint32_t tlb_in_use;
40 int (*map_address) (struct CPUMIPSState *env, hwaddr *physical, int *prot, target_ulong address, int rw, int access_type);
41 void (*helper_tlbwi)(struct CPUMIPSState *env);
42 void (*helper_tlbwr)(struct CPUMIPSState *env);
43 void (*helper_tlbp)(struct CPUMIPSState *env);
44 void (*helper_tlbr)(struct CPUMIPSState *env);
45 union {
46 struct {
47 r4k_tlb_t tlb[MIPS_TLB_MAX];
48 } r4k;
49 } mmu;
50};
51#endif
52
53typedef union fpr_t fpr_t;
54union fpr_t {
55 float64 fd;
56 float32 fs[2];
57 uint64_t d;
58 uint32_t w[2];
59};
60
61
62
63#if defined(HOST_WORDS_BIGENDIAN)
64# define FP_ENDIAN_IDX 1
65#else
66# define FP_ENDIAN_IDX 0
67#endif
68
69typedef struct CPUMIPSFPUContext CPUMIPSFPUContext;
70struct CPUMIPSFPUContext {
71
72 fpr_t fpr[32];
73 float_status fp_status;
74
75 uint32_t fcr0;
76#define FCR0_F64 22
77#define FCR0_L 21
78#define FCR0_W 20
79#define FCR0_3D 19
80#define FCR0_PS 18
81#define FCR0_D 17
82#define FCR0_S 16
83#define FCR0_PRID 8
84#define FCR0_REV 0
85
86 uint32_t fcr31;
87#define SET_FP_COND(num,env) do { ((env).fcr31) |= ((num) ? (1 << ((num) + 24)) : (1 << 23)); } while(0)
88#define CLEAR_FP_COND(num,env) do { ((env).fcr31) &= ~((num) ? (1 << ((num) + 24)) : (1 << 23)); } while(0)
89#define GET_FP_COND(env) ((((env).fcr31 >> 24) & 0xfe) | (((env).fcr31 >> 23) & 0x1))
90#define GET_FP_CAUSE(reg) (((reg) >> 12) & 0x3f)
91#define GET_FP_ENABLE(reg) (((reg) >> 7) & 0x1f)
92#define GET_FP_FLAGS(reg) (((reg) >> 2) & 0x1f)
93#define SET_FP_CAUSE(reg,v) do { (reg) = ((reg) & ~(0x3f << 12)) | ((v & 0x3f) << 12); } while(0)
94#define SET_FP_ENABLE(reg,v) do { (reg) = ((reg) & ~(0x1f << 7)) | ((v & 0x1f) << 7); } while(0)
95#define SET_FP_FLAGS(reg,v) do { (reg) = ((reg) & ~(0x1f << 2)) | ((v & 0x1f) << 2); } while(0)
96#define UPDATE_FP_FLAGS(reg,v) do { (reg) |= ((v & 0x1f) << 2); } while(0)
97#define FP_INEXACT 1
98#define FP_UNDERFLOW 2
99#define FP_OVERFLOW 4
100#define FP_DIV0 8
101#define FP_INVALID 16
102#define FP_UNIMPLEMENTED 32
103};
104
105#define NB_MMU_MODES 3
106
107typedef struct CPUMIPSMVPContext CPUMIPSMVPContext;
108struct CPUMIPSMVPContext {
109 int32_t CP0_MVPControl;
110#define CP0MVPCo_CPA 3
111#define CP0MVPCo_STLB 2
112#define CP0MVPCo_VPC 1
113#define CP0MVPCo_EVP 0
114 int32_t CP0_MVPConf0;
115#define CP0MVPC0_M 31
116#define CP0MVPC0_TLBS 29
117#define CP0MVPC0_GS 28
118#define CP0MVPC0_PCP 27
119#define CP0MVPC0_PTLBE 16
120#define CP0MVPC0_TCA 15
121#define CP0MVPC0_PVPE 10
122#define CP0MVPC0_PTC 0
123 int32_t CP0_MVPConf1;
124#define CP0MVPC1_CIM 31
125#define CP0MVPC1_CIF 30
126#define CP0MVPC1_PCX 20
127#define CP0MVPC1_PCP2 10
128#define CP0MVPC1_PCP1 0
129};
130
131typedef struct mips_def_t mips_def_t;
132
133#define MIPS_SHADOW_SET_MAX 16
134#define MIPS_TC_MAX 5
135#define MIPS_FPU_MAX 1
136#define MIPS_DSP_ACC 4
137
138typedef struct TCState TCState;
139struct TCState {
140 target_ulong gpr[32];
141 target_ulong PC;
142 target_ulong HI[MIPS_DSP_ACC];
143 target_ulong LO[MIPS_DSP_ACC];
144 target_ulong ACX[MIPS_DSP_ACC];
145 target_ulong DSPControl;
146 int32_t CP0_TCStatus;
147#define CP0TCSt_TCU3 31
148#define CP0TCSt_TCU2 30
149#define CP0TCSt_TCU1 29
150#define CP0TCSt_TCU0 28
151#define CP0TCSt_TMX 27
152#define CP0TCSt_RNST 23
153#define CP0TCSt_TDS 21
154#define CP0TCSt_DT 20
155#define CP0TCSt_DA 15
156#define CP0TCSt_A 13
157#define CP0TCSt_TKSU 11
158#define CP0TCSt_IXMT 10
159#define CP0TCSt_TASID 0
160 int32_t CP0_TCBind;
161#define CP0TCBd_CurTC 21
162#define CP0TCBd_TBE 17
163#define CP0TCBd_CurVPE 0
164 target_ulong CP0_TCHalt;
165 target_ulong CP0_TCContext;
166 target_ulong CP0_TCSchedule;
167 target_ulong CP0_TCScheFBack;
168 int32_t CP0_Debug_tcstatus;
169};
170
171typedef struct CPUMIPSState CPUMIPSState;
172struct CPUMIPSState {
173 TCState active_tc;
174 CPUMIPSFPUContext active_fpu;
175
176 uint32_t current_tc;
177 uint32_t current_fpu;
178
179 uint32_t SEGBITS;
180 uint32_t PABITS;
181 target_ulong SEGMask;
182 target_ulong PAMask;
183
184 int32_t CP0_Index;
185
186 int32_t CP0_Random;
187 int32_t CP0_VPEControl;
188#define CP0VPECo_YSI 21
189#define CP0VPECo_GSI 20
190#define CP0VPECo_EXCPT 16
191#define CP0VPECo_TE 15
192#define CP0VPECo_TargTC 0
193 int32_t CP0_VPEConf0;
194#define CP0VPEC0_M 31
195#define CP0VPEC0_XTC 21
196#define CP0VPEC0_TCS 19
197#define CP0VPEC0_SCS 18
198#define CP0VPEC0_DSC 17
199#define CP0VPEC0_ICS 16
200#define CP0VPEC0_MVP 1
201#define CP0VPEC0_VPA 0
202 int32_t CP0_VPEConf1;
203#define CP0VPEC1_NCX 20
204#define CP0VPEC1_NCP2 10
205#define CP0VPEC1_NCP1 0
206 target_ulong CP0_YQMask;
207 target_ulong CP0_VPESchedule;
208 target_ulong CP0_VPEScheFBack;
209 int32_t CP0_VPEOpt;
210#define CP0VPEOpt_IWX7 15
211#define CP0VPEOpt_IWX6 14
212#define CP0VPEOpt_IWX5 13
213#define CP0VPEOpt_IWX4 12
214#define CP0VPEOpt_IWX3 11
215#define CP0VPEOpt_IWX2 10
216#define CP0VPEOpt_IWX1 9
217#define CP0VPEOpt_IWX0 8
218#define CP0VPEOpt_DWX7 7
219#define CP0VPEOpt_DWX6 6
220#define CP0VPEOpt_DWX5 5
221#define CP0VPEOpt_DWX4 4
222#define CP0VPEOpt_DWX3 3
223#define CP0VPEOpt_DWX2 2
224#define CP0VPEOpt_DWX1 1
225#define CP0VPEOpt_DWX0 0
226 target_ulong CP0_EntryLo0;
227 target_ulong CP0_EntryLo1;
228 target_ulong CP0_Context;
229 int32_t CP0_PageMask;
230 int32_t CP0_PageGrain;
231 int32_t CP0_Wired;
232 int32_t CP0_SRSConf0_rw_bitmask;
233 int32_t CP0_SRSConf0;
234#define CP0SRSC0_M 31
235#define CP0SRSC0_SRS3 20
236#define CP0SRSC0_SRS2 10
237#define CP0SRSC0_SRS1 0
238 int32_t CP0_SRSConf1_rw_bitmask;
239 int32_t CP0_SRSConf1;
240#define CP0SRSC1_M 31
241#define CP0SRSC1_SRS6 20
242#define CP0SRSC1_SRS5 10
243#define CP0SRSC1_SRS4 0
244 int32_t CP0_SRSConf2_rw_bitmask;
245 int32_t CP0_SRSConf2;
246#define CP0SRSC2_M 31
247#define CP0SRSC2_SRS9 20
248#define CP0SRSC2_SRS8 10
249#define CP0SRSC2_SRS7 0
250 int32_t CP0_SRSConf3_rw_bitmask;
251 int32_t CP0_SRSConf3;
252#define CP0SRSC3_M 31
253#define CP0SRSC3_SRS12 20
254#define CP0SRSC3_SRS11 10
255#define CP0SRSC3_SRS10 0
256 int32_t CP0_SRSConf4_rw_bitmask;
257 int32_t CP0_SRSConf4;
258#define CP0SRSC4_SRS15 20
259#define CP0SRSC4_SRS14 10
260#define CP0SRSC4_SRS13 0
261 int32_t CP0_HWREna;
262 target_ulong CP0_BadVAddr;
263 int32_t CP0_Count;
264 target_ulong CP0_EntryHi;
265 int32_t CP0_Compare;
266 int32_t CP0_Status;
267#define CP0St_CU3 31
268#define CP0St_CU2 30
269#define CP0St_CU1 29
270#define CP0St_CU0 28
271#define CP0St_RP 27
272#define CP0St_FR 26
273#define CP0St_RE 25
274#define CP0St_MX 24
275#define CP0St_PX 23
276#define CP0St_BEV 22
277#define CP0St_TS 21
278#define CP0St_SR 20
279#define CP0St_NMI 19
280#define CP0St_IM 8
281#define CP0St_KX 7
282#define CP0St_SX 6
283#define CP0St_UX 5
284#define CP0St_KSU 3
285#define CP0St_ERL 2
286#define CP0St_EXL 1
287#define CP0St_IE 0
288 int32_t CP0_IntCtl;
289#define CP0IntCtl_IPTI 29
290#define CP0IntCtl_IPPC1 26
291#define CP0IntCtl_VS 5
292 int32_t CP0_SRSCtl;
293#define CP0SRSCtl_HSS 26
294#define CP0SRSCtl_EICSS 18
295#define CP0SRSCtl_ESS 12
296#define CP0SRSCtl_PSS 6
297#define CP0SRSCtl_CSS 0
298 int32_t CP0_SRSMap;
299#define CP0SRSMap_SSV7 28
300#define CP0SRSMap_SSV6 24
301#define CP0SRSMap_SSV5 20
302#define CP0SRSMap_SSV4 16
303#define CP0SRSMap_SSV3 12
304#define CP0SRSMap_SSV2 8
305#define CP0SRSMap_SSV1 4
306#define CP0SRSMap_SSV0 0
307 int32_t CP0_Cause;
308#define CP0Ca_BD 31
309#define CP0Ca_TI 30
310#define CP0Ca_CE 28
311#define CP0Ca_DC 27
312#define CP0Ca_PCI 26
313#define CP0Ca_IV 23
314#define CP0Ca_WP 22
315#define CP0Ca_IP 8
316#define CP0Ca_IP_mask 0x0000FF00
317#define CP0Ca_EC 2
318 target_ulong CP0_EPC;
319 int32_t CP0_PRid;
320 int32_t CP0_EBase;
321 int32_t CP0_Config0;
322#define CP0C0_M 31
323#define CP0C0_K23 28
324#define CP0C0_KU 25
325#define CP0C0_MDU 20
326#define CP0C0_MM 17
327#define CP0C0_BM 16
328#define CP0C0_BE 15
329#define CP0C0_AT 13
330#define CP0C0_AR 10
331#define CP0C0_MT 7
332#define CP0C0_VI 3
333#define CP0C0_K0 0
334 int32_t CP0_Config1;
335#define CP0C1_M 31
336#define CP0C1_MMU 25
337#define CP0C1_IS 22
338#define CP0C1_IL 19
339#define CP0C1_IA 16
340#define CP0C1_DS 13
341#define CP0C1_DL 10
342#define CP0C1_DA 7
343#define CP0C1_C2 6
344#define CP0C1_MD 5
345#define CP0C1_PC 4
346#define CP0C1_WR 3
347#define CP0C1_CA 2
348#define CP0C1_EP 1
349#define CP0C1_FP 0
350 int32_t CP0_Config2;
351#define CP0C2_M 31
352#define CP0C2_TU 28
353#define CP0C2_TS 24
354#define CP0C2_TL 20
355#define CP0C2_TA 16
356#define CP0C2_SU 12
357#define CP0C2_SS 8
358#define CP0C2_SL 4
359#define CP0C2_SA 0
360 int32_t CP0_Config3;
361#define CP0C3_M 31
362#define CP0C3_ISA_ON_EXC 16
363#define CP0C3_DSPP 10
364#define CP0C3_LPA 7
365#define CP0C3_VEIC 6
366#define CP0C3_VInt 5
367#define CP0C3_SP 4
368#define CP0C3_MT 2
369#define CP0C3_SM 1
370#define CP0C3_TL 0
371 int32_t CP0_Config6;
372 int32_t CP0_Config7;
373
374 target_ulong lladdr;
375 target_ulong llval;
376 target_ulong llnewval;
377 target_ulong llreg;
378 target_ulong CP0_LLAddr_rw_bitmask;
379 int CP0_LLAddr_shift;
380 target_ulong CP0_WatchLo[8];
381 int32_t CP0_WatchHi[8];
382 target_ulong CP0_XContext;
383 int32_t CP0_Framemask;
384 int32_t CP0_Debug;
385#define CP0DB_DBD 31
386#define CP0DB_DM 30
387#define CP0DB_LSNM 28
388#define CP0DB_Doze 27
389#define CP0DB_Halt 26
390#define CP0DB_CNT 25
391#define CP0DB_IBEP 24
392#define CP0DB_DBEP 21
393#define CP0DB_IEXI 20
394#define CP0DB_VER 15
395#define CP0DB_DEC 10
396#define CP0DB_SSt 8
397#define CP0DB_DINT 5
398#define CP0DB_DIB 4
399#define CP0DB_DDBS 3
400#define CP0DB_DDBL 2
401#define CP0DB_DBp 1
402#define CP0DB_DSS 0
403 target_ulong CP0_DEPC;
404 int32_t CP0_Performance0;
405 int32_t CP0_TagLo;
406 int32_t CP0_DataLo;
407 int32_t CP0_TagHi;
408 int32_t CP0_DataHi;
409 target_ulong CP0_ErrorEPC;
410 int32_t CP0_DESAVE;
411
412 TCState tcs[MIPS_SHADOW_SET_MAX];
413 CPUMIPSFPUContext fpus[MIPS_FPU_MAX];
414
415 int error_code;
416 uint32_t hflags;
417
418#define MIPS_HFLAG_TMASK 0xC07FF
419#define MIPS_HFLAG_MODE 0x00007
420
421
422
423#define MIPS_HFLAG_KSU 0x00003
424#define MIPS_HFLAG_UM 0x00002
425#define MIPS_HFLAG_SM 0x00001
426#define MIPS_HFLAG_KM 0x00000
427#define MIPS_HFLAG_DM 0x00004
428#define MIPS_HFLAG_64 0x00008
429#define MIPS_HFLAG_CP0 0x00010
430#define MIPS_HFLAG_FPU 0x00020
431#define MIPS_HFLAG_F64 0x00040
432
433
434
435#define MIPS_HFLAG_COP1X 0x00080
436#define MIPS_HFLAG_RE 0x00100
437#define MIPS_HFLAG_UX 0x00200
438#define MIPS_HFLAG_M16 0x00400
439#define MIPS_HFLAG_M16_SHIFT 10
440
441
442
443
444#define MIPS_HFLAG_BMASK_BASE 0x03800
445#define MIPS_HFLAG_B 0x00800
446#define MIPS_HFLAG_BC 0x01000
447#define MIPS_HFLAG_BL 0x01800
448#define MIPS_HFLAG_BR 0x02000
449
450#define MIPS_HFLAG_BMASK_EXT 0x3C000
451#define MIPS_HFLAG_B16 0x04000
452#define MIPS_HFLAG_BDS16 0x08000
453#define MIPS_HFLAG_BDS32 0x10000
454#define MIPS_HFLAG_BX 0x20000
455#define MIPS_HFLAG_BMASK (MIPS_HFLAG_BMASK_BASE | MIPS_HFLAG_BMASK_EXT)
456
457#define MIPS_HFLAG_DSP 0x40000
458#define MIPS_HFLAG_DSPR2 0x80000
459 target_ulong btarget;
460 target_ulong bcond;
461
462 int SYNCI_Step;
463 int CCRes;
464 uint32_t CP0_Status_rw_bitmask;
465 uint32_t CP0_TCStatus_rw_bitmask;
466 int insn_flags;
467
468 target_ulong tls_value;
469
470 CPU_COMMON
471
472 CPUMIPSMVPContext *mvp;
473#if !defined(CONFIG_USER_ONLY)
474 CPUMIPSTLBContext *tlb;
475#endif
476
477 const mips_def_t *cpu_model;
478 void *irq[8];
479 struct QEMUTimer *timer;
480};
481
482#include "cpu-qom.h"
483
484#if !defined(CONFIG_USER_ONLY)
485int no_mmu_map_address (CPUMIPSState *env, hwaddr *physical, int *prot,
486 target_ulong address, int rw, int access_type);
487int fixed_mmu_map_address (CPUMIPSState *env, hwaddr *physical, int *prot,
488 target_ulong address, int rw, int access_type);
489int r4k_map_address (CPUMIPSState *env, hwaddr *physical, int *prot,
490 target_ulong address, int rw, int access_type);
491void r4k_helper_tlbwi(CPUMIPSState *env);
492void r4k_helper_tlbwr(CPUMIPSState *env);
493void r4k_helper_tlbp(CPUMIPSState *env);
494void r4k_helper_tlbr(CPUMIPSState *env);
495
496void mips_cpu_unassigned_access(CPUState *cpu, hwaddr addr,
497 bool is_write, bool is_exec, int unused,
498 unsigned size);
499#endif
500
501void mips_cpu_list (FILE *f, fprintf_function cpu_fprintf);
502
503#define cpu_exec cpu_mips_exec
504#define cpu_gen_code cpu_mips_gen_code
505#define cpu_signal_handler cpu_mips_signal_handler
506#define cpu_list mips_cpu_list
507
508extern void cpu_wrdsp(uint32_t rs, uint32_t mask_num, CPUMIPSState *env);
509extern uint32_t cpu_rddsp(uint32_t mask_num, CPUMIPSState *env);
510
511#define CPU_SAVE_VERSION 3
512
513
514
515#define MMU_MODE0_SUFFIX _kernel
516#define MMU_MODE1_SUFFIX _super
517#define MMU_MODE2_SUFFIX _user
518#define MMU_USER_IDX 2
519static inline int cpu_mmu_index (CPUMIPSState *env)
520{
521 return env->hflags & MIPS_HFLAG_KSU;
522}
523
524static inline int cpu_mips_hw_interrupts_pending(CPUMIPSState *env)
525{
526 int32_t pending;
527 int32_t status;
528 int r;
529
530 if (!(env->CP0_Status & (1 << CP0St_IE)) ||
531 (env->CP0_Status & (1 << CP0St_EXL)) ||
532 (env->CP0_Status & (1 << CP0St_ERL)) ||
533
534
535
536 (env->active_tc.CP0_TCStatus & (1 << CP0TCSt_IXMT)) ||
537 (env->hflags & MIPS_HFLAG_DM)) {
538
539 return 0;
540 }
541
542 pending = env->CP0_Cause & CP0Ca_IP_mask;
543 status = env->CP0_Status & CP0Ca_IP_mask;
544
545 if (env->CP0_Config3 & (1 << CP0C3_VEIC)) {
546
547
548
549 r = pending > status;
550 } else {
551
552
553
554 r = pending & status;
555 }
556 return r;
557}
558
559#include "exec/cpu-all.h"
560
561
562
563
564enum {
565
566 ACCESS_USER = 0x00,
567 ACCESS_SUPER = 0x01,
568
569 ACCESS_STORE = 0x02,
570
571 ACCESS_CODE = 0x10,
572 ACCESS_INT = 0x20,
573 ACCESS_FLOAT = 0x30,
574};
575
576
577enum {
578 EXCP_NONE = -1,
579 EXCP_RESET = 0,
580 EXCP_SRESET,
581 EXCP_DSS,
582 EXCP_DINT,
583 EXCP_DDBL,
584 EXCP_DDBS,
585 EXCP_NMI,
586 EXCP_MCHECK,
587 EXCP_EXT_INTERRUPT,
588 EXCP_DFWATCH,
589 EXCP_DIB,
590 EXCP_IWATCH,
591 EXCP_AdEL,
592 EXCP_AdES,
593 EXCP_TLBF,
594 EXCP_IBE,
595 EXCP_DBp,
596 EXCP_SYSCALL,
597 EXCP_BREAK,
598 EXCP_CpU,
599 EXCP_RI,
600 EXCP_OVERFLOW,
601 EXCP_TRAP,
602 EXCP_FPE,
603 EXCP_DWATCH,
604 EXCP_LTLBL,
605 EXCP_TLBL,
606 EXCP_TLBS,
607 EXCP_DBE,
608 EXCP_THREAD,
609 EXCP_MDMX,
610 EXCP_C2E,
611 EXCP_CACHE,
612 EXCP_DSPDIS,
613
614 EXCP_LAST = EXCP_DSPDIS,
615};
616
617#define EXCP_SC 0x100
618
619
620
621
622
623
624
625#define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0
626
627int cpu_mips_exec(CPUMIPSState *s);
628void mips_tcg_init(void);
629MIPSCPU *cpu_mips_init(const char *cpu_model);
630int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc);
631
632static inline CPUMIPSState *cpu_init(const char *cpu_model)
633{
634 MIPSCPU *cpu = cpu_mips_init(cpu_model);
635 if (cpu == NULL) {
636 return NULL;
637 }
638 return &cpu->env;
639}
640
641
642void cpu_state_reset(CPUMIPSState *s);
643
644
645uint32_t cpu_mips_get_random (CPUMIPSState *env);
646uint32_t cpu_mips_get_count (CPUMIPSState *env);
647void cpu_mips_store_count (CPUMIPSState *env, uint32_t value);
648void cpu_mips_store_compare (CPUMIPSState *env, uint32_t value);
649void cpu_mips_start_count(CPUMIPSState *env);
650void cpu_mips_stop_count(CPUMIPSState *env);
651
652
653void cpu_mips_soft_irq(CPUMIPSState *env, int irq, int level);
654
655
656int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw,
657 int mmu_idx);
658#define cpu_handle_mmu_fault cpu_mips_handle_mmu_fault
659#if !defined(CONFIG_USER_ONLY)
660void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra);
661hwaddr cpu_mips_translate_address (CPUMIPSState *env, target_ulong address,
662 int rw);
663#endif
664target_ulong exception_resume_pc (CPUMIPSState *env);
665
666static inline void cpu_get_tb_cpu_state(CPUMIPSState *env, target_ulong *pc,
667 target_ulong *cs_base, int *flags)
668{
669 *pc = env->active_tc.PC;
670 *cs_base = 0;
671 *flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
672}
673
674static inline int mips_vpe_active(CPUMIPSState *env)
675{
676 int active = 1;
677
678
679 if (!(env->mvp->CP0_MVPControl & (1 << CP0MVPCo_EVP))) {
680 active = 0;
681 }
682
683 if (!(env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))) {
684 active = 0;
685 }
686
687
688
689
690
691
692
693 if (!(env->active_tc.CP0_TCStatus & (1 << CP0TCSt_A))) {
694
695 active = 0;
696 }
697 if (env->active_tc.CP0_TCHalt & 1) {
698
699 active = 0;
700 }
701
702 return active;
703}
704
705static inline bool cpu_has_work(CPUState *cpu)
706{
707 CPUMIPSState *env = &MIPS_CPU(cpu)->env;
708 bool has_work = false;
709
710
711
712
713 if ((cpu->interrupt_request & CPU_INTERRUPT_HARD) &&
714 cpu_mips_hw_interrupts_pending(env)) {
715 has_work = true;
716 }
717
718
719 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
720
721
722 if (cpu->interrupt_request & CPU_INTERRUPT_WAKE) {
723 has_work = true;
724 }
725
726 if (!mips_vpe_active(env)) {
727 has_work = false;
728 }
729 }
730 return has_work;
731}
732
733#include "exec/exec-all.h"
734
735static inline void compute_hflags(CPUMIPSState *env)
736{
737 env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
738 MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU |
739 MIPS_HFLAG_UX | MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2);
740 if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
741 !(env->CP0_Status & (1 << CP0St_ERL)) &&
742 !(env->hflags & MIPS_HFLAG_DM)) {
743 env->hflags |= (env->CP0_Status >> CP0St_KSU) & MIPS_HFLAG_KSU;
744 }
745#if defined(TARGET_MIPS64)
746 if (((env->hflags & MIPS_HFLAG_KSU) != MIPS_HFLAG_UM) ||
747 (env->CP0_Status & (1 << CP0St_PX)) ||
748 (env->CP0_Status & (1 << CP0St_UX))) {
749 env->hflags |= MIPS_HFLAG_64;
750 }
751 if (env->CP0_Status & (1 << CP0St_UX)) {
752 env->hflags |= MIPS_HFLAG_UX;
753 }
754#endif
755 if ((env->CP0_Status & (1 << CP0St_CU0)) ||
756 !(env->hflags & MIPS_HFLAG_KSU)) {
757 env->hflags |= MIPS_HFLAG_CP0;
758 }
759 if (env->CP0_Status & (1 << CP0St_CU1)) {
760 env->hflags |= MIPS_HFLAG_FPU;
761 }
762 if (env->CP0_Status & (1 << CP0St_FR)) {
763 env->hflags |= MIPS_HFLAG_F64;
764 }
765 if (env->insn_flags & ASE_DSPR2) {
766
767
768 if (env->CP0_Status & (1 << CP0St_MX)) {
769 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
770 }
771
772 } else if (env->insn_flags & ASE_DSP) {
773
774
775 if (env->CP0_Status & (1 << CP0St_MX)) {
776 env->hflags |= MIPS_HFLAG_DSP;
777 }
778
779 }
780 if (env->insn_flags & ISA_MIPS32R2) {
781 if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
782 env->hflags |= MIPS_HFLAG_COP1X;
783 }
784 } else if (env->insn_flags & ISA_MIPS32) {
785 if (env->hflags & MIPS_HFLAG_64) {
786 env->hflags |= MIPS_HFLAG_COP1X;
787 }
788 } else if (env->insn_flags & ISA_MIPS4) {
789
790
791
792
793 if (env->CP0_Status & (1 << CP0St_CU3)) {
794 env->hflags |= MIPS_HFLAG_COP1X;
795 }
796 }
797}
798
799#endif
800