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