Move date/time init to the RTC implementation.
[qemu] / target-mips / translate.c
1 /*
2  *  MIPS32 emulation for qemu: main translation routines.
3  * 
4  *  Copyright (c) 2004-2005 Jocelyn Mayer
5  *  Copyright (c) 2006 Marius Groeger (FPU operations)
6  *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <stdio.h>
26 #include <string.h>
27 #include <inttypes.h>
28
29 #include "cpu.h"
30 #include "exec-all.h"
31 #include "disas.h"
32
33 //#define MIPS_DEBUG_DISAS
34 //#define MIPS_SINGLE_STEP
35
36 #ifdef USE_DIRECT_JUMP
37 #define TBPARAM(x)
38 #else
39 #define TBPARAM(x) (long)(x)
40 #endif
41
42 enum {
43 #define DEF(s, n, copy_size) INDEX_op_ ## s,
44 #include "opc.h"
45 #undef DEF
46     NB_OPS,
47 };
48
49 static uint16_t *gen_opc_ptr;
50 static uint32_t *gen_opparam_ptr;
51
52 #include "gen-op.h"
53
54 /* MIPS major opcodes */
55 #define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
56
57 enum {
58     /* indirect opcode tables */
59     OPC_SPECIAL  = (0x00 << 26),
60     OPC_REGIMM   = (0x01 << 26),
61     OPC_CP0      = (0x10 << 26),
62     OPC_CP1      = (0x11 << 26),
63     OPC_CP2      = (0x12 << 26),
64     OPC_CP3      = (0x13 << 26),
65     OPC_SPECIAL2 = (0x1C << 26),
66     OPC_SPECIAL3 = (0x1F << 26),
67     /* arithmetic with immediate */
68     OPC_ADDI     = (0x08 << 26),
69     OPC_ADDIU    = (0x09 << 26),
70     OPC_SLTI     = (0x0A << 26),
71     OPC_SLTIU    = (0x0B << 26),
72     OPC_ANDI     = (0x0C << 26),
73     OPC_ORI      = (0x0D << 26),
74     OPC_XORI     = (0x0E << 26),
75     OPC_LUI      = (0x0F << 26),
76     OPC_DADDI    = (0x18 << 26),
77     OPC_DADDIU   = (0x19 << 26),
78     /* Jump and branches */
79     OPC_J        = (0x02 << 26),
80     OPC_JAL      = (0x03 << 26),
81     OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
82     OPC_BEQL     = (0x14 << 26),
83     OPC_BNE      = (0x05 << 26),
84     OPC_BNEL     = (0x15 << 26),
85     OPC_BLEZ     = (0x06 << 26),
86     OPC_BLEZL    = (0x16 << 26),
87     OPC_BGTZ     = (0x07 << 26),
88     OPC_BGTZL    = (0x17 << 26),
89     OPC_JALX     = (0x1D << 26),  /* MIPS 16 only */
90     /* Load and stores */
91     OPC_LDL      = (0x1A << 26),
92     OPC_LDR      = (0x1B << 26),
93     OPC_LB       = (0x20 << 26),
94     OPC_LH       = (0x21 << 26),
95     OPC_LWL      = (0x22 << 26),
96     OPC_LW       = (0x23 << 26),
97     OPC_LBU      = (0x24 << 26),
98     OPC_LHU      = (0x25 << 26),
99     OPC_LWR      = (0x26 << 26),
100     OPC_LWU      = (0x27 << 26),
101     OPC_SB       = (0x28 << 26),
102     OPC_SH       = (0x29 << 26),
103     OPC_SWL      = (0x2A << 26),
104     OPC_SW       = (0x2B << 26),
105     OPC_SDL      = (0x2C << 26),
106     OPC_SDR      = (0x2D << 26),
107     OPC_SWR      = (0x2E << 26),
108     OPC_LL       = (0x30 << 26),
109     OPC_LLD      = (0x34 << 26),
110     OPC_LD       = (0x37 << 26),
111     OPC_SC       = (0x38 << 26),
112     OPC_SCD      = (0x3C << 26),
113     OPC_SD       = (0x3F << 26),
114     /* Floating point load/store */
115     OPC_LWC1     = (0x31 << 26),
116     OPC_LWC2     = (0x32 << 26),
117     OPC_LDC1     = (0x35 << 26),
118     OPC_LDC2     = (0x36 << 26),
119     OPC_SWC1     = (0x39 << 26),
120     OPC_SWC2     = (0x3A << 26),
121     OPC_SDC1     = (0x3D << 26),
122     OPC_SDC2     = (0x3E << 26),
123     /* MDMX ASE specific */
124     OPC_MDMX     = (0x1E << 26),
125     /* Cache and prefetch */
126     OPC_CACHE    = (0x2F << 26),
127     OPC_PREF     = (0x33 << 26),
128     /* Reserved major opcode */
129     OPC_MAJOR3B_RESERVED = (0x3B << 26),
130 };
131
132 /* MIPS special opcodes */
133 #define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
134
135 enum {
136     /* Shifts */
137     OPC_SLL      = 0x00 | OPC_SPECIAL,
138     /* NOP is SLL r0, r0, 0   */
139     /* SSNOP is SLL r0, r0, 1 */
140     /* EHB is SLL r0, r0, 3 */
141     OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
142     OPC_SRA      = 0x03 | OPC_SPECIAL,
143     OPC_SLLV     = 0x04 | OPC_SPECIAL,
144     OPC_SRLV     = 0x06 | OPC_SPECIAL,
145     OPC_SRAV     = 0x07 | OPC_SPECIAL,
146     OPC_DSLLV    = 0x14 | OPC_SPECIAL,
147     OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
148     OPC_DSRAV    = 0x17 | OPC_SPECIAL,
149     OPC_DSLL     = 0x38 | OPC_SPECIAL,
150     OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
151     OPC_DSRA     = 0x3B | OPC_SPECIAL,
152     OPC_DSLL32   = 0x3C | OPC_SPECIAL,
153     OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
154     OPC_DSRA32   = 0x3F | OPC_SPECIAL,
155     /* Multiplication / division */
156     OPC_MULT     = 0x18 | OPC_SPECIAL,
157     OPC_MULTU    = 0x19 | OPC_SPECIAL,
158     OPC_DIV      = 0x1A | OPC_SPECIAL,
159     OPC_DIVU     = 0x1B | OPC_SPECIAL,
160     OPC_DMULT    = 0x1C | OPC_SPECIAL,
161     OPC_DMULTU   = 0x1D | OPC_SPECIAL,
162     OPC_DDIV     = 0x1E | OPC_SPECIAL,
163     OPC_DDIVU    = 0x1F | OPC_SPECIAL,
164     /* 2 registers arithmetic / logic */
165     OPC_ADD      = 0x20 | OPC_SPECIAL,
166     OPC_ADDU     = 0x21 | OPC_SPECIAL,
167     OPC_SUB      = 0x22 | OPC_SPECIAL,
168     OPC_SUBU     = 0x23 | OPC_SPECIAL,
169     OPC_AND      = 0x24 | OPC_SPECIAL,
170     OPC_OR       = 0x25 | OPC_SPECIAL,
171     OPC_XOR      = 0x26 | OPC_SPECIAL,
172     OPC_NOR      = 0x27 | OPC_SPECIAL,
173     OPC_SLT      = 0x2A | OPC_SPECIAL,
174     OPC_SLTU     = 0x2B | OPC_SPECIAL,
175     OPC_DADD     = 0x2C | OPC_SPECIAL,
176     OPC_DADDU    = 0x2D | OPC_SPECIAL,
177     OPC_DSUB     = 0x2E | OPC_SPECIAL,
178     OPC_DSUBU    = 0x2F | OPC_SPECIAL,
179     /* Jumps */
180     OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
181     OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
182     /* Traps */
183     OPC_TGE      = 0x30 | OPC_SPECIAL,
184     OPC_TGEU     = 0x31 | OPC_SPECIAL,
185     OPC_TLT      = 0x32 | OPC_SPECIAL,
186     OPC_TLTU     = 0x33 | OPC_SPECIAL,
187     OPC_TEQ      = 0x34 | OPC_SPECIAL,
188     OPC_TNE      = 0x36 | OPC_SPECIAL,
189     /* HI / LO registers load & stores */
190     OPC_MFHI     = 0x10 | OPC_SPECIAL,
191     OPC_MTHI     = 0x11 | OPC_SPECIAL,
192     OPC_MFLO     = 0x12 | OPC_SPECIAL,
193     OPC_MTLO     = 0x13 | OPC_SPECIAL,
194     /* Conditional moves */
195     OPC_MOVZ     = 0x0A | OPC_SPECIAL,
196     OPC_MOVN     = 0x0B | OPC_SPECIAL,
197
198     OPC_MOVCI    = 0x01 | OPC_SPECIAL,
199
200     /* Special */
201     OPC_PMON     = 0x05 | OPC_SPECIAL, /* inofficial */
202     OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
203     OPC_BREAK    = 0x0D | OPC_SPECIAL,
204     OPC_SPIM     = 0x0E | OPC_SPECIAL, /* inofficial */
205     OPC_SYNC     = 0x0F | OPC_SPECIAL,
206
207     OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
208     OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
209     OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
210     OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
211     OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
212     OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
213     OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
214 };
215
216 /* REGIMM (rt field) opcodes */
217 #define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
218
219 enum {
220     OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
221     OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
222     OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
223     OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
224     OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
225     OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
226     OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
227     OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
228     OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
229     OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
230     OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
231     OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
232     OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
233     OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
234     OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
235 };
236
237 /* Special2 opcodes */
238 #define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
239
240 enum {
241     /* Multiply & xxx operations */
242     OPC_MADD     = 0x00 | OPC_SPECIAL2,
243     OPC_MADDU    = 0x01 | OPC_SPECIAL2,
244     OPC_MUL      = 0x02 | OPC_SPECIAL2,
245     OPC_MSUB     = 0x04 | OPC_SPECIAL2,
246     OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
247     /* Misc */
248     OPC_CLZ      = 0x20 | OPC_SPECIAL2,
249     OPC_CLO      = 0x21 | OPC_SPECIAL2,
250     OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
251     OPC_DCLO     = 0x25 | OPC_SPECIAL2,
252     /* Special */
253     OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
254 };
255
256 /* Special3 opcodes */
257 #define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
258
259 enum {
260     OPC_EXT      = 0x00 | OPC_SPECIAL3,
261     OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
262     OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
263     OPC_DEXT     = 0x03 | OPC_SPECIAL3,
264     OPC_INS      = 0x04 | OPC_SPECIAL3,
265     OPC_DINSM    = 0x05 | OPC_SPECIAL3,
266     OPC_DINSU    = 0x06 | OPC_SPECIAL3,
267     OPC_DINS     = 0x07 | OPC_SPECIAL3,
268     OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
269     OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
270     OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
271 };
272
273 /* BSHFL opcodes */
274 #define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
275
276 enum {
277     OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
278     OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
279     OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
280 };
281
282 /* DBSHFL opcodes */
283 #define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
284
285 enum {
286     OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
287     OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
288 };
289
290 /* Coprocessor 0 (rs field) */
291 #define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
292
293 enum {
294     OPC_MFC0     = (0x00 << 21) | OPC_CP0,
295     OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
296     OPC_MTC0     = (0x04 << 21) | OPC_CP0,
297     OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
298     OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
299     OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
300     OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
301     OPC_C0       = (0x10 << 21) | OPC_CP0,
302     OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
303     OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
304 };
305
306 /* MFMC0 opcodes */
307 #define MASK_MFMC0(op)     MASK_CP0(op) | (op & ((0x0C << 11) | (1 << 5)))
308
309 enum {
310     OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
311     OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
312 };
313
314 /* Coprocessor 0 (with rs == C0) */
315 #define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
316
317 enum {
318     OPC_TLBR     = 0x01 | OPC_C0,
319     OPC_TLBWI    = 0x02 | OPC_C0,
320     OPC_TLBWR    = 0x06 | OPC_C0,
321     OPC_TLBP     = 0x08 | OPC_C0,
322     OPC_RFE      = 0x10 | OPC_C0,
323     OPC_ERET     = 0x18 | OPC_C0,
324     OPC_DERET    = 0x1F | OPC_C0,
325     OPC_WAIT     = 0x20 | OPC_C0,
326 };
327
328 /* Coprocessor 1 (rs field) */
329 #define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
330
331 enum {
332     OPC_MFC1     = (0x00 << 21) | OPC_CP1,
333     OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
334     OPC_CFC1     = (0x02 << 21) | OPC_CP1,
335     OPC_MFHCI    = (0x03 << 21) | OPC_CP1,
336     OPC_MTC1     = (0x04 << 21) | OPC_CP1,
337     OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
338     OPC_CTC1     = (0x06 << 21) | OPC_CP1,
339     OPC_MTHCI    = (0x07 << 21) | OPC_CP1,
340     OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
341     OPC_S_FMT    = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */
342     OPC_D_FMT    = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */
343     OPC_E_FMT    = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */
344     OPC_Q_FMT    = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */
345     OPC_W_FMT    = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */
346     OPC_L_FMT    = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */
347 };
348
349 enum {
350     OPC_BC1F     = (0x00 << 16) | OPC_BC1,
351     OPC_BC1T     = (0x01 << 16) | OPC_BC1,
352     OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
353     OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
354 };
355
356 #define MASK_CP1_BCOND(op)      MASK_CP1(op) | (op & (0x3 << 16))
357 #define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
358
359 #define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
360 #define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
361
362 const unsigned char *regnames[] =
363     { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
364       "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
365       "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
366       "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
367
368 /* Warning: no function for r0 register (hard wired to zero) */
369 #define GEN32(func, NAME) \
370 static GenOpFunc *NAME ## _table [32] = {                                     \
371 NULL,       NAME ## 1, NAME ## 2, NAME ## 3,                                  \
372 NAME ## 4,  NAME ## 5, NAME ## 6, NAME ## 7,                                  \
373 NAME ## 8,  NAME ## 9, NAME ## 10, NAME ## 11,                                \
374 NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
375 NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
376 NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
377 NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
378 NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
379 };                                                                            \
380 static inline void func(int n)                                                \
381 {                                                                             \
382     NAME ## _table[n]();                                                      \
383 }
384
385 /* General purpose registers moves */
386 GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
387 GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
388 GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
389
390 GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
391 GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
392
393 static const char *fregnames[] =
394     { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
395       "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
396       "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
397       "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
398
399 # define SFGEN32(func, NAME) \
400 static GenOpFunc *NAME ## _table [32] = {                                     \
401 NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,                                \
402 NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,                                \
403 NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,                               \
404 NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,                               \
405 NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,                               \
406 NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,                               \
407 NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,                               \
408 NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,                               \
409 };                                                                            \
410 static inline void func(int n)                                                \
411 {                                                                             \
412     NAME ## _table[n]();                                                      \
413 }
414
415 # define DFGEN32(func, NAME) \
416 static GenOpFunc *NAME ## _table [32] = {                                     \
417 NAME ## 0,  0, NAME ## 2,  0,                                                 \
418 NAME ## 4,  0, NAME ## 6,  0,                                                 \
419 NAME ## 8,  0, NAME ## 10, 0,                                                 \
420 NAME ## 12, 0, NAME ## 14, 0,                                                 \
421 NAME ## 16, 0, NAME ## 18, 0,                                                 \
422 NAME ## 20, 0, NAME ## 22, 0,                                                 \
423 NAME ## 24, 0, NAME ## 26, 0,                                                 \
424 NAME ## 28, 0, NAME ## 30, 0,                                                 \
425 };                                                                            \
426 static inline void func(int n)                                                \
427 {                                                                             \
428     NAME ## _table[n]();                                                      \
429 }
430
431 SFGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
432 SFGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
433
434 SFGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
435 SFGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
436
437 SFGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
438 SFGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
439
440 DFGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
441 DFGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
442
443 DFGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
444 DFGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
445
446 DFGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
447 DFGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
448
449 #define FOP_CONDS(fmt) \
450 static GenOpFunc * cond_ ## fmt ## _table[16] = {                       \
451     gen_op_cmp_ ## fmt ## _f,                                           \
452     gen_op_cmp_ ## fmt ## _un,                                          \
453     gen_op_cmp_ ## fmt ## _eq,                                          \
454     gen_op_cmp_ ## fmt ## _ueq,                                         \
455     gen_op_cmp_ ## fmt ## _olt,                                         \
456     gen_op_cmp_ ## fmt ## _ult,                                         \
457     gen_op_cmp_ ## fmt ## _ole,                                         \
458     gen_op_cmp_ ## fmt ## _ule,                                         \
459     gen_op_cmp_ ## fmt ## _sf,                                          \
460     gen_op_cmp_ ## fmt ## _ngle,                                        \
461     gen_op_cmp_ ## fmt ## _seq,                                         \
462     gen_op_cmp_ ## fmt ## _ngl,                                         \
463     gen_op_cmp_ ## fmt ## _lt,                                          \
464     gen_op_cmp_ ## fmt ## _nge,                                         \
465     gen_op_cmp_ ## fmt ## _le,                                          \
466     gen_op_cmp_ ## fmt ## _ngt,                                         \
467 };                                                                      \
468 static inline void gen_cmp_ ## fmt(int n)                               \
469 {                                                                       \
470     cond_ ## fmt ## _table[n]();                                        \
471 }
472
473 FOP_CONDS(d)
474 FOP_CONDS(s)
475
476 typedef struct DisasContext {
477     struct TranslationBlock *tb;
478     target_ulong pc, saved_pc;
479     uint32_t opcode;
480     /* Routine used to access memory */
481     int mem_idx;
482     uint32_t hflags, saved_hflags;
483     uint32_t CP0_Status;
484     int bstate;
485     target_ulong btarget;
486 } DisasContext;
487
488 enum {
489     BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
490                       * exception condition
491                       */
492     BS_STOP     = 1, /* We want to stop translation for any reason */
493     BS_BRANCH   = 2, /* We reached a branch condition     */
494     BS_EXCP     = 3, /* We reached an exception condition */
495 };
496
497 #if defined MIPS_DEBUG_DISAS
498 #define MIPS_DEBUG(fmt, args...)                                              \
499 do {                                                                          \
500     if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
501         fprintf(logfile, "%08x: %08x " fmt "\n",                              \
502                 ctx->pc, ctx->opcode , ##args);                               \
503     }                                                                         \
504 } while (0)
505 #else
506 #define MIPS_DEBUG(fmt, args...) do { } while(0)
507 #endif
508
509 #define MIPS_INVAL(op)                                                        \
510 do {                                                                          \
511     MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
512                ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
513 } while (0)
514
515 #define GEN_LOAD_REG_TN(Tn, Rn)                                               \
516 do {                                                                          \
517     if (Rn == 0) {                                                            \
518         glue(gen_op_reset_, Tn)();                                            \
519     } else {                                                                  \
520         glue(gen_op_load_gpr_, Tn)(Rn);                                       \
521     }                                                                         \
522 } while (0)
523
524 #define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
525 do {                                                                          \
526     if (Imm == 0) {                                                           \
527         glue(gen_op_reset_, Tn)();                                            \
528     } else {                                                                  \
529         glue(gen_op_set_, Tn)(Imm);                                           \
530     }                                                                         \
531 } while (0)
532
533 #define GEN_STORE_TN_REG(Rn, Tn)                                              \
534 do {                                                                          \
535     if (Rn != 0) {                                                            \
536         glue(glue(gen_op_store_, Tn),_gpr)(Rn);                               \
537     }                                                                         \
538 } while (0)
539
540 #define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
541 do {                                                                          \
542     glue(gen_op_load_fpr_, FTn)(Fn);                                          \
543 } while (0)
544
545 #define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
546 do {                                                                          \
547     glue(gen_op_store_fpr_, FTn)(Fn);                                         \
548 } while (0)
549
550 static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
551 {
552 #if defined MIPS_DEBUG_DISAS
553     if (loglevel & CPU_LOG_TB_IN_ASM) {
554             fprintf(logfile, "hflags %08x saved %08x\n",
555                     ctx->hflags, ctx->saved_hflags);
556     }
557 #endif
558     if (do_save_pc && ctx->pc != ctx->saved_pc) {
559         gen_op_save_pc(ctx->pc);
560         ctx->saved_pc = ctx->pc;
561     }
562     if (ctx->hflags != ctx->saved_hflags) {
563         gen_op_save_state(ctx->hflags);
564         ctx->saved_hflags = ctx->hflags;
565         if (ctx->hflags & MIPS_HFLAG_BR) {
566             gen_op_save_breg_target();
567         } else if (ctx->hflags & MIPS_HFLAG_B) {
568             gen_op_save_btarget(ctx->btarget);
569         } else if (ctx->hflags & MIPS_HFLAG_BMASK) {
570             gen_op_save_bcond();
571             gen_op_save_btarget(ctx->btarget);
572         }
573     }
574 }
575
576 static inline void generate_exception_err (DisasContext *ctx, int excp, int err)
577 {
578 #if defined MIPS_DEBUG_DISAS
579     if (loglevel & CPU_LOG_TB_IN_ASM)
580             fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
581 #endif
582     save_cpu_state(ctx, 1);
583     if (err == 0)
584         gen_op_raise_exception(excp);
585     else
586         gen_op_raise_exception_err(excp, err);
587     ctx->bstate = BS_EXCP;
588 }
589
590 static inline void generate_exception (DisasContext *ctx, int excp)
591 {
592     generate_exception_err (ctx, excp, 0);
593 }
594
595 #if defined(CONFIG_USER_ONLY)
596 #define op_ldst(name)        gen_op_##name##_raw()
597 #define OP_LD_TABLE(width)
598 #define OP_ST_TABLE(width)
599 #else
600 #define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
601 #define OP_LD_TABLE(width)                                                    \
602 static GenOpFunc *gen_op_l##width[] = {                                       \
603     &gen_op_l##width##_user,                                                  \
604     &gen_op_l##width##_kernel,                                                \
605 }
606 #define OP_ST_TABLE(width)                                                    \
607 static GenOpFunc *gen_op_s##width[] = {                                       \
608     &gen_op_s##width##_user,                                                  \
609     &gen_op_s##width##_kernel,                                                \
610 }
611 #endif
612
613 #ifdef MIPS_HAS_MIPS64
614 OP_LD_TABLE(d);
615 OP_LD_TABLE(dl);
616 OP_LD_TABLE(dr);
617 OP_ST_TABLE(d);
618 OP_ST_TABLE(dl);
619 OP_ST_TABLE(dr);
620 #endif
621 OP_LD_TABLE(w);
622 OP_LD_TABLE(wu);
623 OP_LD_TABLE(wl);
624 OP_LD_TABLE(wr);
625 OP_ST_TABLE(w);
626 OP_ST_TABLE(wl);
627 OP_ST_TABLE(wr);
628 OP_LD_TABLE(h);
629 OP_LD_TABLE(hu);
630 OP_ST_TABLE(h);
631 OP_LD_TABLE(b);
632 OP_LD_TABLE(bu);
633 OP_ST_TABLE(b);
634 OP_LD_TABLE(l);
635 OP_ST_TABLE(c);
636 OP_LD_TABLE(wc1);
637 OP_ST_TABLE(wc1);
638 OP_LD_TABLE(dc1);
639 OP_ST_TABLE(dc1);
640
641 /* Load and store */
642 static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
643                       int base, int16_t offset)
644 {
645     const char *opn = "unk";
646
647     if (base == 0) {
648         GEN_LOAD_IMM_TN(T0, offset);
649     } else if (offset == 0) {
650         gen_op_load_gpr_T0(base);
651     } else {
652         gen_op_load_gpr_T0(base);
653         gen_op_set_T1(offset);
654         gen_op_add();
655     }
656     /* Don't do NOP if destination is zero: we must perform the actual
657      * memory access
658      */
659     switch (opc) {
660 #ifdef MIPS_HAS_MIPS64
661     case OPC_LD:
662         op_ldst(ld);
663         GEN_STORE_TN_REG(rt, T0);
664         opn = "ld";
665         break;
666     case OPC_LLD:
667         op_ldst(lld);
668         GEN_STORE_TN_REG(rt, T0);
669         opn = "lld";
670         break;
671     case OPC_SD:
672         GEN_LOAD_REG_TN(T1, rt);
673         op_ldst(sd);
674         opn = "sd";
675         break;
676     case OPC_SCD:
677         GEN_LOAD_REG_TN(T1, rt);
678         op_ldst(scd);
679         opn = "scd";
680         break;
681     case OPC_LDL:
682         op_ldst(ldl);
683         GEN_STORE_TN_REG(rt, T0);
684         opn = "ldl";
685         break;
686     case OPC_SDL:
687         GEN_LOAD_REG_TN(T1, rt);
688         op_ldst(sdl);
689         opn = "sdl";
690         break;
691     case OPC_LDR:
692         op_ldst(ldr);
693         GEN_STORE_TN_REG(rt, T0);
694         opn = "ldr";
695         break;
696     case OPC_SDR:
697         GEN_LOAD_REG_TN(T1, rt);
698         op_ldst(sdr);
699         opn = "sdr";
700         break;
701 #endif
702     case OPC_LW:
703         op_ldst(lw);
704         GEN_STORE_TN_REG(rt, T0);
705         opn = "lw";
706         break;
707     case OPC_LWU:
708         op_ldst(lwu);
709         GEN_STORE_TN_REG(rt, T0);
710         opn = "lwu";
711         break;
712     case OPC_SW:
713         GEN_LOAD_REG_TN(T1, rt);
714         op_ldst(sw);
715         opn = "sw";
716         break;
717     case OPC_LH:
718         op_ldst(lh);
719         GEN_STORE_TN_REG(rt, T0);
720         opn = "lh";
721         break;
722     case OPC_SH:
723         GEN_LOAD_REG_TN(T1, rt);
724         op_ldst(sh);
725         opn = "sh";
726         break;
727     case OPC_LHU:
728         op_ldst(lhu);
729         GEN_STORE_TN_REG(rt, T0);
730         opn = "lhu";
731         break;
732     case OPC_LB:
733         op_ldst(lb);
734         GEN_STORE_TN_REG(rt, T0);
735         opn = "lb";
736         break;
737     case OPC_SB:
738         GEN_LOAD_REG_TN(T1, rt);
739         op_ldst(sb);
740         opn = "sb";
741         break;
742     case OPC_LBU:
743         op_ldst(lbu);
744         GEN_STORE_TN_REG(rt, T0);
745         opn = "lbu";
746         break;
747     case OPC_LWL:
748         GEN_LOAD_REG_TN(T1, rt);
749         op_ldst(lwl);
750         GEN_STORE_TN_REG(rt, T0);
751         opn = "lwl";
752         break;
753     case OPC_SWL:
754         GEN_LOAD_REG_TN(T1, rt);
755         op_ldst(swl);
756         opn = "swr";
757         break;
758     case OPC_LWR:
759         GEN_LOAD_REG_TN(T1, rt);
760         op_ldst(lwr);
761         GEN_STORE_TN_REG(rt, T0);
762         opn = "lwr";
763         break;
764     case OPC_SWR:
765         GEN_LOAD_REG_TN(T1, rt);
766         op_ldst(swr);
767         opn = "swr";
768         break;
769     case OPC_LL:
770         op_ldst(ll);
771         GEN_STORE_TN_REG(rt, T0);
772         opn = "ll";
773         break;
774     case OPC_SC:
775         GEN_LOAD_REG_TN(T1, rt);
776         op_ldst(sc);
777         GEN_STORE_TN_REG(rt, T0);
778         opn = "sc";
779         break;
780     default:
781         MIPS_INVAL("load/store");
782         generate_exception(ctx, EXCP_RI);
783         return;
784     }
785     MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
786 }
787
788 /* Load and store */
789 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
790                       int base, int16_t offset)
791 {
792     const char *opn = "unk";
793
794     if (base == 0) {
795         GEN_LOAD_IMM_TN(T0, offset);
796     } else if (offset == 0) {
797         gen_op_load_gpr_T0(base);
798     } else {
799         gen_op_load_gpr_T0(base);
800         gen_op_set_T1(offset);
801         gen_op_add();
802     }
803     /* Don't do NOP if destination is zero: we must perform the actual
804      * memory access
805      */
806     switch (opc) {
807     case OPC_LWC1:
808         op_ldst(lwc1);
809         GEN_STORE_FTN_FREG(ft, WT0);
810         opn = "lwc1";
811         break;
812     case OPC_SWC1:
813         GEN_LOAD_FREG_FTN(WT0, ft);
814         op_ldst(swc1);
815         opn = "swc1";
816         break;
817     case OPC_LDC1:
818         op_ldst(ldc1);
819         GEN_STORE_FTN_FREG(ft, DT0);
820         opn = "ldc1";
821         break;
822     case OPC_SDC1:
823         GEN_LOAD_FREG_FTN(DT0, ft);
824         op_ldst(sdc1);
825         opn = "sdc1";
826         break;
827     default:
828         MIPS_INVAL("float load/store");
829         generate_exception_err(ctx, EXCP_CpU, 1);
830         return;
831     }
832     MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
833 }
834
835 /* Arithmetic with immediate operand */
836 static void gen_arith_imm (DisasContext *ctx, uint32_t opc, int rt,
837                            int rs, int16_t imm)
838 {
839     uint32_t uimm;
840     const char *opn = "unk";
841
842     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
843         /* if no destination, treat it as a NOP 
844          * For addi, we must generate the overflow exception when needed.
845          */
846         MIPS_DEBUG("NOP");
847         return;
848     }
849     if (opc == OPC_ADDI || opc == OPC_ADDIU ||
850         opc == OPC_DADDI || opc == OPC_DADDIU ||
851         opc == OPC_SLTI || opc == OPC_SLTIU)
852         uimm = (int32_t)imm; /* Sign extend to 32 bits */
853     else
854         uimm = (uint16_t)imm;
855     if (opc != OPC_LUI) {
856         GEN_LOAD_REG_TN(T0, rs);
857         GEN_LOAD_IMM_TN(T1, uimm);
858     } else {
859         uimm = uimm << 16;
860         GEN_LOAD_IMM_TN(T0, uimm);
861     }
862     switch (opc) {
863     case OPC_ADDI:
864         save_cpu_state(ctx, 1);
865         gen_op_addo();
866         opn = "addi";
867         break;
868     case OPC_ADDIU:
869         gen_op_add();
870         opn = "addiu";
871         break;
872 #ifdef MIPS_HAS_MIPS64
873     case OPC_DADDI:
874         save_cpu_state(ctx, 1);
875         gen_op_daddo();
876         opn = "daddi";
877         break;
878     case OPC_DADDIU:
879         gen_op_dadd();
880         opn = "daddiu";
881         break;
882 #endif
883     case OPC_SLTI:
884         gen_op_lt();
885         opn = "slti";
886         break;
887     case OPC_SLTIU:
888         gen_op_ltu();
889         opn = "sltiu";
890         break;
891     case OPC_ANDI:
892         gen_op_and();
893         opn = "andi";
894         break;
895     case OPC_ORI:
896         gen_op_or();
897         opn = "ori";
898         break;
899     case OPC_XORI:
900         gen_op_xor();
901         opn = "xori";
902         break;
903     case OPC_LUI:
904         opn = "lui";
905         break;
906     case OPC_SLL:
907         gen_op_sll();
908         opn = "sll";
909         break;
910     case OPC_SRA:
911         gen_op_sra();
912         opn = "sra";
913         break;
914     case OPC_SRL:
915        if ((ctx->opcode >> 21) & 1) {
916             gen_op_rotr();
917             opn = "rotr";
918        } else {
919             gen_op_srl();
920             opn = "srl";
921        }
922         break;
923 #ifdef MIPS_HAS_MIPS64
924     case OPC_DSLL:
925         gen_op_dsll();
926         opn = "dsll";
927         break;
928     case OPC_DSRA:
929         gen_op_dsra();
930         opn = "dsra";
931         break;
932     case OPC_DSRL:
933        if ((ctx->opcode >> 21) & 1) {
934             gen_op_drotr();
935             opn = "drotr";
936        } else {
937             gen_op_dsrl();
938             opn = "dsrl";
939        }
940         break;
941     case OPC_DSLL32:
942         gen_op_dsll32();
943         opn = "dsll32";
944         break;
945     case OPC_DSRA32:
946         gen_op_dsra32();
947         opn = "dsra32";
948         break;
949     case OPC_DSRL32:
950        if ((ctx->opcode >> 21) & 1) {
951             gen_op_drotr32();
952             opn = "drotr32";
953        } else {
954             gen_op_dsrl32();
955             opn = "dsrl32";
956        }
957         break;
958 #endif
959     default:
960         MIPS_INVAL("imm arith");
961         generate_exception(ctx, EXCP_RI);
962         return;
963     }
964     GEN_STORE_TN_REG(rt, T0);
965     MIPS_DEBUG("%s %s, %s, %x", opn, regnames[rt], regnames[rs], uimm);
966 }
967
968 /* Arithmetic */
969 static void gen_arith (DisasContext *ctx, uint32_t opc,
970                        int rd, int rs, int rt)
971 {
972     const char *opn = "unk";
973
974     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
975        && opc != OPC_DADD && opc != OPC_DSUB) {
976         /* if no destination, treat it as a NOP 
977          * For add & sub, we must generate the overflow exception when needed.
978          */
979         MIPS_DEBUG("NOP");
980         return;
981     }
982     GEN_LOAD_REG_TN(T0, rs);
983     GEN_LOAD_REG_TN(T1, rt);
984     switch (opc) {
985     case OPC_ADD:
986         save_cpu_state(ctx, 1);
987         gen_op_addo();
988         opn = "add";
989         break;
990     case OPC_ADDU:
991         gen_op_add();
992         opn = "addu";
993         break;
994     case OPC_SUB:
995         save_cpu_state(ctx, 1);
996         gen_op_subo();
997         opn = "sub";
998         break;
999     case OPC_SUBU:
1000         gen_op_sub();
1001         opn = "subu";
1002         break;
1003 #ifdef MIPS_HAS_MIPS64
1004     case OPC_DADD:
1005         save_cpu_state(ctx, 1);
1006         gen_op_daddo();
1007         opn = "dadd";
1008         break;
1009     case OPC_DADDU:
1010         gen_op_dadd();
1011         opn = "daddu";
1012         break;
1013     case OPC_DSUB:
1014         save_cpu_state(ctx, 1);
1015         gen_op_dsubo();
1016         opn = "dsub";
1017         break;
1018     case OPC_DSUBU:
1019         gen_op_dsub();
1020         opn = "dsubu";
1021         break;
1022 #endif
1023     case OPC_SLT:
1024         gen_op_lt();
1025         opn = "slt";
1026         break;
1027     case OPC_SLTU:
1028         gen_op_ltu();
1029         opn = "sltu";
1030         break;
1031     case OPC_AND:
1032         gen_op_and();
1033         opn = "and";
1034         break;
1035     case OPC_NOR:
1036         gen_op_nor();
1037         opn = "nor";
1038         break;
1039     case OPC_OR:
1040         gen_op_or();
1041         opn = "or";
1042         break;
1043     case OPC_XOR:
1044         gen_op_xor();
1045         opn = "xor";
1046         break;
1047     case OPC_MUL:
1048         gen_op_mul();
1049         opn = "mul";
1050         break;
1051     case OPC_MOVN:
1052         gen_op_movn(rd);
1053         opn = "movn";
1054         goto print;
1055     case OPC_MOVZ:
1056         gen_op_movz(rd);
1057         opn = "movz";
1058         goto print;
1059     case OPC_SLLV:
1060         gen_op_sllv();
1061         opn = "sllv";
1062         break;
1063     case OPC_SRAV:
1064         gen_op_srav();
1065         opn = "srav";
1066         break;
1067     case OPC_SRLV:
1068        if ((ctx->opcode >> 6) & 1) {
1069             gen_op_rotrv();
1070             opn = "rotrv";
1071        } else {
1072             gen_op_srlv();
1073             opn = "srlv";
1074        }
1075         break;
1076 #ifdef MIPS_HAS_MIPS64
1077     case OPC_DSLLV:
1078         gen_op_dsllv();
1079         opn = "dsllv";
1080         break;
1081     case OPC_DSRAV:
1082         gen_op_dsrav();
1083         opn = "dsrav";
1084         break;
1085     case OPC_DSRLV:
1086        if ((ctx->opcode >> 6) & 1) {
1087             gen_op_drotrv();
1088             opn = "drotrv";
1089        } else {
1090             gen_op_dsrlv();
1091             opn = "dsrlv";
1092        }
1093         break;
1094 #endif
1095     default:
1096         MIPS_INVAL("arith");
1097         generate_exception(ctx, EXCP_RI);
1098         return;
1099     }
1100     GEN_STORE_TN_REG(rd, T0);
1101  print:
1102     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1103 }
1104
1105 /* Arithmetic on HI/LO registers */
1106 static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1107 {
1108     const char *opn = "unk";
1109
1110     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1111         /* Treat as a NOP */
1112         MIPS_DEBUG("NOP");
1113         return;
1114     }
1115     switch (opc) {
1116     case OPC_MFHI:
1117         gen_op_load_HI();
1118         GEN_STORE_TN_REG(reg, T0);
1119         opn = "mfhi";
1120         break;
1121     case OPC_MFLO:
1122         gen_op_load_LO();
1123         GEN_STORE_TN_REG(reg, T0);
1124         opn = "mflo";
1125         break;
1126     case OPC_MTHI:
1127         GEN_LOAD_REG_TN(T0, reg);
1128         gen_op_store_HI();
1129         opn = "mthi";
1130         break;
1131     case OPC_MTLO:
1132         GEN_LOAD_REG_TN(T0, reg);
1133         gen_op_store_LO();
1134         opn = "mtlo";
1135         break;
1136     default:
1137         MIPS_INVAL("HILO");
1138         generate_exception(ctx, EXCP_RI);
1139         return;
1140     }
1141     MIPS_DEBUG("%s %s", opn, regnames[reg]);
1142 }
1143
1144 static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1145                         int rs, int rt)
1146 {
1147     const char *opn = "unk";
1148
1149     GEN_LOAD_REG_TN(T0, rs);
1150     GEN_LOAD_REG_TN(T1, rt);
1151     switch (opc) {
1152     case OPC_DIV:
1153         gen_op_div();
1154         opn = "div";
1155         break;
1156     case OPC_DIVU:
1157         gen_op_divu();
1158         opn = "divu";
1159         break;
1160     case OPC_MULT:
1161         gen_op_mult();
1162         opn = "mult";
1163         break;
1164     case OPC_MULTU:
1165         gen_op_multu();
1166         opn = "multu";
1167         break;
1168 #ifdef MIPS_HAS_MIPS64
1169     case OPC_DDIV:
1170         gen_op_ddiv();
1171         opn = "ddiv";
1172         break;
1173     case OPC_DDIVU:
1174         gen_op_ddivu();
1175         opn = "ddivu";
1176         break;
1177     case OPC_DMULT:
1178         gen_op_dmult();
1179         opn = "dmult";
1180         break;
1181     case OPC_DMULTU:
1182         gen_op_dmultu();
1183         opn = "dmultu";
1184         break;
1185 #endif
1186     case OPC_MADD:
1187         gen_op_madd();
1188         opn = "madd";
1189         break;
1190     case OPC_MADDU:
1191         gen_op_maddu();
1192         opn = "maddu";
1193         break;
1194     case OPC_MSUB:
1195         gen_op_msub();
1196         opn = "msub";
1197         break;
1198     case OPC_MSUBU:
1199         gen_op_msubu();
1200         opn = "msubu";
1201         break;
1202     default:
1203         MIPS_INVAL("mul/div");
1204         generate_exception(ctx, EXCP_RI);
1205         return;
1206     }
1207     MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1208 }
1209
1210 static void gen_cl (DisasContext *ctx, uint32_t opc,
1211                     int rd, int rs)
1212 {
1213     const char *opn = "unk";
1214     if (rd == 0) {
1215         /* Treat as a NOP */
1216         MIPS_DEBUG("NOP");
1217         return;
1218     }
1219     GEN_LOAD_REG_TN(T0, rs);
1220     switch (opc) {
1221     case OPC_CLO:
1222         gen_op_clo();
1223         opn = "clo";
1224         break;
1225     case OPC_CLZ:
1226         gen_op_clz();
1227         opn = "clz";
1228         break;
1229 #ifdef MIPS_HAS_MIPS64
1230     case OPC_DCLO:
1231         gen_op_dclo();
1232         opn = "dclo";
1233         break;
1234     case OPC_DCLZ:
1235         gen_op_dclz();
1236         opn = "dclz";
1237         break;
1238 #endif
1239     default:
1240         MIPS_INVAL("CLx");
1241         generate_exception(ctx, EXCP_RI);
1242         return;
1243     }
1244     gen_op_store_T0_gpr(rd);
1245     MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1246 }
1247
1248 /* Traps */
1249 static void gen_trap (DisasContext *ctx, uint32_t opc,
1250                       int rs, int rt, int16_t imm)
1251 {
1252     int cond;
1253
1254     cond = 0;
1255     /* Load needed operands */
1256     switch (opc) {
1257     case OPC_TEQ:
1258     case OPC_TGE:
1259     case OPC_TGEU:
1260     case OPC_TLT:
1261     case OPC_TLTU:
1262     case OPC_TNE:
1263         /* Compare two registers */
1264         if (rs != rt) {
1265             GEN_LOAD_REG_TN(T0, rs);
1266             GEN_LOAD_REG_TN(T1, rt);
1267             cond = 1;
1268         }
1269     case OPC_TEQI:
1270     case OPC_TGEI:
1271     case OPC_TGEIU:
1272     case OPC_TLTI:
1273     case OPC_TLTIU:
1274     case OPC_TNEI:
1275         /* Compare register to immediate */
1276         if (rs != 0 || imm != 0) {
1277             GEN_LOAD_REG_TN(T0, rs);
1278             GEN_LOAD_IMM_TN(T1, (int32_t)imm);
1279             cond = 1;
1280         }
1281         break;
1282     }
1283     if (cond == 0) {
1284         switch (opc) {
1285         case OPC_TEQ:   /* rs == rs */
1286         case OPC_TEQI:  /* r0 == 0  */
1287         case OPC_TGE:   /* rs >= rs */
1288         case OPC_TGEI:  /* r0 >= 0  */
1289         case OPC_TGEU:  /* rs >= rs unsigned */
1290         case OPC_TGEIU: /* r0 >= 0  unsigned */
1291             /* Always trap */
1292             gen_op_set_T0(1);
1293             break;
1294         case OPC_TLT:   /* rs < rs           */
1295         case OPC_TLTI:  /* r0 < 0            */
1296         case OPC_TLTU:  /* rs < rs unsigned  */
1297         case OPC_TLTIU: /* r0 < 0  unsigned  */
1298         case OPC_TNE:   /* rs != rs          */
1299         case OPC_TNEI:  /* r0 != 0           */
1300             /* Never trap: treat as NOP */
1301             return;
1302         default:
1303             MIPS_INVAL("TRAP");
1304             generate_exception(ctx, EXCP_RI);
1305             return;
1306         }
1307     } else {
1308         switch (opc) {
1309         case OPC_TEQ:
1310         case OPC_TEQI:
1311             gen_op_eq();
1312             break;
1313         case OPC_TGE:
1314         case OPC_TGEI:
1315             gen_op_ge();
1316             break;
1317         case OPC_TGEU:
1318         case OPC_TGEIU:
1319             gen_op_geu();
1320             break;
1321         case OPC_TLT:
1322         case OPC_TLTI:
1323             gen_op_lt();
1324             break;
1325         case OPC_TLTU:
1326         case OPC_TLTIU:
1327             gen_op_ltu();
1328             break;
1329         case OPC_TNE:
1330         case OPC_TNEI:
1331             gen_op_ne();
1332             break;
1333         default:
1334             MIPS_INVAL("TRAP");
1335             generate_exception(ctx, EXCP_RI);
1336             return;
1337         }
1338     }
1339     save_cpu_state(ctx, 1);
1340     gen_op_trap();
1341     ctx->bstate = BS_STOP;
1342 }
1343
1344 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1345 {
1346     TranslationBlock *tb;
1347     tb = ctx->tb;
1348     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1349         if (n == 0)
1350             gen_op_goto_tb0(TBPARAM(tb));
1351         else
1352             gen_op_goto_tb1(TBPARAM(tb));
1353         gen_op_save_pc(dest);
1354         gen_op_set_T0((long)tb + n);
1355         gen_op_exit_tb();
1356     } else {
1357         gen_op_save_pc(dest);
1358         gen_op_set_T0(0);
1359         gen_op_exit_tb();
1360     }
1361 }
1362
1363 /* Branches (before delay slot) */
1364 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1365                                 int rs, int rt, int32_t offset)
1366 {
1367     target_ulong btarget;
1368     int blink, bcond;
1369
1370     btarget = -1;
1371     blink = 0;
1372     bcond = 0;
1373     /* Load needed operands */
1374     switch (opc) {
1375     case OPC_BEQ:
1376     case OPC_BEQL:
1377     case OPC_BNE:
1378     case OPC_BNEL:
1379         /* Compare two registers */
1380         if (rs != rt) {
1381             GEN_LOAD_REG_TN(T0, rs);
1382             GEN_LOAD_REG_TN(T1, rt);
1383             bcond = 1;
1384         }
1385         btarget = ctx->pc + 4 + offset;
1386         break;
1387     case OPC_BGEZ:
1388     case OPC_BGEZAL:
1389     case OPC_BGEZALL:
1390     case OPC_BGEZL:
1391     case OPC_BGTZ:
1392     case OPC_BGTZL:
1393     case OPC_BLEZ:
1394     case OPC_BLEZL:
1395     case OPC_BLTZ:
1396     case OPC_BLTZAL:
1397     case OPC_BLTZALL:
1398     case OPC_BLTZL:
1399         /* Compare to zero */
1400         if (rs != 0) {
1401             gen_op_load_gpr_T0(rs);
1402             bcond = 1;
1403         }
1404         btarget = ctx->pc + 4 + offset;
1405         break;
1406     case OPC_J:
1407     case OPC_JAL:
1408         /* Jump to immediate */
1409         btarget = ((ctx->pc + 4) & 0xF0000000) | offset;
1410         break;
1411     case OPC_JR:
1412     case OPC_JALR:
1413         /* Jump to register */
1414         if (offset != 0 && offset != 16) {
1415             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1416               others are reserved. */
1417             generate_exception(ctx, EXCP_RI);
1418             return;
1419         }
1420         GEN_LOAD_REG_TN(T2, rs);
1421         break;
1422     default:
1423         MIPS_INVAL("branch/jump");
1424         generate_exception(ctx, EXCP_RI);
1425         return;
1426     }
1427     if (bcond == 0) {
1428         /* No condition to be computed */
1429         switch (opc) {
1430         case OPC_BEQ:     /* rx == rx        */
1431         case OPC_BEQL:    /* rx == rx likely */
1432         case OPC_BGEZ:    /* 0 >= 0          */
1433         case OPC_BGEZL:   /* 0 >= 0 likely   */
1434         case OPC_BLEZ:    /* 0 <= 0          */
1435         case OPC_BLEZL:   /* 0 <= 0 likely   */
1436             /* Always take */
1437             ctx->hflags |= MIPS_HFLAG_B;
1438             MIPS_DEBUG("balways");
1439             break;
1440         case OPC_BGEZAL:  /* 0 >= 0          */
1441         case OPC_BGEZALL: /* 0 >= 0 likely   */
1442             /* Always take and link */
1443             blink = 31;
1444             ctx->hflags |= MIPS_HFLAG_B;
1445             MIPS_DEBUG("balways and link");
1446             break;
1447         case OPC_BNE:     /* rx != rx        */
1448         case OPC_BGTZ:    /* 0 > 0           */
1449         case OPC_BLTZ:    /* 0 < 0           */
1450             /* Treated as NOP */
1451             MIPS_DEBUG("bnever (NOP)");
1452             return;
1453         case OPC_BLTZAL:  /* 0 < 0           */
1454             gen_op_set_T0(ctx->pc + 8);
1455             gen_op_store_T0_gpr(31);
1456             return;
1457         case OPC_BLTZALL: /* 0 < 0 likely */
1458             gen_op_set_T0(ctx->pc + 8);
1459             gen_op_store_T0_gpr(31);
1460             gen_goto_tb(ctx, 0, ctx->pc + 4);
1461             return;
1462         case OPC_BNEL:    /* rx != rx likely */
1463         case OPC_BGTZL:   /* 0 > 0 likely */
1464         case OPC_BLTZL:   /* 0 < 0 likely */
1465             /* Skip the instruction in the delay slot */
1466             MIPS_DEBUG("bnever and skip");
1467             gen_goto_tb(ctx, 0, ctx->pc + 4);
1468             return;
1469         case OPC_J:
1470             ctx->hflags |= MIPS_HFLAG_B;
1471             MIPS_DEBUG("j %08x", btarget);
1472             break;
1473         case OPC_JAL:
1474             blink = 31;
1475             ctx->hflags |= MIPS_HFLAG_B;
1476             MIPS_DEBUG("jal %08x", btarget);
1477             break;
1478         case OPC_JR:
1479             ctx->hflags |= MIPS_HFLAG_BR;
1480             MIPS_DEBUG("jr %s", regnames[rs]);
1481             break;
1482         case OPC_JALR:
1483             blink = rt;
1484             ctx->hflags |= MIPS_HFLAG_BR;
1485             MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
1486             break;
1487         default:
1488             MIPS_INVAL("branch/jump");
1489             generate_exception(ctx, EXCP_RI);
1490             return;
1491         }
1492     } else {
1493         switch (opc) {
1494         case OPC_BEQ:
1495             gen_op_eq();
1496             MIPS_DEBUG("beq %s, %s, %08x",
1497                        regnames[rs], regnames[rt], btarget);
1498             goto not_likely;
1499         case OPC_BEQL:
1500             gen_op_eq();
1501             MIPS_DEBUG("beql %s, %s, %08x",
1502                        regnames[rs], regnames[rt], btarget);
1503             goto likely;
1504         case OPC_BNE:
1505             gen_op_ne();
1506             MIPS_DEBUG("bne %s, %s, %08x",
1507                        regnames[rs], regnames[rt], btarget);
1508             goto not_likely;
1509         case OPC_BNEL:
1510             gen_op_ne();
1511             MIPS_DEBUG("bnel %s, %s, %08x",
1512                        regnames[rs], regnames[rt], btarget);
1513             goto likely;
1514         case OPC_BGEZ:
1515             gen_op_gez();
1516             MIPS_DEBUG("bgez %s, %08x", regnames[rs], btarget);
1517             goto not_likely;
1518         case OPC_BGEZL:
1519             gen_op_gez();
1520             MIPS_DEBUG("bgezl %s, %08x", regnames[rs], btarget);
1521             goto likely;
1522         case OPC_BGEZAL:
1523             gen_op_gez();
1524             MIPS_DEBUG("bgezal %s, %08x", regnames[rs], btarget);
1525             blink = 31;
1526             goto not_likely;
1527         case OPC_BGEZALL:
1528             gen_op_gez();
1529             blink = 31;
1530             MIPS_DEBUG("bgezall %s, %08x", regnames[rs], btarget);
1531             goto likely;
1532         case OPC_BGTZ:
1533             gen_op_gtz();
1534             MIPS_DEBUG("bgtz %s, %08x", regnames[rs], btarget);
1535             goto not_likely;
1536         case OPC_BGTZL:
1537             gen_op_gtz();
1538             MIPS_DEBUG("bgtzl %s, %08x", regnames[rs], btarget);
1539             goto likely;
1540         case OPC_BLEZ:
1541             gen_op_lez();
1542             MIPS_DEBUG("blez %s, %08x", regnames[rs], btarget);
1543             goto not_likely;
1544         case OPC_BLEZL:
1545             gen_op_lez();
1546             MIPS_DEBUG("blezl %s, %08x", regnames[rs], btarget);
1547             goto likely;
1548         case OPC_BLTZ:
1549             gen_op_ltz();
1550             MIPS_DEBUG("bltz %s, %08x", regnames[rs], btarget);
1551             goto not_likely;
1552         case OPC_BLTZL:
1553             gen_op_ltz();
1554             MIPS_DEBUG("bltzl %s, %08x", regnames[rs], btarget);
1555             goto likely;
1556         case OPC_BLTZAL:
1557             gen_op_ltz();
1558             blink = 31;
1559             MIPS_DEBUG("bltzal %s, %08x", regnames[rs], btarget);
1560         not_likely:
1561             ctx->hflags |= MIPS_HFLAG_BC;
1562             break;
1563         case OPC_BLTZALL:
1564             gen_op_ltz();
1565             blink = 31;
1566             MIPS_DEBUG("bltzall %s, %08x", regnames[rs], btarget);
1567         likely:
1568             ctx->hflags |= MIPS_HFLAG_BL;
1569             break;
1570         }
1571         gen_op_set_bcond();
1572     }
1573     MIPS_DEBUG("enter ds: link %d cond %02x target %08x",
1574                blink, ctx->hflags, btarget);
1575     ctx->btarget = btarget;
1576     if (blink > 0) {
1577         gen_op_set_T0(ctx->pc + 8);
1578         gen_op_store_T0_gpr(blink);
1579     }
1580     return;
1581 }
1582
1583 /* special3 bitfield operations */
1584 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1585                        int rs, int lsb, int msb)
1586 {
1587     GEN_LOAD_REG_TN(T1, rs);
1588     switch (opc) {
1589     case OPC_EXT:
1590         if (lsb + msb > 31)
1591             goto fail;
1592         gen_op_ext(lsb, msb + 1);
1593         break;
1594     case OPC_DEXTM:
1595         if (lsb + msb > 63)
1596             goto fail;
1597         gen_op_ext(lsb, msb + 1 + 32);
1598         break;
1599     case OPC_DEXTU:
1600         if (lsb + msb > 63)
1601             goto fail;
1602         gen_op_ext(lsb + 32, msb + 1);
1603         break;
1604     case OPC_DEXT:
1605         gen_op_ext(lsb, msb + 1);
1606         break;
1607     case OPC_INS:
1608         if (lsb > msb)
1609             goto fail;
1610         GEN_LOAD_REG_TN(T2, rt);
1611         gen_op_ins(lsb, msb - lsb + 1);
1612         break;
1613     case OPC_DINSM:
1614         if (lsb > msb)
1615             goto fail;
1616         GEN_LOAD_REG_TN(T2, rt);
1617         gen_op_ins(lsb, msb - lsb + 1 + 32);
1618         break;
1619     case OPC_DINSU:
1620         if (lsb > msb)
1621             goto fail;
1622         GEN_LOAD_REG_TN(T2, rt);
1623         gen_op_ins(lsb + 32, msb - lsb + 1);
1624         break;
1625     case OPC_DINS:
1626         if (lsb > msb)
1627             goto fail;
1628         GEN_LOAD_REG_TN(T2, rt);
1629         gen_op_ins(lsb, msb - lsb + 1);
1630         break;
1631     default:
1632 fail:
1633         MIPS_INVAL("bitops");
1634         generate_exception(ctx, EXCP_RI);
1635         return;
1636     }
1637     GEN_STORE_TN_REG(rt, T0);
1638 }
1639
1640 /* CP0 (MMU and control) */
1641 static void gen_mfc0 (DisasContext *ctx, int reg, int sel)
1642 {
1643     const char *rn = "invalid";
1644
1645     switch (reg) {
1646     case 0:
1647         switch (sel) {
1648         case 0:
1649            gen_op_mfc0_index();
1650             rn = "Index";
1651             break;
1652         case 1:
1653 //         gen_op_mfc0_mvpcontrol(); /* MT ASE */
1654             rn = "MVPControl";
1655 //         break;
1656         case 2:
1657 //         gen_op_mfc0_mvpconf0(); /* MT ASE */
1658             rn = "MVPConf0";
1659 //         break;
1660         case 3:
1661 //         gen_op_mfc0_mvpconf1(); /* MT ASE */
1662             rn = "MVPConf1";
1663 //         break;
1664         default:
1665             goto die;
1666         }
1667         break;
1668     case 1:
1669         switch (sel) {
1670         case 0:
1671             gen_op_mfc0_random();
1672             rn = "Random";
1673            break;
1674         case 1:
1675 //         gen_op_mfc0_vpecontrol(); /* MT ASE */
1676             rn = "VPEControl";
1677 //         break;
1678         case 2:
1679 //         gen_op_mfc0_vpeconf0(); /* MT ASE */
1680             rn = "VPEConf0";
1681 //         break;
1682         case 3:
1683 //         gen_op_mfc0_vpeconf1(); /* MT ASE */
1684             rn = "VPEConf1";
1685 //         break;
1686         case 4:
1687 //         gen_op_mfc0_YQMask(); /* MT ASE */
1688             rn = "YQMask";
1689 //         break;
1690         case 5:
1691 //         gen_op_mfc0_vpeschedule(); /* MT ASE */
1692             rn = "VPESchedule";
1693 //         break;
1694         case 6:
1695 //         gen_op_mfc0_vpeschefback(); /* MT ASE */
1696             rn = "VPEScheFBack";
1697 //         break;
1698         case 7:
1699 //         gen_op_mfc0_vpeopt(); /* MT ASE */
1700             rn = "VPEOpt";
1701 //         break;
1702         default:
1703             goto die;
1704         }
1705         break;
1706     case 2:
1707         switch (sel) {
1708         case 0:
1709            gen_op_mfc0_entrylo0();
1710            rn = "EntryLo0";
1711            break;
1712         case 1:
1713 //         gen_op_mfc0_tcstatus(); /* MT ASE */
1714            rn = "TCStatus";
1715 //         break;
1716         case 2:
1717 //         gen_op_mfc0_tcbind(); /* MT ASE */
1718            rn = "TCBind";
1719 //         break;
1720         case 3:
1721 //         gen_op_mfc0_tcrestart(); /* MT ASE */
1722            rn = "TCRestart";
1723 //         break;
1724         case 4:
1725 //         gen_op_mfc0_tchalt(); /* MT ASE */
1726            rn = "TCHalt";
1727 //         break;
1728         case 5:
1729 //         gen_op_mfc0_tccontext(); /* MT ASE */
1730            rn = "TCContext";
1731 //         break;
1732         case 6:
1733 //         gen_op_mfc0_tcschedule(); /* MT ASE */
1734            rn = "TCSchedule";
1735 //         break;
1736         case 7:
1737 //         gen_op_mfc0_tcschefback(); /* MT ASE */
1738            rn = "TCScheFBack";
1739 //         break;
1740         default:
1741             goto die;
1742         }
1743         break;
1744     case 3:
1745         switch (sel) {
1746         case 0:
1747            gen_op_mfc0_entrylo1();
1748            rn = "EntryLo1";
1749            break;
1750         default:
1751             goto die;
1752        }
1753         break;
1754     case 4:
1755         switch (sel) {
1756         case 0:
1757            gen_op_mfc0_context();
1758            rn = "Context";
1759            break;
1760         case 1:
1761 //         gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
1762            rn = "ContextConfig";
1763 //         break;
1764         default:
1765             goto die;
1766        }
1767         break;
1768     case 5:
1769         switch (sel) {
1770         case 0:
1771            gen_op_mfc0_pagemask();
1772            rn = "PageMask";
1773            break;
1774         case 1:
1775            gen_op_mfc0_pagegrain();
1776            rn = "PageGrain";
1777            break;
1778         default:
1779             goto die;
1780        }
1781         break;
1782     case 6:
1783         switch (sel) {
1784         case 0:
1785            gen_op_mfc0_wired();
1786            rn = "Wired";
1787            break;
1788         case 1:
1789 //         gen_op_mfc0_srsconf0(); /* shadow registers */
1790            rn = "SRSConf0";
1791 //         break;
1792         case 2:
1793 //         gen_op_mfc0_srsconf1(); /* shadow registers */
1794            rn = "SRSConf1";
1795 //         break;
1796         case 3:
1797 //         gen_op_mfc0_srsconf2(); /* shadow registers */
1798            rn = "SRSConf2";
1799 //         break;
1800         case 4:
1801 //         gen_op_mfc0_srsconf3(); /* shadow registers */
1802            rn = "SRSConf3";
1803 //         break;
1804         case 5:
1805 //         gen_op_mfc0_srsconf4(); /* shadow registers */
1806            rn = "SRSConf4";
1807 //         break;
1808         default:
1809             goto die;
1810        }
1811         break;
1812     case 7:
1813         switch (sel) {
1814         case 0:
1815            gen_op_mfc0_hwrena();
1816            rn = "HWREna";
1817            break;
1818         default:
1819             goto die;
1820        }
1821         break;
1822     case 8:
1823         switch (sel) {
1824         case 0:
1825            gen_op_mfc0_badvaddr();
1826            rn = "BadVaddr";
1827            break;
1828         default:
1829             goto die;
1830        }
1831         break;
1832     case 9:
1833         switch (sel) {
1834         case 0:
1835            gen_op_mfc0_count();
1836            rn = "Count";
1837            break;
1838        /* 6,7 are implementation dependent */
1839         default:
1840             goto die;
1841        }
1842         break;
1843     case 10:
1844         switch (sel) {
1845         case 0:
1846            gen_op_mfc0_entryhi();
1847            rn = "EntryHi";
1848            break;
1849         default:
1850             goto die;
1851        }
1852         break;
1853     case 11:
1854         switch (sel) {
1855         case 0:
1856            gen_op_mfc0_compare();
1857            rn = "Compare";
1858            break;
1859        /* 6,7 are implementation dependent */
1860         default:
1861             goto die;
1862        }
1863         break;
1864     case 12:
1865         switch (sel) {
1866         case 0:
1867            gen_op_mfc0_status();
1868            rn = "Status";
1869            break;
1870         case 1:
1871            gen_op_mfc0_intctl();
1872            rn = "IntCtl";
1873            break;
1874         case 2:
1875            gen_op_mfc0_srsctl();
1876            rn = "SRSCtl";
1877            break;
1878         case 3:
1879 //         gen_op_mfc0_srsmap(); /* shadow registers */
1880            rn = "SRSMap";
1881 //         break;
1882         default:
1883             goto die;
1884        }
1885         break;
1886     case 13:
1887         switch (sel) {
1888         case 0:
1889            gen_op_mfc0_cause();
1890            rn = "Cause";
1891            break;
1892         default:
1893             goto die;
1894        }
1895         break;
1896     case 14:
1897         switch (sel) {
1898         case 0:
1899            gen_op_mfc0_epc();
1900            rn = "EPC";
1901            break;
1902         default:
1903             goto die;
1904        }
1905         break;
1906     case 15:
1907         switch (sel) {
1908         case 0:
1909            gen_op_mfc0_prid();
1910            rn = "PRid";
1911            break;
1912         case 1:
1913            gen_op_mfc0_ebase();
1914            rn = "EBase";
1915            break;
1916         default:
1917             goto die;
1918        }
1919         break;
1920     case 16:
1921         switch (sel) {
1922         case 0:
1923            gen_op_mfc0_config0();
1924             rn = "Config";
1925             break;
1926         case 1:
1927            gen_op_mfc0_config1();
1928             rn = "Config1";
1929             break;
1930         case 2:
1931            gen_op_mfc0_config2();
1932             rn = "Config2";
1933             break;
1934         case 3:
1935            gen_op_mfc0_config3();
1936             rn = "Config3";
1937             break;
1938        /* 6,7 are implementation dependent */
1939         default:
1940             goto die;
1941         }
1942         break;
1943     case 17:
1944         switch (sel) {
1945         case 0:
1946            gen_op_mfc0_lladdr();
1947            rn = "LLAddr";
1948            break;
1949         default:
1950             goto die;
1951         }
1952         break;
1953     case 18:
1954         switch (sel) {
1955         case 0:
1956            gen_op_mfc0_watchlo0();
1957            rn = "WatchLo";
1958            break;
1959         case 1:
1960 //         gen_op_mfc0_watchlo1();
1961            rn = "WatchLo1";
1962 //         break;
1963         case 2:
1964 //         gen_op_mfc0_watchlo2();
1965            rn = "WatchLo2";
1966 //         break;
1967         case 3:
1968 //         gen_op_mfc0_watchlo3();
1969            rn = "WatchLo3";
1970 //         break;
1971         case 4:
1972 //         gen_op_mfc0_watchlo4();
1973            rn = "WatchLo4";
1974 //         break;
1975         case 5:
1976 //         gen_op_mfc0_watchlo5();
1977            rn = "WatchLo5";
1978 //         break;
1979         case 6:
1980 //         gen_op_mfc0_watchlo6();
1981            rn = "WatchLo6";
1982 //         break;
1983         case 7:
1984 //         gen_op_mfc0_watchlo7();
1985            rn = "WatchLo7";
1986 //         break;
1987         default:
1988             goto die;
1989         }
1990         break;
1991     case 19:
1992         switch (sel) {
1993         case 0:
1994            gen_op_mfc0_watchhi0();
1995            rn = "WatchHi";
1996            break;
1997         case 1:
1998 //         gen_op_mfc0_watchhi1();
1999            rn = "WatchHi1";
2000 //         break;
2001         case 2:
2002 //         gen_op_mfc0_watchhi2();
2003            rn = "WatchHi2";
2004 //         break;
2005         case 3:
2006 //         gen_op_mfc0_watchhi3();
2007            rn = "WatchHi3";
2008 //         break;
2009         case 4:
2010 //         gen_op_mfc0_watchhi4();
2011            rn = "WatchHi4";
2012 //         break;
2013         case 5:
2014 //         gen_op_mfc0_watchhi5();
2015            rn = "WatchHi5";
2016 //         break;
2017         case 6:
2018 //         gen_op_mfc0_watchhi6();
2019            rn = "WatchHi6";
2020 //         break;
2021         case 7:
2022 //         gen_op_mfc0_watchhi7();
2023            rn = "WatchHi7";
2024 //         break;
2025         default:
2026             goto die;
2027         }
2028         break;
2029     case 20:
2030         switch (sel) {
2031         case 0:
2032            /* 64 bit MMU only */
2033            gen_op_mfc0_xcontext();
2034            rn = "XContext";
2035            break;
2036         default:
2037             goto die;
2038         }
2039         break;
2040     case 21:
2041        /* Officially reserved, but sel 0 is used for R1x000 framemask */
2042         switch (sel) {
2043         case 0:
2044            gen_op_mfc0_framemask();
2045            rn = "Framemask";
2046            break;
2047         default:
2048             goto die;
2049         }
2050         break;
2051     case 22:
2052        /* ignored */
2053        rn = "'Diagnostic"; /* implementation dependent */
2054        break;
2055     case 23:
2056         switch (sel) {
2057         case 0:
2058            gen_op_mfc0_debug(); /* EJTAG support */
2059            rn = "Debug";
2060            break;
2061         case 1:
2062 //         gen_op_mfc0_tracecontrol(); /* PDtrace support */
2063            rn = "TraceControl";
2064 //         break;
2065         case 2:
2066 //         gen_op_mfc0_tracecontrol2(); /* PDtrace support */
2067            rn = "TraceControl2";
2068 //         break;
2069         case 3:
2070 //         gen_op_mfc0_usertracedata(); /* PDtrace support */
2071            rn = "UserTraceData";
2072 //         break;
2073         case 4:
2074 //         gen_op_mfc0_debug(); /* PDtrace support */
2075            rn = "TraceBPC";
2076 //         break;
2077         default:
2078             goto die;
2079         }
2080         break;
2081     case 24:
2082         switch (sel) {
2083         case 0:
2084            gen_op_mfc0_depc(); /* EJTAG support */
2085            rn = "DEPC";
2086            break;
2087         default:
2088             goto die;
2089         }
2090         break;
2091     case 25:
2092         switch (sel) {
2093         case 0:
2094            gen_op_mfc0_performance0();
2095            rn = "Performance0";
2096             break;
2097         case 1:
2098 //         gen_op_mfc0_performance1();
2099            rn = "Performance1";
2100 //         break;
2101         case 2:
2102 //         gen_op_mfc0_performance2();
2103            rn = "Performance2";
2104 //         break;
2105         case 3:
2106 //         gen_op_mfc0_performance3();
2107            rn = "Performance3";
2108 //         break;
2109         case 4:
2110 //         gen_op_mfc0_performance4();
2111            rn = "Performance4";
2112 //         break;
2113         case 5:
2114 //         gen_op_mfc0_performance5();
2115            rn = "Performance5";
2116 //         break;
2117         case 6:
2118 //         gen_op_mfc0_performance6();
2119            rn = "Performance6";
2120 //         break;
2121         case 7:
2122 //         gen_op_mfc0_performance7();
2123            rn = "Performance7";
2124 //         break;
2125         default:
2126             goto die;
2127         }
2128         break;
2129     case 26:
2130        rn = "ECC";
2131        break;
2132     case 27:
2133         switch (sel) {
2134         /* ignored */
2135         case 0 ... 3:
2136            rn = "CacheErr";
2137            break;
2138         default:
2139             goto die;
2140         }
2141         break;
2142     case 28:
2143         switch (sel) {
2144         case 0:
2145         case 2:
2146         case 4:
2147         case 6:
2148             gen_op_mfc0_taglo();
2149             rn = "TagLo";
2150             break;
2151         case 1:
2152         case 3:
2153         case 5:
2154         case 7:
2155             gen_op_mfc0_datalo();
2156             rn = "DataLo";
2157             break;
2158         default:
2159             goto die;
2160         }
2161         break;
2162     case 29:
2163         switch (sel) {
2164         case 0:
2165         case 2:
2166         case 4:
2167         case 6:
2168             gen_op_mfc0_taghi();
2169             rn = "TagHi";
2170             break;
2171         case 1:
2172         case 3:
2173         case 5:
2174         case 7:
2175             gen_op_mfc0_datahi();
2176             rn = "DataHi";
2177             break;
2178         default:
2179             goto die;
2180         }
2181         break;
2182     case 30:
2183         switch (sel) {
2184         case 0:
2185            gen_op_mfc0_errorepc();
2186            rn = "ErrorEPC";
2187            break;
2188         default:
2189             goto die;
2190         }
2191         break;
2192     case 31:
2193         switch (sel) {
2194         case 0:
2195            gen_op_mfc0_desave(); /* EJTAG support */
2196            rn = "DESAVE";
2197            break;
2198         default:
2199             goto die;
2200         }
2201         break;
2202     default:
2203        goto die;
2204     }
2205 #if defined MIPS_DEBUG_DISAS
2206     if (loglevel & CPU_LOG_TB_IN_ASM) {
2207         fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2208                 rn, reg, sel);
2209     }
2210 #endif
2211     return;
2212
2213 die:
2214 #if defined MIPS_DEBUG_DISAS
2215     if (loglevel & CPU_LOG_TB_IN_ASM) {
2216         fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
2217                 rn, reg, sel);
2218     }
2219 #endif
2220     generate_exception(ctx, EXCP_RI);
2221 }
2222
2223 static void gen_mtc0 (DisasContext *ctx, int reg, int sel)
2224 {
2225     const char *rn = "invalid";
2226
2227     switch (reg) {
2228     case 0:
2229         switch (sel) {
2230         case 0:
2231            gen_op_mtc0_index();
2232             rn = "Index";
2233             break;
2234         case 1:
2235 //         gen_op_mtc0_mvpcontrol(); /* MT ASE */
2236             rn = "MVPControl";
2237 //         break;
2238         case 2:
2239 //         gen_op_mtc0_mvpconf0(); /* MT ASE */
2240             rn = "MVPConf0";
2241 //         break;
2242         case 3:
2243 //         gen_op_mtc0_mvpconf1(); /* MT ASE */
2244             rn = "MVPConf1";
2245 //         break;
2246         default:
2247             goto die;
2248         }
2249         break;
2250     case 1:
2251         switch (sel) {
2252         case 0:
2253            /* ignored */
2254             rn = "Random";
2255            break;
2256         case 1:
2257 //         gen_op_mtc0_vpecontrol(); /* MT ASE */
2258             rn = "VPEControl";
2259 //         break;
2260         case 2:
2261 //         gen_op_mtc0_vpeconf0(); /* MT ASE */
2262             rn = "VPEConf0";
2263 //         break;
2264         case 3:
2265 //         gen_op_mtc0_vpeconf1(); /* MT ASE */
2266             rn = "VPEConf1";
2267 //         break;
2268         case 4:
2269 //         gen_op_mtc0_YQMask(); /* MT ASE */
2270             rn = "YQMask";
2271 //         break;
2272         case 5:
2273 //         gen_op_mtc0_vpeschedule(); /* MT ASE */
2274             rn = "VPESchedule";
2275 //         break;
2276         case 6:
2277 //         gen_op_mtc0_vpeschefback(); /* MT ASE */
2278             rn = "VPEScheFBack";
2279 //         break;
2280         case 7:
2281 //         gen_op_mtc0_vpeopt(); /* MT ASE */
2282             rn = "VPEOpt";
2283 //         break;
2284         default:
2285             goto die;
2286         }
2287         break;
2288     case 2:
2289         switch (sel) {
2290         case 0:
2291            gen_op_mtc0_entrylo0();
2292            rn = "EntryLo0";
2293            break;
2294         case 1:
2295 //         gen_op_mtc0_tcstatus(); /* MT ASE */
2296            rn = "TCStatus";
2297 //         break;
2298         case 2:
2299 //         gen_op_mtc0_tcbind(); /* MT ASE */
2300            rn = "TCBind";
2301 //         break;
2302         case 3:
2303 //         gen_op_mtc0_tcrestart(); /* MT ASE */
2304            rn = "TCRestart";
2305 //         break;
2306         case 4:
2307 //         gen_op_mtc0_tchalt(); /* MT ASE */
2308            rn = "TCHalt";
2309 //         break;
2310         case 5:
2311 //         gen_op_mtc0_tccontext(); /* MT ASE */
2312            rn = "TCContext";
2313 //         break;
2314         case 6:
2315 //         gen_op_mtc0_tcschedule(); /* MT ASE */
2316            rn = "TCSchedule";
2317 //         break;
2318         case 7:
2319 //         gen_op_mtc0_tcschefback(); /* MT ASE */
2320            rn = "TCScheFBack";
2321 //         break;
2322         default:
2323             goto die;
2324         }
2325         break;
2326     case 3:
2327         switch (sel) {
2328         case 0:
2329            gen_op_mtc0_entrylo1();
2330            rn = "EntryLo1";
2331            break;
2332         default:
2333             goto die;
2334        }
2335         break;
2336     case 4:
2337         switch (sel) {
2338         case 0:
2339            gen_op_mtc0_context();
2340            rn = "Context";
2341            break;
2342         case 1:
2343 //         gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
2344            rn = "ContextConfig";
2345 //         break;
2346         default:
2347             goto die;
2348        }
2349         break;
2350     case 5:
2351         switch (sel) {
2352         case 0:
2353            gen_op_mtc0_pagemask();
2354            rn = "PageMask";
2355            break;
2356         case 1:
2357            gen_op_mtc0_pagegrain();
2358            rn = "PageGrain";
2359            break;
2360         default:
2361             goto die;
2362        }
2363         break;
2364     case 6:
2365         switch (sel) {
2366         case 0:
2367            gen_op_mtc0_wired();
2368            rn = "Wired";
2369            break;
2370         case 1:
2371 //         gen_op_mtc0_srsconf0(); /* shadow registers */
2372            rn = "SRSConf0";
2373 //         break;
2374         case 2:
2375 //         gen_op_mtc0_srsconf1(); /* shadow registers */
2376            rn = "SRSConf1";
2377 //         break;
2378         case 3:
2379 //         gen_op_mtc0_srsconf2(); /* shadow registers */
2380            rn = "SRSConf2";
2381 //         break;
2382         case 4:
2383 //         gen_op_mtc0_srsconf3(); /* shadow registers */
2384            rn = "SRSConf3";
2385 //         break;
2386         case 5:
2387 //         gen_op_mtc0_srsconf4(); /* shadow registers */
2388            rn = "SRSConf4";
2389 //         break;
2390         default:
2391             goto die;
2392        }
2393         break;
2394     case 7:
2395         switch (sel) {
2396         case 0:
2397            gen_op_mtc0_hwrena();
2398            rn = "HWREna";
2399            break;
2400         default:
2401             goto die;
2402        }
2403         break;
2404     case 8:
2405         /* ignored */
2406         rn = "BadVaddr";
2407         break;
2408     case 9:
2409         switch (sel) {
2410         case 0:
2411            gen_op_mtc0_count();
2412            rn = "Count";
2413            break;
2414        /* 6,7 are implementation dependent */
2415         default:
2416             goto die;
2417        }
2418        /* Stop translation as we may have switched the execution mode */
2419        ctx->bstate = BS_STOP;
2420         break;
2421     case 10:
2422         switch (sel) {
2423         case 0:
2424            gen_op_mtc0_entryhi();
2425            rn = "EntryHi";
2426            break;
2427         default:
2428             goto die;
2429        }
2430         break;
2431     case 11:
2432         switch (sel) {
2433         case 0:
2434            gen_op_mtc0_compare();
2435            rn = "Compare";
2436            break;
2437        /* 6,7 are implementation dependent */
2438         default:
2439             goto die;
2440        }
2441        /* Stop translation as we may have switched the execution mode */
2442        ctx->bstate = BS_STOP;
2443         break;
2444     case 12:
2445         switch (sel) {
2446         case 0:
2447            gen_op_mtc0_status();
2448            rn = "Status";
2449            break;
2450         case 1:
2451            gen_op_mtc0_intctl();
2452            rn = "IntCtl";
2453            break;
2454         case 2:
2455            gen_op_mtc0_srsctl();
2456            rn = "SRSCtl";
2457            break;
2458         case 3:
2459 //         gen_op_mtc0_srsmap(); /* shadow registers */
2460            rn = "SRSMap";
2461 //         break;
2462         default:
2463             goto die;
2464        }
2465        /* Stop translation as we may have switched the execution mode */
2466        ctx->bstate = BS_STOP;
2467         break;
2468     case 13:
2469         switch (sel) {
2470         case 0:
2471            gen_op_mtc0_cause();
2472            rn = "Cause";
2473            break;
2474         default:
2475             goto die;
2476        }
2477        /* Stop translation as we may have switched the execution mode */
2478        ctx->bstate = BS_STOP;
2479         break;
2480     case 14:
2481         switch (sel) {
2482         case 0:
2483            gen_op_mtc0_epc();
2484            rn = "EPC";
2485            break;
2486         default:
2487             goto die;
2488        }
2489         break;
2490     case 15:
2491         switch (sel) {
2492         case 0:
2493            /* ignored */
2494            rn = "PRid";
2495            break;
2496         case 1:
2497            gen_op_mtc0_ebase();
2498            rn = "EBase";
2499            break;
2500         default:
2501             goto die;
2502        }
2503         break;
2504     case 16:
2505         switch (sel) {
2506         case 0:
2507            gen_op_mtc0_config0();
2508             rn = "Config";
2509             break;
2510         case 1:
2511            /* ignored */
2512             rn = "Config1";
2513             break;
2514         case 2:
2515            gen_op_mtc0_config2();
2516             rn = "Config2";
2517             break;
2518         case 3:
2519            /* ignored */
2520             rn = "Config3";
2521             break;
2522        /* 6,7 are implementation dependent */
2523         default:
2524             rn = "Invalid config selector";
2525             goto die;
2526         }
2527        /* Stop translation as we may have switched the execution mode */
2528        ctx->bstate = BS_STOP;
2529         break;
2530     case 17:
2531         switch (sel) {
2532         case 0:
2533            /* ignored */
2534            rn = "LLAddr";
2535            break;
2536         default:
2537             goto die;
2538         }
2539         break;
2540     case 18:
2541         switch (sel) {
2542         case 0:
2543            gen_op_mtc0_watchlo0();
2544            rn = "WatchLo";
2545            break;
2546         case 1:
2547 //         gen_op_mtc0_watchlo1();
2548            rn = "WatchLo1";
2549 //         break;
2550         case 2:
2551 //         gen_op_mtc0_watchlo2();
2552            rn = "WatchLo2";
2553 //         break;
2554         case 3:
2555 //         gen_op_mtc0_watchlo3();
2556            rn = "WatchLo3";
2557 //         break;
2558         case 4:
2559 //         gen_op_mtc0_watchlo4();
2560            rn = "WatchLo4";
2561 //         break;
2562         case 5:
2563 //         gen_op_mtc0_watchlo5();
2564            rn = "WatchLo5";
2565 //         break;
2566         case 6:
2567 //         gen_op_mtc0_watchlo6();
2568            rn = "WatchLo6";
2569 //         break;
2570         case 7:
2571 //         gen_op_mtc0_watchlo7();
2572            rn = "WatchLo7";
2573 //         break;
2574         default:
2575             goto die;
2576         }
2577         break;
2578     case 19:
2579         switch (sel) {
2580         case 0:
2581            gen_op_mtc0_watchhi0();
2582            rn = "WatchHi";
2583            break;
2584         case 1:
2585 //         gen_op_mtc0_watchhi1();
2586            rn = "WatchHi1";
2587 //         break;
2588         case 2:
2589 //         gen_op_mtc0_watchhi2();
2590            rn = "WatchHi2";
2591 //         break;
2592         case 3:
2593 //         gen_op_mtc0_watchhi3();
2594            rn = "WatchHi3";
2595 //         break;
2596         case 4:
2597 //         gen_op_mtc0_watchhi4();
2598            rn = "WatchHi4";
2599 //         break;
2600         case 5:
2601 //         gen_op_mtc0_watchhi5();
2602            rn = "WatchHi5";
2603 //         break;
2604         case 6:
2605 //         gen_op_mtc0_watchhi6();
2606            rn = "WatchHi6";
2607 //         break;
2608         case 7:
2609 //         gen_op_mtc0_watchhi7();
2610            rn = "WatchHi7";
2611 //         break;
2612         default:
2613             goto die;
2614         }
2615         break;
2616     case 20:
2617         switch (sel) {
2618         case 0:
2619            /* 64 bit MMU only */
2620            gen_op_mtc0_xcontext();
2621            rn = "XContext";
2622            break;
2623         default:
2624             goto die;
2625         }
2626         break;
2627     case 21:
2628        /* Officially reserved, but sel 0 is used for R1x000 framemask */
2629         switch (sel) {
2630         case 0:
2631            gen_op_mtc0_framemask();
2632            rn = "Framemask";
2633            break;
2634         default:
2635             goto die;
2636         }
2637         break;
2638     case 22:
2639         /* ignored */
2640         rn = "Diagnostic"; /* implementation dependent */
2641        break;
2642     case 23:
2643         switch (sel) {
2644         case 0:
2645            gen_op_mtc0_debug(); /* EJTAG support */
2646            rn = "Debug";
2647            break;
2648         case 1:
2649 //         gen_op_mtc0_tracecontrol(); /* PDtrace support */
2650            rn = "TraceControl";
2651 //         break;
2652         case 2:
2653 //         gen_op_mtc0_tracecontrol2(); /* PDtrace support */
2654            rn = "TraceControl2";
2655 //         break;
2656         case 3:
2657 //         gen_op_mtc0_usertracedata(); /* PDtrace support */
2658            rn = "UserTraceData";
2659 //         break;
2660         case 4:
2661 //         gen_op_mtc0_debug(); /* PDtrace support */
2662            rn = "TraceBPC";
2663 //         break;
2664         default:
2665             goto die;
2666         }
2667        /* Stop translation as we may have switched the execution mode */
2668        ctx->bstate = BS_STOP;
2669         break;
2670     case 24:
2671         switch (sel) {
2672         case 0:
2673            gen_op_mtc0_depc(); /* EJTAG support */
2674            rn = "DEPC";
2675            break;
2676         default:
2677             goto die;
2678         }
2679         break;
2680     case 25:
2681         switch (sel) {
2682         case 0:
2683            gen_op_mtc0_performance0();
2684            rn = "Performance0";
2685            break;
2686         case 1:
2687 //         gen_op_mtc0_performance1();
2688            rn = "Performance1";
2689 //         break;
2690         case 2:
2691 //         gen_op_mtc0_performance2();
2692            rn = "Performance2";
2693 //         break;
2694         case 3:
2695 //         gen_op_mtc0_performance3();
2696            rn = "Performance3";
2697 //         break;
2698         case 4:
2699 //         gen_op_mtc0_performance4();
2700            rn = "Performance4";
2701 //         break;
2702         case 5:
2703 //         gen_op_mtc0_performance5();
2704            rn = "Performance5";
2705 //         break;
2706         case 6:
2707 //         gen_op_mtc0_performance6();
2708            rn = "Performance6";
2709 //         break;
2710         case 7:
2711 //         gen_op_mtc0_performance7();
2712            rn = "Performance7";
2713 //         break;
2714         default:
2715             goto die;
2716         }
2717        break;
2718     case 26:
2719        /* ignored */
2720         rn = "ECC";
2721        break;
2722     case 27:
2723         switch (sel) {
2724         case 0 ... 3:
2725            /* ignored */
2726            rn = "CacheErr";
2727            break;
2728         default:
2729             goto die;
2730         }
2731        break;
2732     case 28:
2733         switch (sel) {
2734         case 0:
2735         case 2:
2736         case 4:
2737         case 6:
2738             gen_op_mtc0_taglo();
2739             rn = "TagLo";
2740             break;
2741         case 1:
2742         case 3:
2743         case 5:
2744         case 7:
2745            gen_op_mtc0_datalo();
2746             rn = "DataLo";
2747             break;
2748         default:
2749             goto die;
2750         }
2751         break;
2752     case 29:
2753         switch (sel) {
2754         case 0:
2755         case 2:
2756         case 4:
2757         case 6:
2758             gen_op_mtc0_taghi();
2759             rn = "TagHi";
2760             break;
2761         case 1:
2762         case 3:
2763         case 5:
2764         case 7:
2765            gen_op_mtc0_datahi();
2766             rn = "DataHi";
2767             break;
2768         default:
2769             rn = "invalid sel";
2770             goto die;
2771         }
2772        break;
2773     case 30:
2774         switch (sel) {
2775         case 0:
2776            gen_op_mtc0_errorepc();
2777            rn = "ErrorEPC";
2778            break;
2779         default:
2780             goto die;
2781         }
2782         break;
2783     case 31:
2784         switch (sel) {
2785         case 0:
2786            gen_op_mtc0_desave(); /* EJTAG support */
2787            rn = "DESAVE";
2788            break;
2789         default:
2790             goto die;
2791         }
2792        /* Stop translation as we may have switched the execution mode */
2793        ctx->bstate = BS_STOP;
2794         break;
2795     default:
2796        goto die;
2797     }
2798 #if defined MIPS_DEBUG_DISAS
2799     if (loglevel & CPU_LOG_TB_IN_ASM) {
2800         fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2801                 rn, reg, sel);
2802     }
2803 #endif
2804     return;
2805
2806 die:
2807 #if defined MIPS_DEBUG_DISAS
2808     if (loglevel & CPU_LOG_TB_IN_ASM) {
2809         fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2810                 rn, reg, sel);
2811     }
2812 #endif
2813     generate_exception(ctx, EXCP_RI);
2814 }
2815
2816 static void gen_cp0 (DisasContext *ctx, uint32_t opc, int rt, int rd)
2817 {
2818     const char *opn = "unk";
2819
2820     if ((!ctx->CP0_Status & (1 << CP0St_CU0) &&
2821           (ctx->hflags & MIPS_HFLAG_UM)) &&
2822         !(ctx->hflags & MIPS_HFLAG_ERL) &&
2823         !(ctx->hflags & MIPS_HFLAG_EXL)) {
2824         if (loglevel & CPU_LOG_TB_IN_ASM) {
2825             fprintf(logfile, "CP0 is not usable\n");
2826         }
2827         generate_exception (ctx, EXCP_CpU);
2828         return;
2829     }
2830
2831     switch (opc) {
2832     case OPC_MFC0:
2833         if (rt == 0) {
2834             /* Treat as NOP */
2835             return;
2836         }
2837         gen_mfc0(ctx, rd, ctx->opcode & 0x7);
2838         gen_op_store_T0_gpr(rt);
2839         opn = "mfc0";
2840         break;
2841     case OPC_MTC0:
2842         /* If we get an exception, we want to restart at next instruction */
2843        /* XXX: breaks for mtc in delay slot */
2844         ctx->pc += 4;
2845         save_cpu_state(ctx, 1);
2846         ctx->pc -= 4;
2847         GEN_LOAD_REG_TN(T0, rt);
2848         gen_mtc0(ctx, rd, ctx->opcode & 0x7);
2849         opn = "mtc0";
2850         break;
2851 #if defined(MIPS_USES_R4K_TLB)
2852     case OPC_TLBWI:
2853         gen_op_tlbwi();
2854         opn = "tlbwi";
2855         break;
2856     case OPC_TLBWR:
2857         gen_op_tlbwr();
2858         opn = "tlbwr";
2859         break;
2860     case OPC_TLBP:
2861         gen_op_tlbp();
2862         opn = "tlbp";
2863         break;
2864     case OPC_TLBR:
2865         gen_op_tlbr();
2866         opn = "tlbr";
2867         break;
2868 #endif
2869     case OPC_ERET:
2870         opn = "eret";
2871         save_cpu_state(ctx, 0);
2872         gen_op_eret();
2873         ctx->bstate = BS_EXCP;
2874         break;
2875     case OPC_DERET:
2876         opn = "deret";
2877         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
2878             generate_exception(ctx, EXCP_RI);
2879         } else {
2880             save_cpu_state(ctx, 0);
2881             gen_op_deret();
2882             ctx->bstate = BS_EXCP;
2883         }
2884         break;
2885     case OPC_WAIT:
2886         opn = "wait";
2887         /* If we get an exception, we want to restart at next instruction */
2888         ctx->pc += 4;
2889         save_cpu_state(ctx, 1);
2890         ctx->pc -= 4;
2891         gen_op_wait();
2892         ctx->bstate = BS_EXCP;
2893         break;
2894     default:
2895         if (loglevel & CPU_LOG_TB_IN_ASM) {
2896             fprintf(logfile, "Invalid CP0 opcode: %08x %03x %03x %03x\n",
2897                     ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
2898                     ((ctx->opcode >> 16) & 0x1F));
2899         }
2900         generate_exception(ctx, EXCP_RI);
2901         return;
2902     }
2903     MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
2904 }
2905
2906 /* CP1 Branches (before delay slot) */
2907 static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
2908                                  int32_t offset)
2909 {
2910     target_ulong btarget;
2911
2912     btarget = ctx->pc + 4 + offset;
2913
2914     switch (op) {
2915     case OPC_BC1F:
2916         gen_op_bc1f();
2917         MIPS_DEBUG("bc1f %08x", btarget);
2918         goto not_likely;
2919     case OPC_BC1FL:
2920         gen_op_bc1f();
2921         MIPS_DEBUG("bc1fl %08x", btarget);
2922         goto likely;
2923     case OPC_BC1T:
2924         gen_op_bc1t();
2925         MIPS_DEBUG("bc1t %08x", btarget);
2926     not_likely:
2927         ctx->hflags |= MIPS_HFLAG_BC;
2928         break;
2929     case OPC_BC1TL:
2930         gen_op_bc1t();
2931         MIPS_DEBUG("bc1tl %08x", btarget);
2932     likely:
2933         ctx->hflags |= MIPS_HFLAG_BL;
2934         break;
2935     default:    
2936         MIPS_INVAL("cp1 branch/jump");
2937         generate_exception_err (ctx, EXCP_RI, 1);
2938         return;
2939     }
2940     gen_op_set_bcond();
2941
2942     MIPS_DEBUG("enter ds: cond %02x target %08x",
2943                ctx->hflags, btarget);
2944     ctx->btarget = btarget;
2945
2946     return;
2947 }
2948
2949 /* Coprocessor 1 (FPU) */
2950 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
2951 {
2952     const char *opn = "unk";
2953
2954     switch (opc) {
2955     case OPC_MFC1:
2956         GEN_LOAD_FREG_FTN(WT0, fs);
2957         gen_op_mfc1();
2958         GEN_STORE_TN_REG(rt, T0);
2959         opn = "mfc1";
2960         break;
2961     case OPC_MTC1:
2962         GEN_LOAD_REG_TN(T0, rt);
2963         gen_op_mtc1();
2964         GEN_STORE_FTN_FREG(fs, WT0);
2965         opn = "mtc1";
2966         break;
2967     case OPC_CFC1:
2968         if (fs != 0 && fs != 31) {
2969             MIPS_INVAL("cfc1 freg");
2970             generate_exception_err (ctx, EXCP_RI, 1);
2971             return;
2972         }
2973         GEN_LOAD_IMM_TN(T1, fs);
2974         gen_op_cfc1();
2975         GEN_STORE_TN_REG(rt, T0);
2976         opn = "cfc1";
2977         break;
2978     case OPC_CTC1:
2979          if (fs != 0 && fs != 31) {
2980             MIPS_INVAL("ctc1 freg");
2981             generate_exception_err (ctx, EXCP_RI, 1);
2982             return;
2983         }
2984         GEN_LOAD_IMM_TN(T1, fs);
2985         GEN_LOAD_REG_TN(T0, rt);
2986         gen_op_ctc1();
2987         opn = "ctc1";
2988         break;
2989     default:
2990         if (loglevel & CPU_LOG_TB_IN_ASM) {
2991             fprintf(logfile, "Invalid CP1 opcode: %08x %03x %03x %03x\n",
2992                     ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
2993                     ((ctx->opcode >> 16) & 0x1F));
2994         }
2995         generate_exception_err (ctx, EXCP_RI, 1);
2996         return;
2997     }
2998     MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
2999 }
3000
3001 /* verify if floating point register is valid; an operation is not defined
3002  * if bit 0 of any register specification is set and the FR bit in the
3003  * Status register equals zero, since the register numbers specify an
3004  * even-odd pair of adjacent coprocessor general registers. When the FR bit
3005  * in the Status register equals one, both even and odd register numbers
3006  * are valid.
3007  * 
3008  * Multiple float registers can be checked by calling
3009  * CHECK_FR(ctx, freg1 | freg2 | ... | fregN);
3010  */
3011 #define CHECK_FR(ctx, freg) do { \
3012         if (!((ctx)->CP0_Status & (1<<CP0St_FR)) && ((freg) & 1)) { \
3013             generate_exception_err (ctx, EXCP_RI, 1); \
3014             return; \
3015         } \
3016     } while(0)
3017
3018 #define FOP(func, fmt) (((fmt) << 21) | (func))
3019
3020 static void gen_farith (DisasContext *ctx, uint32_t op1, int ft, int fs, int fd)
3021 {
3022     const char *opn = "unk";
3023     const char *condnames[] = {
3024             "c.f",
3025             "c.un",
3026             "c.eq",
3027             "c.ueq",
3028             "c.olt",
3029             "c.ult",
3030             "c.ole",
3031             "c.ule",
3032             "c.sf",
3033             "c.ngle",
3034             "c.seq",
3035             "c.ngl",
3036             "c.lt",
3037             "c.nge",
3038             "c.le",
3039             "c.ngt",
3040     };
3041     int binary = 0;
3042     uint32_t func = ctx->opcode & 0x3f;
3043
3044     switch (ctx->opcode & FOP(0x3f, 0x1f)) {
3045     case FOP(0, 17):
3046         CHECK_FR(ctx, fs | ft | fd);
3047         GEN_LOAD_FREG_FTN(DT0, fs);
3048         GEN_LOAD_FREG_FTN(DT1, ft);
3049         gen_op_float_add_d();
3050         GEN_STORE_FTN_FREG(fd, DT2);
3051         opn = "add.d";
3052         binary = 1;
3053         break;
3054     case FOP(1, 17):
3055         CHECK_FR(ctx, fs | ft | fd);
3056         GEN_LOAD_FREG_FTN(DT0, fs);
3057         GEN_LOAD_FREG_FTN(DT1, ft);
3058         gen_op_float_sub_d();
3059         GEN_STORE_FTN_FREG(fd, DT2);
3060         opn = "sub.d";
3061         binary = 1;
3062         break;
3063     case FOP(2, 17):
3064         CHECK_FR(ctx, fs | ft | fd);
3065         GEN_LOAD_FREG_FTN(DT0, fs);
3066         GEN_LOAD_FREG_FTN(DT1, ft);
3067         gen_op_float_mul_d();
3068         GEN_STORE_FTN_FREG(fd, DT2);
3069         opn = "mul.d";
3070         binary = 1;
3071         break;
3072     case FOP(3, 17):
3073         CHECK_FR(ctx, fs | ft | fd);
3074         GEN_LOAD_FREG_FTN(DT0, fs);
3075         GEN_LOAD_FREG_FTN(DT1, ft);
3076         gen_op_float_div_d();
3077         GEN_STORE_FTN_FREG(fd, DT2);
3078         opn = "div.d";
3079         binary = 1;
3080         break;
3081     case FOP(4, 17):
3082         CHECK_FR(ctx, fs | fd);
3083         GEN_LOAD_FREG_FTN(DT0, fs);
3084         gen_op_float_sqrt_d();
3085         GEN_STORE_FTN_FREG(fd, DT2);
3086         opn = "sqrt.d";
3087         break;
3088     case FOP(5, 17):
3089         CHECK_FR(ctx, fs | fd);
3090         GEN_LOAD_FREG_FTN(DT0, fs);
3091         gen_op_float_abs_d();
3092         GEN_STORE_FTN_FREG(fd, DT2);
3093         opn = "abs.d";
3094         break;
3095     case FOP(6, 17):
3096         CHECK_FR(ctx, fs | fd);
3097         GEN_LOAD_FREG_FTN(DT0, fs);
3098         gen_op_float_mov_d();
3099         GEN_STORE_FTN_FREG(fd, DT2);
3100         opn = "mov.d";
3101         break;
3102     case FOP(7, 17):
3103         CHECK_FR(ctx, fs | fd);
3104         GEN_LOAD_FREG_FTN(DT0, fs);
3105         gen_op_float_chs_d();
3106         GEN_STORE_FTN_FREG(fd, DT2);
3107         opn = "neg.d";
3108         break;
3109     /*  8 - round.l */
3110     /*  9 - trunc.l */
3111     /* 10 - ceil.l  */
3112     /* 11 - floor.l */
3113     case FOP(12, 17):
3114         CHECK_FR(ctx, fs | fd);
3115         GEN_LOAD_FREG_FTN(DT0, fs);
3116         gen_op_float_roundw_d();
3117         GEN_STORE_FTN_FREG(fd, WT2);
3118         opn = "round.w.d";
3119         break;
3120     case FOP(13, 17):
3121         CHECK_FR(ctx, fs | fd);
3122         GEN_LOAD_FREG_FTN(DT0, fs);
3123         gen_op_float_truncw_d();
3124         GEN_STORE_FTN_FREG(fd, WT2);
3125         opn = "trunc.w.d";
3126         break;
3127     case FOP(14, 17):
3128         CHECK_FR(ctx, fs | fd);
3129         GEN_LOAD_FREG_FTN(DT0, fs);
3130         gen_op_float_ceilw_d();
3131         GEN_STORE_FTN_FREG(fd, WT2);
3132         opn = "ceil.w.d";
3133         break;
3134     case FOP(15, 17):
3135         CHECK_FR(ctx, fs | fd);
3136         GEN_LOAD_FREG_FTN(DT0, fs);
3137         gen_op_float_floorw_d();
3138         GEN_STORE_FTN_FREG(fd, WT2);
3139         opn = "floor.w.d";
3140         break;
3141     case FOP(33, 16): /* cvt.d.s */
3142         CHECK_FR(ctx, fs | fd);
3143         GEN_LOAD_FREG_FTN(WT0, fs);
3144         gen_op_float_cvtd_s();
3145         GEN_STORE_FTN_FREG(fd, DT2);
3146         opn = "cvt.d.s";
3147         break;
3148     case FOP(33, 20): /* cvt.d.w */
3149         CHECK_FR(ctx, fs | fd);
3150         GEN_LOAD_FREG_FTN(WT0, fs);
3151         gen_op_float_cvtd_w();
3152         GEN_STORE_FTN_FREG(fd, DT2);
3153         opn = "cvt.d.w";
3154         break;
3155     case FOP(48, 17):
3156     case FOP(49, 17):
3157     case FOP(50, 17):
3158     case FOP(51, 17):
3159     case FOP(52, 17):
3160     case FOP(53, 17):
3161     case FOP(54, 17):
3162     case FOP(55, 17):
3163     case FOP(56, 17):
3164     case FOP(57, 17):
3165     case FOP(58, 17):
3166     case FOP(59, 17):
3167     case FOP(60, 17):
3168     case FOP(61, 17):
3169     case FOP(62, 17):
3170     case FOP(63, 17):
3171         CHECK_FR(ctx, fs | ft);
3172         GEN_LOAD_FREG_FTN(DT0, fs);
3173         GEN_LOAD_FREG_FTN(DT1, ft);
3174         gen_cmp_d(func-48);
3175         opn = condnames[func-48];
3176         break;
3177     case FOP(0, 16):
3178         CHECK_FR(ctx, fs | ft | fd);
3179         GEN_LOAD_FREG_FTN(WT0, fs);
3180         GEN_LOAD_FREG_FTN(WT1, ft);
3181         gen_op_float_add_s();
3182         GEN_STORE_FTN_FREG(fd, WT2);
3183         opn = "add.s";
3184         binary = 1;
3185         break;
3186     case FOP(1, 16):
3187         CHECK_FR(ctx, fs | ft | fd);
3188         GEN_LOAD_FREG_FTN(WT0, fs);
3189         GEN_LOAD_FREG_FTN(WT1, ft);
3190         gen_op_float_sub_s();
3191         GEN_STORE_FTN_FREG(fd, WT2);
3192         opn = "sub.s";
3193         binary = 1;
3194         break;
3195     case FOP(2, 16):
3196         CHECK_FR(ctx, fs | ft | fd);
3197         GEN_LOAD_FREG_FTN(WT0, fs);
3198         GEN_LOAD_FREG_FTN(WT1, ft);
3199         gen_op_float_mul_s();
3200         GEN_STORE_FTN_FREG(fd, WT2);
3201         opn = "mul.s";
3202         binary = 1;
3203         break;
3204     case FOP(3, 16):
3205         CHECK_FR(ctx, fs | ft | fd);
3206         GEN_LOAD_FREG_FTN(WT0, fs);
3207         GEN_LOAD_FREG_FTN(WT1, ft);
3208         gen_op_float_div_s();
3209         GEN_STORE_FTN_FREG(fd, WT2);
3210         opn = "div.s";
3211         binary = 1;
3212         break;
3213     case FOP(4, 16):
3214         CHECK_FR(ctx, fs | fd);
3215         GEN_LOAD_FREG_FTN(WT0, fs);
3216         gen_op_float_sqrt_s();
3217         GEN_STORE_FTN_FREG(fd, WT2);
3218         opn = "sqrt.s";
3219         break;
3220     case FOP(5, 16):
3221         CHECK_FR(ctx, fs | fd);
3222         GEN_LOAD_FREG_FTN(WT0, fs);
3223         gen_op_float_abs_s();
3224         GEN_STORE_FTN_FREG(fd, WT2);
3225         opn = "abs.s";
3226         break;
3227     case FOP(6, 16):
3228         CHECK_FR(ctx, fs | fd);
3229         GEN_LOAD_FREG_FTN(WT0, fs);
3230         gen_op_float_mov_s();
3231         GEN_STORE_FTN_FREG(fd, WT2);
3232         opn = "mov.s";
3233         break;
3234     case FOP(7, 16):
3235         CHECK_FR(ctx, fs | fd);
3236         GEN_LOAD_FREG_FTN(WT0, fs);
3237         gen_op_float_chs_s();
3238         GEN_STORE_FTN_FREG(fd, WT2);
3239         opn = "neg.s";
3240         break;
3241     case FOP(12, 16):
3242         CHECK_FR(ctx, fs | fd);
3243         GEN_LOAD_FREG_FTN(WT0, fs);
3244         gen_op_float_roundw_s();
3245         GEN_STORE_FTN_FREG(fd, WT2);
3246         opn = "round.w.s";
3247         break;
3248     case FOP(13, 16):
3249         CHECK_FR(ctx, fs | fd);
3250         GEN_LOAD_FREG_FTN(WT0, fs);
3251         gen_op_float_truncw_s();
3252         GEN_STORE_FTN_FREG(fd, WT2);
3253         opn = "trunc.w.s";
3254         break;
3255     case FOP(32, 17): /* cvt.s.d */
3256         CHECK_FR(ctx, fs | fd);
3257         GEN_LOAD_FREG_FTN(DT0, fs);
3258         gen_op_float_cvts_d();
3259         GEN_STORE_FTN_FREG(fd, WT2);
3260         opn = "cvt.s.d";
3261         break;
3262     case FOP(32, 20): /* cvt.s.w */
3263         CHECK_FR(ctx, fs | fd);
3264         GEN_LOAD_FREG_FTN(WT0, fs);
3265         gen_op_float_cvts_w();
3266         GEN_STORE_FTN_FREG(fd, WT2);
3267         opn = "cvt.s.w";
3268         break;
3269     case FOP(36, 16): /* cvt.w.s */
3270         CHECK_FR(ctx, fs | fd);
3271         GEN_LOAD_FREG_FTN(WT0, fs);
3272         gen_op_float_cvtw_s();
3273         GEN_STORE_FTN_FREG(fd, WT2);
3274         opn = "cvt.w.s";
3275         break;
3276     case FOP(36, 17): /* cvt.w.d */
3277         CHECK_FR(ctx, fs | fd);
3278         GEN_LOAD_FREG_FTN(DT0, fs);
3279         gen_op_float_cvtw_d();
3280         GEN_STORE_FTN_FREG(fd, WT2);
3281         opn = "cvt.w.d";
3282         break;
3283     case FOP(48, 16):
3284     case FOP(49, 16):
3285     case FOP(50, 16):
3286     case FOP(51, 16):
3287     case FOP(52, 16):
3288     case FOP(53, 16):
3289     case FOP(54, 16):
3290     case FOP(55, 16):
3291     case FOP(56, 16):
3292     case FOP(57, 16):
3293     case FOP(58, 16):
3294     case FOP(59, 16):
3295     case FOP(60, 16):
3296     case FOP(61, 16):
3297     case FOP(62, 16):
3298     case FOP(63, 16):
3299         CHECK_FR(ctx, fs | ft);
3300         GEN_LOAD_FREG_FTN(WT0, fs);
3301         GEN_LOAD_FREG_FTN(WT1, ft);
3302         gen_cmp_s(func-48);
3303         opn = condnames[func-48];
3304         break;
3305     default:    
3306         if (loglevel & CPU_LOG_TB_IN_ASM) {
3307             fprintf(logfile, "Invalid FP arith function: %08x %03x %03x %03x\n",
3308                     ctx->opcode, ctx->opcode >> 26, ctx->opcode & 0x3F,
3309                     ((ctx->opcode >> 16) & 0x1F));
3310         }
3311         generate_exception_err (ctx, EXCP_RI, 1);
3312         return;
3313     }
3314     if (binary)
3315         MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
3316     else
3317         MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
3318 }
3319
3320 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
3321 {
3322     uint32_t ccbit;
3323
3324     if (cc)
3325         ccbit = 1 << (24 + cc);
3326     else
3327         ccbit = 1 << 23;
3328     if (!tf)
3329         gen_op_movf(ccbit, rd, rs);
3330     else
3331        gen_op_movt(ccbit, rd, rs);
3332 }
3333
3334 /* ISA extensions (ASEs) */
3335 /* MIPS16 extension to MIPS32 */
3336 /* SmartMIPS extension to MIPS32 */
3337
3338 #ifdef MIPS_HAS_MIPS64
3339 static void gen_arith64 (DisasContext *ctx, uint32_t opc)
3340 {
3341     if (func == 0x02 && rd == 0) {
3342         /* NOP */
3343         return;
3344     }
3345     if (rs == 0 || rt == 0) {
3346         gen_op_reset_T0();
3347         gen_op_save64();
3348     } else {
3349         gen_op_load_gpr_T0(rs);
3350         gen_op_load_gpr_T1(rt);
3351         gen_op_save64();
3352         if (func & 0x01)
3353             gen_op_mul64u();
3354         else
3355             gen_op_mul64s();
3356     }
3357     if (func & 0x02)
3358         gen_op_add64();
3359     else
3360         gen_op_sub64();
3361 }
3362
3363 /* Coprocessor 3 (FPU) */
3364
3365 /* MDMX extension to MIPS64 */
3366 /* MIPS-3D extension to MIPS64 */
3367
3368 #endif
3369
3370 static void gen_blikely(DisasContext *ctx)
3371 {
3372     int l1;
3373     l1 = gen_new_label();
3374     gen_op_jnz_T2(l1);
3375     gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
3376     gen_goto_tb(ctx, 1, ctx->pc + 4);
3377     gen_set_label(l1);
3378 }
3379
3380 static void decode_opc (DisasContext *ctx)
3381 {
3382     int32_t offset;
3383     int rs, rt, rd, sa;
3384     uint32_t op, op1, op2;
3385     int16_t imm;
3386
3387     /* make sure instructions are on a word boundary */
3388     if (ctx->pc & 0x3) {
3389         generate_exception(ctx, EXCP_AdEL);
3390         return;
3391     }
3392
3393     if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
3394         /* Handle blikely not taken case */
3395         MIPS_DEBUG("blikely condition (%08x)", ctx->pc + 4);
3396         gen_blikely(ctx);
3397     }
3398     op = MASK_OP_MAJOR(ctx->opcode);
3399     rs = (ctx->opcode >> 21) & 0x1f;
3400     rt = (ctx->opcode >> 16) & 0x1f;
3401     rd = (ctx->opcode >> 11) & 0x1f;
3402     sa = (ctx->opcode >> 6) & 0x1f;
3403     imm = (int16_t)ctx->opcode;
3404     switch (op) {
3405     case OPC_SPECIAL:
3406         op1 = MASK_SPECIAL(ctx->opcode);
3407         switch (op1) {
3408         case OPC_SLL:          /* Arithmetic with immediate */
3409         case OPC_SRL ... OPC_SRA:
3410             gen_arith_imm(ctx, op1, rd, rt, sa);
3411             break;
3412         case OPC_SLLV:         /* Arithmetic */
3413         case OPC_SRLV ... OPC_SRAV:
3414         case OPC_MOVZ ... OPC_MOVN:
3415         case OPC_ADD ... OPC_NOR:
3416         case OPC_SLT ... OPC_SLTU:
3417             gen_arith(ctx, op1, rd, rs, rt);
3418             break;
3419         case OPC_MULT ... OPC_DIVU:
3420             gen_muldiv(ctx, op1, rs, rt);
3421             break;
3422         case OPC_JR ... OPC_JALR:
3423             gen_compute_branch(ctx, op1, rs, rd, sa);
3424             return;
3425         case OPC_TGE ... OPC_TEQ: /* Traps */
3426         case OPC_TNE:
3427             gen_trap(ctx, op1, rs, rt, -1);
3428             break;
3429         case OPC_MFHI:          /* Move from HI/LO */
3430         case OPC_MFLO:
3431             gen_HILO(ctx, op1, rd);
3432             break;
3433         case OPC_MTHI:
3434         case OPC_MTLO:          /* Move to HI/LO */
3435             gen_HILO(ctx, op1, rs);
3436             break;
3437         case OPC_PMON:          /* Pmon entry point */
3438             gen_op_pmon(sa);
3439             break;
3440         case OPC_SYSCALL:
3441             generate_exception(ctx, EXCP_SYSCALL);
3442             ctx->bstate = BS_EXCP;
3443             break;
3444         case OPC_BREAK:
3445             generate_exception(ctx, EXCP_BREAK);
3446             break;
3447         case OPC_SPIM:        /* SPIM ? */
3448            /* Implemented as RI exception for now. */
3449             MIPS_INVAL("spim (unofficial)");
3450             generate_exception(ctx, EXCP_RI);
3451             break;
3452         case OPC_SYNC:
3453             /* Treat as a noop. */
3454             break;
3455
3456         case OPC_MOVCI:
3457             gen_op_cp1_enabled();
3458             gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
3459                       (ctx->opcode >> 16) & 1);
3460             break;
3461
3462 #ifdef MIPS_HAS_MIPS64
3463        /* MIPS64 specific opcodes */
3464         case OPC_DSLL:
3465         case OPC_DSRL ... OPC_DSRA:
3466         case OPC_DSLL32:
3467         case OPC_DSRL32 ... OPC_DSRA32:
3468             gen_arith_imm(ctx, op1, rd, rt, sa);
3469             break;
3470         case OPC_DSLLV:
3471         case OPC_DSRLV ... OPC_DSRAV:
3472         case OPC_DADD ... OPC_DSUBU:
3473             gen_arith(ctx, op1, rd, rs, rt);
3474             break;
3475         case OPC_DMULT ... OPC_DDIVU:
3476             gen_muldiv(ctx, op1, rs, rt);
3477             break;
3478 #endif
3479         default:            /* Invalid */
3480             MIPS_INVAL("special");
3481             generate_exception(ctx, EXCP_RI);
3482             break;
3483         }
3484         break;
3485     case OPC_SPECIAL2:
3486         op1 = MASK_SPECIAL2(ctx->opcode);
3487         switch (op1) {
3488         case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
3489         case OPC_MSUB ... OPC_MSUBU:
3490             gen_muldiv(ctx, op1, rs, rt);
3491             break;
3492         case OPC_MUL:
3493             gen_arith(ctx, op1, rd, rs, rt);
3494             break;
3495         case OPC_CLZ ... OPC_CLO:
3496             gen_cl(ctx, op1, rd, rs);
3497             break;
3498         case OPC_SDBBP:
3499             /* XXX: not clear which exception should be raised
3500              *      when in debug mode...
3501              */
3502             if (!(ctx->hflags & MIPS_HFLAG_DM)) {
3503                 generate_exception(ctx, EXCP_DBp);
3504             } else {
3505                 generate_exception(ctx, EXCP_DBp);
3506             }
3507             /* Treat as a noop */
3508             break;
3509 #ifdef MIPS_HAS_MIPS64
3510         case OPC_DCLZ ... OPC_DCLO:
3511             gen_cl(ctx, op1, rd, rs);
3512             break;
3513 #endif
3514         default:            /* Invalid */
3515             MIPS_INVAL("special2");
3516             generate_exception(ctx, EXCP_RI);
3517             break;
3518         }
3519         break;
3520     case OPC_SPECIAL3:
3521         op1 = MASK_SPECIAL3(ctx->opcode);
3522         switch (op1) {
3523         case OPC_EXT:
3524         case OPC_INS:
3525             gen_bitops(ctx, op1, rt, rs, sa, rd);
3526             break;
3527         case OPC_BSHFL:
3528             op2 = MASK_BSHFL(ctx->opcode);
3529             switch (op2) {
3530             case OPC_WSBH:
3531                 GEN_LOAD_REG_TN(T1, rt);
3532                 gen_op_wsbh();
3533                 break;
3534             case OPC_SEB:
3535                 GEN_LOAD_REG_TN(T1, rt);
3536                 gen_op_seb();
3537                 break;
3538             case OPC_SEH:
3539                 GEN_LOAD_REG_TN(T1, rt);
3540                 gen_op_seh();
3541                 break;
3542              default:            /* Invalid */
3543                 MIPS_INVAL("bshfl");
3544                 generate_exception(ctx, EXCP_RI);
3545                 break;
3546            }
3547            GEN_STORE_TN_REG(rd, T0);
3548            break;
3549        case OPC_RDHWR:
3550            switch (rd) {
3551            case 0:
3552                gen_op_rdhwr_cpunum();
3553                break;
3554            case 1:
3555                gen_op_rdhwr_synci_step();
3556                break;
3557            case 2:
3558                gen_op_rdhwr_cc();
3559                break;
3560            case 3:
3561                gen_op_rdhwr_ccres();
3562                break;
3563            default:            /* Invalid */
3564                MIPS_INVAL("rdhwr");
3565                generate_exception(ctx, EXCP_RI);
3566                break;
3567            }
3568            GEN_STORE_TN_REG(rt, T0);
3569            break;
3570 #ifdef MIPS_HAS_MIPS64
3571        case OPC_DEXTM ... OPC_DEXT:
3572        case OPC_DINSM ... OPC_DINS:
3573            gen_bitops(ctx, op1, rt, rs, sa, rd);
3574             break;
3575        case OPC_DBSHFL:
3576            op2 = MASK_DBSHFL(ctx->opcode);
3577            switch (op2) {
3578            case OPC_DSBH:
3579                GEN_LOAD_REG_TN(T1, rt);
3580                gen_op_dsbh();
3581                break;
3582            case OPC_DSHD:
3583                GEN_LOAD_REG_TN(T1, rt);
3584                gen_op_dshd();
3585                break;
3586             default:            /* Invalid */
3587                 MIPS_INVAL("dbshfl");
3588                 generate_exception(ctx, EXCP_RI);
3589                 break;
3590            }
3591            GEN_STORE_TN_REG(rd, T0);
3592 #endif
3593         default:            /* Invalid */
3594             MIPS_INVAL("special3");
3595             generate_exception(ctx, EXCP_RI);
3596             break;
3597         }
3598         break;
3599     case OPC_REGIMM:
3600         op1 = MASK_REGIMM(ctx->opcode);
3601         switch (op1) {
3602         case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
3603         case OPC_BLTZAL ... OPC_BGEZALL:
3604             gen_compute_branch(ctx, op1, rs, -1, imm << 2);
3605             return;
3606         case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
3607         case OPC_TNEI:
3608             gen_trap(ctx, op1, rs, -1, imm);
3609             break;
3610         case OPC_SYNCI:
3611            /* treat as noop */
3612             break;
3613         default:            /* Invalid */
3614             MIPS_INVAL("REGIMM");
3615             generate_exception(ctx, EXCP_RI);
3616             break;
3617         }
3618         break;
3619     case OPC_CP0:
3620         op1 = MASK_CP0(ctx->opcode);
3621         switch (op1) {
3622         case OPC_MFC0:
3623         case OPC_MTC0:
3624 #ifdef MIPS_HAS_MIPS64
3625         case OPC_DMFC0:
3626         case OPC_DMTC0:
3627 #endif
3628             gen_cp0(ctx, op1, rt, rd);
3629             break;
3630         case OPC_C0_FIRST ... OPC_C0_LAST:
3631             gen_cp0(ctx, MASK_C0(ctx->opcode), rt, rd);
3632             break;
3633         case OPC_MFMC0:
3634             op2 = MASK_MFMC0(ctx->opcode);
3635             switch (op2) {
3636             case OPC_DI:
3637                 gen_op_di();
3638                 /* Stop translation as we may have switched the execution mode */
3639                 ctx->bstate = BS_STOP;
3640                 break;
3641             case OPC_EI:
3642                 gen_op_ei();
3643                 /* Stop translation as we may have switched the execution mode */
3644                 ctx->bstate = BS_STOP;
3645                 break;
3646             default:            /* Invalid */
3647                 MIPS_INVAL("MFMC0");
3648                 generate_exception(ctx, EXCP_RI);
3649                 break;
3650             }
3651             GEN_STORE_TN_REG(rt, T0);
3652             break;
3653         /* Shadow registers (not implemented). */
3654         case OPC_RDPGPR:
3655         case OPC_WRPGPR:
3656         default:
3657             generate_exception(ctx, EXCP_RI);
3658             break;
3659         }
3660         break;
3661     case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
3662          gen_arith_imm(ctx, op, rt, rs, imm);
3663          break;
3664     case OPC_J ... OPC_JAL: /* Jump */
3665          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
3666          gen_compute_branch(ctx, op, rs, rt, offset);
3667          return;
3668     case OPC_BEQ ... OPC_BGTZ: /* Branch */
3669     case OPC_BEQL ... OPC_BGTZL:
3670          gen_compute_branch(ctx, op, rs, rt, imm << 2);
3671          return;
3672     case OPC_LB ... OPC_LWR: /* Load and stores */
3673     case OPC_SB ... OPC_SW:
3674     case OPC_SWR:
3675     case OPC_LL:
3676     case OPC_SC:
3677          gen_ldst(ctx, op, rt, rs, imm);
3678          break;
3679     case OPC_CACHE:
3680          /* Treat as a noop */
3681          break;
3682     case OPC_PREF:
3683         /* Treat as a noop */
3684         break;
3685
3686     /* Floating point.  */
3687     case OPC_LWC1:
3688     case OPC_LDC1:
3689     case OPC_SWC1:
3690     case OPC_SDC1:
3691 #if defined(MIPS_USES_FPU)
3692         save_cpu_state(ctx, 1);
3693         gen_op_cp1_enabled();
3694         gen_flt_ldst(ctx, op, rt, rs, imm);
3695 #else
3696         generate_exception_err(ctx, EXCP_CpU, 1);
3697 #endif
3698         break;
3699
3700     case OPC_CP1:
3701 #if defined(MIPS_USES_FPU)
3702         save_cpu_state(ctx, 1);
3703         gen_op_cp1_enabled();
3704         op1 = MASK_CP1(ctx->opcode);
3705         switch (op1) {
3706         case OPC_MFC1:
3707         case OPC_CFC1:
3708         case OPC_MTC1:
3709         case OPC_CTC1:
3710             gen_cp1(ctx, op1, rt, rd);
3711             break;
3712         case OPC_BC1:
3713             gen_compute_branch1(ctx, MASK_CP1_BCOND(ctx->opcode), imm << 2);
3714             return;
3715         case OPC_S_FMT:
3716         case OPC_D_FMT:
3717         case OPC_W_FMT:
3718         case OPC_L_FMT:
3719             gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa);
3720             break;
3721         default:
3722             generate_exception_err(ctx, EXCP_RI, 1);
3723             break;
3724         }
3725 #else
3726         generate_exception_err(ctx, EXCP_CpU, 1);
3727 #endif
3728         break;
3729
3730     /* COP2.  */
3731     case OPC_LWC2:
3732     case OPC_LDC2:
3733     case OPC_SWC2:
3734     case OPC_SDC2:
3735     case OPC_CP2:
3736         /* COP2: Not implemented. */
3737         generate_exception_err(ctx, EXCP_CpU, 2);
3738         break;
3739
3740     case OPC_CP3:
3741         gen_op_cp1_enabled();
3742         op1 = MASK_CP3(ctx->opcode);
3743         switch (op1) {
3744         /* Not implemented */
3745         default:
3746             generate_exception_err(ctx, EXCP_RI, 1);
3747             break;
3748         }
3749         break;
3750
3751 #ifdef MIPS_HAS_MIPS64
3752     /* MIPS64 opcodes */
3753     case OPC_LWU:
3754     case OPC_LDL ... OPC_LDR:
3755     case OPC_SDL ... OPC_SDR:
3756     case OPC_LLD:
3757     case OPC_LD:
3758     case OPC_SCD:
3759     case OPC_SD:
3760         gen_ldst(ctx, op, rt, rs, imm);
3761         break;
3762     case OPC_DADDI ... OPC_DADDIU:
3763         gen_arith_imm(ctx, op, rt, rs, imm);
3764         break;
3765 #endif
3766 #ifdef MIPS_HAS_MIPS16
3767     case OPC_JALX:
3768         /* MIPS16: Not implemented. */
3769 #endif
3770 #ifdef MIPS_HAS_MDMX
3771     case OPC_MDMX:
3772         /* MDMX: Not implemented. */
3773 #endif
3774     default:            /* Invalid */
3775         MIPS_INVAL("");
3776         generate_exception(ctx, EXCP_RI);
3777         break;
3778     }
3779     if (ctx->hflags & MIPS_HFLAG_BMASK) {
3780         int hflags = ctx->hflags;
3781         /* Branches completion */
3782         ctx->hflags &= ~MIPS_HFLAG_BMASK;
3783         ctx->bstate = BS_BRANCH;
3784         save_cpu_state(ctx, 0);
3785         switch (hflags & MIPS_HFLAG_BMASK) {
3786         case MIPS_HFLAG_B:
3787             /* unconditional branch */
3788             MIPS_DEBUG("unconditional branch");
3789             gen_goto_tb(ctx, 0, ctx->btarget);
3790             break;
3791         case MIPS_HFLAG_BL:
3792             /* blikely taken case */
3793             MIPS_DEBUG("blikely branch taken");
3794             gen_goto_tb(ctx, 0, ctx->btarget);
3795             break;
3796         case MIPS_HFLAG_BC:
3797             /* Conditional branch */
3798             MIPS_DEBUG("conditional branch");
3799             {
3800               int l1;
3801               l1 = gen_new_label();
3802               gen_op_jnz_T2(l1);
3803               gen_goto_tb(ctx, 1, ctx->pc + 4);
3804               gen_set_label(l1);
3805               gen_goto_tb(ctx, 0, ctx->btarget);
3806             }
3807             break;
3808         case MIPS_HFLAG_BR:
3809             /* unconditional branch to register */
3810             MIPS_DEBUG("branch to register");
3811             gen_op_breg();
3812             break;
3813         default:
3814             MIPS_DEBUG("unknown branch");
3815             break;
3816         }
3817     }
3818 }
3819
3820 int gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
3821                                     int search_pc)
3822 {
3823     DisasContext ctx, *ctxp = &ctx;
3824     target_ulong pc_start;
3825     uint16_t *gen_opc_end;
3826     int j, lj = -1;
3827
3828     if (search_pc && loglevel)
3829         fprintf (logfile, "search pc %d\n", search_pc);
3830
3831     pc_start = tb->pc;
3832     gen_opc_ptr = gen_opc_buf;
3833     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
3834     gen_opparam_ptr = gen_opparam_buf;
3835     nb_gen_labels = 0;
3836     ctx.pc = pc_start;
3837     ctx.saved_pc = -1;
3838     ctx.tb = tb;
3839     ctx.bstate = BS_NONE;
3840     /* Restore delay slot state from the tb context.  */
3841     ctx.hflags = tb->flags;
3842     ctx.saved_hflags = ctx.hflags;
3843     if (ctx.hflags & MIPS_HFLAG_BR) {
3844         gen_op_restore_breg_target();
3845     } else if (ctx.hflags & MIPS_HFLAG_B) {
3846         ctx.btarget = env->btarget;
3847     } else if (ctx.hflags & MIPS_HFLAG_BMASK) {
3848         /* If we are in the delay slot of a conditional branch,
3849          * restore the branch condition from env->bcond to T2
3850          */
3851         ctx.btarget = env->btarget;
3852         gen_op_restore_bcond();
3853     }
3854 #if defined(CONFIG_USER_ONLY)
3855     ctx.mem_idx = 0;
3856 #else
3857     ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
3858 #endif
3859     ctx.CP0_Status = env->CP0_Status;
3860 #ifdef DEBUG_DISAS
3861     if (loglevel & CPU_LOG_TB_CPU) {
3862         fprintf(logfile, "------------------------------------------------\n");
3863         /* FIXME: This may print out stale hflags from env... */
3864         cpu_dump_state(env, logfile, fprintf, 0);
3865     }
3866 #endif
3867 #if defined MIPS_DEBUG_DISAS
3868     if (loglevel & CPU_LOG_TB_IN_ASM)
3869         fprintf(logfile, "\ntb %p super %d cond %04x\n",
3870                 tb, ctx.mem_idx, ctx.hflags);
3871 #endif
3872     while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
3873         if (env->nb_breakpoints > 0) {
3874             for(j = 0; j < env->nb_breakpoints; j++) {
3875                 if (env->breakpoints[j] == ctx.pc) {
3876                     save_cpu_state(ctxp, 1);
3877                     ctx.bstate = BS_BRANCH;
3878                     gen_op_debug();
3879                     goto done_generating;
3880                 }
3881             }
3882         }
3883
3884         if (search_pc) {
3885             j = gen_opc_ptr - gen_opc_buf;
3886             if (lj < j) {
3887                 lj++;
3888                 while (lj < j)
3889                     gen_opc_instr_start[lj++] = 0;
3890             }
3891             gen_opc_pc[lj] = ctx.pc;
3892             gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
3893             gen_opc_instr_start[lj] = 1;
3894         }
3895         ctx.opcode = ldl_code(ctx.pc);
3896         decode_opc(&ctx);
3897         ctx.pc += 4;
3898
3899         if (env->singlestep_enabled)
3900             break;
3901
3902         if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
3903             break;
3904
3905 #if defined (MIPS_SINGLE_STEP)
3906         break;
3907 #endif
3908     }
3909     if (env->singlestep_enabled) {
3910         save_cpu_state(ctxp, ctx.bstate == BS_NONE);
3911         gen_op_debug();
3912         goto done_generating;
3913     }
3914     else if (ctx.bstate != BS_BRANCH && ctx.bstate != BS_EXCP) {
3915         save_cpu_state(ctxp, 0);
3916         gen_goto_tb(&ctx, 0, ctx.pc);
3917     }
3918     gen_op_reset_T0();
3919     /* Generate the return instruction */
3920     gen_op_exit_tb();
3921 done_generating:
3922     *gen_opc_ptr = INDEX_op_end;
3923     if (search_pc) {
3924         j = gen_opc_ptr - gen_opc_buf;
3925         lj++;
3926         while (lj <= j)
3927             gen_opc_instr_start[lj++] = 0;
3928         tb->size = 0;
3929     } else {
3930         tb->size = ctx.pc - pc_start;
3931     }
3932 #ifdef DEBUG_DISAS
3933 #if defined MIPS_DEBUG_DISAS
3934     if (loglevel & CPU_LOG_TB_IN_ASM)
3935         fprintf(logfile, "\n");
3936 #endif
3937     if (loglevel & CPU_LOG_TB_IN_ASM) {
3938         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
3939     target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
3940         fprintf(logfile, "\n");
3941     }
3942     if (loglevel & CPU_LOG_TB_OP) {
3943         fprintf(logfile, "OP:\n");
3944         dump_ops(gen_opc_buf, gen_opparam_buf);
3945         fprintf(logfile, "\n");
3946     }
3947     if (loglevel & CPU_LOG_TB_CPU) {
3948         fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
3949     }
3950 #endif
3951     
3952     return 0;
3953 }
3954
3955 int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
3956 {
3957     return gen_intermediate_code_internal(env, tb, 0);
3958 }
3959
3960 int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
3961 {
3962     return gen_intermediate_code_internal(env, tb, 1);
3963 }
3964
3965 void fpu_dump_state(CPUState *env, FILE *f, 
3966                     int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
3967                     int flags)
3968 {
3969     int i;
3970
3971 #   define printfpr(fp) do { \
3972         fpu_fprintf(f, "w:%08x d:%08lx%08lx fd:%g fs:%g\n", \
3973                 (fp)->w[FP_ENDIAN_IDX], (fp)->w[0], (fp)->w[1], (fp)->fd, (fp)->fs[FP_ENDIAN_IDX]); \
3974     } while(0)
3975
3976     fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d\n",
3977                 env->fcr0, env->fcr31,
3978                 (env->CP0_Status & (1 << CP0St_FR)) != 0);
3979     fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
3980     fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
3981     fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
3982     for(i = 0; i < 32; i += 2) {
3983         fpu_fprintf(f, "%s: ", fregnames[i]);
3984         printfpr(FPR(env, i));
3985     }
3986
3987 #undef printfpr
3988 }
3989
3990 void dump_fpu (CPUState *env)
3991 {
3992     if (loglevel) { 
3993        fprintf(logfile, "pc=0x%08x HI=0x%08x LO=0x%08x ds %04x %08x %d\n",
3994                env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
3995        fpu_dump_state(env, logfile, fprintf, 0);
3996     }
3997 }
3998
3999 void cpu_dump_state (CPUState *env, FILE *f, 
4000                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
4001                      int flags)
4002 {
4003     uint32_t c0_status;
4004     int i;
4005     
4006     cpu_fprintf(f, "pc=0x%08x HI=0x%08x LO=0x%08x ds %04x %08x %d\n",
4007                 env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
4008     for (i = 0; i < 32; i++) {
4009         if ((i & 3) == 0)
4010             cpu_fprintf(f, "GPR%02d:", i);
4011         cpu_fprintf(f, " %s %08x", regnames[i], env->gpr[i]);
4012         if ((i & 3) == 3)
4013             cpu_fprintf(f, "\n");
4014     }
4015
4016     c0_status = env->CP0_Status;
4017     if (env->hflags & MIPS_HFLAG_UM)
4018         c0_status |= (1 << CP0St_UM);
4019     if (env->hflags & MIPS_HFLAG_ERL)
4020         c0_status |= (1 << CP0St_ERL);
4021     if (env->hflags & MIPS_HFLAG_EXL)
4022         c0_status |= (1 << CP0St_EXL);
4023
4024     cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x%08x\n",
4025                 c0_status, env->CP0_Cause, env->CP0_EPC);
4026     cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%08x\n",
4027                 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
4028     if (c0_status & (1 << CP0St_CU1))
4029         fpu_dump_state(env, f, cpu_fprintf, flags);
4030 }
4031
4032 CPUMIPSState *cpu_mips_init (void)
4033 {
4034     CPUMIPSState *env;
4035
4036     env = qemu_mallocz(sizeof(CPUMIPSState));
4037     if (!env)
4038         return NULL;
4039     cpu_exec_init(env);
4040     cpu_reset(env);
4041     return env;
4042 }
4043
4044 void cpu_reset (CPUMIPSState *env)
4045 {
4046     memset(env, 0, offsetof(CPUMIPSState, breakpoints));
4047
4048     tlb_flush(env, 1);
4049
4050     /* Minimal init */
4051     if (env->hflags & MIPS_HFLAG_BMASK) {
4052         /* If the exception was raised from a delay slot,
4053          * come back to the jump.  */
4054         env->CP0_ErrorEPC = env->PC - 4;
4055         env->hflags &= ~MIPS_HFLAG_BMASK;
4056     } else {
4057         env->CP0_ErrorEPC = env->PC;
4058     }
4059     env->PC = 0xBFC00000;
4060 #if defined (MIPS_USES_R4K_TLB)
4061     env->CP0_random = MIPS_TLB_NB - 1;
4062     env->tlb_in_use = MIPS_TLB_NB;
4063 #endif
4064     env->CP0_Wired = 0;
4065     /* SMP not implemented */
4066     env->CP0_EBase = 0x80000000;
4067     env->CP0_Config0 = MIPS_CONFIG0;
4068     env->CP0_Config1 = MIPS_CONFIG1;
4069     env->CP0_Config2 = MIPS_CONFIG2;
4070     env->CP0_Config3 = MIPS_CONFIG3;
4071     env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
4072     env->CP0_WatchLo = 0;
4073     env->hflags = MIPS_HFLAG_ERL;
4074     /* Count register increments in debug mode, EJTAG version 1 */
4075     env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
4076     env->CP0_PRid = MIPS_CPU;
4077     env->exception_index = EXCP_NONE;
4078 #if defined(CONFIG_USER_ONLY)
4079     env->hflags |= MIPS_HFLAG_UM;
4080 #endif
4081 #ifdef MIPS_USES_FPU
4082     env->fcr0 = MIPS_FCR0;      
4083 #endif
4084     /* XXX some guesswork here, values are CPU specific */
4085     env->SYNCI_Step = 16;
4086     env->CCRes = 2;
4087 }