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