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