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