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