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