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