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