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 "cpu-defs.h"
16#include "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 cpu_unassigned_access(CPUMIPSState *env, hwaddr addr,
497 int is_write, int is_exec, int unused, int size);
498#endif
499
500void mips_cpu_list (FILE *f, fprintf_function cpu_fprintf);
501
502#define cpu_exec cpu_mips_exec
503#define cpu_gen_code cpu_mips_gen_code
504#define cpu_signal_handler cpu_mips_signal_handler
505#define cpu_list mips_cpu_list
506
507#define CPU_SAVE_VERSION 3
508
509
510
511#define MMU_MODE0_SUFFIX _kernel
512#define MMU_MODE1_SUFFIX _super
513#define MMU_MODE2_SUFFIX _user
514#define MMU_USER_IDX 2
515static inline int cpu_mmu_index (CPUMIPSState *env)
516{
517 return env->hflags & MIPS_HFLAG_KSU;
518}
519
520static inline void cpu_clone_regs(CPUMIPSState *env, target_ulong newsp)
521{
522 if (newsp)
523 env->active_tc.gpr[29] = newsp;
524 env->active_tc.gpr[7] = 0;
525 env->active_tc.gpr[2] = 0;
526}
527
528static inline int cpu_mips_hw_interrupts_pending(CPUMIPSState *env)
529{
530 int32_t pending;
531 int32_t status;
532 int r;
533
534 if (!(env->CP0_Status & (1 << CP0St_IE)) ||
535 (env->CP0_Status & (1 << CP0St_EXL)) ||
536 (env->CP0_Status & (1 << CP0St_ERL)) ||
537
538
539
540 (env->active_tc.CP0_TCStatus & (1 << CP0TCSt_IXMT)) ||
541 (env->hflags & MIPS_HFLAG_DM)) {
542
543 return 0;
544 }
545
546 pending = env->CP0_Cause & CP0Ca_IP_mask;
547 status = env->CP0_Status & CP0Ca_IP_mask;
548
549 if (env->CP0_Config3 & (1 << CP0C3_VEIC)) {
550
551
552
553 r = pending > status;
554 } else {
555
556
557
558 r = pending & status;
559 }
560 return r;
561}
562
563#include "cpu-all.h"
564
565
566
567
568enum {
569
570 ACCESS_USER = 0x00,
571 ACCESS_SUPER = 0x01,
572
573 ACCESS_STORE = 0x02,
574
575 ACCESS_CODE = 0x10,
576 ACCESS_INT = 0x20,
577 ACCESS_FLOAT = 0x30,
578};
579
580
581enum {
582 EXCP_NONE = -1,
583 EXCP_RESET = 0,
584 EXCP_SRESET,
585 EXCP_DSS,
586 EXCP_DINT,
587 EXCP_DDBL,
588 EXCP_DDBS,
589 EXCP_NMI,
590 EXCP_MCHECK,
591 EXCP_EXT_INTERRUPT,
592 EXCP_DFWATCH,
593 EXCP_DIB,
594 EXCP_IWATCH,
595 EXCP_AdEL,
596 EXCP_AdES,
597 EXCP_TLBF,
598 EXCP_IBE,
599 EXCP_DBp,
600 EXCP_SYSCALL,
601 EXCP_BREAK,
602 EXCP_CpU,
603 EXCP_RI,
604 EXCP_OVERFLOW,
605 EXCP_TRAP,
606 EXCP_FPE,
607 EXCP_DWATCH,
608 EXCP_LTLBL,
609 EXCP_TLBL,
610 EXCP_TLBS,
611 EXCP_DBE,
612 EXCP_THREAD,
613 EXCP_MDMX,
614 EXCP_C2E,
615 EXCP_CACHE,
616 EXCP_DSPDIS,
617
618 EXCP_LAST = EXCP_DSPDIS,
619};
620
621#define EXCP_SC 0x100
622
623
624
625
626
627
628
629#define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0
630
631int cpu_mips_exec(CPUMIPSState *s);
632MIPSCPU *cpu_mips_init(const char *cpu_model);
633int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc);
634
635static inline CPUMIPSState *cpu_init(const char *cpu_model)
636{
637 MIPSCPU *cpu = cpu_mips_init(cpu_model);
638 if (cpu == NULL) {
639 return NULL;
640 }
641 return &cpu->env;
642}
643
644
645void cpu_state_reset(CPUMIPSState *s);
646
647
648uint32_t cpu_mips_get_random (CPUMIPSState *env);
649uint32_t cpu_mips_get_count (CPUMIPSState *env);
650void cpu_mips_store_count (CPUMIPSState *env, uint32_t value);
651void cpu_mips_store_compare (CPUMIPSState *env, uint32_t value);
652void cpu_mips_start_count(CPUMIPSState *env);
653void cpu_mips_stop_count(CPUMIPSState *env);
654
655
656void cpu_mips_soft_irq(CPUMIPSState *env, int irq, int level);
657
658
659int cpu_mips_handle_mmu_fault (CPUMIPSState *env, target_ulong address, int rw,
660 int mmu_idx);
661#define cpu_handle_mmu_fault cpu_mips_handle_mmu_fault
662void do_interrupt (CPUMIPSState *env);
663#if !defined(CONFIG_USER_ONLY)
664void r4k_invalidate_tlb (CPUMIPSState *env, int idx, int use_extra);
665hwaddr cpu_mips_translate_address (CPUMIPSState *env, target_ulong address,
666 int rw);
667#endif
668
669static inline void cpu_get_tb_cpu_state(CPUMIPSState *env, target_ulong *pc,
670 target_ulong *cs_base, int *flags)
671{
672 *pc = env->active_tc.PC;
673 *cs_base = 0;
674 *flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
675}
676
677static inline void cpu_set_tls(CPUMIPSState *env, target_ulong newtls)
678{
679 env->tls_value = newtls;
680}
681
682static inline int mips_vpe_active(CPUMIPSState *env)
683{
684 int active = 1;
685
686
687 if (!(env->mvp->CP0_MVPControl & (1 << CP0MVPCo_EVP))) {
688 active = 0;
689 }
690
691 if (!(env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))) {
692 active = 0;
693 }
694
695
696
697
698
699
700
701 if (!(env->active_tc.CP0_TCStatus & (1 << CP0TCSt_A))) {
702
703 active = 0;
704 }
705 if (env->active_tc.CP0_TCHalt & 1) {
706
707 active = 0;
708 }
709
710 return active;
711}
712
713static inline bool cpu_has_work(CPUState *cpu)
714{
715 CPUMIPSState *env = &MIPS_CPU(cpu)->env;
716 bool has_work = false;
717
718
719
720
721 if ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
722 cpu_mips_hw_interrupts_pending(env)) {
723 has_work = true;
724 }
725
726
727 if (env->CP0_Config3 & (1 << CP0C3_MT)) {
728
729
730 if (env->interrupt_request & CPU_INTERRUPT_WAKE) {
731 has_work = true;
732 }
733
734 if (!mips_vpe_active(env)) {
735 has_work = false;
736 }
737 }
738 return has_work;
739}
740
741#include "exec-all.h"
742
743static inline void cpu_pc_from_tb(CPUMIPSState *env, TranslationBlock *tb)
744{
745 env->active_tc.PC = tb->pc;
746 env->hflags &= ~MIPS_HFLAG_BMASK;
747 env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
748}
749
750static inline void compute_hflags(CPUMIPSState *env)
751{
752 env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 |
753 MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU |
754 MIPS_HFLAG_UX);
755 if (!(env->CP0_Status & (1 << CP0St_EXL)) &&
756 !(env->CP0_Status & (1 << CP0St_ERL)) &&
757 !(env->hflags & MIPS_HFLAG_DM)) {
758 env->hflags |= (env->CP0_Status >> CP0St_KSU) & MIPS_HFLAG_KSU;
759 }
760#if defined(TARGET_MIPS64)
761 if (((env->hflags & MIPS_HFLAG_KSU) != MIPS_HFLAG_UM) ||
762 (env->CP0_Status & (1 << CP0St_PX)) ||
763 (env->CP0_Status & (1 << CP0St_UX))) {
764 env->hflags |= MIPS_HFLAG_64;
765 }
766 if (env->CP0_Status & (1 << CP0St_UX)) {
767 env->hflags |= MIPS_HFLAG_UX;
768 }
769#endif
770 if ((env->CP0_Status & (1 << CP0St_CU0)) ||
771 !(env->hflags & MIPS_HFLAG_KSU)) {
772 env->hflags |= MIPS_HFLAG_CP0;
773 }
774 if (env->CP0_Status & (1 << CP0St_CU1)) {
775 env->hflags |= MIPS_HFLAG_FPU;
776 }
777 if (env->CP0_Status & (1 << CP0St_FR)) {
778 env->hflags |= MIPS_HFLAG_F64;
779 }
780 if (env->insn_flags & ASE_DSPR2) {
781
782
783 if (env->CP0_Status & (1 << CP0St_MX)) {
784 env->hflags |= MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2;
785 }
786
787 } else if (env->insn_flags & ASE_DSP) {
788
789
790 if (env->CP0_Status & (1 << CP0St_MX)) {
791 env->hflags |= MIPS_HFLAG_DSP;
792 }
793
794 }
795 if (env->insn_flags & ISA_MIPS32R2) {
796 if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
797 env->hflags |= MIPS_HFLAG_COP1X;
798 }
799 } else if (env->insn_flags & ISA_MIPS32) {
800 if (env->hflags & MIPS_HFLAG_64) {
801 env->hflags |= MIPS_HFLAG_COP1X;
802 }
803 } else if (env->insn_flags & ISA_MIPS4) {
804
805
806
807
808 if (env->CP0_Status & (1 << CP0St_CU3)) {
809 env->hflags |= MIPS_HFLAG_COP1X;
810 }
811 }
812}
813
814#endif
815