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