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