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