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