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