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