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