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