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