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