update
[qemu] / target-mips / cpu.h
1 #if !defined (__MIPS_CPU_H__)
2 #define __MIPS_CPU_H__
3
4 #include "mips-defs.h"
5 #include "cpu-defs.h"
6 #include "config.h"
7 #include "softfloat.h"
8
9 typedef union fpr_t fpr_t;
10 union fpr_t {
11     double d;
12     float  f;
13     uint32_t u[2];
14 };
15
16 #if defined(MIPS_USES_R4K_TLB)
17 typedef struct tlb_t tlb_t;
18 struct tlb_t {
19     target_ulong VPN;
20     target_ulong end;
21     uint8_t ASID;
22     uint8_t G;
23     uint8_t C[2];
24     uint8_t V[2];
25     uint8_t D[2];
26     target_ulong PFN[2];
27 };
28 #endif
29
30 typedef struct CPUMIPSState CPUMIPSState;
31 struct CPUMIPSState {
32     /* General integer registers */
33     target_ulong gpr[32];
34     /* Special registers */
35     target_ulong PC;
36     uint32_t HI, LO;
37     uint32_t DCR; /* ? */
38 #if defined(MIPS_USES_FPU)
39     /* Floating point registers */
40     fpr_t fpr[16];
41     /* Floating point special purpose registers */
42     uint32_t fcr0;
43     uint32_t fcr25;
44     uint32_t fcr26;
45     uint32_t fcr28;
46     uint32_t fcsr;
47 #endif
48 #if defined(MIPS_USES_R4K_TLB)
49     tlb_t tlb[16];
50 #endif
51     uint32_t CP0_index;
52     uint32_t CP0_random;
53     uint32_t CP0_EntryLo0;
54     uint32_t CP0_EntryLo1;
55     uint32_t CP0_Context;
56     uint32_t CP0_PageMask;
57     uint32_t CP0_Wired;
58     uint32_t CP0_BadVAddr;
59     uint32_t CP0_Count;
60     uint32_t CP0_EntryHi;
61     uint32_t CP0_Compare;
62     uint32_t CP0_Status;
63 #define CP0St_CU3   31
64 #define CP0St_CU2   30
65 #define CP0St_CU1   29
66 #define CP0St_CU0   28
67 #define CP0St_RP    27
68 #define CP0St_RE    25
69 #define CP0St_BEV   22
70 #define CP0St_TS    21
71 #define CP0St_SR    20
72 #define CP0St_NMI   19
73 #define CP0St_IM    8
74 #define CP0St_UM    4
75 #define CP0St_ERL   2
76 #define CP0St_EXL   1
77 #define CP0St_IE    0
78     uint32_t CP0_Cause;
79 #define CP0Ca_IV   23
80     uint32_t CP0_EPC;
81     uint32_t CP0_PRid;
82     uint32_t CP0_Config0;
83 #define CP0C0_M    31
84 #define CP0C0_K23  28
85 #define CP0C0_KU   25
86 #define CP0C0_MDU  20
87 #define CP0C0_MM   17
88 #define CP0C0_BM   16
89 #define CP0C0_BE   15
90 #define CP0C0_AT   13
91 #define CP0C0_AR   10
92 #define CP0C0_MT   7
93 #define CP0C0_K0   0
94     uint32_t CP0_Config1;
95 #define CP0C1_MMU  25
96 #define CP0C1_IS   22
97 #define CP0C1_IL   19
98 #define CP0C1_IA   16
99 #define CP0C1_DS   13
100 #define CP0C1_DL   10
101 #define CP0C1_DA   7
102 #define CP0C1_PC   4
103 #define CP0C1_WR   3
104 #define CP0C1_CA   2
105 #define CP0C1_EP   1
106 #define CP0C1_FP   0
107     uint32_t CP0_LLAddr;
108     uint32_t CP0_WatchLo;
109     uint32_t CP0_WatchHi;
110     uint32_t CP0_Debug;
111 #define CPDB_DBD   31
112 #define CP0DB_DM   30
113 #define CP0DB_LSNM 28
114 #define CP0DB_Doze 27
115 #define CP0DB_Halt 26
116 #define CP0DB_CNT  25
117 #define CP0DB_IBEP 24
118 #define CP0DB_DBEP 21
119 #define CP0DB_IEXI 20
120 #define CP0DB_VER  15
121 #define CP0DB_DEC  10
122 #define CP0DB_SSt  8
123 #define CP0DB_DINT 5
124 #define CP0DB_DIB  4
125 #define CP0DB_DDBS 3
126 #define CP0DB_DDBL 2
127 #define CP0DB_DBp  1
128 #define CP0DB_DSS  0
129     uint32_t CP0_DEPC;
130     uint32_t CP0_TagLo;
131     uint32_t CP0_DataLo;
132     uint32_t CP0_ErrorEPC;
133     uint32_t CP0_DESAVE;
134     /* Qemu */
135 #if defined (USE_HOST_FLOAT_REGS) && defined(MIPS_USES_FPU)
136     double ft0, ft1, ft2;
137 #endif
138     struct QEMUTimer *timer; /* Internal timer */
139     int interrupt_request;
140     jmp_buf jmp_env;
141     int exception_index;
142     int error_code;
143     int user_mode_only; /* user mode only simulation */
144     uint32_t hflags;    /* CPU State */
145     /* TMASK defines different execution modes */
146 #define MIPS_HFLAGS_TMASK 0x00FF
147 #define MIPS_HFLAG_MODE   0x001F /* execution modes                    */
148 #define MIPS_HFLAG_UM     0x0001 /* user mode                          */
149 #define MIPS_HFLAG_ERL    0x0002 /* Error mode                         */
150 #define MIPS_HFLAG_EXL    0x0004 /* Exception mode                     */
151 #define MIPS_HFLAG_DM     0x0008 /* Debug mode                         */
152 #define MIPS_HFLAG_SM     0x0010 /* Supervisor mode                    */
153 #define MIPS_HFLAG_RE     0x0040 /* Reversed endianness                */
154 #define MIPS_HFLAG_DS     0x0080 /* In / out of delay slot             */
155     /* Those flags keep the branch state if the translation is interrupted
156      * between the branch instruction and the delay slot
157      */
158 #define MIPS_HFLAG_BMASK  0x0F00
159 #define MIPS_HFLAG_B      0x0100 /* Unconditional branch               */
160 #define MIPS_HFLAG_BC     0x0200 /* Conditional branch                 */
161 #define MIPS_HFLAG_BL     0x0400 /* Likely branch                      */
162 #define MIPS_HFLAG_BR     0x0800 /* branch to register (can't link TB) */
163     target_ulong btarget;        /* Jump / branch target               */
164     int bcond;                   /* Branch condition (if needed)       */
165     struct TranslationBlock *current_tb; /* currently executing TB  */
166     /* soft mmu support */
167     /* in order to avoid passing too many arguments to the memory
168        write helpers, we store some rarely used information in the CPU
169        context) */
170     target_ulong mem_write_pc; /* host pc at which the memory was
171                                    written */
172     unsigned long mem_write_vaddr; /* target virtual addr at which the
173                                       memory was written */
174     /* 0 = kernel, 1 = user (may have 2 = kernel code, 3 = user code ?) */
175     CPUTLBEntry tlb_read[2][CPU_TLB_SIZE];
176     CPUTLBEntry tlb_write[2][CPU_TLB_SIZE];
177     /* ice debug support */
178     target_ulong breakpoints[MAX_BREAKPOINTS];
179     int nb_breakpoints;
180     int singlestep_enabled; /* XXX: should use CPU single step mode instead */
181     /* user data */
182     void *opaque;
183 };
184
185 #include "cpu-all.h"
186
187 /* Memory access type :
188  * may be needed for precise access rights control and precise exceptions.
189  */
190 enum {
191     /* 1 bit to define user level / supervisor access */
192     ACCESS_USER  = 0x00,
193     ACCESS_SUPER = 0x01,
194     /* 1 bit to indicate direction */
195     ACCESS_STORE = 0x02,
196     /* Type of instruction that generated the access */
197     ACCESS_CODE  = 0x10, /* Code fetch access                */
198     ACCESS_INT   = 0x20, /* Integer load/store access        */
199     ACCESS_FLOAT = 0x30, /* floating point load/store access */
200 };
201
202 /* Exceptions */
203 enum {
204     EXCP_NONE          = -1,
205     EXCP_RESET         = 0,
206     EXCP_SRESET,
207     EXCP_DSS,
208     EXCP_DINT,
209     EXCP_NMI,
210     EXCP_MCHECK,
211     EXCP_EXT_INTERRUPT,
212     EXCP_DFWATCH,
213     EXCP_DIB, /* 8 */
214     EXCP_IWATCH,
215     EXCP_AdEL,
216     EXCP_AdES,
217     EXCP_TLBF,
218     EXCP_IBE,
219     EXCP_DBp,
220     EXCP_SYSCALL,
221     EXCP_BREAK,
222     EXCP_CpU, /* 16 */
223     EXCP_RI,
224     EXCP_OVERFLOW,
225     EXCP_TRAP,
226     EXCP_DDBS,
227     EXCP_DWATCH,
228     EXCP_LAE, /* 22 */
229     EXCP_SAE,
230     EXCP_LTLBL,
231     EXCP_TLBL,
232     EXCP_TLBS,
233     EXCP_DBE,
234     EXCP_DDBL,
235     EXCP_MTCP0         = 0x104, /* mtmsr instruction:               */
236                                 /* may change privilege level       */
237     EXCP_BRANCH        = 0x108, /* branch instruction               */
238     EXCP_ERET          = 0x10C, /* return from interrupt            */
239     EXCP_SYSCALL_USER  = 0x110, /* System call in user mode only    */
240     EXCP_FLUSH         = 0x109,
241 };
242
243 /* MIPS opcodes */
244 #define EXT_SPECIAL  0x100
245 #define EXT_SPECIAL2 0x200
246 #define EXT_REGIMM   0x300
247 #define EXT_CP0      0x400
248 #define EXT_CP1      0x500
249 #define EXT_CP2      0x600
250 #define EXT_CP3      0x700
251
252 enum {
253     /* indirect opcode tables */
254     OPC_SPECIAL  = 0x00,
255     OPC_BREGIMM  = 0x01,
256     OPC_CP0      = 0x10,
257     OPC_CP1      = 0x11,
258     OPC_CP2      = 0x12,
259     OPC_CP3      = 0x13,
260     OPC_SPECIAL2 = 0x1C,
261     /* arithmetic with immediate */
262     OPC_ADDI     = 0x08,
263     OPC_ADDIU    = 0x09,
264     OPC_SLTI     = 0x0A,
265     OPC_SLTIU    = 0x0B,
266     OPC_ANDI     = 0x0C,
267     OPC_ORI      = 0x0D,
268     OPC_XORI     = 0x0E,
269     OPC_LUI      = 0x0F,
270     /* Jump and branches */
271     OPC_J        = 0x02,
272     OPC_JAL      = 0x03,
273     OPC_BEQ      = 0x04,  /* Unconditional if rs = rt = 0 (B) */
274     OPC_BEQL     = 0x14,
275     OPC_BNE      = 0x05,
276     OPC_BNEL     = 0x15,
277     OPC_BLEZ     = 0x06,
278     OPC_BLEZL    = 0x16,
279     OPC_BGTZ     = 0x07,
280     OPC_BGTZL    = 0x17,
281     OPC_JALX     = 0x1D,  /* MIPS 16 only */
282     /* Load and stores */
283     OPC_LB       = 0x20,
284     OPC_LH       = 0x21,
285     OPC_LWL      = 0x22,
286     OPC_LW       = 0x23,
287     OPC_LBU      = 0x24,
288     OPC_LHU      = 0x25,
289     OPC_LWR      = 0x26,
290     OPC_SB       = 0x28,
291     OPC_SH       = 0x29,
292     OPC_SWL      = 0x2A,
293     OPC_SW       = 0x2B,
294     OPC_SWR      = 0x2E,
295     OPC_LL       = 0x30,
296     OPC_SC       = 0x38,
297     /* Floating point load/store */
298     OPC_LWC1     = 0x31,
299     OPC_LWC2     = 0x32,
300     OPC_LDC1     = 0x35,
301     OPC_LDC2     = 0x36,
302     OPC_SWC1     = 0x39,
303     OPC_SWC2     = 0x3A,
304     OPC_SDC1     = 0x3D,
305     OPC_SDC2     = 0x3E,
306     /* Cache and prefetch */
307     OPC_CACHE    = 0x2F,
308     OPC_PREF     = 0x33,
309 };
310
311 /* MIPS special opcodes */
312 enum {
313     /* Shifts */
314     OPC_SLL      = 0x00 | EXT_SPECIAL,
315     /* NOP is SLL r0, r0, 0   */
316     /* SSNOP is SLL r0, r0, 1 */
317     OPC_SRL      = 0x02 | EXT_SPECIAL,
318     OPC_SRA      = 0x03 | EXT_SPECIAL,
319     OPC_SLLV     = 0x04 | EXT_SPECIAL,
320     OPC_SRLV     = 0x06 | EXT_SPECIAL,
321     OPC_SRAV     = 0x07 | EXT_SPECIAL,
322     /* Multiplication / division */
323     OPC_MULT     = 0x18 | EXT_SPECIAL,
324     OPC_MULTU    = 0x19 | EXT_SPECIAL,
325     OPC_DIV      = 0x1A | EXT_SPECIAL,
326     OPC_DIVU     = 0x1B | EXT_SPECIAL,
327     /* 2 registers arithmetic / logic */
328     OPC_ADD      = 0x20 | EXT_SPECIAL,
329     OPC_ADDU     = 0x21 | EXT_SPECIAL,
330     OPC_SUB      = 0x22 | EXT_SPECIAL,
331     OPC_SUBU     = 0x23 | EXT_SPECIAL,
332     OPC_AND      = 0x24 | EXT_SPECIAL,
333     OPC_OR       = 0x25 | EXT_SPECIAL,
334     OPC_XOR      = 0x26 | EXT_SPECIAL,
335     OPC_NOR      = 0x27 | EXT_SPECIAL,
336     OPC_SLT      = 0x2A | EXT_SPECIAL,
337     OPC_SLTU     = 0x2B | EXT_SPECIAL,
338     /* Jumps */
339     OPC_JR       = 0x08 | EXT_SPECIAL,
340     OPC_JALR     = 0x09 | EXT_SPECIAL,
341     /* Traps */
342     OPC_TGE      = 0x30 | EXT_SPECIAL,
343     OPC_TGEU     = 0x31 | EXT_SPECIAL,
344     OPC_TLT      = 0x32 | EXT_SPECIAL,
345     OPC_TLTU     = 0x33 | EXT_SPECIAL,
346     OPC_TEQ      = 0x34 | EXT_SPECIAL,
347     OPC_TNE      = 0x36 | EXT_SPECIAL,
348     /* HI / LO registers load & stores */
349     OPC_MFHI     = 0x10 | EXT_SPECIAL,
350     OPC_MTHI     = 0x11 | EXT_SPECIAL,
351     OPC_MFLO     = 0x12 | EXT_SPECIAL,
352     OPC_MTLO     = 0x13 | EXT_SPECIAL,
353     /* Conditional moves */
354     OPC_MOVZ     = 0x0A | EXT_SPECIAL,
355     OPC_MOVN     = 0x0B | EXT_SPECIAL,
356
357     OPC_MOVCI    = 0x01 | EXT_SPECIAL,
358
359     /* Special */
360     OPC_PMON     = 0x05 | EXT_SPECIAL,
361     OPC_SYSCALL  = 0x0C | EXT_SPECIAL,
362     OPC_BREAK    = 0x0D | EXT_SPECIAL,
363     OPC_SYNC     = 0x0F | EXT_SPECIAL,
364 };
365
366 enum {
367     /* Mutiply & xxx operations */
368     OPC_MADD     = 0x00 | EXT_SPECIAL2,
369     OPC_MADDU    = 0x01 | EXT_SPECIAL2,
370     OPC_MUL      = 0x02 | EXT_SPECIAL2,
371     OPC_MSUB     = 0x04 | EXT_SPECIAL2,
372     OPC_MSUBU    = 0x05 | EXT_SPECIAL2,
373     /* Misc */
374     OPC_CLZ      = 0x20 | EXT_SPECIAL2,
375     OPC_CLO      = 0x21 | EXT_SPECIAL2,
376     /* Special */
377     OPC_SDBBP    = 0x3F | EXT_SPECIAL2,
378 };
379
380 /* Branch REGIMM */
381 enum {
382     OPC_BLTZ     = 0x00 | EXT_REGIMM,
383     OPC_BLTZL    = 0x02 | EXT_REGIMM,
384     OPC_BGEZ     = 0x01 | EXT_REGIMM,
385     OPC_BGEZL    = 0x03 | EXT_REGIMM,
386     OPC_BLTZAL   = 0x10 | EXT_REGIMM,
387     OPC_BLTZALL  = 0x12 | EXT_REGIMM,
388     OPC_BGEZAL   = 0x11 | EXT_REGIMM,
389     OPC_BGEZALL  = 0x13 | EXT_REGIMM,
390     OPC_TGEI     = 0x08 | EXT_REGIMM,
391     OPC_TGEIU    = 0x09 | EXT_REGIMM,
392     OPC_TLTI     = 0x0A | EXT_REGIMM,
393     OPC_TLTIU    = 0x0B | EXT_REGIMM,
394     OPC_TEQI     = 0x0C | EXT_REGIMM,
395     OPC_TNEI     = 0x0E | EXT_REGIMM,
396 };
397
398 enum {
399     /* Coprocessor 0 (MMU) */
400     OPC_MFC0     = 0x00 | EXT_CP0,
401     OPC_MTC0     = 0x04 | EXT_CP0,
402     OPC_TLBR     = 0x01 | EXT_CP0,
403     OPC_TLBWI    = 0x02 | EXT_CP0,
404     OPC_TLBWR    = 0x06 | EXT_CP0,
405     OPC_TLBP     = 0x08 | EXT_CP0,
406     OPC_ERET     = 0x18 | EXT_CP0,
407     OPC_DERET    = 0x1F | EXT_CP0,
408     OPC_WAIT     = 0x20 | EXT_CP0,
409 };
410
411 int cpu_mips_exec(CPUMIPSState *s);
412 CPUMIPSState *cpu_mips_init(void);
413 uint32_t cpu_mips_get_clock (void);
414
415 #endif /* !defined (__MIPS_CPU_H__) */