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