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