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