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