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