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