]> Git Repo - qemu.git/blob - target-mips/translate.c
Simplify code.
[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             rn = "Status";
2631             break;
2632         case 1:
2633             gen_op_mtc0_intctl();
2634             rn = "IntCtl";
2635             break;
2636         case 2:
2637             gen_op_mtc0_srsctl();
2638             rn = "SRSCtl";
2639             break;
2640         case 3:
2641             gen_op_mtc0_srsmap();
2642             rn = "SRSMap";
2643             break;
2644         default:
2645             goto die;
2646         }
2647         /* Stop translation as we may have switched the execution mode */
2648         ctx->bstate = BS_STOP;
2649         break;
2650     case 13:
2651         switch (sel) {
2652         case 0:
2653             gen_op_mtc0_cause();
2654             rn = "Cause";
2655             break;
2656         default:
2657             goto die;
2658         }
2659         /* Stop translation as we may have switched the execution mode */
2660         ctx->bstate = BS_STOP;
2661         break;
2662     case 14:
2663         switch (sel) {
2664         case 0:
2665             gen_op_mtc0_epc();
2666             rn = "EPC";
2667             break;
2668         default:
2669             goto die;
2670         }
2671         break;
2672     case 15:
2673         switch (sel) {
2674         case 0:
2675             /* ignored */
2676             rn = "PRid";
2677             break;
2678         case 1:
2679             gen_op_mtc0_ebase();
2680             rn = "EBase";
2681             break;
2682         default:
2683             goto die;
2684         }
2685         break;
2686     case 16:
2687         switch (sel) {
2688         case 0:
2689             gen_op_mtc0_config0();
2690             rn = "Config";
2691             /* Stop translation as we may have switched the execution mode */
2692             ctx->bstate = BS_STOP;
2693             break;
2694         case 1:
2695             /* ignored, read only */
2696             rn = "Config1";
2697             break;
2698         case 2:
2699             gen_op_mtc0_config2();
2700             rn = "Config2";
2701             /* Stop translation as we may have switched the execution mode */
2702             ctx->bstate = BS_STOP;
2703             break;
2704         case 3:
2705             /* ignored, read only */
2706             rn = "Config3";
2707             break;
2708         /* 4,5 are reserved */
2709         /* 6,7 are implementation dependent */
2710         case 6:
2711             /* ignored */
2712             rn = "Config6";
2713             break;
2714         case 7:
2715             /* ignored */
2716             rn = "Config7";
2717             break;
2718         default:
2719             rn = "Invalid config selector";
2720             goto die;
2721         }
2722         break;
2723     case 17:
2724         switch (sel) {
2725         case 0:
2726             /* ignored */
2727             rn = "LLAddr";
2728             break;
2729         default:
2730             goto die;
2731         }
2732         break;
2733     case 18:
2734         switch (sel) {
2735         case 0 ... 7:
2736             gen_op_mtc0_watchlo(sel);
2737             rn = "WatchLo";
2738             break;
2739         default:
2740             goto die;
2741         }
2742         break;
2743     case 19:
2744         switch (sel) {
2745         case 0 ... 7:
2746             gen_op_mtc0_watchhi(sel);
2747             rn = "WatchHi";
2748             break;
2749         default:
2750             goto die;
2751         }
2752         break;
2753     case 20:
2754         switch (sel) {
2755         case 0:
2756 #ifdef TARGET_MIPS64
2757             gen_op_mtc0_xcontext();
2758             rn = "XContext";
2759             break;
2760 #endif
2761         default:
2762             goto die;
2763         }
2764         break;
2765     case 21:
2766        /* Officially reserved, but sel 0 is used for R1x000 framemask */
2767         switch (sel) {
2768         case 0:
2769             gen_op_mtc0_framemask();
2770             rn = "Framemask";
2771             break;
2772         default:
2773             goto die;
2774         }
2775         break;
2776     case 22:
2777         /* ignored */
2778         rn = "Diagnostic"; /* implementation dependent */
2779         break;
2780     case 23:
2781         switch (sel) {
2782         case 0:
2783             gen_op_mtc0_debug(); /* EJTAG support */
2784             rn = "Debug";
2785             break;
2786         case 1:
2787 //            gen_op_mtc0_tracecontrol(); /* PDtrace support */
2788             rn = "TraceControl";
2789 //            break;
2790         case 2:
2791 //            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
2792             rn = "TraceControl2";
2793 //            break;
2794         case 3:
2795 //            gen_op_mtc0_usertracedata(); /* PDtrace support */
2796             rn = "UserTraceData";
2797 //            break;
2798         case 4:
2799 //            gen_op_mtc0_debug(); /* PDtrace support */
2800             rn = "TraceBPC";
2801 //            break;
2802         default:
2803             goto die;
2804         }
2805         /* Stop translation as we may have switched the execution mode */
2806         ctx->bstate = BS_STOP;
2807         break;
2808     case 24:
2809         switch (sel) {
2810         case 0:
2811             gen_op_mtc0_depc(); /* EJTAG support */
2812             rn = "DEPC";
2813             break;
2814         default:
2815             goto die;
2816         }
2817         break;
2818     case 25:
2819         switch (sel) {
2820         case 0:
2821             gen_op_mtc0_performance0();
2822             rn = "Performance0";
2823             break;
2824         case 1:
2825 //            gen_op_mtc0_performance1();
2826             rn = "Performance1";
2827 //            break;
2828         case 2:
2829 //            gen_op_mtc0_performance2();
2830             rn = "Performance2";
2831 //            break;
2832         case 3:
2833 //            gen_op_mtc0_performance3();
2834             rn = "Performance3";
2835 //            break;
2836         case 4:
2837 //            gen_op_mtc0_performance4();
2838             rn = "Performance4";
2839 //            break;
2840         case 5:
2841 //            gen_op_mtc0_performance5();
2842             rn = "Performance5";
2843 //            break;
2844         case 6:
2845 //            gen_op_mtc0_performance6();
2846             rn = "Performance6";
2847 //            break;
2848         case 7:
2849 //            gen_op_mtc0_performance7();
2850             rn = "Performance7";
2851 //            break;
2852         default:
2853             goto die;
2854         }
2855        break;
2856     case 26:
2857         /* ignored */
2858         rn = "ECC";
2859         break;
2860     case 27:
2861         switch (sel) {
2862         case 0 ... 3:
2863             /* ignored */
2864             rn = "CacheErr";
2865             break;
2866         default:
2867             goto die;
2868         }
2869        break;
2870     case 28:
2871         switch (sel) {
2872         case 0:
2873         case 2:
2874         case 4:
2875         case 6:
2876             gen_op_mtc0_taglo();
2877             rn = "TagLo";
2878             break;
2879         case 1:
2880         case 3:
2881         case 5:
2882         case 7:
2883             gen_op_mtc0_datalo();
2884             rn = "DataLo";
2885             break;
2886         default:
2887             goto die;
2888         }
2889         break;
2890     case 29:
2891         switch (sel) {
2892         case 0:
2893         case 2:
2894         case 4:
2895         case 6:
2896             gen_op_mtc0_taghi();
2897             rn = "TagHi";
2898             break;
2899         case 1:
2900         case 3:
2901         case 5:
2902         case 7:
2903             gen_op_mtc0_datahi();
2904             rn = "DataHi";
2905             break;
2906         default:
2907             rn = "invalid sel";
2908             goto die;
2909         }
2910        break;
2911     case 30:
2912         switch (sel) {
2913         case 0:
2914             gen_op_mtc0_errorepc();
2915             rn = "ErrorEPC";
2916             break;
2917         default:
2918             goto die;
2919         }
2920         break;
2921     case 31:
2922         switch (sel) {
2923         case 0:
2924             gen_op_mtc0_desave(); /* EJTAG support */
2925             rn = "DESAVE";
2926             break;
2927         default:
2928             goto die;
2929         }
2930         /* Stop translation as we may have switched the execution mode */
2931         ctx->bstate = BS_STOP;
2932         break;
2933     default:
2934        goto die;
2935     }
2936 #if defined MIPS_DEBUG_DISAS
2937     if (loglevel & CPU_LOG_TB_IN_ASM) {
2938         fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2939                 rn, reg, sel);
2940     }
2941 #endif
2942     return;
2943
2944 die:
2945 #if defined MIPS_DEBUG_DISAS
2946     if (loglevel & CPU_LOG_TB_IN_ASM) {
2947         fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
2948                 rn, reg, sel);
2949     }
2950 #endif
2951     generate_exception(ctx, EXCP_RI);
2952 }
2953
2954 #ifdef TARGET_MIPS64
2955 static void gen_dmfc0 (DisasContext *ctx, int reg, int sel)
2956 {
2957     const char *rn = "invalid";
2958
2959     switch (reg) {
2960     case 0:
2961         switch (sel) {
2962         case 0:
2963             gen_op_mfc0_index();
2964             rn = "Index";
2965             break;
2966         case 1:
2967 //            gen_op_dmfc0_mvpcontrol(); /* MT ASE */
2968             rn = "MVPControl";
2969 //            break;
2970         case 2:
2971 //            gen_op_dmfc0_mvpconf0(); /* MT ASE */
2972             rn = "MVPConf0";
2973 //            break;
2974         case 3:
2975 //            gen_op_dmfc0_mvpconf1(); /* MT ASE */
2976             rn = "MVPConf1";
2977 //            break;
2978         default:
2979             goto die;
2980         }
2981         break;
2982     case 1:
2983         switch (sel) {
2984         case 0:
2985             gen_op_mfc0_random();
2986             rn = "Random";
2987             break;
2988         case 1:
2989 //            gen_op_dmfc0_vpecontrol(); /* MT ASE */
2990             rn = "VPEControl";
2991 //            break;
2992         case 2:
2993 //            gen_op_dmfc0_vpeconf0(); /* MT ASE */
2994             rn = "VPEConf0";
2995 //            break;
2996         case 3:
2997 //            gen_op_dmfc0_vpeconf1(); /* MT ASE */
2998             rn = "VPEConf1";
2999 //            break;
3000         case 4:
3001 //            gen_op_dmfc0_YQMask(); /* MT ASE */
3002             rn = "YQMask";
3003 //            break;
3004         case 5:
3005 //            gen_op_dmfc0_vpeschedule(); /* MT ASE */
3006             rn = "VPESchedule";
3007 //            break;
3008         case 6:
3009 //            gen_op_dmfc0_vpeschefback(); /* MT ASE */
3010             rn = "VPEScheFBack";
3011 //            break;
3012         case 7:
3013 //            gen_op_dmfc0_vpeopt(); /* MT ASE */
3014             rn = "VPEOpt";
3015 //            break;
3016         default:
3017             goto die;
3018         }
3019         break;
3020     case 2:
3021         switch (sel) {
3022         case 0:
3023             gen_op_dmfc0_entrylo0();
3024             rn = "EntryLo0";
3025             break;
3026         case 1:
3027 //            gen_op_dmfc0_tcstatus(); /* MT ASE */
3028             rn = "TCStatus";
3029 //            break;
3030         case 2:
3031 //            gen_op_dmfc0_tcbind(); /* MT ASE */
3032             rn = "TCBind";
3033 //            break;
3034         case 3:
3035 //            gen_op_dmfc0_tcrestart(); /* MT ASE */
3036             rn = "TCRestart";
3037 //            break;
3038         case 4:
3039 //            gen_op_dmfc0_tchalt(); /* MT ASE */
3040             rn = "TCHalt";
3041 //            break;
3042         case 5:
3043 //            gen_op_dmfc0_tccontext(); /* MT ASE */
3044             rn = "TCContext";
3045 //            break;
3046         case 6:
3047 //            gen_op_dmfc0_tcschedule(); /* MT ASE */
3048             rn = "TCSchedule";
3049 //            break;
3050         case 7:
3051 //            gen_op_dmfc0_tcschefback(); /* MT ASE */
3052             rn = "TCScheFBack";
3053 //            break;
3054         default:
3055             goto die;
3056         }
3057         break;
3058     case 3:
3059         switch (sel) {
3060         case 0:
3061             gen_op_dmfc0_entrylo1();
3062             rn = "EntryLo1";
3063             break;
3064         default:
3065             goto die;
3066         }
3067         break;
3068     case 4:
3069         switch (sel) {
3070         case 0:
3071             gen_op_dmfc0_context();
3072             rn = "Context";
3073             break;
3074         case 1:
3075 //            gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
3076             rn = "ContextConfig";
3077 //            break;
3078         default:
3079             goto die;
3080         }
3081         break;
3082     case 5:
3083         switch (sel) {
3084         case 0:
3085             gen_op_mfc0_pagemask();
3086             rn = "PageMask";
3087             break;
3088         case 1:
3089             gen_op_mfc0_pagegrain();
3090             rn = "PageGrain";
3091             break;
3092         default:
3093             goto die;
3094         }
3095         break;
3096     case 6:
3097         switch (sel) {
3098         case 0:
3099             gen_op_mfc0_wired();
3100             rn = "Wired";
3101             break;
3102         case 1:
3103 //            gen_op_dmfc0_srsconf0(); /* shadow registers */
3104             rn = "SRSConf0";
3105 //            break;
3106         case 2:
3107 //            gen_op_dmfc0_srsconf1(); /* shadow registers */
3108             rn = "SRSConf1";
3109 //            break;
3110         case 3:
3111 //            gen_op_dmfc0_srsconf2(); /* shadow registers */
3112             rn = "SRSConf2";
3113 //            break;
3114         case 4:
3115 //            gen_op_dmfc0_srsconf3(); /* shadow registers */
3116             rn = "SRSConf3";
3117 //            break;
3118         case 5:
3119 //            gen_op_dmfc0_srsconf4(); /* shadow registers */
3120             rn = "SRSConf4";
3121 //            break;
3122         default:
3123             goto die;
3124         }
3125         break;
3126     case 7:
3127         switch (sel) {
3128         case 0:
3129             gen_op_mfc0_hwrena();
3130             rn = "HWREna";
3131             break;
3132         default:
3133             goto die;
3134         }
3135         break;
3136     case 8:
3137         switch (sel) {
3138         case 0:
3139             gen_op_dmfc0_badvaddr();
3140             rn = "BadVaddr";
3141             break;
3142         default:
3143             goto die;
3144         }
3145         break;
3146     case 9:
3147         switch (sel) {
3148         case 0:
3149             gen_op_mfc0_count();
3150             rn = "Count";
3151             break;
3152         /* 6,7 are implementation dependent */
3153         default:
3154             goto die;
3155         }
3156         break;
3157     case 10:
3158         switch (sel) {
3159         case 0:
3160             gen_op_dmfc0_entryhi();
3161             rn = "EntryHi";
3162             break;
3163         default:
3164             goto die;
3165         }
3166         break;
3167     case 11:
3168         switch (sel) {
3169         case 0:
3170             gen_op_mfc0_compare();
3171             rn = "Compare";
3172             break;
3173         /* 6,7 are implementation dependent */
3174         default:
3175             goto die;
3176         }
3177         break;
3178     case 12:
3179         switch (sel) {
3180         case 0:
3181             gen_op_mfc0_status();
3182             rn = "Status";
3183             break;
3184         case 1:
3185             gen_op_mfc0_intctl();
3186             rn = "IntCtl";
3187             break;
3188         case 2:
3189             gen_op_mfc0_srsctl();
3190             rn = "SRSCtl";
3191             break;
3192         case 3:
3193             gen_op_mfc0_srsmap(); /* shadow registers */
3194             rn = "SRSMap";
3195             break;
3196         default:
3197             goto die;
3198         }
3199         break;
3200     case 13:
3201         switch (sel) {
3202         case 0:
3203             gen_op_mfc0_cause();
3204             rn = "Cause";
3205             break;
3206         default:
3207             goto die;
3208         }
3209         break;
3210     case 14:
3211         switch (sel) {
3212         case 0:
3213             gen_op_dmfc0_epc();
3214             rn = "EPC";
3215             break;
3216         default:
3217             goto die;
3218         }
3219         break;
3220     case 15:
3221         switch (sel) {
3222         case 0:
3223             gen_op_mfc0_prid();
3224             rn = "PRid";
3225             break;
3226         case 1:
3227             gen_op_mfc0_ebase();
3228             rn = "EBase";
3229             break;
3230         default:
3231             goto die;
3232         }
3233         break;
3234     case 16:
3235         switch (sel) {
3236         case 0:
3237             gen_op_mfc0_config0();
3238             rn = "Config";
3239             break;
3240         case 1:
3241             gen_op_mfc0_config1();
3242             rn = "Config1";
3243             break;
3244         case 2:
3245             gen_op_mfc0_config2();
3246             rn = "Config2";
3247             break;
3248         case 3:
3249             gen_op_mfc0_config3();
3250             rn = "Config3";
3251             break;
3252        /* 6,7 are implementation dependent */
3253         default:
3254             goto die;
3255         }
3256         break;
3257     case 17:
3258         switch (sel) {
3259         case 0:
3260             gen_op_dmfc0_lladdr();
3261             rn = "LLAddr";
3262             break;
3263         default:
3264             goto die;
3265         }
3266         break;
3267     case 18:
3268         switch (sel) {
3269         case 0 ... 7:
3270             gen_op_dmfc0_watchlo(sel);
3271             rn = "WatchLo";
3272             break;
3273         default:
3274             goto die;
3275         }
3276         break;
3277     case 19:
3278         switch (sel) {
3279         case 0 ... 7:
3280             gen_op_mfc0_watchhi(sel);
3281             rn = "WatchHi";
3282             break;
3283         default:
3284             goto die;
3285         }
3286         break;
3287     case 20:
3288         switch (sel) {
3289         case 0:
3290 #ifdef TARGET_MIPS64
3291             gen_op_dmfc0_xcontext();
3292             rn = "XContext";
3293             break;
3294 #endif
3295         default:
3296             goto die;
3297         }
3298         break;
3299     case 21:
3300        /* Officially reserved, but sel 0 is used for R1x000 framemask */
3301         switch (sel) {
3302         case 0:
3303             gen_op_mfc0_framemask();
3304             rn = "Framemask";
3305             break;
3306         default:
3307             goto die;
3308         }
3309         break;
3310     case 22:
3311         /* ignored */
3312         rn = "'Diagnostic"; /* implementation dependent */
3313         break;
3314     case 23:
3315         switch (sel) {
3316         case 0:
3317             gen_op_mfc0_debug(); /* EJTAG support */
3318             rn = "Debug";
3319             break;
3320         case 1:
3321 //            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
3322             rn = "TraceControl";
3323 //            break;
3324         case 2:
3325 //            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
3326             rn = "TraceControl2";
3327 //            break;
3328         case 3:
3329 //            gen_op_dmfc0_usertracedata(); /* PDtrace support */
3330             rn = "UserTraceData";
3331 //            break;
3332         case 4:
3333 //            gen_op_dmfc0_debug(); /* PDtrace support */
3334             rn = "TraceBPC";
3335 //            break;
3336         default:
3337             goto die;
3338         }
3339         break;
3340     case 24:
3341         switch (sel) {
3342         case 0:
3343             gen_op_dmfc0_depc(); /* EJTAG support */
3344             rn = "DEPC";
3345             break;
3346         default:
3347             goto die;
3348         }
3349         break;
3350     case 25:
3351         switch (sel) {
3352         case 0:
3353             gen_op_mfc0_performance0();
3354             rn = "Performance0";
3355             break;
3356         case 1:
3357 //            gen_op_dmfc0_performance1();
3358             rn = "Performance1";
3359 //            break;
3360         case 2:
3361 //            gen_op_dmfc0_performance2();
3362             rn = "Performance2";
3363 //            break;
3364         case 3:
3365 //            gen_op_dmfc0_performance3();
3366             rn = "Performance3";
3367 //            break;
3368         case 4:
3369 //            gen_op_dmfc0_performance4();
3370             rn = "Performance4";
3371 //            break;
3372         case 5:
3373 //            gen_op_dmfc0_performance5();
3374             rn = "Performance5";
3375 //            break;
3376         case 6:
3377 //            gen_op_dmfc0_performance6();
3378             rn = "Performance6";
3379 //            break;
3380         case 7:
3381 //            gen_op_dmfc0_performance7();
3382             rn = "Performance7";
3383 //            break;
3384         default:
3385             goto die;
3386         }
3387         break;
3388     case 26:
3389        rn = "ECC";
3390        break;
3391     case 27:
3392         switch (sel) {
3393         /* ignored */
3394         case 0 ... 3:
3395             rn = "CacheErr";
3396             break;
3397         default:
3398             goto die;
3399         }
3400         break;
3401     case 28:
3402         switch (sel) {
3403         case 0:
3404         case 2:
3405         case 4:
3406         case 6:
3407             gen_op_mfc0_taglo();
3408             rn = "TagLo";
3409             break;
3410         case 1:
3411         case 3:
3412         case 5:
3413         case 7:
3414             gen_op_mfc0_datalo();
3415             rn = "DataLo";
3416             break;
3417         default:
3418             goto die;
3419         }
3420         break;
3421     case 29:
3422         switch (sel) {
3423         case 0:
3424         case 2:
3425         case 4:
3426         case 6:
3427             gen_op_mfc0_taghi();
3428             rn = "TagHi";
3429             break;
3430         case 1:
3431         case 3:
3432         case 5:
3433         case 7:
3434             gen_op_mfc0_datahi();
3435             rn = "DataHi";
3436             break;
3437         default:
3438             goto die;
3439         }
3440         break;
3441     case 30:
3442         switch (sel) {
3443         case 0:
3444             gen_op_dmfc0_errorepc();
3445             rn = "ErrorEPC";
3446             break;
3447         default:
3448             goto die;
3449         }
3450         break;
3451     case 31:
3452         switch (sel) {
3453         case 0:
3454             gen_op_mfc0_desave(); /* EJTAG support */
3455             rn = "DESAVE";
3456             break;
3457         default:
3458             goto die;
3459         }
3460         break;
3461     default:
3462         goto die;
3463     }
3464 #if defined MIPS_DEBUG_DISAS
3465     if (loglevel & CPU_LOG_TB_IN_ASM) {
3466         fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3467                 rn, reg, sel);
3468     }
3469 #endif
3470     return;
3471
3472 die:
3473 #if defined MIPS_DEBUG_DISAS
3474     if (loglevel & CPU_LOG_TB_IN_ASM) {
3475         fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
3476                 rn, reg, sel);
3477     }
3478 #endif
3479     generate_exception(ctx, EXCP_RI);
3480 }
3481
3482 static void gen_dmtc0 (DisasContext *ctx, int reg, int sel)
3483 {
3484     const char *rn = "invalid";
3485
3486     switch (reg) {
3487     case 0:
3488         switch (sel) {
3489         case 0:
3490             gen_op_mtc0_index();
3491             rn = "Index";
3492             break;
3493         case 1:
3494 //            gen_op_mtc0_mvpcontrol(); /* MT ASE */
3495             rn = "MVPControl";
3496 //            break;
3497         case 2:
3498 //            gen_op_mtc0_mvpconf0(); /* MT ASE */
3499             rn = "MVPConf0";
3500 //            break;
3501         case 3:
3502 //            gen_op_mtc0_mvpconf1(); /* MT ASE */
3503             rn = "MVPConf1";
3504 //            break;
3505         default:
3506             goto die;
3507         }
3508         break;
3509     case 1:
3510         switch (sel) {
3511         case 0:
3512             /* ignored */
3513             rn = "Random";
3514             break;
3515         case 1:
3516 //            gen_op_mtc0_vpecontrol(); /* MT ASE */
3517             rn = "VPEControl";
3518 //            break;
3519         case 2:
3520 //            gen_op_mtc0_vpeconf0(); /* MT ASE */
3521             rn = "VPEConf0";
3522 //            break;
3523         case 3:
3524 //            gen_op_mtc0_vpeconf1(); /* MT ASE */
3525             rn = "VPEConf1";
3526 //            break;
3527         case 4:
3528 //            gen_op_mtc0_YQMask(); /* MT ASE */
3529             rn = "YQMask";
3530 //            break;
3531         case 5:
3532 //            gen_op_mtc0_vpeschedule(); /* MT ASE */
3533             rn = "VPESchedule";
3534 //            break;
3535         case 6:
3536 //            gen_op_mtc0_vpeschefback(); /* MT ASE */
3537             rn = "VPEScheFBack";
3538 //            break;
3539         case 7:
3540 //            gen_op_mtc0_vpeopt(); /* MT ASE */
3541             rn = "VPEOpt";
3542 //            break;
3543         default:
3544             goto die;
3545         }
3546         break;
3547     case 2:
3548         switch (sel) {
3549         case 0:
3550             gen_op_mtc0_entrylo0();
3551             rn = "EntryLo0";
3552             break;
3553         case 1:
3554 //            gen_op_mtc0_tcstatus(); /* MT ASE */
3555             rn = "TCStatus";
3556 //            break;
3557         case 2:
3558 //            gen_op_mtc0_tcbind(); /* MT ASE */
3559             rn = "TCBind";
3560 //            break;
3561         case 3:
3562 //            gen_op_mtc0_tcrestart(); /* MT ASE */
3563             rn = "TCRestart";
3564 //            break;
3565         case 4:
3566 //            gen_op_mtc0_tchalt(); /* MT ASE */
3567             rn = "TCHalt";
3568 //            break;
3569         case 5:
3570 //            gen_op_mtc0_tccontext(); /* MT ASE */
3571             rn = "TCContext";
3572 //            break;
3573         case 6:
3574 //            gen_op_mtc0_tcschedule(); /* MT ASE */
3575             rn = "TCSchedule";
3576 //            break;
3577         case 7:
3578 //            gen_op_mtc0_tcschefback(); /* MT ASE */
3579             rn = "TCScheFBack";
3580 //            break;
3581         default:
3582             goto die;
3583         }
3584         break;
3585     case 3:
3586         switch (sel) {
3587         case 0:
3588             gen_op_mtc0_entrylo1();
3589             rn = "EntryLo1";
3590             break;
3591         default:
3592             goto die;
3593         }
3594         break;
3595     case 4:
3596         switch (sel) {
3597         case 0:
3598             gen_op_mtc0_context();
3599             rn = "Context";
3600             break;
3601         case 1:
3602 //           gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
3603             rn = "ContextConfig";
3604 //           break;
3605         default:
3606             goto die;
3607         }
3608         break;
3609     case 5:
3610         switch (sel) {
3611         case 0:
3612             gen_op_mtc0_pagemask();
3613             rn = "PageMask";
3614             break;
3615         case 1:
3616             gen_op_mtc0_pagegrain();
3617             rn = "PageGrain";
3618             break;
3619         default:
3620             goto die;
3621         }
3622         break;
3623     case 6:
3624         switch (sel) {
3625         case 0:
3626             gen_op_mtc0_wired();
3627             rn = "Wired";
3628             break;
3629         case 1:
3630 //            gen_op_mtc0_srsconf0(); /* shadow registers */
3631             rn = "SRSConf0";
3632 //            break;
3633         case 2:
3634 //            gen_op_mtc0_srsconf1(); /* shadow registers */
3635             rn = "SRSConf1";
3636 //            break;
3637         case 3:
3638 //            gen_op_mtc0_srsconf2(); /* shadow registers */
3639             rn = "SRSConf2";
3640 //            break;
3641         case 4:
3642 //            gen_op_mtc0_srsconf3(); /* shadow registers */
3643             rn = "SRSConf3";
3644 //            break;
3645         case 5:
3646 //            gen_op_mtc0_srsconf4(); /* shadow registers */
3647             rn = "SRSConf4";
3648 //            break;
3649         default:
3650             goto die;
3651         }
3652         break;
3653     case 7:
3654         switch (sel) {
3655         case 0:
3656             gen_op_mtc0_hwrena();
3657             rn = "HWREna";
3658             break;
3659         default:
3660             goto die;
3661         }
3662         break;
3663     case 8:
3664         /* ignored */
3665         rn = "BadVaddr";
3666         break;
3667     case 9:
3668         switch (sel) {
3669         case 0:
3670             gen_op_mtc0_count();
3671             rn = "Count";
3672             break;
3673         /* 6,7 are implementation dependent */
3674         default:
3675             goto die;
3676         }
3677         /* Stop translation as we may have switched the execution mode */
3678         ctx->bstate = BS_STOP;
3679         break;
3680     case 10:
3681         switch (sel) {
3682         case 0:
3683             gen_op_mtc0_entryhi();
3684             rn = "EntryHi";
3685             break;
3686         default:
3687             goto die;
3688         }
3689         break;
3690     case 11:
3691         switch (sel) {
3692         case 0:
3693             gen_op_mtc0_compare();
3694             rn = "Compare";
3695             break;
3696         /* 6,7 are implementation dependent */
3697         default:
3698             goto die;
3699         }
3700         /* Stop translation as we may have switched the execution mode */
3701         ctx->bstate = BS_STOP;
3702         break;
3703     case 12:
3704         switch (sel) {
3705         case 0:
3706             gen_op_mtc0_status();
3707             rn = "Status";
3708             break;
3709         case 1:
3710             gen_op_mtc0_intctl();
3711             rn = "IntCtl";
3712             break;
3713         case 2:
3714             gen_op_mtc0_srsctl();
3715             rn = "SRSCtl";
3716             break;
3717         case 3:
3718             gen_op_mtc0_srsmap();
3719             rn = "SRSMap";
3720             break;
3721         default:
3722             goto die;
3723         }
3724         /* Stop translation as we may have switched the execution mode */
3725         ctx->bstate = BS_STOP;
3726         break;
3727     case 13:
3728         switch (sel) {
3729         case 0:
3730             gen_op_mtc0_cause();
3731             rn = "Cause";
3732             break;
3733         default:
3734             goto die;
3735         }
3736         /* Stop translation as we may have switched the execution mode */
3737         ctx->bstate = BS_STOP;
3738         break;
3739     case 14:
3740         switch (sel) {
3741         case 0:
3742             gen_op_mtc0_epc();
3743             rn = "EPC";
3744             break;
3745         default:
3746             goto die;
3747         }
3748         break;
3749     case 15:
3750         switch (sel) {
3751         case 0:
3752             /* ignored */
3753             rn = "PRid";
3754             break;
3755         case 1:
3756             gen_op_mtc0_ebase();
3757             rn = "EBase";
3758             break;
3759         default:
3760             goto die;
3761         }
3762         break;
3763     case 16:
3764         switch (sel) {
3765         case 0:
3766             gen_op_mtc0_config0();
3767             rn = "Config";
3768             /* Stop translation as we may have switched the execution mode */
3769             ctx->bstate = BS_STOP;
3770             break;
3771         case 1:
3772             /* ignored */
3773             rn = "Config1";
3774             break;
3775         case 2:
3776             gen_op_mtc0_config2();
3777             rn = "Config2";
3778             /* Stop translation as we may have switched the execution mode */
3779             ctx->bstate = BS_STOP;
3780             break;
3781         case 3:
3782             /* ignored */
3783             rn = "Config3";
3784             break;
3785         /* 6,7 are implementation dependent */
3786         default:
3787             rn = "Invalid config selector";
3788             goto die;
3789         }
3790         break;
3791     case 17:
3792         switch (sel) {
3793         case 0:
3794             /* ignored */
3795             rn = "LLAddr";
3796             break;
3797         default:
3798             goto die;
3799         }
3800         break;
3801     case 18:
3802         switch (sel) {
3803         case 0 ... 7:
3804             gen_op_mtc0_watchlo(sel);
3805             rn = "WatchLo";
3806             break;
3807         default:
3808             goto die;
3809         }
3810         break;
3811     case 19:
3812         switch (sel) {
3813         case 0 ... 7:
3814             gen_op_mtc0_watchhi(sel);
3815             rn = "WatchHi";
3816             break;
3817         default:
3818             goto die;
3819         }
3820         break;
3821     case 20:
3822         switch (sel) {
3823         case 0:
3824 #ifdef TARGET_MIPS64
3825             gen_op_mtc0_xcontext();
3826             rn = "XContext";
3827             break;
3828 #endif
3829         default:
3830             goto die;
3831         }
3832         break;
3833     case 21:
3834        /* Officially reserved, but sel 0 is used for R1x000 framemask */
3835         switch (sel) {
3836         case 0:
3837             gen_op_mtc0_framemask();
3838             rn = "Framemask";
3839             break;
3840         default:
3841             goto die;
3842         }
3843         break;
3844     case 22:
3845         /* ignored */
3846         rn = "Diagnostic"; /* implementation dependent */
3847         break;
3848     case 23:
3849         switch (sel) {
3850         case 0:
3851             gen_op_mtc0_debug(); /* EJTAG support */
3852             rn = "Debug";
3853             break;
3854         case 1:
3855 //            gen_op_mtc0_tracecontrol(); /* PDtrace support */
3856             rn = "TraceControl";
3857 //            break;
3858         case 2:
3859 //            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
3860             rn = "TraceControl2";
3861 //            break;
3862         case 3:
3863 //            gen_op_mtc0_usertracedata(); /* PDtrace support */
3864             rn = "UserTraceData";
3865 //            break;
3866         case 4:
3867 //            gen_op_mtc0_debug(); /* PDtrace support */
3868             rn = "TraceBPC";
3869 //            break;
3870         default:
3871             goto die;
3872         }
3873         /* Stop translation as we may have switched the execution mode */
3874         ctx->bstate = BS_STOP;
3875         break;
3876     case 24:
3877         switch (sel) {
3878         case 0:
3879             gen_op_mtc0_depc(); /* EJTAG support */
3880             rn = "DEPC";
3881             break;
3882         default:
3883             goto die;
3884         }
3885         break;
3886     case 25:
3887         switch (sel) {
3888         case 0:
3889             gen_op_mtc0_performance0();
3890             rn = "Performance0";
3891             break;
3892         case 1:
3893 //            gen_op_mtc0_performance1();
3894             rn = "Performance1";
3895 //            break;
3896         case 2:
3897 //            gen_op_mtc0_performance2();
3898             rn = "Performance2";
3899 //            break;
3900         case 3:
3901 //            gen_op_mtc0_performance3();
3902             rn = "Performance3";
3903 //            break;
3904         case 4:
3905 //            gen_op_mtc0_performance4();
3906             rn = "Performance4";
3907 //            break;
3908         case 5:
3909 //            gen_op_mtc0_performance5();
3910             rn = "Performance5";
3911 //            break;
3912         case 6:
3913 //            gen_op_mtc0_performance6();
3914             rn = "Performance6";
3915 //            break;
3916         case 7:
3917 //            gen_op_mtc0_performance7();
3918             rn = "Performance7";
3919 //            break;
3920         default:
3921             goto die;
3922         }
3923         break;
3924     case 26:
3925         /* ignored */
3926         rn = "ECC";
3927         break;
3928     case 27:
3929         switch (sel) {
3930         case 0 ... 3:
3931             /* ignored */
3932             rn = "CacheErr";
3933             break;
3934         default:
3935             goto die;
3936         }
3937         break;
3938     case 28:
3939         switch (sel) {
3940         case 0:
3941         case 2:
3942         case 4:
3943         case 6:
3944             gen_op_mtc0_taglo();
3945             rn = "TagLo";
3946             break;
3947         case 1:
3948         case 3:
3949         case 5:
3950         case 7:
3951             gen_op_mtc0_datalo();
3952             rn = "DataLo";
3953             break;
3954         default:
3955             goto die;
3956         }
3957         break;
3958     case 29:
3959         switch (sel) {
3960         case 0:
3961         case 2:
3962         case 4:
3963         case 6:
3964             gen_op_mtc0_taghi();
3965             rn = "TagHi";
3966             break;
3967         case 1:
3968         case 3:
3969         case 5:
3970         case 7:
3971             gen_op_mtc0_datahi();
3972             rn = "DataHi";
3973             break;
3974         default:
3975             rn = "invalid sel";
3976             goto die;
3977         }
3978         break;
3979     case 30:
3980         switch (sel) {
3981         case 0:
3982             gen_op_mtc0_errorepc();
3983             rn = "ErrorEPC";
3984             break;
3985         default:
3986             goto die;
3987         }
3988         break;
3989     case 31:
3990         switch (sel) {
3991         case 0:
3992             gen_op_mtc0_desave(); /* EJTAG support */
3993             rn = "DESAVE";
3994             break;
3995         default:
3996             goto die;
3997         }
3998         /* Stop translation as we may have switched the execution mode */
3999         ctx->bstate = BS_STOP;
4000         break;
4001     default:
4002         goto die;
4003     }
4004 #if defined MIPS_DEBUG_DISAS
4005     if (loglevel & CPU_LOG_TB_IN_ASM) {
4006         fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4007                 rn, reg, sel);
4008     }
4009 #endif
4010     return;
4011
4012 die:
4013 #if defined MIPS_DEBUG_DISAS
4014     if (loglevel & CPU_LOG_TB_IN_ASM) {
4015         fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
4016                 rn, reg, sel);
4017     }
4018 #endif
4019     generate_exception(ctx, EXCP_RI);
4020 }
4021 #endif /* TARGET_MIPS64 */
4022
4023 static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
4024 {
4025     const char *opn = "ldst";
4026
4027     switch (opc) {
4028     case OPC_MFC0:
4029         if (rt == 0) {
4030             /* Treat as NOP */
4031             return;
4032         }
4033         gen_mfc0(ctx, rd, ctx->opcode & 0x7);
4034         gen_op_store_T0_gpr(rt);
4035         opn = "mfc0";
4036         break;
4037     case OPC_MTC0:
4038         GEN_LOAD_REG_TN(T0, rt);
4039         gen_mtc0(ctx, rd, ctx->opcode & 0x7);
4040         opn = "mtc0";
4041         break;
4042 #ifdef TARGET_MIPS64
4043     case OPC_DMFC0:
4044         if (rt == 0) {
4045             /* Treat as NOP */
4046             return;
4047         }
4048         gen_dmfc0(ctx, rd, ctx->opcode & 0x7);
4049         gen_op_store_T0_gpr(rt);
4050         opn = "dmfc0";
4051         break;
4052     case OPC_DMTC0:
4053         GEN_LOAD_REG_TN(T0, rt);
4054         gen_dmtc0(ctx, rd, ctx->opcode & 0x7);
4055         opn = "dmtc0";
4056         break;
4057 #endif
4058     case OPC_TLBWI:
4059         opn = "tlbwi";
4060         if (!env->do_tlbwi)
4061             goto die;
4062         gen_op_tlbwi();
4063         break;
4064     case OPC_TLBWR:
4065         opn = "tlbwr";
4066         if (!env->do_tlbwr)
4067             goto die;
4068         gen_op_tlbwr();
4069         break;
4070     case OPC_TLBP:
4071         opn = "tlbp";
4072         if (!env->do_tlbp)
4073             goto die;
4074         gen_op_tlbp();
4075         break;
4076     case OPC_TLBR:
4077         opn = "tlbr";
4078         if (!env->do_tlbr)
4079             goto die;
4080         gen_op_tlbr();
4081         break;
4082     case OPC_ERET:
4083         opn = "eret";
4084         gen_op_eret();
4085         ctx->bstate = BS_EXCP;
4086         break;
4087     case OPC_DERET:
4088         opn = "deret";
4089         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
4090             MIPS_INVAL(opn);
4091             generate_exception(ctx, EXCP_RI);
4092         } else {
4093             gen_op_deret();
4094             ctx->bstate = BS_EXCP;
4095         }
4096         break;
4097     case OPC_WAIT:
4098         opn = "wait";
4099         /* If we get an exception, we want to restart at next instruction */
4100         ctx->pc += 4;
4101         save_cpu_state(ctx, 1);
4102         ctx->pc -= 4;
4103         gen_op_wait();
4104         ctx->bstate = BS_EXCP;
4105         break;
4106     default:
4107  die:
4108         MIPS_INVAL(opn);
4109         generate_exception(ctx, EXCP_RI);
4110         return;
4111     }
4112     MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
4113 }
4114
4115 /* CP1 Branches (before delay slot) */
4116 static void gen_compute_branch1 (DisasContext *ctx, uint32_t op,
4117                                  int32_t cc, int32_t offset)
4118 {
4119     target_ulong btarget;
4120     const char *opn = "cp1 cond branch";
4121
4122     btarget = ctx->pc + 4 + offset;
4123
4124     switch (op) {
4125     case OPC_BC1F:
4126         gen_op_bc1f(cc);
4127         opn = "bc1f";
4128         goto not_likely;
4129     case OPC_BC1FL:
4130         gen_op_bc1f(cc);
4131         opn = "bc1fl";
4132         goto likely;
4133     case OPC_BC1T:
4134         gen_op_bc1t(cc);
4135         opn = "bc1t";
4136         goto not_likely;
4137     case OPC_BC1TL:
4138         gen_op_bc1t(cc);
4139         opn = "bc1tl";
4140     likely:
4141         ctx->hflags |= MIPS_HFLAG_BL;
4142         gen_op_set_bcond();
4143         gen_op_save_bcond();
4144         break;
4145     case OPC_BC1FANY2:
4146         gen_op_bc1any2f(cc);
4147         opn = "bc1any2f";
4148         goto not_likely;
4149     case OPC_BC1TANY2:
4150         gen_op_bc1any2t(cc);
4151         opn = "bc1any2t";
4152         goto not_likely;
4153     case OPC_BC1FANY4:
4154         gen_op_bc1any4f(cc);
4155         opn = "bc1any4f";
4156         goto not_likely;
4157     case OPC_BC1TANY4:
4158         gen_op_bc1any4t(cc);
4159         opn = "bc1any4t";
4160     not_likely:
4161         ctx->hflags |= MIPS_HFLAG_BC;
4162         gen_op_set_bcond();
4163         break;
4164     default:
4165         MIPS_INVAL(opn);
4166         generate_exception (ctx, EXCP_RI);
4167         return;
4168     }
4169     MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
4170                ctx->hflags, btarget);
4171     ctx->btarget = btarget;
4172 }
4173
4174 /* Coprocessor 1 (FPU) */
4175
4176 #define FOP(func, fmt) (((fmt) << 21) | (func))
4177
4178 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
4179 {
4180     const char *opn = "cp1 move";
4181
4182     switch (opc) {
4183     case OPC_MFC1:
4184         GEN_LOAD_FREG_FTN(WT0, fs);
4185         gen_op_mfc1();
4186         GEN_STORE_TN_REG(rt, T0);
4187         opn = "mfc1";
4188         break;
4189     case OPC_MTC1:
4190         GEN_LOAD_REG_TN(T0, rt);
4191         gen_op_mtc1();
4192         GEN_STORE_FTN_FREG(fs, WT0);
4193         opn = "mtc1";
4194         break;
4195     case OPC_CFC1:
4196         GEN_LOAD_IMM_TN(T1, fs);
4197         gen_op_cfc1();
4198         GEN_STORE_TN_REG(rt, T0);
4199         opn = "cfc1";
4200         break;
4201     case OPC_CTC1:
4202         GEN_LOAD_IMM_TN(T1, fs);
4203         GEN_LOAD_REG_TN(T0, rt);
4204         gen_op_ctc1();
4205         opn = "ctc1";
4206         break;
4207     case OPC_DMFC1:
4208         GEN_LOAD_FREG_FTN(DT0, fs);
4209         gen_op_dmfc1();
4210         GEN_STORE_TN_REG(rt, T0);
4211         opn = "dmfc1";
4212         break;
4213     case OPC_DMTC1:
4214         GEN_LOAD_REG_TN(T0, rt);
4215         gen_op_dmtc1();
4216         GEN_STORE_FTN_FREG(fs, DT0);
4217         opn = "dmtc1";
4218         break;
4219     case OPC_MFHC1:
4220         GEN_LOAD_FREG_FTN(WTH0, fs);
4221         gen_op_mfhc1();
4222         GEN_STORE_TN_REG(rt, T0);
4223         opn = "mfhc1";
4224         break;
4225     case OPC_MTHC1:
4226         GEN_LOAD_REG_TN(T0, rt);
4227         gen_op_mthc1();
4228         GEN_STORE_FTN_FREG(fs, WTH0);
4229         opn = "mthc1";
4230         break;
4231     default:
4232         MIPS_INVAL(opn);
4233         generate_exception (ctx, EXCP_RI);
4234         return;
4235     }
4236     MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
4237 }
4238
4239 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
4240 {
4241     uint32_t ccbit;
4242
4243     GEN_LOAD_REG_TN(T0, rd);
4244     GEN_LOAD_REG_TN(T1, rs);
4245     if (cc) {
4246         ccbit = 1 << (24 + cc);
4247     } else
4248         ccbit = 1 << 23;
4249     if (!tf)
4250         gen_op_movf(ccbit);
4251     else
4252         gen_op_movt(ccbit);
4253     GEN_STORE_TN_REG(rd, T0);
4254 }
4255
4256 #define GEN_MOVCF(fmt)                                                \
4257 static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
4258 {                                                                     \
4259     uint32_t ccbit;                                                   \
4260                                                                       \
4261     if (cc) {                                                         \
4262         ccbit = 1 << (24 + cc);                                       \
4263     } else                                                            \
4264         ccbit = 1 << 23;                                              \
4265     if (!tf)                                                          \
4266         glue(gen_op_float_movf_, fmt)(ccbit);                         \
4267     else                                                              \
4268         glue(gen_op_float_movt_, fmt)(ccbit);                         \
4269 }
4270 GEN_MOVCF(d);
4271 GEN_MOVCF(s);
4272 GEN_MOVCF(ps);
4273 #undef GEN_MOVCF
4274
4275 static void gen_farith (DisasContext *ctx, uint32_t op1,
4276                         int ft, int fs, int fd, int cc)
4277 {
4278     const char *opn = "farith";
4279     const char *condnames[] = {
4280             "c.f",
4281             "c.un",
4282             "c.eq",
4283             "c.ueq",
4284             "c.olt",
4285             "c.ult",
4286             "c.ole",
4287             "c.ule",
4288             "c.sf",
4289             "c.ngle",
4290             "c.seq",
4291             "c.ngl",
4292             "c.lt",
4293             "c.nge",
4294             "c.le",
4295             "c.ngt",
4296     };
4297     const char *condnames_abs[] = {
4298             "cabs.f",
4299             "cabs.un",
4300             "cabs.eq",
4301             "cabs.ueq",
4302             "cabs.olt",
4303             "cabs.ult",
4304             "cabs.ole",
4305             "cabs.ule",
4306             "cabs.sf",
4307             "cabs.ngle",
4308             "cabs.seq",
4309             "cabs.ngl",
4310             "cabs.lt",
4311             "cabs.nge",
4312             "cabs.le",
4313             "cabs.ngt",
4314     };
4315     enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
4316     uint32_t func = ctx->opcode & 0x3f;
4317
4318     switch (ctx->opcode & FOP(0x3f, 0x1f)) {
4319     case FOP(0, 16):
4320         GEN_LOAD_FREG_FTN(WT0, fs);
4321         GEN_LOAD_FREG_FTN(WT1, ft);
4322         gen_op_float_add_s();
4323         GEN_STORE_FTN_FREG(fd, WT2);
4324         opn = "add.s";
4325         optype = BINOP;
4326         break;
4327     case FOP(1, 16):
4328         GEN_LOAD_FREG_FTN(WT0, fs);
4329         GEN_LOAD_FREG_FTN(WT1, ft);
4330         gen_op_float_sub_s();
4331         GEN_STORE_FTN_FREG(fd, WT2);
4332         opn = "sub.s";
4333         optype = BINOP;
4334         break;
4335     case FOP(2, 16):
4336         GEN_LOAD_FREG_FTN(WT0, fs);
4337         GEN_LOAD_FREG_FTN(WT1, ft);
4338         gen_op_float_mul_s();
4339         GEN_STORE_FTN_FREG(fd, WT2);
4340         opn = "mul.s";
4341         optype = BINOP;
4342         break;
4343     case FOP(3, 16):
4344         GEN_LOAD_FREG_FTN(WT0, fs);
4345         GEN_LOAD_FREG_FTN(WT1, ft);
4346         gen_op_float_div_s();
4347         GEN_STORE_FTN_FREG(fd, WT2);
4348         opn = "div.s";
4349         optype = BINOP;
4350         break;
4351     case FOP(4, 16):
4352         GEN_LOAD_FREG_FTN(WT0, fs);
4353         gen_op_float_sqrt_s();
4354         GEN_STORE_FTN_FREG(fd, WT2);
4355         opn = "sqrt.s";
4356         break;
4357     case FOP(5, 16):
4358         GEN_LOAD_FREG_FTN(WT0, fs);
4359         gen_op_float_abs_s();
4360         GEN_STORE_FTN_FREG(fd, WT2);
4361         opn = "abs.s";
4362         break;
4363     case FOP(6, 16):
4364         GEN_LOAD_FREG_FTN(WT0, fs);
4365         gen_op_float_mov_s();
4366         GEN_STORE_FTN_FREG(fd, WT2);
4367         opn = "mov.s";
4368         break;
4369     case FOP(7, 16):
4370         GEN_LOAD_FREG_FTN(WT0, fs);
4371         gen_op_float_chs_s();
4372         GEN_STORE_FTN_FREG(fd, WT2);
4373         opn = "neg.s";
4374         break;
4375     case FOP(8, 16):
4376         check_cp1_64bitmode(ctx);
4377         GEN_LOAD_FREG_FTN(WT0, fs);
4378         gen_op_float_roundl_s();
4379         GEN_STORE_FTN_FREG(fd, DT2);
4380         opn = "round.l.s";
4381         break;
4382     case FOP(9, 16):
4383         check_cp1_64bitmode(ctx);
4384         GEN_LOAD_FREG_FTN(WT0, fs);
4385         gen_op_float_truncl_s();
4386         GEN_STORE_FTN_FREG(fd, DT2);
4387         opn = "trunc.l.s";
4388         break;
4389     case FOP(10, 16):
4390         check_cp1_64bitmode(ctx);
4391         GEN_LOAD_FREG_FTN(WT0, fs);
4392         gen_op_float_ceill_s();
4393         GEN_STORE_FTN_FREG(fd, DT2);
4394         opn = "ceil.l.s";
4395         break;
4396     case FOP(11, 16):
4397         check_cp1_64bitmode(ctx);
4398         GEN_LOAD_FREG_FTN(WT0, fs);
4399         gen_op_float_floorl_s();
4400         GEN_STORE_FTN_FREG(fd, DT2);
4401         opn = "floor.l.s";
4402         break;
4403     case FOP(12, 16):
4404         GEN_LOAD_FREG_FTN(WT0, fs);
4405         gen_op_float_roundw_s();
4406         GEN_STORE_FTN_FREG(fd, WT2);
4407         opn = "round.w.s";
4408         break;
4409     case FOP(13, 16):
4410         GEN_LOAD_FREG_FTN(WT0, fs);
4411         gen_op_float_truncw_s();
4412         GEN_STORE_FTN_FREG(fd, WT2);
4413         opn = "trunc.w.s";
4414         break;
4415     case FOP(14, 16):
4416         GEN_LOAD_FREG_FTN(WT0, fs);
4417         gen_op_float_ceilw_s();
4418         GEN_STORE_FTN_FREG(fd, WT2);
4419         opn = "ceil.w.s";
4420         break;
4421     case FOP(15, 16):
4422         GEN_LOAD_FREG_FTN(WT0, fs);
4423         gen_op_float_floorw_s();
4424         GEN_STORE_FTN_FREG(fd, WT2);
4425         opn = "floor.w.s";
4426         break;
4427     case FOP(17, 16):
4428         GEN_LOAD_REG_TN(T0, ft);
4429         GEN_LOAD_FREG_FTN(WT0, fs);
4430         GEN_LOAD_FREG_FTN(WT2, fd);
4431         gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
4432         GEN_STORE_FTN_FREG(fd, WT2);
4433         opn = "movcf.s";
4434         break;
4435     case FOP(18, 16):
4436         GEN_LOAD_REG_TN(T0, ft);
4437         GEN_LOAD_FREG_FTN(WT0, fs);
4438         GEN_LOAD_FREG_FTN(WT2, fd);
4439         gen_op_float_movz_s();
4440         GEN_STORE_FTN_FREG(fd, WT2);
4441         opn = "movz.s";
4442         break;
4443     case FOP(19, 16):
4444         GEN_LOAD_REG_TN(T0, ft);
4445         GEN_LOAD_FREG_FTN(WT0, fs);
4446         GEN_LOAD_FREG_FTN(WT2, fd);
4447         gen_op_float_movn_s();
4448         GEN_STORE_FTN_FREG(fd, WT2);
4449         opn = "movn.s";
4450         break;
4451     case FOP(21, 16):
4452         GEN_LOAD_FREG_FTN(WT0, fs);
4453         gen_op_float_recip_s();
4454         GEN_STORE_FTN_FREG(fd, WT2);
4455         opn = "recip.s";
4456         break;
4457     case FOP(22, 16):
4458         GEN_LOAD_FREG_FTN(WT0, fs);
4459         gen_op_float_rsqrt_s();
4460         GEN_STORE_FTN_FREG(fd, WT2);
4461         opn = "rsqrt.s";
4462         break;
4463     case FOP(28, 16):
4464         check_cp1_64bitmode(ctx);
4465         GEN_LOAD_FREG_FTN(WT0, fs);
4466         GEN_LOAD_FREG_FTN(WT2, fd);
4467         gen_op_float_recip2_s();
4468         GEN_STORE_FTN_FREG(fd, WT2);
4469         opn = "recip2.s";
4470         break;
4471     case FOP(29, 16):
4472         check_cp1_64bitmode(ctx);
4473         GEN_LOAD_FREG_FTN(WT0, fs);
4474         gen_op_float_recip1_s();
4475         GEN_STORE_FTN_FREG(fd, WT2);
4476         opn = "recip1.s";
4477         break;
4478     case FOP(30, 16):
4479         check_cp1_64bitmode(ctx);
4480         GEN_LOAD_FREG_FTN(WT0, fs);
4481         gen_op_float_rsqrt1_s();
4482         GEN_STORE_FTN_FREG(fd, WT2);
4483         opn = "rsqrt1.s";
4484         break;
4485     case FOP(31, 16):
4486         check_cp1_64bitmode(ctx);
4487         GEN_LOAD_FREG_FTN(WT0, fs);
4488         GEN_LOAD_FREG_FTN(WT2, fd);
4489         gen_op_float_rsqrt2_s();
4490         GEN_STORE_FTN_FREG(fd, WT2);
4491         opn = "rsqrt2.s";
4492         break;
4493     case FOP(33, 16):
4494         check_cp1_registers(ctx, fd);
4495         GEN_LOAD_FREG_FTN(WT0, fs);
4496         gen_op_float_cvtd_s();
4497         GEN_STORE_FTN_FREG(fd, DT2);
4498         opn = "cvt.d.s";
4499         break;
4500     case FOP(36, 16):
4501         GEN_LOAD_FREG_FTN(WT0, fs);
4502         gen_op_float_cvtw_s();
4503         GEN_STORE_FTN_FREG(fd, WT2);
4504         opn = "cvt.w.s";
4505         break;
4506     case FOP(37, 16):
4507         check_cp1_64bitmode(ctx);
4508         GEN_LOAD_FREG_FTN(WT0, fs);
4509         gen_op_float_cvtl_s();
4510         GEN_STORE_FTN_FREG(fd, DT2);
4511         opn = "cvt.l.s";
4512         break;
4513     case FOP(38, 16):
4514         check_cp1_64bitmode(ctx);
4515         GEN_LOAD_FREG_FTN(WT1, fs);
4516         GEN_LOAD_FREG_FTN(WT0, ft);
4517         gen_op_float_cvtps_s();
4518         GEN_STORE_FTN_FREG(fd, DT2);
4519         opn = "cvt.ps.s";
4520         break;
4521     case FOP(48, 16):
4522     case FOP(49, 16):
4523     case FOP(50, 16):
4524     case FOP(51, 16):
4525     case FOP(52, 16):
4526     case FOP(53, 16):
4527     case FOP(54, 16):
4528     case FOP(55, 16):
4529     case FOP(56, 16):
4530     case FOP(57, 16):
4531     case FOP(58, 16):
4532     case FOP(59, 16):
4533     case FOP(60, 16):
4534     case FOP(61, 16):
4535     case FOP(62, 16):
4536     case FOP(63, 16):
4537         GEN_LOAD_FREG_FTN(WT0, fs);
4538         GEN_LOAD_FREG_FTN(WT1, ft);
4539         if (ctx->opcode & (1 << 6)) {
4540             check_cp1_64bitmode(ctx);
4541             gen_cmpabs_s(func-48, cc);
4542             opn = condnames_abs[func-48];
4543         } else {
4544             gen_cmp_s(func-48, cc);
4545             opn = condnames[func-48];
4546         }
4547         break;
4548     case FOP(0, 17):
4549         check_cp1_registers(ctx, fs | ft | fd);
4550         GEN_LOAD_FREG_FTN(DT0, fs);
4551         GEN_LOAD_FREG_FTN(DT1, ft);
4552         gen_op_float_add_d();
4553         GEN_STORE_FTN_FREG(fd, DT2);
4554         opn = "add.d";
4555         optype = BINOP;
4556         break;
4557     case FOP(1, 17):
4558         check_cp1_registers(ctx, fs | ft | fd);
4559         GEN_LOAD_FREG_FTN(DT0, fs);
4560         GEN_LOAD_FREG_FTN(DT1, ft);
4561         gen_op_float_sub_d();
4562         GEN_STORE_FTN_FREG(fd, DT2);
4563         opn = "sub.d";
4564         optype = BINOP;
4565         break;
4566     case FOP(2, 17):
4567         check_cp1_registers(ctx, fs | ft | fd);
4568         GEN_LOAD_FREG_FTN(DT0, fs);
4569         GEN_LOAD_FREG_FTN(DT1, ft);
4570         gen_op_float_mul_d();
4571         GEN_STORE_FTN_FREG(fd, DT2);
4572         opn = "mul.d";
4573         optype = BINOP;
4574         break;
4575     case FOP(3, 17):
4576         check_cp1_registers(ctx, fs | ft | fd);
4577         GEN_LOAD_FREG_FTN(DT0, fs);
4578         GEN_LOAD_FREG_FTN(DT1, ft);
4579         gen_op_float_div_d();
4580         GEN_STORE_FTN_FREG(fd, DT2);
4581         opn = "div.d";
4582         optype = BINOP;
4583         break;
4584     case FOP(4, 17):
4585         check_cp1_registers(ctx, fs | fd);
4586         GEN_LOAD_FREG_FTN(DT0, fs);
4587         gen_op_float_sqrt_d();
4588         GEN_STORE_FTN_FREG(fd, DT2);
4589         opn = "sqrt.d";
4590         break;
4591     case FOP(5, 17):
4592         check_cp1_registers(ctx, fs | fd);
4593         GEN_LOAD_FREG_FTN(DT0, fs);
4594         gen_op_float_abs_d();
4595         GEN_STORE_FTN_FREG(fd, DT2);
4596         opn = "abs.d";
4597         break;
4598     case FOP(6, 17):
4599         check_cp1_registers(ctx, fs | fd);
4600         GEN_LOAD_FREG_FTN(DT0, fs);
4601         gen_op_float_mov_d();
4602         GEN_STORE_FTN_FREG(fd, DT2);
4603         opn = "mov.d";
4604         break;
4605     case FOP(7, 17):
4606         check_cp1_registers(ctx, fs | fd);
4607         GEN_LOAD_FREG_FTN(DT0, fs);
4608         gen_op_float_chs_d();
4609         GEN_STORE_FTN_FREG(fd, DT2);
4610         opn = "neg.d";
4611         break;
4612     case FOP(8, 17):
4613         check_cp1_64bitmode(ctx);
4614         GEN_LOAD_FREG_FTN(DT0, fs);
4615         gen_op_float_roundl_d();
4616         GEN_STORE_FTN_FREG(fd, DT2);
4617         opn = "round.l.d";
4618         break;
4619     case FOP(9, 17):
4620         check_cp1_64bitmode(ctx);
4621         GEN_LOAD_FREG_FTN(DT0, fs);
4622         gen_op_float_truncl_d();
4623         GEN_STORE_FTN_FREG(fd, DT2);
4624         opn = "trunc.l.d";
4625         break;
4626     case FOP(10, 17):
4627         check_cp1_64bitmode(ctx);
4628         GEN_LOAD_FREG_FTN(DT0, fs);
4629         gen_op_float_ceill_d();
4630         GEN_STORE_FTN_FREG(fd, DT2);
4631         opn = "ceil.l.d";
4632         break;
4633     case FOP(11, 17):
4634         check_cp1_64bitmode(ctx);
4635         GEN_LOAD_FREG_FTN(DT0, fs);
4636         gen_op_float_floorl_d();
4637         GEN_STORE_FTN_FREG(fd, DT2);
4638         opn = "floor.l.d";
4639         break;
4640     case FOP(12, 17):
4641         check_cp1_registers(ctx, fs);
4642         GEN_LOAD_FREG_FTN(DT0, fs);
4643         gen_op_float_roundw_d();
4644         GEN_STORE_FTN_FREG(fd, WT2);
4645         opn = "round.w.d";
4646         break;
4647     case FOP(13, 17):
4648         check_cp1_registers(ctx, fs);
4649         GEN_LOAD_FREG_FTN(DT0, fs);
4650         gen_op_float_truncw_d();
4651         GEN_STORE_FTN_FREG(fd, WT2);
4652         opn = "trunc.w.d";
4653         break;
4654     case FOP(14, 17):
4655         check_cp1_registers(ctx, fs);
4656         GEN_LOAD_FREG_FTN(DT0, fs);
4657         gen_op_float_ceilw_d();
4658         GEN_STORE_FTN_FREG(fd, WT2);
4659         opn = "ceil.w.d";
4660         break;
4661     case FOP(15, 17):
4662         check_cp1_registers(ctx, fs);
4663         GEN_LOAD_FREG_FTN(DT0, fs);
4664         gen_op_float_floorw_d();
4665         GEN_STORE_FTN_FREG(fd, WT2);
4666         opn = "floor.w.d";
4667         break;
4668     case FOP(17, 17):
4669         GEN_LOAD_REG_TN(T0, ft);
4670         GEN_LOAD_FREG_FTN(DT0, fs);
4671         GEN_LOAD_FREG_FTN(DT2, fd);
4672         gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1);
4673         GEN_STORE_FTN_FREG(fd, DT2);
4674         opn = "movcf.d";
4675         break;
4676     case FOP(18, 17):
4677         GEN_LOAD_REG_TN(T0, ft);
4678         GEN_LOAD_FREG_FTN(DT0, fs);
4679         GEN_LOAD_FREG_FTN(DT2, fd);
4680         gen_op_float_movz_d();
4681         GEN_STORE_FTN_FREG(fd, DT2);
4682         opn = "movz.d";
4683         break;
4684     case FOP(19, 17):
4685         GEN_LOAD_REG_TN(T0, ft);
4686         GEN_LOAD_FREG_FTN(DT0, fs);
4687         GEN_LOAD_FREG_FTN(DT2, fd);
4688         gen_op_float_movn_d();
4689         GEN_STORE_FTN_FREG(fd, DT2);
4690         opn = "movn.d";
4691         break;
4692     case FOP(21, 17):
4693         check_cp1_registers(ctx, fs | fd);
4694         GEN_LOAD_FREG_FTN(DT0, fs);
4695         gen_op_float_recip_d();
4696         GEN_STORE_FTN_FREG(fd, DT2);
4697         opn = "recip.d";
4698         break;
4699     case FOP(22, 17):
4700         check_cp1_registers(ctx, fs | fd);
4701         GEN_LOAD_FREG_FTN(DT0, fs);
4702         gen_op_float_rsqrt_d();
4703         GEN_STORE_FTN_FREG(fd, DT2);
4704         opn = "rsqrt.d";
4705         break;
4706     case FOP(28, 17):
4707         check_cp1_64bitmode(ctx);
4708         GEN_LOAD_FREG_FTN(DT0, fs);
4709         GEN_LOAD_FREG_FTN(DT2, ft);
4710         gen_op_float_recip2_d();
4711         GEN_STORE_FTN_FREG(fd, DT2);
4712         opn = "recip2.d";
4713         break;
4714     case FOP(29, 17):
4715         check_cp1_64bitmode(ctx);
4716         GEN_LOAD_FREG_FTN(DT0, fs);
4717         gen_op_float_recip1_d();
4718         GEN_STORE_FTN_FREG(fd, DT2);
4719         opn = "recip1.d";
4720         break;
4721     case FOP(30, 17):
4722         check_cp1_64bitmode(ctx);
4723         GEN_LOAD_FREG_FTN(DT0, fs);
4724         gen_op_float_rsqrt1_d();
4725         GEN_STORE_FTN_FREG(fd, DT2);
4726         opn = "rsqrt1.d";
4727         break;
4728     case FOP(31, 17):
4729         check_cp1_64bitmode(ctx);
4730         GEN_LOAD_FREG_FTN(DT0, fs);
4731         GEN_LOAD_FREG_FTN(DT2, ft);
4732         gen_op_float_rsqrt2_d();
4733         GEN_STORE_FTN_FREG(fd, DT2);
4734         opn = "rsqrt2.d";
4735         break;
4736     case FOP(48, 17):
4737     case FOP(49, 17):
4738     case FOP(50, 17):
4739     case FOP(51, 17):
4740     case FOP(52, 17):
4741     case FOP(53, 17):
4742     case FOP(54, 17):
4743     case FOP(55, 17):
4744     case FOP(56, 17):
4745     case FOP(57, 17):
4746     case FOP(58, 17):
4747     case FOP(59, 17):
4748     case FOP(60, 17):
4749     case FOP(61, 17):
4750     case FOP(62, 17):
4751     case FOP(63, 17):
4752         GEN_LOAD_FREG_FTN(DT0, fs);
4753         GEN_LOAD_FREG_FTN(DT1, ft);
4754         if (ctx->opcode & (1 << 6)) {
4755             check_cp1_64bitmode(ctx);
4756             gen_cmpabs_d(func-48, cc);
4757             opn = condnames_abs[func-48];
4758         } else {
4759             check_cp1_registers(ctx, fs | ft);
4760             gen_cmp_d(func-48, cc);
4761             opn = condnames[func-48];
4762         }
4763         break;
4764     case FOP(32, 17):
4765         check_cp1_registers(ctx, fs);
4766         GEN_LOAD_FREG_FTN(DT0, fs);
4767         gen_op_float_cvts_d();
4768         GEN_STORE_FTN_FREG(fd, WT2);
4769         opn = "cvt.s.d";
4770         break;
4771     case FOP(36, 17):
4772         check_cp1_registers(ctx, fs);
4773         GEN_LOAD_FREG_FTN(DT0, fs);
4774         gen_op_float_cvtw_d();
4775         GEN_STORE_FTN_FREG(fd, WT2);
4776         opn = "cvt.w.d";
4777         break;
4778     case FOP(37, 17):
4779         check_cp1_64bitmode(ctx);
4780         GEN_LOAD_FREG_FTN(DT0, fs);
4781         gen_op_float_cvtl_d();
4782         GEN_STORE_FTN_FREG(fd, DT2);
4783         opn = "cvt.l.d";
4784         break;
4785     case FOP(32, 20):
4786         GEN_LOAD_FREG_FTN(WT0, fs);
4787         gen_op_float_cvts_w();
4788         GEN_STORE_FTN_FREG(fd, WT2);
4789         opn = "cvt.s.w";
4790         break;
4791     case FOP(33, 20):
4792         check_cp1_registers(ctx, fd);
4793         GEN_LOAD_FREG_FTN(WT0, fs);
4794         gen_op_float_cvtd_w();
4795         GEN_STORE_FTN_FREG(fd, DT2);
4796         opn = "cvt.d.w";
4797         break;
4798     case FOP(32, 21):
4799         check_cp1_64bitmode(ctx);
4800         GEN_LOAD_FREG_FTN(DT0, fs);
4801         gen_op_float_cvts_l();
4802         GEN_STORE_FTN_FREG(fd, WT2);
4803         opn = "cvt.s.l";
4804         break;
4805     case FOP(33, 21):
4806         check_cp1_64bitmode(ctx);
4807         GEN_LOAD_FREG_FTN(DT0, fs);
4808         gen_op_float_cvtd_l();
4809         GEN_STORE_FTN_FREG(fd, DT2);
4810         opn = "cvt.d.l";
4811         break;
4812     case FOP(38, 20):
4813     case FOP(38, 21):
4814         check_cp1_64bitmode(ctx);
4815         GEN_LOAD_FREG_FTN(WT0, fs);
4816         GEN_LOAD_FREG_FTN(WTH0, fs);
4817         gen_op_float_cvtps_pw();
4818         GEN_STORE_FTN_FREG(fd, WT2);
4819         GEN_STORE_FTN_FREG(fd, WTH2);
4820         opn = "cvt.ps.pw";
4821         break;
4822     case FOP(0, 22):
4823         check_cp1_64bitmode(ctx);
4824         GEN_LOAD_FREG_FTN(WT0, fs);
4825         GEN_LOAD_FREG_FTN(WTH0, fs);
4826         GEN_LOAD_FREG_FTN(WT1, ft);
4827         GEN_LOAD_FREG_FTN(WTH1, ft);
4828         gen_op_float_add_ps();
4829         GEN_STORE_FTN_FREG(fd, WT2);
4830         GEN_STORE_FTN_FREG(fd, WTH2);
4831         opn = "add.ps";
4832         break;
4833     case FOP(1, 22):
4834         check_cp1_64bitmode(ctx);
4835         GEN_LOAD_FREG_FTN(WT0, fs);
4836         GEN_LOAD_FREG_FTN(WTH0, fs);
4837         GEN_LOAD_FREG_FTN(WT1, ft);
4838         GEN_LOAD_FREG_FTN(WTH1, ft);
4839         gen_op_float_sub_ps();
4840         GEN_STORE_FTN_FREG(fd, WT2);
4841         GEN_STORE_FTN_FREG(fd, WTH2);
4842         opn = "sub.ps";
4843         break;
4844     case FOP(2, 22):
4845         check_cp1_64bitmode(ctx);
4846         GEN_LOAD_FREG_FTN(WT0, fs);
4847         GEN_LOAD_FREG_FTN(WTH0, fs);
4848         GEN_LOAD_FREG_FTN(WT1, ft);
4849         GEN_LOAD_FREG_FTN(WTH1, ft);
4850         gen_op_float_mul_ps();
4851         GEN_STORE_FTN_FREG(fd, WT2);
4852         GEN_STORE_FTN_FREG(fd, WTH2);
4853         opn = "mul.ps";
4854         break;
4855     case FOP(5, 22):
4856         check_cp1_64bitmode(ctx);
4857         GEN_LOAD_FREG_FTN(WT0, fs);
4858         GEN_LOAD_FREG_FTN(WTH0, fs);
4859         gen_op_float_abs_ps();
4860         GEN_STORE_FTN_FREG(fd, WT2);
4861         GEN_STORE_FTN_FREG(fd, WTH2);
4862         opn = "abs.ps";
4863         break;
4864     case FOP(6, 22):
4865         check_cp1_64bitmode(ctx);
4866         GEN_LOAD_FREG_FTN(WT0, fs);
4867         GEN_LOAD_FREG_FTN(WTH0, fs);
4868         gen_op_float_mov_ps();
4869         GEN_STORE_FTN_FREG(fd, WT2);
4870         GEN_STORE_FTN_FREG(fd, WTH2);
4871         opn = "mov.ps";
4872         break;
4873     case FOP(7, 22):
4874         check_cp1_64bitmode(ctx);
4875         GEN_LOAD_FREG_FTN(WT0, fs);
4876         GEN_LOAD_FREG_FTN(WTH0, fs);
4877         gen_op_float_chs_ps();
4878         GEN_STORE_FTN_FREG(fd, WT2);
4879         GEN_STORE_FTN_FREG(fd, WTH2);
4880         opn = "neg.ps";
4881         break;
4882     case FOP(17, 22):
4883         check_cp1_64bitmode(ctx);
4884         GEN_LOAD_REG_TN(T0, ft);
4885         GEN_LOAD_FREG_FTN(WT0, fs);
4886         GEN_LOAD_FREG_FTN(WTH0, fs);
4887         GEN_LOAD_FREG_FTN(WT2, fd);
4888         GEN_LOAD_FREG_FTN(WTH2, fd);
4889         gen_movcf_ps(ctx, (ft >> 2) & 0x7, ft & 0x1);
4890         GEN_STORE_FTN_FREG(fd, WT2);
4891         GEN_STORE_FTN_FREG(fd, WTH2);
4892         opn = "movcf.ps";
4893         break;
4894     case FOP(18, 22):
4895         check_cp1_64bitmode(ctx);
4896         GEN_LOAD_REG_TN(T0, ft);
4897         GEN_LOAD_FREG_FTN(WT0, fs);
4898         GEN_LOAD_FREG_FTN(WTH0, fs);
4899         GEN_LOAD_FREG_FTN(WT2, fd);
4900         GEN_LOAD_FREG_FTN(WTH2, fd);
4901         gen_op_float_movz_ps();
4902         GEN_STORE_FTN_FREG(fd, WT2);
4903         GEN_STORE_FTN_FREG(fd, WTH2);
4904         opn = "movz.ps";
4905         break;
4906     case FOP(19, 22):
4907         check_cp1_64bitmode(ctx);
4908         GEN_LOAD_REG_TN(T0, ft);
4909         GEN_LOAD_FREG_FTN(WT0, fs);
4910         GEN_LOAD_FREG_FTN(WTH0, fs);
4911         GEN_LOAD_FREG_FTN(WT2, fd);
4912         GEN_LOAD_FREG_FTN(WTH2, fd);
4913         gen_op_float_movn_ps();
4914         GEN_STORE_FTN_FREG(fd, WT2);
4915         GEN_STORE_FTN_FREG(fd, WTH2);
4916         opn = "movn.ps";
4917         break;
4918     case FOP(24, 22):
4919         check_cp1_64bitmode(ctx);
4920         GEN_LOAD_FREG_FTN(WT0, ft);
4921         GEN_LOAD_FREG_FTN(WTH0, ft);
4922         GEN_LOAD_FREG_FTN(WT1, fs);
4923         GEN_LOAD_FREG_FTN(WTH1, fs);
4924         gen_op_float_addr_ps();
4925         GEN_STORE_FTN_FREG(fd, WT2);
4926         GEN_STORE_FTN_FREG(fd, WTH2);
4927         opn = "addr.ps";
4928         break;
4929     case FOP(26, 22):
4930         check_cp1_64bitmode(ctx);
4931         GEN_LOAD_FREG_FTN(WT0, ft);
4932         GEN_LOAD_FREG_FTN(WTH0, ft);
4933         GEN_LOAD_FREG_FTN(WT1, fs);
4934         GEN_LOAD_FREG_FTN(WTH1, fs);
4935         gen_op_float_mulr_ps();
4936         GEN_STORE_FTN_FREG(fd, WT2);
4937         GEN_STORE_FTN_FREG(fd, WTH2);
4938         opn = "mulr.ps";
4939         break;
4940     case FOP(28, 22):
4941         check_cp1_64bitmode(ctx);
4942         GEN_LOAD_FREG_FTN(WT0, fs);
4943         GEN_LOAD_FREG_FTN(WTH0, fs);
4944         GEN_LOAD_FREG_FTN(WT2, fd);
4945         GEN_LOAD_FREG_FTN(WTH2, fd);
4946         gen_op_float_recip2_ps();
4947         GEN_STORE_FTN_FREG(fd, WT2);
4948         GEN_STORE_FTN_FREG(fd, WTH2);
4949         opn = "recip2.ps";
4950         break;
4951     case FOP(29, 22):
4952         check_cp1_64bitmode(ctx);
4953         GEN_LOAD_FREG_FTN(WT0, fs);
4954         GEN_LOAD_FREG_FTN(WTH0, fs);
4955         gen_op_float_recip1_ps();
4956         GEN_STORE_FTN_FREG(fd, WT2);
4957         GEN_STORE_FTN_FREG(fd, WTH2);
4958         opn = "recip1.ps";
4959         break;
4960     case FOP(30, 22):
4961         check_cp1_64bitmode(ctx);
4962         GEN_LOAD_FREG_FTN(WT0, fs);
4963         GEN_LOAD_FREG_FTN(WTH0, fs);
4964         gen_op_float_rsqrt1_ps();
4965         GEN_STORE_FTN_FREG(fd, WT2);
4966         GEN_STORE_FTN_FREG(fd, WTH2);
4967         opn = "rsqrt1.ps";
4968         break;
4969     case FOP(31, 22):
4970         check_cp1_64bitmode(ctx);
4971         GEN_LOAD_FREG_FTN(WT0, fs);
4972         GEN_LOAD_FREG_FTN(WTH0, fs);
4973         GEN_LOAD_FREG_FTN(WT2, fd);
4974         GEN_LOAD_FREG_FTN(WTH2, fd);
4975         gen_op_float_rsqrt2_ps();
4976         GEN_STORE_FTN_FREG(fd, WT2);
4977         GEN_STORE_FTN_FREG(fd, WTH2);
4978         opn = "rsqrt2.ps";
4979         break;
4980     case FOP(32, 22):
4981         check_cp1_64bitmode(ctx);
4982         GEN_LOAD_FREG_FTN(WTH0, fs);
4983         gen_op_float_cvts_pu();
4984         GEN_STORE_FTN_FREG(fd, WT2);
4985         opn = "cvt.s.pu";
4986         break;
4987     case FOP(36, 22):
4988         check_cp1_64bitmode(ctx);
4989         GEN_LOAD_FREG_FTN(WT0, fs);
4990         GEN_LOAD_FREG_FTN(WTH0, fs);
4991         gen_op_float_cvtpw_ps();
4992         GEN_STORE_FTN_FREG(fd, WT2);
4993         GEN_STORE_FTN_FREG(fd, WTH2);
4994         opn = "cvt.pw.ps";
4995         break;
4996     case FOP(40, 22):
4997         check_cp1_64bitmode(ctx);
4998         GEN_LOAD_FREG_FTN(WT0, fs);
4999         gen_op_float_cvts_pl();
5000         GEN_STORE_FTN_FREG(fd, WT2);
5001         opn = "cvt.s.pl";
5002         break;
5003     case FOP(44, 22):
5004         check_cp1_64bitmode(ctx);
5005         GEN_LOAD_FREG_FTN(WT0, fs);
5006         GEN_LOAD_FREG_FTN(WT1, ft);
5007         gen_op_float_pll_ps();
5008         GEN_STORE_FTN_FREG(fd, DT2);
5009         opn = "pll.ps";
5010         break;
5011     case FOP(45, 22):
5012         check_cp1_64bitmode(ctx);
5013         GEN_LOAD_FREG_FTN(WT0, fs);
5014         GEN_LOAD_FREG_FTN(WTH1, ft);
5015         gen_op_float_plu_ps();
5016         GEN_STORE_FTN_FREG(fd, DT2);
5017         opn = "plu.ps";
5018         break;
5019     case FOP(46, 22):
5020         check_cp1_64bitmode(ctx);
5021         GEN_LOAD_FREG_FTN(WTH0, fs);
5022         GEN_LOAD_FREG_FTN(WT1, ft);
5023         gen_op_float_pul_ps();
5024         GEN_STORE_FTN_FREG(fd, DT2);
5025         opn = "pul.ps";
5026         break;
5027     case FOP(47, 22):
5028         check_cp1_64bitmode(ctx);
5029         GEN_LOAD_FREG_FTN(WTH0, fs);
5030         GEN_LOAD_FREG_FTN(WTH1, ft);
5031         gen_op_float_puu_ps();
5032         GEN_STORE_FTN_FREG(fd, DT2);
5033         opn = "puu.ps";
5034         break;
5035     case FOP(48, 22):
5036     case FOP(49, 22):
5037     case FOP(50, 22):
5038     case FOP(51, 22):
5039     case FOP(52, 22):
5040     case FOP(53, 22):
5041     case FOP(54, 22):
5042     case FOP(55, 22):
5043     case FOP(56, 22):
5044     case FOP(57, 22):
5045     case FOP(58, 22):
5046     case FOP(59, 22):
5047     case FOP(60, 22):
5048     case FOP(61, 22):
5049     case FOP(62, 22):
5050     case FOP(63, 22):
5051         check_cp1_64bitmode(ctx);
5052         GEN_LOAD_FREG_FTN(WT0, fs);
5053         GEN_LOAD_FREG_FTN(WTH0, fs);
5054         GEN_LOAD_FREG_FTN(WT1, ft);
5055         GEN_LOAD_FREG_FTN(WTH1, ft);
5056         if (ctx->opcode & (1 << 6)) {
5057             gen_cmpabs_ps(func-48, cc);
5058             opn = condnames_abs[func-48];
5059         } else {
5060             gen_cmp_ps(func-48, cc);
5061             opn = condnames[func-48];
5062         }
5063         break;
5064     default:
5065         MIPS_INVAL(opn);
5066         generate_exception (ctx, EXCP_RI);
5067         return;
5068     }
5069     switch (optype) {
5070     case BINOP:
5071         MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
5072         break;
5073     case CMPOP:
5074         MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
5075         break;
5076     default:
5077         MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
5078         break;
5079     }
5080 }
5081
5082 /* Coprocessor 3 (FPU) */
5083 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
5084                            int fd, int fs, int base, int index)
5085 {
5086     const char *opn = "extended float load/store";
5087     int store = 0;
5088
5089     /* All of those work only on 64bit FPUs. */
5090     check_cp1_64bitmode(ctx);
5091     if (base == 0) {
5092         if (index == 0)
5093             gen_op_reset_T0();
5094         else
5095             GEN_LOAD_REG_TN(T0, index);
5096     } else if (index == 0) {
5097         GEN_LOAD_REG_TN(T0, base);
5098     } else {
5099         GEN_LOAD_REG_TN(T0, base);
5100         GEN_LOAD_REG_TN(T1, index);
5101         gen_op_addr_add();
5102     }
5103     /* Don't do NOP if destination is zero: we must perform the actual
5104      * memory access
5105      */
5106     switch (opc) {
5107     case OPC_LWXC1:
5108         op_ldst(lwc1);
5109         GEN_STORE_FTN_FREG(fd, WT0);
5110         opn = "lwxc1";
5111         break;
5112     case OPC_LDXC1:
5113         op_ldst(ldc1);
5114         GEN_STORE_FTN_FREG(fd, DT0);
5115         opn = "ldxc1";
5116         break;
5117     case OPC_LUXC1:
5118         op_ldst(luxc1);
5119         GEN_STORE_FTN_FREG(fd, DT0);
5120         opn = "luxc1";
5121         break;
5122     case OPC_SWXC1:
5123         GEN_LOAD_FREG_FTN(WT0, fs);
5124         op_ldst(swc1);
5125         opn = "swxc1";
5126         store = 1;
5127         break;
5128     case OPC_SDXC1:
5129         GEN_LOAD_FREG_FTN(DT0, fs);
5130         op_ldst(sdc1);
5131         opn = "sdxc1";
5132         store = 1;
5133         break;
5134     case OPC_SUXC1:
5135         GEN_LOAD_FREG_FTN(DT0, fs);
5136         op_ldst(suxc1);
5137         opn = "suxc1";
5138         store = 1;
5139         break;
5140     default:
5141         MIPS_INVAL(opn);
5142         generate_exception(ctx, EXCP_RI);
5143         return;
5144     }
5145     MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
5146                regnames[index], regnames[base]);
5147 }
5148
5149 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
5150                             int fd, int fr, int fs, int ft)
5151 {
5152     const char *opn = "flt3_arith";
5153
5154     /* All of those work only on 64bit FPUs. */
5155     check_cp1_64bitmode(ctx);
5156     switch (opc) {
5157     case OPC_ALNV_PS:
5158         GEN_LOAD_REG_TN(T0, fr);
5159         GEN_LOAD_FREG_FTN(DT0, fs);
5160         GEN_LOAD_FREG_FTN(DT1, ft);
5161         gen_op_float_alnv_ps();
5162         GEN_STORE_FTN_FREG(fd, DT2);
5163         opn = "alnv.ps";
5164         break;
5165     case OPC_MADD_S:
5166         GEN_LOAD_FREG_FTN(WT0, fs);
5167         GEN_LOAD_FREG_FTN(WT1, ft);
5168         GEN_LOAD_FREG_FTN(WT2, fr);
5169         gen_op_float_muladd_s();
5170         GEN_STORE_FTN_FREG(fd, WT2);
5171         opn = "madd.s";
5172         break;
5173     case OPC_MADD_D:
5174         GEN_LOAD_FREG_FTN(DT0, fs);
5175         GEN_LOAD_FREG_FTN(DT1, ft);
5176         GEN_LOAD_FREG_FTN(DT2, fr);
5177         gen_op_float_muladd_d();
5178         GEN_STORE_FTN_FREG(fd, DT2);
5179         opn = "madd.d";
5180         break;
5181     case OPC_MADD_PS:
5182         GEN_LOAD_FREG_FTN(WT0, fs);
5183         GEN_LOAD_FREG_FTN(WTH0, fs);
5184         GEN_LOAD_FREG_FTN(WT1, ft);
5185         GEN_LOAD_FREG_FTN(WTH1, ft);
5186         GEN_LOAD_FREG_FTN(WT2, fr);
5187         GEN_LOAD_FREG_FTN(WTH2, fr);
5188         gen_op_float_muladd_ps();
5189         GEN_STORE_FTN_FREG(fd, WT2);
5190         GEN_STORE_FTN_FREG(fd, WTH2);
5191         opn = "madd.ps";
5192         break;
5193     case OPC_MSUB_S:
5194         GEN_LOAD_FREG_FTN(WT0, fs);
5195         GEN_LOAD_FREG_FTN(WT1, ft);
5196         GEN_LOAD_FREG_FTN(WT2, fr);
5197         gen_op_float_mulsub_s();
5198         GEN_STORE_FTN_FREG(fd, WT2);
5199         opn = "msub.s";
5200         break;
5201     case OPC_MSUB_D:
5202         GEN_LOAD_FREG_FTN(DT0, fs);
5203         GEN_LOAD_FREG_FTN(DT1, ft);
5204         GEN_LOAD_FREG_FTN(DT2, fr);
5205         gen_op_float_mulsub_d();
5206         GEN_STORE_FTN_FREG(fd, DT2);
5207         opn = "msub.d";
5208         break;
5209     case OPC_MSUB_PS:
5210         GEN_LOAD_FREG_FTN(WT0, fs);
5211         GEN_LOAD_FREG_FTN(WTH0, fs);
5212         GEN_LOAD_FREG_FTN(WT1, ft);
5213         GEN_LOAD_FREG_FTN(WTH1, ft);
5214         GEN_LOAD_FREG_FTN(WT2, fr);
5215         GEN_LOAD_FREG_FTN(WTH2, fr);
5216         gen_op_float_mulsub_ps();
5217         GEN_STORE_FTN_FREG(fd, WT2);
5218         GEN_STORE_FTN_FREG(fd, WTH2);
5219         opn = "msub.ps";
5220         break;
5221     case OPC_NMADD_S:
5222         GEN_LOAD_FREG_FTN(WT0, fs);
5223         GEN_LOAD_FREG_FTN(WT1, ft);
5224         GEN_LOAD_FREG_FTN(WT2, fr);
5225         gen_op_float_nmuladd_s();
5226         GEN_STORE_FTN_FREG(fd, WT2);
5227         opn = "nmadd.s";
5228         break;
5229     case OPC_NMADD_D:
5230         GEN_LOAD_FREG_FTN(DT0, fs);
5231         GEN_LOAD_FREG_FTN(DT1, ft);
5232         GEN_LOAD_FREG_FTN(DT2, fr);
5233         gen_op_float_nmuladd_d();
5234         GEN_STORE_FTN_FREG(fd, DT2);
5235         opn = "nmadd.d";
5236         break;
5237     case OPC_NMADD_PS:
5238         GEN_LOAD_FREG_FTN(WT0, fs);
5239         GEN_LOAD_FREG_FTN(WTH0, fs);
5240         GEN_LOAD_FREG_FTN(WT1, ft);
5241         GEN_LOAD_FREG_FTN(WTH1, ft);
5242         GEN_LOAD_FREG_FTN(WT2, fr);
5243         GEN_LOAD_FREG_FTN(WTH2, fr);
5244         gen_op_float_nmuladd_ps();
5245         GEN_STORE_FTN_FREG(fd, WT2);
5246         GEN_STORE_FTN_FREG(fd, WTH2);
5247         opn = "nmadd.ps";
5248         break;
5249     case OPC_NMSUB_S:
5250         GEN_LOAD_FREG_FTN(WT0, fs);
5251         GEN_LOAD_FREG_FTN(WT1, ft);
5252         GEN_LOAD_FREG_FTN(WT2, fr);
5253         gen_op_float_nmulsub_s();
5254         GEN_STORE_FTN_FREG(fd, WT2);
5255         opn = "nmsub.s";
5256         break;
5257     case OPC_NMSUB_D:
5258         GEN_LOAD_FREG_FTN(DT0, fs);
5259         GEN_LOAD_FREG_FTN(DT1, ft);
5260         GEN_LOAD_FREG_FTN(DT2, fr);
5261         gen_op_float_nmulsub_d();
5262         GEN_STORE_FTN_FREG(fd, DT2);
5263         opn = "nmsub.d";
5264         break;
5265     case OPC_NMSUB_PS:
5266         GEN_LOAD_FREG_FTN(WT0, fs);
5267         GEN_LOAD_FREG_FTN(WTH0, fs);
5268         GEN_LOAD_FREG_FTN(WT1, ft);
5269         GEN_LOAD_FREG_FTN(WTH1, ft);
5270         GEN_LOAD_FREG_FTN(WT2, fr);
5271         GEN_LOAD_FREG_FTN(WTH2, fr);
5272         gen_op_float_nmulsub_ps();
5273         GEN_STORE_FTN_FREG(fd, WT2);
5274         GEN_STORE_FTN_FREG(fd, WTH2);
5275         opn = "nmsub.ps";
5276         break;
5277     default:
5278         MIPS_INVAL(opn);
5279         generate_exception (ctx, EXCP_RI);
5280         return;
5281     }
5282     MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
5283                fregnames[fs], fregnames[ft]);
5284 }
5285
5286 /* ISA extensions (ASEs) */
5287 /* MIPS16 extension to MIPS32 */
5288 /* SmartMIPS extension to MIPS32 */
5289
5290 #ifdef TARGET_MIPS64
5291
5292 /* MDMX extension to MIPS64 */
5293 /* MIPS-3D extension to MIPS64 */
5294
5295 #endif
5296
5297 static void decode_opc (CPUState *env, DisasContext *ctx)
5298 {
5299     int32_t offset;
5300     int rs, rt, rd, sa;
5301     uint32_t op, op1, op2;
5302     int16_t imm;
5303
5304     /* make sure instructions are on a word boundary */
5305     if (ctx->pc & 0x3) {
5306         env->CP0_BadVAddr = ctx->pc;
5307         generate_exception(ctx, EXCP_AdEL);
5308         return;
5309     }
5310
5311     if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
5312         int l1;
5313         /* Handle blikely not taken case */
5314         MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
5315         l1 = gen_new_label();
5316         gen_op_jnz_T2(l1);
5317         gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
5318         gen_goto_tb(ctx, 1, ctx->pc + 4);
5319         gen_set_label(l1);
5320     }
5321     op = MASK_OP_MAJOR(ctx->opcode);
5322     rs = (ctx->opcode >> 21) & 0x1f;
5323     rt = (ctx->opcode >> 16) & 0x1f;
5324     rd = (ctx->opcode >> 11) & 0x1f;
5325     sa = (ctx->opcode >> 6) & 0x1f;
5326     imm = (int16_t)ctx->opcode;
5327     switch (op) {
5328     case OPC_SPECIAL:
5329         op1 = MASK_SPECIAL(ctx->opcode);
5330         switch (op1) {
5331         case OPC_SLL:          /* Arithmetic with immediate */
5332         case OPC_SRL ... OPC_SRA:
5333             gen_arith_imm(ctx, op1, rd, rt, sa);
5334             break;
5335         case OPC_SLLV:         /* Arithmetic */
5336         case OPC_SRLV ... OPC_SRAV:
5337         case OPC_MOVZ ... OPC_MOVN:
5338         case OPC_ADD ... OPC_NOR:
5339         case OPC_SLT ... OPC_SLTU:
5340             gen_arith(ctx, op1, rd, rs, rt);
5341             break;
5342         case OPC_MULT ... OPC_DIVU:
5343             gen_muldiv(ctx, op1, rs, rt);
5344             break;
5345         case OPC_JR ... OPC_JALR:
5346             gen_compute_branch(ctx, op1, rs, rd, sa);
5347             return;
5348         case OPC_TGE ... OPC_TEQ: /* Traps */
5349         case OPC_TNE:
5350             gen_trap(ctx, op1, rs, rt, -1);
5351             break;
5352         case OPC_MFHI:          /* Move from HI/LO */
5353         case OPC_MFLO:
5354             gen_HILO(ctx, op1, rd);
5355             break;
5356         case OPC_MTHI:
5357         case OPC_MTLO:          /* Move to HI/LO */
5358             gen_HILO(ctx, op1, rs);
5359             break;
5360         case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
5361 #ifdef MIPS_STRICT_STANDARD
5362             MIPS_INVAL("PMON / selsl");
5363             generate_exception(ctx, EXCP_RI);
5364 #else
5365             gen_op_pmon(sa);
5366 #endif
5367             break;
5368         case OPC_SYSCALL:
5369             generate_exception(ctx, EXCP_SYSCALL);
5370             break;
5371         case OPC_BREAK:
5372             /* XXX: Hack to work around wrong handling of self-modifying code. */
5373             ctx->pc += 4;
5374             save_cpu_state(ctx, 1);
5375             ctx->pc -= 4;
5376             generate_exception(ctx, EXCP_BREAK);
5377             break;
5378         case OPC_SPIM:
5379 #ifdef MIPS_STRICT_STANDARD
5380             MIPS_INVAL("SPIM");
5381             generate_exception(ctx, EXCP_RI);
5382 #else
5383            /* Implemented as RI exception for now. */
5384             MIPS_INVAL("spim (unofficial)");
5385             generate_exception(ctx, EXCP_RI);
5386 #endif
5387             break;
5388         case OPC_SYNC:
5389             /* Treat as a noop. */
5390             break;
5391
5392         case OPC_MOVCI:
5393             if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5394                 save_cpu_state(ctx, 1);
5395                 check_cp1_enabled(ctx);
5396                 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
5397                           (ctx->opcode >> 16) & 1);
5398             } else {
5399                 generate_exception_err(ctx, EXCP_CpU, 1);
5400             }
5401             break;
5402
5403 #ifdef TARGET_MIPS64
5404        /* MIPS64 specific opcodes */
5405         case OPC_DSLL:
5406         case OPC_DSRL ... OPC_DSRA:
5407         case OPC_DSLL32:
5408         case OPC_DSRL32 ... OPC_DSRA32:
5409             if (!(ctx->hflags & MIPS_HFLAG_64))
5410                 generate_exception(ctx, EXCP_RI);
5411             gen_arith_imm(ctx, op1, rd, rt, sa);
5412             break;
5413         case OPC_DSLLV:
5414         case OPC_DSRLV ... OPC_DSRAV:
5415         case OPC_DADD ... OPC_DSUBU:
5416             if (!(ctx->hflags & MIPS_HFLAG_64))
5417                 generate_exception(ctx, EXCP_RI);
5418             gen_arith(ctx, op1, rd, rs, rt);
5419             break;
5420         case OPC_DMULT ... OPC_DDIVU:
5421             if (!(ctx->hflags & MIPS_HFLAG_64))
5422                 generate_exception(ctx, EXCP_RI);
5423             gen_muldiv(ctx, op1, rs, rt);
5424             break;
5425 #endif
5426         default:            /* Invalid */
5427             MIPS_INVAL("special");
5428             generate_exception(ctx, EXCP_RI);
5429             break;
5430         }
5431         break;
5432     case OPC_SPECIAL2:
5433         op1 = MASK_SPECIAL2(ctx->opcode);
5434         switch (op1) {
5435         case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
5436         case OPC_MSUB ... OPC_MSUBU:
5437             gen_muldiv(ctx, op1, rs, rt);
5438             break;
5439         case OPC_MUL:
5440             gen_arith(ctx, op1, rd, rs, rt);
5441             break;
5442         case OPC_CLZ ... OPC_CLO:
5443             gen_cl(ctx, op1, rd, rs);
5444             break;
5445         case OPC_SDBBP:
5446             /* XXX: not clear which exception should be raised
5447              *      when in debug mode...
5448              */
5449             if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5450                 generate_exception(ctx, EXCP_DBp);
5451             } else {
5452                 generate_exception(ctx, EXCP_DBp);
5453             }
5454             /* Treat as a noop */
5455             break;
5456 #ifdef TARGET_MIPS64
5457         case OPC_DCLZ ... OPC_DCLO:
5458             if (!(ctx->hflags & MIPS_HFLAG_64))
5459                 generate_exception(ctx, EXCP_RI);
5460             gen_cl(ctx, op1, rd, rs);
5461             break;
5462 #endif
5463         default:            /* Invalid */
5464             MIPS_INVAL("special2");
5465             generate_exception(ctx, EXCP_RI);
5466             break;
5467         }
5468         break;
5469     case OPC_SPECIAL3:
5470          op1 = MASK_SPECIAL3(ctx->opcode);
5471          switch (op1) {
5472          case OPC_EXT:
5473          case OPC_INS:
5474              gen_bitops(ctx, op1, rt, rs, sa, rd);
5475              break;
5476          case OPC_BSHFL:
5477              op2 = MASK_BSHFL(ctx->opcode);
5478              switch (op2) {
5479              case OPC_WSBH:
5480                  GEN_LOAD_REG_TN(T1, rt);
5481                  gen_op_wsbh();
5482                  break;
5483              case OPC_SEB:
5484                  GEN_LOAD_REG_TN(T1, rt);
5485                  gen_op_seb();
5486                  break;
5487              case OPC_SEH:
5488                  GEN_LOAD_REG_TN(T1, rt);
5489                  gen_op_seh();
5490                  break;
5491              default:            /* Invalid */
5492                  MIPS_INVAL("bshfl");
5493                  generate_exception(ctx, EXCP_RI);
5494                  break;
5495             }
5496             GEN_STORE_TN_REG(rd, T0);
5497             break;
5498         case OPC_RDHWR:
5499             switch (rd) {
5500             case 0:
5501                 save_cpu_state(ctx, 1);
5502                 gen_op_rdhwr_cpunum();
5503                 break;
5504             case 1:
5505                 save_cpu_state(ctx, 1);
5506                 gen_op_rdhwr_synci_step();
5507                 break;
5508             case 2:
5509                 save_cpu_state(ctx, 1);
5510                 gen_op_rdhwr_cc();
5511                 break;
5512             case 3:
5513                 save_cpu_state(ctx, 1);
5514                 gen_op_rdhwr_ccres();
5515                 break;
5516             case 29:
5517 #if defined (CONFIG_USER_ONLY)
5518                 gen_op_tls_value ();
5519                 break;
5520 #endif
5521             default:            /* Invalid */
5522                 MIPS_INVAL("rdhwr");
5523                 generate_exception(ctx, EXCP_RI);
5524                 break;
5525             }
5526             GEN_STORE_TN_REG(rt, T0);
5527             break;
5528 #ifdef TARGET_MIPS64
5529         case OPC_DEXTM ... OPC_DEXT:
5530         case OPC_DINSM ... OPC_DINS:
5531             if (!(ctx->hflags & MIPS_HFLAG_64))
5532                 generate_exception(ctx, EXCP_RI);
5533             gen_bitops(ctx, op1, rt, rs, sa, rd);
5534             break;
5535         case OPC_DBSHFL:
5536             if (!(ctx->hflags & MIPS_HFLAG_64))
5537                 generate_exception(ctx, EXCP_RI);
5538             op2 = MASK_DBSHFL(ctx->opcode);
5539             switch (op2) {
5540             case OPC_DSBH:
5541                 GEN_LOAD_REG_TN(T1, rt);
5542                 gen_op_dsbh();
5543                 break;
5544             case OPC_DSHD:
5545                 GEN_LOAD_REG_TN(T1, rt);
5546                 gen_op_dshd();
5547                 break;
5548             default:            /* Invalid */
5549                 MIPS_INVAL("dbshfl");
5550                 generate_exception(ctx, EXCP_RI);
5551                 break;
5552             }
5553             GEN_STORE_TN_REG(rd, T0);
5554 #endif
5555         default:            /* Invalid */
5556             MIPS_INVAL("special3");
5557             generate_exception(ctx, EXCP_RI);
5558             break;
5559         }
5560         break;
5561     case OPC_REGIMM:
5562         op1 = MASK_REGIMM(ctx->opcode);
5563         switch (op1) {
5564         case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
5565         case OPC_BLTZAL ... OPC_BGEZALL:
5566             gen_compute_branch(ctx, op1, rs, -1, imm << 2);
5567             return;
5568         case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
5569         case OPC_TNEI:
5570             gen_trap(ctx, op1, rs, -1, imm);
5571             break;
5572         case OPC_SYNCI:
5573             /* treat as noop */
5574             break;
5575         default:            /* Invalid */
5576             MIPS_INVAL("regimm");
5577             generate_exception(ctx, EXCP_RI);
5578             break;
5579         }
5580         break;
5581     case OPC_CP0:
5582         save_cpu_state(ctx, 1);
5583         gen_op_cp0_enabled();
5584         op1 = MASK_CP0(ctx->opcode);
5585         switch (op1) {
5586         case OPC_MFC0:
5587         case OPC_MTC0:
5588 #ifdef TARGET_MIPS64
5589         case OPC_DMFC0:
5590         case OPC_DMTC0:
5591 #endif
5592             gen_cp0(env, ctx, op1, rt, rd);
5593             break;
5594         case OPC_C0_FIRST ... OPC_C0_LAST:
5595             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
5596             break;
5597         case OPC_MFMC0:
5598             op2 = MASK_MFMC0(ctx->opcode);
5599             switch (op2) {
5600             case OPC_DI:
5601                 gen_op_di();
5602                 /* Stop translation as we may have switched the execution mode */
5603                 ctx->bstate = BS_STOP;
5604                 break;
5605             case OPC_EI:
5606                 gen_op_ei();
5607                 /* Stop translation as we may have switched the execution mode */
5608                 ctx->bstate = BS_STOP;
5609                 break;
5610             default:            /* Invalid */
5611                 MIPS_INVAL("mfmc0");
5612                 generate_exception(ctx, EXCP_RI);
5613                 break;
5614             }
5615             GEN_STORE_TN_REG(rt, T0);
5616             break;
5617         case OPC_RDPGPR:
5618         case OPC_WRPGPR:
5619             if ((env->CP0_Config0 & (0x7 << CP0C0_AR)) == (1 << CP0C0_AR)) {
5620                 /* Shadow registers not implemented. */
5621                 GEN_LOAD_REG_TN(T0, rt);
5622                 GEN_STORE_TN_REG(rd, T0);
5623             } else {
5624                 MIPS_INVAL("shadow register move");
5625                 generate_exception(ctx, EXCP_RI);
5626             }
5627             break;
5628         default:
5629             MIPS_INVAL("cp0");
5630             generate_exception(ctx, EXCP_RI);
5631             break;
5632         }
5633         break;
5634     case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
5635          gen_arith_imm(ctx, op, rt, rs, imm);
5636          break;
5637     case OPC_J ... OPC_JAL: /* Jump */
5638          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
5639          gen_compute_branch(ctx, op, rs, rt, offset);
5640          return;
5641     case OPC_BEQ ... OPC_BGTZ: /* Branch */
5642     case OPC_BEQL ... OPC_BGTZL:
5643          gen_compute_branch(ctx, op, rs, rt, imm << 2);
5644          return;
5645     case OPC_LB ... OPC_LWR: /* Load and stores */
5646     case OPC_SB ... OPC_SW:
5647     case OPC_SWR:
5648     case OPC_LL:
5649     case OPC_SC:
5650          gen_ldst(ctx, op, rt, rs, imm);
5651          break;
5652     case OPC_CACHE:
5653         /* Treat as a noop */
5654         break;
5655     case OPC_PREF:
5656         /* Treat as a noop */
5657         break;
5658
5659     /* Floating point (COP1). */
5660     case OPC_LWC1:
5661     case OPC_LDC1:
5662     case OPC_SWC1:
5663     case OPC_SDC1:
5664         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5665             save_cpu_state(ctx, 1);
5666             check_cp1_enabled(ctx);
5667             gen_flt_ldst(ctx, op, rt, rs, imm);
5668         } else {
5669             generate_exception_err(ctx, EXCP_CpU, 1);
5670         }
5671         break;
5672
5673     case OPC_CP1:
5674         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5675             save_cpu_state(ctx, 1);
5676             check_cp1_enabled(ctx);
5677             op1 = MASK_CP1(ctx->opcode);
5678             switch (op1) {
5679             case OPC_MFC1:
5680             case OPC_CFC1:
5681             case OPC_MTC1:
5682             case OPC_CTC1:
5683 #ifdef TARGET_MIPS64
5684             case OPC_DMFC1:
5685             case OPC_DMTC1:
5686 #endif
5687             case OPC_MFHC1:
5688             case OPC_MTHC1:
5689                 gen_cp1(ctx, op1, rt, rd);
5690                 break;
5691             case OPC_BC1:
5692             case OPC_BC1ANY2:
5693             case OPC_BC1ANY4:
5694                 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
5695                                     (rt >> 2) & 0x7, imm << 2);
5696                 return;
5697             case OPC_S_FMT:
5698             case OPC_D_FMT:
5699             case OPC_W_FMT:
5700             case OPC_L_FMT:
5701             case OPC_PS_FMT:
5702                 gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
5703                            (imm >> 8) & 0x7);
5704                 break;
5705             default:
5706                 MIPS_INVAL("cp1");
5707                 generate_exception (ctx, EXCP_RI);
5708                 break;
5709             }
5710         } else {
5711             generate_exception_err(ctx, EXCP_CpU, 1);
5712         }
5713         break;
5714
5715     /* COP2.  */
5716     case OPC_LWC2:
5717     case OPC_LDC2:
5718     case OPC_SWC2:
5719     case OPC_SDC2:
5720     case OPC_CP2:
5721         /* COP2: Not implemented. */
5722         generate_exception_err(ctx, EXCP_CpU, 2);
5723         break;
5724
5725     case OPC_CP3:
5726         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
5727             save_cpu_state(ctx, 1);
5728             check_cp1_enabled(ctx);
5729             op1 = MASK_CP3(ctx->opcode);
5730             switch (op1) {
5731             case OPC_LWXC1:
5732             case OPC_LDXC1:
5733             case OPC_LUXC1:
5734             case OPC_SWXC1:
5735             case OPC_SDXC1:
5736             case OPC_SUXC1:
5737                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
5738                 break;
5739             case OPC_PREFX:
5740                 /* treat as noop */
5741                 break;
5742             case OPC_ALNV_PS:
5743             case OPC_MADD_S:
5744             case OPC_MADD_D:
5745             case OPC_MADD_PS:
5746             case OPC_MSUB_S:
5747             case OPC_MSUB_D:
5748             case OPC_MSUB_PS:
5749             case OPC_NMADD_S:
5750             case OPC_NMADD_D:
5751             case OPC_NMADD_PS:
5752             case OPC_NMSUB_S:
5753             case OPC_NMSUB_D:
5754             case OPC_NMSUB_PS:
5755                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
5756                 break;
5757             default:
5758                 MIPS_INVAL("cp3");
5759                 generate_exception (ctx, EXCP_RI);
5760                 break;
5761             }
5762         } else {
5763             generate_exception_err(ctx, EXCP_CpU, 1);
5764         }
5765         break;
5766
5767 #ifdef TARGET_MIPS64
5768     /* MIPS64 opcodes */
5769     case OPC_LWU:
5770     case OPC_LDL ... OPC_LDR:
5771     case OPC_SDL ... OPC_SDR:
5772     case OPC_LLD:
5773     case OPC_LD:
5774     case OPC_SCD:
5775     case OPC_SD:
5776         if (!(ctx->hflags & MIPS_HFLAG_64))
5777             generate_exception(ctx, EXCP_RI);
5778         gen_ldst(ctx, op, rt, rs, imm);
5779         break;
5780     case OPC_DADDI ... OPC_DADDIU:
5781         if (!(ctx->hflags & MIPS_HFLAG_64))
5782             generate_exception(ctx, EXCP_RI);
5783         gen_arith_imm(ctx, op, rt, rs, imm);
5784         break;
5785 #endif
5786 #ifdef MIPS_HAS_MIPS16
5787     case OPC_JALX:
5788         /* MIPS16: Not implemented. */
5789 #endif
5790 #ifdef MIPS_HAS_MDMX
5791     case OPC_MDMX:
5792         /* MDMX: Not implemented. */
5793 #endif
5794     default:            /* Invalid */
5795         MIPS_INVAL("major opcode");
5796         generate_exception(ctx, EXCP_RI);
5797         break;
5798     }
5799     if (ctx->hflags & MIPS_HFLAG_BMASK) {
5800         int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
5801         /* Branches completion */
5802         ctx->hflags &= ~MIPS_HFLAG_BMASK;
5803         ctx->bstate = BS_BRANCH;
5804         save_cpu_state(ctx, 0);
5805         switch (hflags) {
5806         case MIPS_HFLAG_B:
5807             /* unconditional branch */
5808             MIPS_DEBUG("unconditional branch");
5809             gen_goto_tb(ctx, 0, ctx->btarget);
5810             break;
5811         case MIPS_HFLAG_BL:
5812             /* blikely taken case */
5813             MIPS_DEBUG("blikely branch taken");
5814             gen_goto_tb(ctx, 0, ctx->btarget);
5815             break;
5816         case MIPS_HFLAG_BC:
5817             /* Conditional branch */
5818             MIPS_DEBUG("conditional branch");
5819             {
5820               int l1;
5821               l1 = gen_new_label();
5822               gen_op_jnz_T2(l1);
5823               gen_goto_tb(ctx, 1, ctx->pc + 4);
5824               gen_set_label(l1);
5825               gen_goto_tb(ctx, 0, ctx->btarget);
5826             }
5827             break;
5828         case MIPS_HFLAG_BR:
5829             /* unconditional branch to register */
5830             MIPS_DEBUG("branch to register");
5831             gen_op_breg();
5832             gen_op_reset_T0();
5833             gen_op_exit_tb();
5834             break;
5835         default:
5836             MIPS_DEBUG("unknown branch");
5837             break;
5838         }
5839     }
5840 }
5841
5842 static inline int
5843 gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
5844                                 int search_pc)
5845 {
5846     DisasContext ctx;
5847     target_ulong pc_start;
5848     uint16_t *gen_opc_end;
5849     int j, lj = -1;
5850
5851     if (search_pc && loglevel)
5852         fprintf (logfile, "search pc %d\n", search_pc);
5853
5854     pc_start = tb->pc;
5855     gen_opc_ptr = gen_opc_buf;
5856     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
5857     gen_opparam_ptr = gen_opparam_buf;
5858     nb_gen_labels = 0;
5859     ctx.pc = pc_start;
5860     ctx.saved_pc = -1;
5861     ctx.tb = tb;
5862     ctx.bstate = BS_NONE;
5863     /* Restore delay slot state from the tb context.  */
5864     ctx.hflags = tb->flags;
5865     restore_cpu_state(env, &ctx);
5866 #if defined(CONFIG_USER_ONLY)
5867     ctx.mem_idx = 0;
5868 #else
5869     ctx.mem_idx = !((ctx.hflags & MIPS_HFLAG_MODE) == MIPS_HFLAG_UM);
5870 #endif
5871 #ifdef DEBUG_DISAS
5872     if (loglevel & CPU_LOG_TB_CPU) {
5873         fprintf(logfile, "------------------------------------------------\n");
5874         /* FIXME: This may print out stale hflags from env... */
5875         cpu_dump_state(env, logfile, fprintf, 0);
5876     }
5877 #endif
5878 #ifdef MIPS_DEBUG_DISAS
5879     if (loglevel & CPU_LOG_TB_IN_ASM)
5880         fprintf(logfile, "\ntb %p super %d cond %04x\n",
5881                 tb, ctx.mem_idx, ctx.hflags);
5882 #endif
5883     while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
5884         if (env->nb_breakpoints > 0) {
5885             for(j = 0; j < env->nb_breakpoints; j++) {
5886                 if (env->breakpoints[j] == ctx.pc) {
5887                     save_cpu_state(&ctx, 1);
5888                     ctx.bstate = BS_BRANCH;
5889                     gen_op_debug();
5890                     goto done_generating;
5891                 }
5892             }
5893         }
5894
5895         if (search_pc) {
5896             j = gen_opc_ptr - gen_opc_buf;
5897             if (lj < j) {
5898                 lj++;
5899                 while (lj < j)
5900                     gen_opc_instr_start[lj++] = 0;
5901             }
5902             gen_opc_pc[lj] = ctx.pc;
5903             gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
5904             gen_opc_instr_start[lj] = 1;
5905         }
5906         ctx.opcode = ldl_code(ctx.pc);
5907         decode_opc(env, &ctx);
5908         ctx.pc += 4;
5909
5910         if (env->singlestep_enabled)
5911             break;
5912
5913         if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
5914             break;
5915
5916 #if defined (MIPS_SINGLE_STEP)
5917         break;
5918 #endif
5919     }
5920     if (env->singlestep_enabled) {
5921         save_cpu_state(&ctx, ctx.bstate == BS_NONE);
5922         gen_op_debug();
5923     } else {
5924         switch (ctx.bstate) {
5925         case BS_STOP:
5926             gen_op_interrupt_restart();
5927             gen_goto_tb(&ctx, 0, ctx.pc);
5928             break;
5929         case BS_NONE:
5930             save_cpu_state(&ctx, 0);
5931             gen_goto_tb(&ctx, 0, ctx.pc);
5932             break;
5933         case BS_EXCP:
5934             gen_op_interrupt_restart();
5935             gen_op_reset_T0();
5936             gen_op_exit_tb();
5937             break;
5938         case BS_BRANCH:
5939         default:
5940             break;
5941         }
5942     }
5943 done_generating:
5944     *gen_opc_ptr = INDEX_op_end;
5945     if (search_pc) {
5946         j = gen_opc_ptr - gen_opc_buf;
5947         lj++;
5948         while (lj <= j)
5949             gen_opc_instr_start[lj++] = 0;
5950         tb->size = 0;
5951     } else {
5952         tb->size = ctx.pc - pc_start;
5953     }
5954 #ifdef DEBUG_DISAS
5955 #if defined MIPS_DEBUG_DISAS
5956     if (loglevel & CPU_LOG_TB_IN_ASM)
5957         fprintf(logfile, "\n");
5958 #endif
5959     if (loglevel & CPU_LOG_TB_IN_ASM) {
5960         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
5961         target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
5962         fprintf(logfile, "\n");
5963     }
5964     if (loglevel & CPU_LOG_TB_OP) {
5965         fprintf(logfile, "OP:\n");
5966         dump_ops(gen_opc_buf, gen_opparam_buf);
5967         fprintf(logfile, "\n");
5968     }
5969     if (loglevel & CPU_LOG_TB_CPU) {
5970         fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
5971     }
5972 #endif
5973     
5974     return 0;
5975 }
5976
5977 int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
5978 {
5979     return gen_intermediate_code_internal(env, tb, 0);
5980 }
5981
5982 int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
5983 {
5984     return gen_intermediate_code_internal(env, tb, 1);
5985 }
5986
5987 void fpu_dump_state(CPUState *env, FILE *f, 
5988                     int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
5989                     int flags)
5990 {
5991     int i;
5992     int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
5993
5994 #define printfpr(fp)                                                        \
5995     do {                                                                    \
5996         if (is_fpu64)                                                       \
5997             fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
5998                         (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
5999                         (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
6000         else {                                                              \
6001             fpr_t tmp;                                                      \
6002             tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
6003             tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
6004             fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
6005                         tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
6006                         tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
6007         }                                                                   \
6008     } while(0)
6009
6010
6011     fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
6012                 env->fcr0, env->fcr31, is_fpu64, env->fp_status, get_float_exception_flags(&env->fp_status));
6013     fpu_fprintf(f, "FT0: "); printfpr(&env->ft0);
6014     fpu_fprintf(f, "FT1: "); printfpr(&env->ft1);
6015     fpu_fprintf(f, "FT2: "); printfpr(&env->ft2);
6016     for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
6017         fpu_fprintf(f, "%3s: ", fregnames[i]);
6018         printfpr(&env->fpr[i]);
6019     }
6020
6021 #undef printfpr
6022 }
6023
6024 void dump_fpu (CPUState *env)
6025 {
6026     if (loglevel) { 
6027        fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
6028                env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
6029        fpu_dump_state(env, logfile, fprintf, 0);
6030     }
6031 }
6032
6033 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6034 /* Debug help: The architecture requires 32bit code to maintain proper
6035    sign-extened values on 64bit machines.  */
6036
6037 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
6038
6039 void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
6040                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6041                      int flags)
6042 {
6043     int i;
6044
6045     if (!SIGN_EXT_P(env->PC))
6046         cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC);
6047     if (!SIGN_EXT_P(env->HI))
6048         cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI);
6049     if (!SIGN_EXT_P(env->LO))
6050         cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO);
6051     if (!SIGN_EXT_P(env->btarget))
6052         cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
6053
6054     for (i = 0; i < 32; i++) {
6055         if (!SIGN_EXT_P(env->gpr[i]))
6056             cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i]);
6057     }
6058
6059     if (!SIGN_EXT_P(env->CP0_EPC))
6060         cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
6061     if (!SIGN_EXT_P(env->CP0_LLAddr))
6062         cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
6063 }
6064 #endif
6065
6066 void cpu_dump_state (CPUState *env, FILE *f, 
6067                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
6068                      int flags)
6069 {
6070     int i;
6071     
6072     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",
6073                 env->PC, env->HI, env->LO, env->hflags, env->btarget, env->bcond);
6074     for (i = 0; i < 32; i++) {
6075         if ((i & 3) == 0)
6076             cpu_fprintf(f, "GPR%02d:", i);
6077         cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i]);
6078         if ((i & 3) == 3)
6079             cpu_fprintf(f, "\n");
6080     }
6081
6082     cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
6083                 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
6084     cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
6085                 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
6086     if (env->hflags & MIPS_HFLAG_FPU)
6087         fpu_dump_state(env, f, cpu_fprintf, flags);
6088 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
6089     cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
6090 #endif
6091 }
6092
6093 CPUMIPSState *cpu_mips_init (void)
6094 {
6095     CPUMIPSState *env;
6096
6097     env = qemu_mallocz(sizeof(CPUMIPSState));
6098     if (!env)
6099         return NULL;
6100     cpu_exec_init(env);
6101     cpu_reset(env);
6102     return env;
6103 }
6104
6105 void cpu_reset (CPUMIPSState *env)
6106 {
6107     memset(env, 0, offsetof(CPUMIPSState, breakpoints));
6108
6109     tlb_flush(env, 1);
6110
6111     /* Minimal init */
6112 #if !defined(CONFIG_USER_ONLY)
6113     if (env->hflags & MIPS_HFLAG_BMASK) {
6114         /* If the exception was raised from a delay slot,
6115          * come back to the jump.  */
6116         env->CP0_ErrorEPC = env->PC - 4;
6117     } else {
6118         env->CP0_ErrorEPC = env->PC;
6119     }
6120 #ifdef TARGET_MIPS64
6121     env->hflags = MIPS_HFLAG_64;
6122 #else
6123     env->hflags = 0;
6124 #endif
6125     env->PC = (int32_t)0xBFC00000;
6126     env->CP0_Wired = 0;
6127     /* SMP not implemented */
6128     env->CP0_EBase = 0x80000000;
6129     env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
6130     /* vectored interrupts not implemented, timer on int 7,
6131        no performance counters. */
6132     env->CP0_IntCtl = 0xe0000000;
6133     {
6134         int i;
6135
6136         for (i = 0; i < 7; i++) {
6137             env->CP0_WatchLo[i] = 0;
6138             env->CP0_WatchHi[i] = 0x80000000;
6139         }
6140         env->CP0_WatchLo[7] = 0;
6141         env->CP0_WatchHi[7] = 0;
6142     }
6143     /* Count register increments in debug mode, EJTAG version 1 */
6144     env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
6145 #endif
6146     env->exception_index = EXCP_NONE;
6147 #if defined(CONFIG_USER_ONLY)
6148     env->hflags |= MIPS_HFLAG_UM;
6149     env->user_mode_only = 1;
6150 #endif
6151 }
6152
6153 #include "translate_init.c"
This page took 0.354563 seconds and 4 git commands to generate.