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