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