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