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