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