target-mips: optimize gen_movci()
[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     uint32_t ccbit;
5726     int cond;
5727     TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5728     TCGv_i32 fp0 = tcg_temp_local_new_i32();
5729     int l1 = gen_new_label();
5730
5731     if (cc)
5732         ccbit = 1 << (24 + cc);
5733     else
5734         ccbit = 1 << 23;
5735
5736     if (tf)
5737         cond = TCG_COND_EQ;
5738     else
5739         cond = TCG_COND_NE;
5740
5741     gen_load_fpr32(fp0, fd);
5742     tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
5743     tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5744     tcg_temp_free_i32(r_tmp1);
5745     gen_load_fpr32(fp0, fs);
5746     gen_set_label(l1);
5747     gen_store_fpr32(fp0, fd);
5748     tcg_temp_free_i32(fp0);
5749 }
5750
5751 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
5752 {
5753     uint32_t ccbit;
5754     int cond;
5755     TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5756     TCGv_i64 fp0 = tcg_temp_local_new_i64();
5757     int l1 = gen_new_label();
5758
5759     if (cc)
5760         ccbit = 1 << (24 + cc);
5761     else
5762         ccbit = 1 << 23;
5763
5764     if (tf)
5765         cond = TCG_COND_EQ;
5766     else
5767         cond = TCG_COND_NE;
5768
5769     gen_load_fpr64(ctx, fp0, fd);
5770     tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
5771     tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5772     tcg_temp_free_i32(r_tmp1);
5773     gen_load_fpr64(ctx, fp0, fs);
5774     gen_set_label(l1);
5775     gen_store_fpr64(ctx, fp0, fd);
5776     tcg_temp_free_i64(fp0);
5777 }
5778
5779 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
5780 {
5781     uint32_t ccbit1, ccbit2;
5782     int cond;
5783     TCGv_i32 r_tmp1 = tcg_temp_new_i32();
5784     TCGv_i32 fp0 = tcg_temp_local_new_i32();
5785     int l1 = gen_new_label();
5786     int l2 = gen_new_label();
5787
5788     if (cc) {
5789         ccbit1 = 1 << (24 + cc);
5790         ccbit2 = 1 << (25 + cc);
5791     } else {
5792         ccbit1 = 1 << 23;
5793         ccbit2 = 1 << 25;
5794     }
5795
5796     if (tf)
5797         cond = TCG_COND_EQ;
5798     else
5799         cond = TCG_COND_NE;
5800
5801     gen_load_fpr32(fp0, fd);
5802     tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit1);
5803     tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5804     gen_load_fpr32(fp0, fs);
5805     gen_set_label(l1);
5806     gen_store_fpr32(fp0, fd);
5807
5808     gen_load_fpr32h(fp0, fd);
5809     tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit2);
5810     tcg_gen_brcondi_i32(cond, r_tmp1, 0, l2);
5811     gen_load_fpr32h(fp0, fs);
5812     gen_set_label(l2);
5813     gen_store_fpr32h(fp0, fd);
5814
5815     tcg_temp_free_i32(r_tmp1);
5816     tcg_temp_free_i32(fp0);
5817 }
5818
5819
5820 static void gen_farith (DisasContext *ctx, uint32_t op1,
5821                         int ft, int fs, int fd, int cc)
5822 {
5823     const char *opn = "farith";
5824     const char *condnames[] = {
5825             "c.f",
5826             "c.un",
5827             "c.eq",
5828             "c.ueq",
5829             "c.olt",
5830             "c.ult",
5831             "c.ole",
5832             "c.ule",
5833             "c.sf",
5834             "c.ngle",
5835             "c.seq",
5836             "c.ngl",
5837             "c.lt",
5838             "c.nge",
5839             "c.le",
5840             "c.ngt",
5841     };
5842     const char *condnames_abs[] = {
5843             "cabs.f",
5844             "cabs.un",
5845             "cabs.eq",
5846             "cabs.ueq",
5847             "cabs.olt",
5848             "cabs.ult",
5849             "cabs.ole",
5850             "cabs.ule",
5851             "cabs.sf",
5852             "cabs.ngle",
5853             "cabs.seq",
5854             "cabs.ngl",
5855             "cabs.lt",
5856             "cabs.nge",
5857             "cabs.le",
5858             "cabs.ngt",
5859     };
5860     enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
5861     uint32_t func = ctx->opcode & 0x3f;
5862
5863     switch (ctx->opcode & FOP(0x3f, 0x1f)) {
5864     case FOP(0, 16):
5865         {
5866             TCGv_i32 fp0 = tcg_temp_new_i32();
5867             TCGv_i32 fp1 = tcg_temp_new_i32();
5868
5869             gen_load_fpr32(fp0, fs);
5870             gen_load_fpr32(fp1, ft);
5871             gen_helper_float_add_s(fp0, fp0, fp1);
5872             tcg_temp_free_i32(fp1);
5873             gen_store_fpr32(fp0, fd);
5874             tcg_temp_free_i32(fp0);
5875         }
5876         opn = "add.s";
5877         optype = BINOP;
5878         break;
5879     case FOP(1, 16):
5880         {
5881             TCGv_i32 fp0 = tcg_temp_new_i32();
5882             TCGv_i32 fp1 = tcg_temp_new_i32();
5883
5884             gen_load_fpr32(fp0, fs);
5885             gen_load_fpr32(fp1, ft);
5886             gen_helper_float_sub_s(fp0, fp0, fp1);
5887             tcg_temp_free_i32(fp1);
5888             gen_store_fpr32(fp0, fd);
5889             tcg_temp_free_i32(fp0);
5890         }
5891         opn = "sub.s";
5892         optype = BINOP;
5893         break;
5894     case FOP(2, 16):
5895         {
5896             TCGv_i32 fp0 = tcg_temp_new_i32();
5897             TCGv_i32 fp1 = tcg_temp_new_i32();
5898
5899             gen_load_fpr32(fp0, fs);
5900             gen_load_fpr32(fp1, ft);
5901             gen_helper_float_mul_s(fp0, fp0, fp1);
5902             tcg_temp_free_i32(fp1);
5903             gen_store_fpr32(fp0, fd);
5904             tcg_temp_free_i32(fp0);
5905         }
5906         opn = "mul.s";
5907         optype = BINOP;
5908         break;
5909     case FOP(3, 16):
5910         {
5911             TCGv_i32 fp0 = tcg_temp_new_i32();
5912             TCGv_i32 fp1 = tcg_temp_new_i32();
5913
5914             gen_load_fpr32(fp0, fs);
5915             gen_load_fpr32(fp1, ft);
5916             gen_helper_float_div_s(fp0, fp0, fp1);
5917             tcg_temp_free_i32(fp1);
5918             gen_store_fpr32(fp0, fd);
5919             tcg_temp_free_i32(fp0);
5920         }
5921         opn = "div.s";
5922         optype = BINOP;
5923         break;
5924     case FOP(4, 16):
5925         {
5926             TCGv_i32 fp0 = tcg_temp_new_i32();
5927
5928             gen_load_fpr32(fp0, fs);
5929             gen_helper_float_sqrt_s(fp0, fp0);
5930             gen_store_fpr32(fp0, fd);
5931             tcg_temp_free_i32(fp0);
5932         }
5933         opn = "sqrt.s";
5934         break;
5935     case FOP(5, 16):
5936         {
5937             TCGv_i32 fp0 = tcg_temp_new_i32();
5938
5939             gen_load_fpr32(fp0, fs);
5940             gen_helper_float_abs_s(fp0, fp0);
5941             gen_store_fpr32(fp0, fd);
5942             tcg_temp_free_i32(fp0);
5943         }
5944         opn = "abs.s";
5945         break;
5946     case FOP(6, 16):
5947         {
5948             TCGv_i32 fp0 = tcg_temp_new_i32();
5949
5950             gen_load_fpr32(fp0, fs);
5951             gen_store_fpr32(fp0, fd);
5952             tcg_temp_free_i32(fp0);
5953         }
5954         opn = "mov.s";
5955         break;
5956     case FOP(7, 16):
5957         {
5958             TCGv_i32 fp0 = tcg_temp_new_i32();
5959
5960             gen_load_fpr32(fp0, fs);
5961             gen_helper_float_chs_s(fp0, fp0);
5962             gen_store_fpr32(fp0, fd);
5963             tcg_temp_free_i32(fp0);
5964         }
5965         opn = "neg.s";
5966         break;
5967     case FOP(8, 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_roundl_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 = "round.l.s";
5980         break;
5981     case FOP(9, 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_truncl_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 = "trunc.l.s";
5994         break;
5995     case FOP(10, 16):
5996         check_cp1_64bitmode(ctx);
5997         {
5998             TCGv_i32 fp32 = tcg_temp_new_i32();
5999             TCGv_i64 fp64 = tcg_temp_new_i64();
6000
6001             gen_load_fpr32(fp32, fs);
6002             gen_helper_float_ceill_s(fp64, fp32);
6003             tcg_temp_free_i32(fp32);
6004             gen_store_fpr64(ctx, fp64, fd);
6005             tcg_temp_free_i64(fp64);
6006         }
6007         opn = "ceil.l.s";
6008         break;
6009     case FOP(11, 16):
6010         check_cp1_64bitmode(ctx);
6011         {
6012             TCGv_i32 fp32 = tcg_temp_new_i32();
6013             TCGv_i64 fp64 = tcg_temp_new_i64();
6014
6015             gen_load_fpr32(fp32, fs);
6016             gen_helper_float_floorl_s(fp64, fp32);
6017             tcg_temp_free_i32(fp32);
6018             gen_store_fpr64(ctx, fp64, fd);
6019             tcg_temp_free_i64(fp64);
6020         }
6021         opn = "floor.l.s";
6022         break;
6023     case FOP(12, 16):
6024         {
6025             TCGv_i32 fp0 = tcg_temp_new_i32();
6026
6027             gen_load_fpr32(fp0, fs);
6028             gen_helper_float_roundw_s(fp0, fp0);
6029             gen_store_fpr32(fp0, fd);
6030             tcg_temp_free_i32(fp0);
6031         }
6032         opn = "round.w.s";
6033         break;
6034     case FOP(13, 16):
6035         {
6036             TCGv_i32 fp0 = tcg_temp_new_i32();
6037
6038             gen_load_fpr32(fp0, fs);
6039             gen_helper_float_truncw_s(fp0, fp0);
6040             gen_store_fpr32(fp0, fd);
6041             tcg_temp_free_i32(fp0);
6042         }
6043         opn = "trunc.w.s";
6044         break;
6045     case FOP(14, 16):
6046         {
6047             TCGv_i32 fp0 = tcg_temp_new_i32();
6048
6049             gen_load_fpr32(fp0, fs);
6050             gen_helper_float_ceilw_s(fp0, fp0);
6051             gen_store_fpr32(fp0, fd);
6052             tcg_temp_free_i32(fp0);
6053         }
6054         opn = "ceil.w.s";
6055         break;
6056     case FOP(15, 16):
6057         {
6058             TCGv_i32 fp0 = tcg_temp_new_i32();
6059
6060             gen_load_fpr32(fp0, fs);
6061             gen_helper_float_floorw_s(fp0, fp0);
6062             gen_store_fpr32(fp0, fd);
6063             tcg_temp_free_i32(fp0);
6064         }
6065         opn = "floor.w.s";
6066         break;
6067     case FOP(17, 16):
6068         gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6069         opn = "movcf.s";
6070         break;
6071     case FOP(18, 16):
6072         {
6073             int l1 = gen_new_label();
6074             TCGv t0 = tcg_temp_new();
6075             TCGv_i32 fp0 = tcg_temp_local_new_i32();
6076
6077             gen_load_gpr(t0, ft);
6078             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6079             gen_load_fpr32(fp0, fs);
6080             gen_store_fpr32(fp0, fd);
6081             tcg_temp_free_i32(fp0);
6082             gen_set_label(l1);
6083             tcg_temp_free(t0);
6084         }
6085         opn = "movz.s";
6086         break;
6087     case FOP(19, 16):
6088         {
6089             int l1 = gen_new_label();
6090             TCGv t0 = tcg_temp_new();
6091             TCGv_i32 fp0 = tcg_temp_local_new_i32();
6092
6093             gen_load_gpr(t0, ft);
6094             tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6095             gen_load_fpr32(fp0, fs);
6096             gen_store_fpr32(fp0, fd);
6097             tcg_temp_free_i32(fp0);
6098             gen_set_label(l1);
6099             tcg_temp_free(t0);
6100         }
6101         opn = "movn.s";
6102         break;
6103     case FOP(21, 16):
6104         check_cop1x(ctx);
6105         {
6106             TCGv_i32 fp0 = tcg_temp_new_i32();
6107
6108             gen_load_fpr32(fp0, fs);
6109             gen_helper_float_recip_s(fp0, fp0);
6110             gen_store_fpr32(fp0, fd);
6111             tcg_temp_free_i32(fp0);
6112         }
6113         opn = "recip.s";
6114         break;
6115     case FOP(22, 16):
6116         check_cop1x(ctx);
6117         {
6118             TCGv_i32 fp0 = tcg_temp_new_i32();
6119
6120             gen_load_fpr32(fp0, fs);
6121             gen_helper_float_rsqrt_s(fp0, fp0);
6122             gen_store_fpr32(fp0, fd);
6123             tcg_temp_free_i32(fp0);
6124         }
6125         opn = "rsqrt.s";
6126         break;
6127     case FOP(28, 16):
6128         check_cp1_64bitmode(ctx);
6129         {
6130             TCGv_i32 fp0 = tcg_temp_new_i32();
6131             TCGv_i32 fp1 = tcg_temp_new_i32();
6132
6133             gen_load_fpr32(fp0, fs);
6134             gen_load_fpr32(fp1, fd);
6135             gen_helper_float_recip2_s(fp0, fp0, fp1);
6136             tcg_temp_free_i32(fp1);
6137             gen_store_fpr32(fp0, fd);
6138             tcg_temp_free_i32(fp0);
6139         }
6140         opn = "recip2.s";
6141         break;
6142     case FOP(29, 16):
6143         check_cp1_64bitmode(ctx);
6144         {
6145             TCGv_i32 fp0 = tcg_temp_new_i32();
6146
6147             gen_load_fpr32(fp0, fs);
6148             gen_helper_float_recip1_s(fp0, fp0);
6149             gen_store_fpr32(fp0, fd);
6150             tcg_temp_free_i32(fp0);
6151         }
6152         opn = "recip1.s";
6153         break;
6154     case FOP(30, 16):
6155         check_cp1_64bitmode(ctx);
6156         {
6157             TCGv_i32 fp0 = tcg_temp_new_i32();
6158
6159             gen_load_fpr32(fp0, fs);
6160             gen_helper_float_rsqrt1_s(fp0, fp0);
6161             gen_store_fpr32(fp0, fd);
6162             tcg_temp_free_i32(fp0);
6163         }
6164         opn = "rsqrt1.s";
6165         break;
6166     case FOP(31, 16):
6167         check_cp1_64bitmode(ctx);
6168         {
6169             TCGv_i32 fp0 = tcg_temp_new_i32();
6170             TCGv_i32 fp1 = tcg_temp_new_i32();
6171
6172             gen_load_fpr32(fp0, fs);
6173             gen_load_fpr32(fp1, ft);
6174             gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6175             tcg_temp_free_i32(fp1);
6176             gen_store_fpr32(fp0, fd);
6177             tcg_temp_free_i32(fp0);
6178         }
6179         opn = "rsqrt2.s";
6180         break;
6181     case FOP(33, 16):
6182         check_cp1_registers(ctx, fd);
6183         {
6184             TCGv_i32 fp32 = tcg_temp_new_i32();
6185             TCGv_i64 fp64 = tcg_temp_new_i64();
6186
6187             gen_load_fpr32(fp32, fs);
6188             gen_helper_float_cvtd_s(fp64, fp32);
6189             tcg_temp_free_i32(fp32);
6190             gen_store_fpr64(ctx, fp64, fd);
6191             tcg_temp_free_i64(fp64);
6192         }
6193         opn = "cvt.d.s";
6194         break;
6195     case FOP(36, 16):
6196         {
6197             TCGv_i32 fp0 = tcg_temp_new_i32();
6198
6199             gen_load_fpr32(fp0, fs);
6200             gen_helper_float_cvtw_s(fp0, fp0);
6201             gen_store_fpr32(fp0, fd);
6202             tcg_temp_free_i32(fp0);
6203         }
6204         opn = "cvt.w.s";
6205         break;
6206     case FOP(37, 16):
6207         check_cp1_64bitmode(ctx);
6208         {
6209             TCGv_i32 fp32 = tcg_temp_new_i32();
6210             TCGv_i64 fp64 = tcg_temp_new_i64();
6211
6212             gen_load_fpr32(fp32, fs);
6213             gen_helper_float_cvtl_s(fp64, fp32);
6214             tcg_temp_free_i32(fp32);
6215             gen_store_fpr64(ctx, fp64, fd);
6216             tcg_temp_free_i64(fp64);
6217         }
6218         opn = "cvt.l.s";
6219         break;
6220     case FOP(38, 16):
6221         check_cp1_64bitmode(ctx);
6222         {
6223             TCGv_i64 fp64 = tcg_temp_new_i64();
6224             TCGv_i32 fp32_0 = tcg_temp_new_i32();
6225             TCGv_i32 fp32_1 = tcg_temp_new_i32();
6226
6227             gen_load_fpr32(fp32_0, fs);
6228             gen_load_fpr32(fp32_1, ft);
6229             tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6230             tcg_temp_free_i32(fp32_1);
6231             tcg_temp_free_i32(fp32_0);
6232             gen_store_fpr64(ctx, fp64, fd);
6233             tcg_temp_free_i64(fp64);
6234         }
6235         opn = "cvt.ps.s";
6236         break;
6237     case FOP(48, 16):
6238     case FOP(49, 16):
6239     case FOP(50, 16):
6240     case FOP(51, 16):
6241     case FOP(52, 16):
6242     case FOP(53, 16):
6243     case FOP(54, 16):
6244     case FOP(55, 16):
6245     case FOP(56, 16):
6246     case FOP(57, 16):
6247     case FOP(58, 16):
6248     case FOP(59, 16):
6249     case FOP(60, 16):
6250     case FOP(61, 16):
6251     case FOP(62, 16):
6252     case FOP(63, 16):
6253         {
6254             TCGv_i32 fp0 = tcg_temp_new_i32();
6255             TCGv_i32 fp1 = tcg_temp_new_i32();
6256
6257             gen_load_fpr32(fp0, fs);
6258             gen_load_fpr32(fp1, ft);
6259             if (ctx->opcode & (1 << 6)) {
6260                 check_cop1x(ctx);
6261                 gen_cmpabs_s(func-48, fp0, fp1, cc);
6262                 opn = condnames_abs[func-48];
6263             } else {
6264                 gen_cmp_s(func-48, fp0, fp1, cc);
6265                 opn = condnames[func-48];
6266             }
6267             tcg_temp_free_i32(fp0);
6268             tcg_temp_free_i32(fp1);
6269         }
6270         break;
6271     case FOP(0, 17):
6272         check_cp1_registers(ctx, fs | ft | fd);
6273         {
6274             TCGv_i64 fp0 = tcg_temp_new_i64();
6275             TCGv_i64 fp1 = tcg_temp_new_i64();
6276
6277             gen_load_fpr64(ctx, fp0, fs);
6278             gen_load_fpr64(ctx, fp1, ft);
6279             gen_helper_float_add_d(fp0, fp0, fp1);
6280             tcg_temp_free_i64(fp1);
6281             gen_store_fpr64(ctx, fp0, fd);
6282             tcg_temp_free_i64(fp0);
6283         }
6284         opn = "add.d";
6285         optype = BINOP;
6286         break;
6287     case FOP(1, 17):
6288         check_cp1_registers(ctx, fs | ft | fd);
6289         {
6290             TCGv_i64 fp0 = tcg_temp_new_i64();
6291             TCGv_i64 fp1 = tcg_temp_new_i64();
6292
6293             gen_load_fpr64(ctx, fp0, fs);
6294             gen_load_fpr64(ctx, fp1, ft);
6295             gen_helper_float_sub_d(fp0, fp0, fp1);
6296             tcg_temp_free_i64(fp1);
6297             gen_store_fpr64(ctx, fp0, fd);
6298             tcg_temp_free_i64(fp0);
6299         }
6300         opn = "sub.d";
6301         optype = BINOP;
6302         break;
6303     case FOP(2, 17):
6304         check_cp1_registers(ctx, fs | ft | fd);
6305         {
6306             TCGv_i64 fp0 = tcg_temp_new_i64();
6307             TCGv_i64 fp1 = tcg_temp_new_i64();
6308
6309             gen_load_fpr64(ctx, fp0, fs);
6310             gen_load_fpr64(ctx, fp1, ft);
6311             gen_helper_float_mul_d(fp0, fp0, fp1);
6312             tcg_temp_free_i64(fp1);
6313             gen_store_fpr64(ctx, fp0, fd);
6314             tcg_temp_free_i64(fp0);
6315         }
6316         opn = "mul.d";
6317         optype = BINOP;
6318         break;
6319     case FOP(3, 17):
6320         check_cp1_registers(ctx, fs | ft | fd);
6321         {
6322             TCGv_i64 fp0 = tcg_temp_new_i64();
6323             TCGv_i64 fp1 = tcg_temp_new_i64();
6324
6325             gen_load_fpr64(ctx, fp0, fs);
6326             gen_load_fpr64(ctx, fp1, ft);
6327             gen_helper_float_div_d(fp0, fp0, fp1);
6328             tcg_temp_free_i64(fp1);
6329             gen_store_fpr64(ctx, fp0, fd);
6330             tcg_temp_free_i64(fp0);
6331         }
6332         opn = "div.d";
6333         optype = BINOP;
6334         break;
6335     case FOP(4, 17):
6336         check_cp1_registers(ctx, fs | fd);
6337         {
6338             TCGv_i64 fp0 = tcg_temp_new_i64();
6339
6340             gen_load_fpr64(ctx, fp0, fs);
6341             gen_helper_float_sqrt_d(fp0, fp0);
6342             gen_store_fpr64(ctx, fp0, fd);
6343             tcg_temp_free_i64(fp0);
6344         }
6345         opn = "sqrt.d";
6346         break;
6347     case FOP(5, 17):
6348         check_cp1_registers(ctx, fs | fd);
6349         {
6350             TCGv_i64 fp0 = tcg_temp_new_i64();
6351
6352             gen_load_fpr64(ctx, fp0, fs);
6353             gen_helper_float_abs_d(fp0, fp0);
6354             gen_store_fpr64(ctx, fp0, fd);
6355             tcg_temp_free_i64(fp0);
6356         }
6357         opn = "abs.d";
6358         break;
6359     case FOP(6, 17):
6360         check_cp1_registers(ctx, fs | fd);
6361         {
6362             TCGv_i64 fp0 = tcg_temp_new_i64();
6363
6364             gen_load_fpr64(ctx, fp0, fs);
6365             gen_store_fpr64(ctx, fp0, fd);
6366             tcg_temp_free_i64(fp0);
6367         }
6368         opn = "mov.d";
6369         break;
6370     case FOP(7, 17):
6371         check_cp1_registers(ctx, fs | fd);
6372         {
6373             TCGv_i64 fp0 = tcg_temp_new_i64();
6374
6375             gen_load_fpr64(ctx, fp0, fs);
6376             gen_helper_float_chs_d(fp0, fp0);
6377             gen_store_fpr64(ctx, fp0, fd);
6378             tcg_temp_free_i64(fp0);
6379         }
6380         opn = "neg.d";
6381         break;
6382     case FOP(8, 17):
6383         check_cp1_64bitmode(ctx);
6384         {
6385             TCGv_i64 fp0 = tcg_temp_new_i64();
6386
6387             gen_load_fpr64(ctx, fp0, fs);
6388             gen_helper_float_roundl_d(fp0, fp0);
6389             gen_store_fpr64(ctx, fp0, fd);
6390             tcg_temp_free_i64(fp0);
6391         }
6392         opn = "round.l.d";
6393         break;
6394     case FOP(9, 17):
6395         check_cp1_64bitmode(ctx);
6396         {
6397             TCGv_i64 fp0 = tcg_temp_new_i64();
6398
6399             gen_load_fpr64(ctx, fp0, fs);
6400             gen_helper_float_truncl_d(fp0, fp0);
6401             gen_store_fpr64(ctx, fp0, fd);
6402             tcg_temp_free_i64(fp0);
6403         }
6404         opn = "trunc.l.d";
6405         break;
6406     case FOP(10, 17):
6407         check_cp1_64bitmode(ctx);
6408         {
6409             TCGv_i64 fp0 = tcg_temp_new_i64();
6410
6411             gen_load_fpr64(ctx, fp0, fs);
6412             gen_helper_float_ceill_d(fp0, fp0);
6413             gen_store_fpr64(ctx, fp0, fd);
6414             tcg_temp_free_i64(fp0);
6415         }
6416         opn = "ceil.l.d";
6417         break;
6418     case FOP(11, 17):
6419         check_cp1_64bitmode(ctx);
6420         {
6421             TCGv_i64 fp0 = tcg_temp_new_i64();
6422
6423             gen_load_fpr64(ctx, fp0, fs);
6424             gen_helper_float_floorl_d(fp0, fp0);
6425             gen_store_fpr64(ctx, fp0, fd);
6426             tcg_temp_free_i64(fp0);
6427         }
6428         opn = "floor.l.d";
6429         break;
6430     case FOP(12, 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_roundw_d(fp32, fp64);
6438             tcg_temp_free_i64(fp64);
6439             gen_store_fpr32(fp32, fd);
6440             tcg_temp_free_i32(fp32);
6441         }
6442         opn = "round.w.d";
6443         break;
6444     case FOP(13, 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_truncw_d(fp32, fp64);
6452             tcg_temp_free_i64(fp64);
6453             gen_store_fpr32(fp32, fd);
6454             tcg_temp_free_i32(fp32);
6455         }
6456         opn = "trunc.w.d";
6457         break;
6458     case FOP(14, 17):
6459         check_cp1_registers(ctx, fs);
6460         {
6461             TCGv_i32 fp32 = tcg_temp_new_i32();
6462             TCGv_i64 fp64 = tcg_temp_new_i64();
6463
6464             gen_load_fpr64(ctx, fp64, fs);
6465             gen_helper_float_ceilw_d(fp32, fp64);
6466             tcg_temp_free_i64(fp64);
6467             gen_store_fpr32(fp32, fd);
6468             tcg_temp_free_i32(fp32);
6469         }
6470         opn = "ceil.w.d";
6471         break;
6472     case FOP(15, 17):
6473         check_cp1_registers(ctx, fs);
6474         {
6475             TCGv_i32 fp32 = tcg_temp_new_i32();
6476             TCGv_i64 fp64 = tcg_temp_new_i64();
6477
6478             gen_load_fpr64(ctx, fp64, fs);
6479             gen_helper_float_floorw_d(fp32, fp64);
6480             tcg_temp_free_i64(fp64);
6481             gen_store_fpr32(fp32, fd);
6482             tcg_temp_free_i32(fp32);
6483         }
6484         opn = "floor.w.d";
6485         break;
6486     case FOP(17, 17):
6487         gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6488         opn = "movcf.d";
6489         break;
6490     case FOP(18, 17):
6491         {
6492             int l1 = gen_new_label();
6493             TCGv t0 = tcg_temp_new();
6494             TCGv_i64 fp0 = tcg_temp_local_new_i64();
6495
6496             gen_load_gpr(t0, ft);
6497             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6498             gen_load_fpr64(ctx, fp0, fs);
6499             gen_store_fpr64(ctx, fp0, fd);
6500             tcg_temp_free_i64(fp0);
6501             gen_set_label(l1);
6502             tcg_temp_free(t0);
6503         }
6504         opn = "movz.d";
6505         break;
6506     case FOP(19, 17):
6507         {
6508             int l1 = gen_new_label();
6509             TCGv t0 = tcg_temp_new();
6510             TCGv_i64 fp0 = tcg_temp_local_new_i64();
6511
6512             gen_load_gpr(t0, ft);
6513             tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6514             gen_load_fpr64(ctx, fp0, fs);
6515             gen_store_fpr64(ctx, fp0, fd);
6516             tcg_temp_free_i64(fp0);
6517             gen_set_label(l1);
6518             tcg_temp_free(t0);
6519         }
6520         opn = "movn.d";
6521         break;
6522     case FOP(21, 17):
6523         check_cp1_64bitmode(ctx);
6524         {
6525             TCGv_i64 fp0 = tcg_temp_new_i64();
6526
6527             gen_load_fpr64(ctx, fp0, fs);
6528             gen_helper_float_recip_d(fp0, fp0);
6529             gen_store_fpr64(ctx, fp0, fd);
6530             tcg_temp_free_i64(fp0);
6531         }
6532         opn = "recip.d";
6533         break;
6534     case FOP(22, 17):
6535         check_cp1_64bitmode(ctx);
6536         {
6537             TCGv_i64 fp0 = tcg_temp_new_i64();
6538
6539             gen_load_fpr64(ctx, fp0, fs);
6540             gen_helper_float_rsqrt_d(fp0, fp0);
6541             gen_store_fpr64(ctx, fp0, fd);
6542             tcg_temp_free_i64(fp0);
6543         }
6544         opn = "rsqrt.d";
6545         break;
6546     case FOP(28, 17):
6547         check_cp1_64bitmode(ctx);
6548         {
6549             TCGv_i64 fp0 = tcg_temp_new_i64();
6550             TCGv_i64 fp1 = tcg_temp_new_i64();
6551
6552             gen_load_fpr64(ctx, fp0, fs);
6553             gen_load_fpr64(ctx, fp1, ft);
6554             gen_helper_float_recip2_d(fp0, fp0, fp1);
6555             tcg_temp_free_i64(fp1);
6556             gen_store_fpr64(ctx, fp0, fd);
6557             tcg_temp_free_i64(fp0);
6558         }
6559         opn = "recip2.d";
6560         break;
6561     case FOP(29, 17):
6562         check_cp1_64bitmode(ctx);
6563         {
6564             TCGv_i64 fp0 = tcg_temp_new_i64();
6565
6566             gen_load_fpr64(ctx, fp0, fs);
6567             gen_helper_float_recip1_d(fp0, fp0);
6568             gen_store_fpr64(ctx, fp0, fd);
6569             tcg_temp_free_i64(fp0);
6570         }
6571         opn = "recip1.d";
6572         break;
6573     case FOP(30, 17):
6574         check_cp1_64bitmode(ctx);
6575         {
6576             TCGv_i64 fp0 = tcg_temp_new_i64();
6577
6578             gen_load_fpr64(ctx, fp0, fs);
6579             gen_helper_float_rsqrt1_d(fp0, fp0);
6580             gen_store_fpr64(ctx, fp0, fd);
6581             tcg_temp_free_i64(fp0);
6582         }
6583         opn = "rsqrt1.d";
6584         break;
6585     case FOP(31, 17):
6586         check_cp1_64bitmode(ctx);
6587         {
6588             TCGv_i64 fp0 = tcg_temp_new_i64();
6589             TCGv_i64 fp1 = tcg_temp_new_i64();
6590
6591             gen_load_fpr64(ctx, fp0, fs);
6592             gen_load_fpr64(ctx, fp1, ft);
6593             gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6594             tcg_temp_free_i64(fp1);
6595             gen_store_fpr64(ctx, fp0, fd);
6596             tcg_temp_free_i64(fp0);
6597         }
6598         opn = "rsqrt2.d";
6599         break;
6600     case FOP(48, 17):
6601     case FOP(49, 17):
6602     case FOP(50, 17):
6603     case FOP(51, 17):
6604     case FOP(52, 17):
6605     case FOP(53, 17):
6606     case FOP(54, 17):
6607     case FOP(55, 17):
6608     case FOP(56, 17):
6609     case FOP(57, 17):
6610     case FOP(58, 17):
6611     case FOP(59, 17):
6612     case FOP(60, 17):
6613     case FOP(61, 17):
6614     case FOP(62, 17):
6615     case FOP(63, 17):
6616         {
6617             TCGv_i64 fp0 = tcg_temp_new_i64();
6618             TCGv_i64 fp1 = tcg_temp_new_i64();
6619
6620             gen_load_fpr64(ctx, fp0, fs);
6621             gen_load_fpr64(ctx, fp1, ft);
6622             if (ctx->opcode & (1 << 6)) {
6623                 check_cop1x(ctx);
6624                 check_cp1_registers(ctx, fs | ft);
6625                 gen_cmpabs_d(func-48, fp0, fp1, cc);
6626                 opn = condnames_abs[func-48];
6627             } else {
6628                 check_cp1_registers(ctx, fs | ft);
6629                 gen_cmp_d(func-48, fp0, fp1, cc);
6630                 opn = condnames[func-48];
6631             }
6632             tcg_temp_free_i64(fp0);
6633             tcg_temp_free_i64(fp1);
6634         }
6635         break;
6636     case FOP(32, 17):
6637         check_cp1_registers(ctx, fs);
6638         {
6639             TCGv_i32 fp32 = tcg_temp_new_i32();
6640             TCGv_i64 fp64 = tcg_temp_new_i64();
6641
6642             gen_load_fpr64(ctx, fp64, fs);
6643             gen_helper_float_cvts_d(fp32, fp64);
6644             tcg_temp_free_i64(fp64);
6645             gen_store_fpr32(fp32, fd);
6646             tcg_temp_free_i32(fp32);
6647         }
6648         opn = "cvt.s.d";
6649         break;
6650     case FOP(36, 17):
6651         check_cp1_registers(ctx, fs);
6652         {
6653             TCGv_i32 fp32 = tcg_temp_new_i32();
6654             TCGv_i64 fp64 = tcg_temp_new_i64();
6655
6656             gen_load_fpr64(ctx, fp64, fs);
6657             gen_helper_float_cvtw_d(fp32, fp64);
6658             tcg_temp_free_i64(fp64);
6659             gen_store_fpr32(fp32, fd);
6660             tcg_temp_free_i32(fp32);
6661         }
6662         opn = "cvt.w.d";
6663         break;
6664     case FOP(37, 17):
6665         check_cp1_64bitmode(ctx);
6666         {
6667             TCGv_i64 fp0 = tcg_temp_new_i64();
6668
6669             gen_load_fpr64(ctx, fp0, fs);
6670             gen_helper_float_cvtl_d(fp0, fp0);
6671             gen_store_fpr64(ctx, fp0, fd);
6672             tcg_temp_free_i64(fp0);
6673         }
6674         opn = "cvt.l.d";
6675         break;
6676     case FOP(32, 20):
6677         {
6678             TCGv_i32 fp0 = tcg_temp_new_i32();
6679
6680             gen_load_fpr32(fp0, fs);
6681             gen_helper_float_cvts_w(fp0, fp0);
6682             gen_store_fpr32(fp0, fd);
6683             tcg_temp_free_i32(fp0);
6684         }
6685         opn = "cvt.s.w";
6686         break;
6687     case FOP(33, 20):
6688         check_cp1_registers(ctx, fd);
6689         {
6690             TCGv_i32 fp32 = tcg_temp_new_i32();
6691             TCGv_i64 fp64 = tcg_temp_new_i64();
6692
6693             gen_load_fpr32(fp32, fs);
6694             gen_helper_float_cvtd_w(fp64, fp32);
6695             tcg_temp_free_i32(fp32);
6696             gen_store_fpr64(ctx, fp64, fd);
6697             tcg_temp_free_i64(fp64);
6698         }
6699         opn = "cvt.d.w";
6700         break;
6701     case FOP(32, 21):
6702         check_cp1_64bitmode(ctx);
6703         {
6704             TCGv_i32 fp32 = tcg_temp_new_i32();
6705             TCGv_i64 fp64 = tcg_temp_new_i64();
6706
6707             gen_load_fpr64(ctx, fp64, fs);
6708             gen_helper_float_cvts_l(fp32, fp64);
6709             tcg_temp_free_i64(fp64);
6710             gen_store_fpr32(fp32, fd);
6711             tcg_temp_free_i32(fp32);
6712         }
6713         opn = "cvt.s.l";
6714         break;
6715     case FOP(33, 21):
6716         check_cp1_64bitmode(ctx);
6717         {
6718             TCGv_i64 fp0 = tcg_temp_new_i64();
6719
6720             gen_load_fpr64(ctx, fp0, fs);
6721             gen_helper_float_cvtd_l(fp0, fp0);
6722             gen_store_fpr64(ctx, fp0, fd);
6723             tcg_temp_free_i64(fp0);
6724         }
6725         opn = "cvt.d.l";
6726         break;
6727     case FOP(38, 20):
6728         check_cp1_64bitmode(ctx);
6729         {
6730             TCGv_i64 fp0 = tcg_temp_new_i64();
6731
6732             gen_load_fpr64(ctx, fp0, fs);
6733             gen_helper_float_cvtps_pw(fp0, fp0);
6734             gen_store_fpr64(ctx, fp0, fd);
6735             tcg_temp_free_i64(fp0);
6736         }
6737         opn = "cvt.ps.pw";
6738         break;
6739     case FOP(0, 22):
6740         check_cp1_64bitmode(ctx);
6741         {
6742             TCGv_i64 fp0 = tcg_temp_new_i64();
6743             TCGv_i64 fp1 = tcg_temp_new_i64();
6744
6745             gen_load_fpr64(ctx, fp0, fs);
6746             gen_load_fpr64(ctx, fp1, ft);
6747             gen_helper_float_add_ps(fp0, fp0, fp1);
6748             tcg_temp_free_i64(fp1);
6749             gen_store_fpr64(ctx, fp0, fd);
6750             tcg_temp_free_i64(fp0);
6751         }
6752         opn = "add.ps";
6753         break;
6754     case FOP(1, 22):
6755         check_cp1_64bitmode(ctx);
6756         {
6757             TCGv_i64 fp0 = tcg_temp_new_i64();
6758             TCGv_i64 fp1 = tcg_temp_new_i64();
6759
6760             gen_load_fpr64(ctx, fp0, fs);
6761             gen_load_fpr64(ctx, fp1, ft);
6762             gen_helper_float_sub_ps(fp0, fp0, fp1);
6763             tcg_temp_free_i64(fp1);
6764             gen_store_fpr64(ctx, fp0, fd);
6765             tcg_temp_free_i64(fp0);
6766         }
6767         opn = "sub.ps";
6768         break;
6769     case FOP(2, 22):
6770         check_cp1_64bitmode(ctx);
6771         {
6772             TCGv_i64 fp0 = tcg_temp_new_i64();
6773             TCGv_i64 fp1 = tcg_temp_new_i64();
6774
6775             gen_load_fpr64(ctx, fp0, fs);
6776             gen_load_fpr64(ctx, fp1, ft);
6777             gen_helper_float_mul_ps(fp0, fp0, fp1);
6778             tcg_temp_free_i64(fp1);
6779             gen_store_fpr64(ctx, fp0, fd);
6780             tcg_temp_free_i64(fp0);
6781         }
6782         opn = "mul.ps";
6783         break;
6784     case FOP(5, 22):
6785         check_cp1_64bitmode(ctx);
6786         {
6787             TCGv_i64 fp0 = tcg_temp_new_i64();
6788
6789             gen_load_fpr64(ctx, fp0, fs);
6790             gen_helper_float_abs_ps(fp0, fp0);
6791             gen_store_fpr64(ctx, fp0, fd);
6792             tcg_temp_free_i64(fp0);
6793         }
6794         opn = "abs.ps";
6795         break;
6796     case FOP(6, 22):
6797         check_cp1_64bitmode(ctx);
6798         {
6799             TCGv_i64 fp0 = tcg_temp_new_i64();
6800
6801             gen_load_fpr64(ctx, fp0, fs);
6802             gen_store_fpr64(ctx, fp0, fd);
6803             tcg_temp_free_i64(fp0);
6804         }
6805         opn = "mov.ps";
6806         break;
6807     case FOP(7, 22):
6808         check_cp1_64bitmode(ctx);
6809         {
6810             TCGv_i64 fp0 = tcg_temp_new_i64();
6811
6812             gen_load_fpr64(ctx, fp0, fs);
6813             gen_helper_float_chs_ps(fp0, fp0);
6814             gen_store_fpr64(ctx, fp0, fd);
6815             tcg_temp_free_i64(fp0);
6816         }
6817         opn = "neg.ps";
6818         break;
6819     case FOP(17, 22):
6820         check_cp1_64bitmode(ctx);
6821         gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6822         opn = "movcf.ps";
6823         break;
6824     case FOP(18, 22):
6825         check_cp1_64bitmode(ctx);
6826         {
6827             int l1 = gen_new_label();
6828             TCGv t0 = tcg_temp_new();
6829             TCGv_i32 fp0 = tcg_temp_local_new_i32();
6830             TCGv_i32 fph0 = tcg_temp_local_new_i32();
6831
6832             gen_load_gpr(t0, ft);
6833             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6834             gen_load_fpr32(fp0, fs);
6835             gen_load_fpr32h(fph0, fs);
6836             gen_store_fpr32(fp0, fd);
6837             gen_store_fpr32h(fph0, fd);
6838             tcg_temp_free_i32(fp0);
6839             tcg_temp_free_i32(fph0);
6840             gen_set_label(l1);
6841             tcg_temp_free(t0);
6842         }
6843         opn = "movz.ps";
6844         break;
6845     case FOP(19, 22):
6846         check_cp1_64bitmode(ctx);
6847         {
6848             int l1 = gen_new_label();
6849             TCGv t0 = tcg_temp_new();
6850             TCGv_i32 fp0 = tcg_temp_local_new_i32();
6851             TCGv_i32 fph0 = tcg_temp_local_new_i32();
6852
6853             gen_load_gpr(t0, ft);
6854             tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6855             gen_load_fpr32(fp0, fs);
6856             gen_load_fpr32h(fph0, fs);
6857             gen_store_fpr32(fp0, fd);
6858             gen_store_fpr32h(fph0, fd);
6859             tcg_temp_free_i32(fp0);
6860             tcg_temp_free_i32(fph0);
6861             gen_set_label(l1);
6862             tcg_temp_free(t0);
6863         }
6864         opn = "movn.ps";
6865         break;
6866     case FOP(24, 22):
6867         check_cp1_64bitmode(ctx);
6868         {
6869             TCGv_i64 fp0 = tcg_temp_new_i64();
6870             TCGv_i64 fp1 = tcg_temp_new_i64();
6871
6872             gen_load_fpr64(ctx, fp0, ft);
6873             gen_load_fpr64(ctx, fp1, fs);
6874             gen_helper_float_addr_ps(fp0, fp0, fp1);
6875             tcg_temp_free_i64(fp1);
6876             gen_store_fpr64(ctx, fp0, fd);
6877             tcg_temp_free_i64(fp0);
6878         }
6879         opn = "addr.ps";
6880         break;
6881     case FOP(26, 22):
6882         check_cp1_64bitmode(ctx);
6883         {
6884             TCGv_i64 fp0 = tcg_temp_new_i64();
6885             TCGv_i64 fp1 = tcg_temp_new_i64();
6886
6887             gen_load_fpr64(ctx, fp0, ft);
6888             gen_load_fpr64(ctx, fp1, fs);
6889             gen_helper_float_mulr_ps(fp0, fp0, fp1);
6890             tcg_temp_free_i64(fp1);
6891             gen_store_fpr64(ctx, fp0, fd);
6892             tcg_temp_free_i64(fp0);
6893         }
6894         opn = "mulr.ps";
6895         break;
6896     case FOP(28, 22):
6897         check_cp1_64bitmode(ctx);
6898         {
6899             TCGv_i64 fp0 = tcg_temp_new_i64();
6900             TCGv_i64 fp1 = tcg_temp_new_i64();
6901
6902             gen_load_fpr64(ctx, fp0, fs);
6903             gen_load_fpr64(ctx, fp1, fd);
6904             gen_helper_float_recip2_ps(fp0, fp0, fp1);
6905             tcg_temp_free_i64(fp1);
6906             gen_store_fpr64(ctx, fp0, fd);
6907             tcg_temp_free_i64(fp0);
6908         }
6909         opn = "recip2.ps";
6910         break;
6911     case FOP(29, 22):
6912         check_cp1_64bitmode(ctx);
6913         {
6914             TCGv_i64 fp0 = tcg_temp_new_i64();
6915
6916             gen_load_fpr64(ctx, fp0, fs);
6917             gen_helper_float_recip1_ps(fp0, fp0);
6918             gen_store_fpr64(ctx, fp0, fd);
6919             tcg_temp_free_i64(fp0);
6920         }
6921         opn = "recip1.ps";
6922         break;
6923     case FOP(30, 22):
6924         check_cp1_64bitmode(ctx);
6925         {
6926             TCGv_i64 fp0 = tcg_temp_new_i64();
6927
6928             gen_load_fpr64(ctx, fp0, fs);
6929             gen_helper_float_rsqrt1_ps(fp0, fp0);
6930             gen_store_fpr64(ctx, fp0, fd);
6931             tcg_temp_free_i64(fp0);
6932         }
6933         opn = "rsqrt1.ps";
6934         break;
6935     case FOP(31, 22):
6936         check_cp1_64bitmode(ctx);
6937         {
6938             TCGv_i64 fp0 = tcg_temp_new_i64();
6939             TCGv_i64 fp1 = tcg_temp_new_i64();
6940
6941             gen_load_fpr64(ctx, fp0, fs);
6942             gen_load_fpr64(ctx, fp1, ft);
6943             gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
6944             tcg_temp_free_i64(fp1);
6945             gen_store_fpr64(ctx, fp0, fd);
6946             tcg_temp_free_i64(fp0);
6947         }
6948         opn = "rsqrt2.ps";
6949         break;
6950     case FOP(32, 22):
6951         check_cp1_64bitmode(ctx);
6952         {
6953             TCGv_i32 fp0 = tcg_temp_new_i32();
6954
6955             gen_load_fpr32h(fp0, fs);
6956             gen_helper_float_cvts_pu(fp0, fp0);
6957             gen_store_fpr32(fp0, fd);
6958             tcg_temp_free_i32(fp0);
6959         }
6960         opn = "cvt.s.pu";
6961         break;
6962     case FOP(36, 22):
6963         check_cp1_64bitmode(ctx);
6964         {
6965             TCGv_i64 fp0 = tcg_temp_new_i64();
6966
6967             gen_load_fpr64(ctx, fp0, fs);
6968             gen_helper_float_cvtpw_ps(fp0, fp0);
6969             gen_store_fpr64(ctx, fp0, fd);
6970             tcg_temp_free_i64(fp0);
6971         }
6972         opn = "cvt.pw.ps";
6973         break;
6974     case FOP(40, 22):
6975         check_cp1_64bitmode(ctx);
6976         {
6977             TCGv_i32 fp0 = tcg_temp_new_i32();
6978
6979             gen_load_fpr32(fp0, fs);
6980             gen_helper_float_cvts_pl(fp0, fp0);
6981             gen_store_fpr32(fp0, fd);
6982             tcg_temp_free_i32(fp0);
6983         }
6984         opn = "cvt.s.pl";
6985         break;
6986     case FOP(44, 22):
6987         check_cp1_64bitmode(ctx);
6988         {
6989             TCGv_i32 fp0 = tcg_temp_new_i32();
6990             TCGv_i32 fp1 = tcg_temp_new_i32();
6991
6992             gen_load_fpr32(fp0, fs);
6993             gen_load_fpr32(fp1, ft);
6994             gen_store_fpr32h(fp0, fd);
6995             gen_store_fpr32(fp1, fd);
6996             tcg_temp_free_i32(fp0);
6997             tcg_temp_free_i32(fp1);
6998         }
6999         opn = "pll.ps";
7000         break;
7001     case FOP(45, 22):
7002         check_cp1_64bitmode(ctx);
7003         {
7004             TCGv_i32 fp0 = tcg_temp_new_i32();
7005             TCGv_i32 fp1 = tcg_temp_new_i32();
7006
7007             gen_load_fpr32(fp0, fs);
7008             gen_load_fpr32h(fp1, ft);
7009             gen_store_fpr32(fp1, fd);
7010             gen_store_fpr32h(fp0, fd);
7011             tcg_temp_free_i32(fp0);
7012             tcg_temp_free_i32(fp1);
7013         }
7014         opn = "plu.ps";
7015         break;
7016     case FOP(46, 22):
7017         check_cp1_64bitmode(ctx);
7018         {
7019             TCGv_i32 fp0 = tcg_temp_new_i32();
7020             TCGv_i32 fp1 = tcg_temp_new_i32();
7021
7022             gen_load_fpr32h(fp0, fs);
7023             gen_load_fpr32(fp1, ft);
7024             gen_store_fpr32(fp1, fd);
7025             gen_store_fpr32h(fp0, fd);
7026             tcg_temp_free_i32(fp0);
7027             tcg_temp_free_i32(fp1);
7028         }
7029         opn = "pul.ps";
7030         break;
7031     case FOP(47, 22):
7032         check_cp1_64bitmode(ctx);
7033         {
7034             TCGv_i32 fp0 = tcg_temp_new_i32();
7035             TCGv_i32 fp1 = tcg_temp_new_i32();
7036
7037             gen_load_fpr32h(fp0, fs);
7038             gen_load_fpr32h(fp1, ft);
7039             gen_store_fpr32(fp1, fd);
7040             gen_store_fpr32h(fp0, fd);
7041             tcg_temp_free_i32(fp0);
7042             tcg_temp_free_i32(fp1);
7043         }
7044         opn = "puu.ps";
7045         break;
7046     case FOP(48, 22):
7047     case FOP(49, 22):
7048     case FOP(50, 22):
7049     case FOP(51, 22):
7050     case FOP(52, 22):
7051     case FOP(53, 22):
7052     case FOP(54, 22):
7053     case FOP(55, 22):
7054     case FOP(56, 22):
7055     case FOP(57, 22):
7056     case FOP(58, 22):
7057     case FOP(59, 22):
7058     case FOP(60, 22):
7059     case FOP(61, 22):
7060     case FOP(62, 22):
7061     case FOP(63, 22):
7062         check_cp1_64bitmode(ctx);
7063         {
7064             TCGv_i64 fp0 = tcg_temp_new_i64();
7065             TCGv_i64 fp1 = tcg_temp_new_i64();
7066
7067             gen_load_fpr64(ctx, fp0, fs);
7068             gen_load_fpr64(ctx, fp1, ft);
7069             if (ctx->opcode & (1 << 6)) {
7070                 gen_cmpabs_ps(func-48, fp0, fp1, cc);
7071                 opn = condnames_abs[func-48];
7072             } else {
7073                 gen_cmp_ps(func-48, fp0, fp1, cc);
7074                 opn = condnames[func-48];
7075             }
7076             tcg_temp_free_i64(fp0);
7077             tcg_temp_free_i64(fp1);
7078         }
7079         break;
7080     default:
7081         MIPS_INVAL(opn);
7082         generate_exception (ctx, EXCP_RI);
7083         return;
7084     }
7085     switch (optype) {
7086     case BINOP:
7087         MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7088         break;
7089     case CMPOP:
7090         MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7091         break;
7092     default:
7093         MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7094         break;
7095     }
7096 }
7097
7098 /* Coprocessor 3 (FPU) */
7099 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7100                            int fd, int fs, int base, int index)
7101 {
7102     const char *opn = "extended float load/store";
7103     int store = 0;
7104     TCGv t0 = tcg_temp_local_new();
7105     TCGv t1 = tcg_temp_local_new();
7106
7107     if (base == 0) {
7108         gen_load_gpr(t0, index);
7109     } else if (index == 0) {
7110         gen_load_gpr(t0, base);
7111     } else {
7112         gen_load_gpr(t0, index);
7113         gen_op_addr_add(ctx, t0, cpu_gpr[base]);
7114     }
7115     /* Don't do NOP if destination is zero: we must perform the actual
7116        memory access. */
7117     switch (opc) {
7118     case OPC_LWXC1:
7119         check_cop1x(ctx);
7120         {
7121             TCGv_i32 fp0 = tcg_temp_new_i32();
7122
7123             tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
7124             tcg_gen_trunc_tl_i32(fp0, t1);
7125             gen_store_fpr32(fp0, fd);
7126             tcg_temp_free_i32(fp0);
7127         }
7128         opn = "lwxc1";
7129         break;
7130     case OPC_LDXC1:
7131         check_cop1x(ctx);
7132         check_cp1_registers(ctx, fd);
7133         {
7134             TCGv_i64 fp0 = tcg_temp_new_i64();
7135
7136             tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7137             gen_store_fpr64(ctx, fp0, fd);
7138             tcg_temp_free_i64(fp0);
7139         }
7140         opn = "ldxc1";
7141         break;
7142     case OPC_LUXC1:
7143         check_cp1_64bitmode(ctx);
7144         tcg_gen_andi_tl(t0, t0, ~0x7);
7145         {
7146             TCGv_i64 fp0 = tcg_temp_new_i64();
7147
7148             tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7149             gen_store_fpr64(ctx, fp0, fd);
7150             tcg_temp_free_i64(fp0);
7151         }
7152         opn = "luxc1";
7153         break;
7154     case OPC_SWXC1:
7155         check_cop1x(ctx);
7156         {
7157             TCGv_i32 fp0 = tcg_temp_new_i32();
7158
7159             gen_load_fpr32(fp0, fs);
7160             tcg_gen_extu_i32_tl(t1, fp0);
7161             tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7162             tcg_temp_free_i32(fp0);
7163         }
7164         opn = "swxc1";
7165         store = 1;
7166         break;
7167     case OPC_SDXC1:
7168         check_cop1x(ctx);
7169         check_cp1_registers(ctx, fs);
7170         {
7171             TCGv_i64 fp0 = tcg_temp_new_i64();
7172
7173             gen_load_fpr64(ctx, fp0, fs);
7174             tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7175             tcg_temp_free_i64(fp0);
7176         }
7177         opn = "sdxc1";
7178         store = 1;
7179         break;
7180     case OPC_SUXC1:
7181         check_cp1_64bitmode(ctx);
7182         tcg_gen_andi_tl(t0, t0, ~0x7);
7183         {
7184             TCGv_i64 fp0 = tcg_temp_new_i64();
7185
7186             gen_load_fpr64(ctx, fp0, fs);
7187             tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7188             tcg_temp_free_i64(fp0);
7189         }
7190         opn = "suxc1";
7191         store = 1;
7192         break;
7193     default:
7194         MIPS_INVAL(opn);
7195         generate_exception(ctx, EXCP_RI);
7196         tcg_temp_free(t0);
7197         tcg_temp_free(t1);
7198         return;
7199     }
7200     tcg_temp_free(t0);
7201     tcg_temp_free(t1);
7202     MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7203                regnames[index], regnames[base]);
7204 }
7205
7206 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7207                             int fd, int fr, int fs, int ft)
7208 {
7209     const char *opn = "flt3_arith";
7210
7211     switch (opc) {
7212     case OPC_ALNV_PS:
7213         check_cp1_64bitmode(ctx);
7214         {
7215             TCGv t0 = tcg_temp_local_new();
7216             TCGv_i32 fp0 = tcg_temp_local_new_i32();
7217             TCGv_i32 fph0 = tcg_temp_local_new_i32();
7218             TCGv_i32 fp1 = tcg_temp_local_new_i32();
7219             TCGv_i32 fph1 = tcg_temp_local_new_i32();
7220             int l1 = gen_new_label();
7221             int l2 = gen_new_label();
7222
7223             gen_load_gpr(t0, fr);
7224             tcg_gen_andi_tl(t0, t0, 0x7);
7225             gen_load_fpr32(fp0, fs);
7226             gen_load_fpr32h(fph0, fs);
7227             gen_load_fpr32(fp1, ft);
7228             gen_load_fpr32h(fph1, ft);
7229
7230             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7231             gen_store_fpr32(fp0, fd);
7232             gen_store_fpr32h(fph0, fd);
7233             tcg_gen_br(l2);
7234             gen_set_label(l1);
7235             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7236             tcg_temp_free(t0);
7237 #ifdef TARGET_WORDS_BIGENDIAN
7238             gen_store_fpr32(fph1, fd);
7239             gen_store_fpr32h(fp0, fd);
7240 #else
7241             gen_store_fpr32(fph0, fd);
7242             gen_store_fpr32h(fp1, fd);
7243 #endif
7244             gen_set_label(l2);
7245             tcg_temp_free_i32(fp0);
7246             tcg_temp_free_i32(fph0);
7247             tcg_temp_free_i32(fp1);
7248             tcg_temp_free_i32(fph1);
7249         }
7250         opn = "alnv.ps";
7251         break;
7252     case OPC_MADD_S:
7253         check_cop1x(ctx);
7254         {
7255             TCGv_i32 fp0 = tcg_temp_new_i32();
7256             TCGv_i32 fp1 = tcg_temp_new_i32();
7257             TCGv_i32 fp2 = tcg_temp_new_i32();
7258
7259             gen_load_fpr32(fp0, fs);
7260             gen_load_fpr32(fp1, ft);
7261             gen_load_fpr32(fp2, fr);
7262             gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7263             tcg_temp_free_i32(fp0);
7264             tcg_temp_free_i32(fp1);
7265             gen_store_fpr32(fp2, fd);
7266             tcg_temp_free_i32(fp2);
7267         }
7268         opn = "madd.s";
7269         break;
7270     case OPC_MADD_D:
7271         check_cop1x(ctx);
7272         check_cp1_registers(ctx, fd | fs | ft | fr);
7273         {
7274             TCGv_i64 fp0 = tcg_temp_new_i64();
7275             TCGv_i64 fp1 = tcg_temp_new_i64();
7276             TCGv_i64 fp2 = tcg_temp_new_i64();
7277
7278             gen_load_fpr64(ctx, fp0, fs);
7279             gen_load_fpr64(ctx, fp1, ft);
7280             gen_load_fpr64(ctx, fp2, fr);
7281             gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7282             tcg_temp_free_i64(fp0);
7283             tcg_temp_free_i64(fp1);
7284             gen_store_fpr64(ctx, fp2, fd);
7285             tcg_temp_free_i64(fp2);
7286         }
7287         opn = "madd.d";
7288         break;
7289     case OPC_MADD_PS:
7290         check_cp1_64bitmode(ctx);
7291         {
7292             TCGv_i64 fp0 = tcg_temp_new_i64();
7293             TCGv_i64 fp1 = tcg_temp_new_i64();
7294             TCGv_i64 fp2 = tcg_temp_new_i64();
7295
7296             gen_load_fpr64(ctx, fp0, fs);
7297             gen_load_fpr64(ctx, fp1, ft);
7298             gen_load_fpr64(ctx, fp2, fr);
7299             gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7300             tcg_temp_free_i64(fp0);
7301             tcg_temp_free_i64(fp1);
7302             gen_store_fpr64(ctx, fp2, fd);
7303             tcg_temp_free_i64(fp2);
7304         }
7305         opn = "madd.ps";
7306         break;
7307     case OPC_MSUB_S:
7308         check_cop1x(ctx);
7309         {
7310             TCGv_i32 fp0 = tcg_temp_new_i32();
7311             TCGv_i32 fp1 = tcg_temp_new_i32();
7312             TCGv_i32 fp2 = tcg_temp_new_i32();
7313
7314             gen_load_fpr32(fp0, fs);
7315             gen_load_fpr32(fp1, ft);
7316             gen_load_fpr32(fp2, fr);
7317             gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7318             tcg_temp_free_i32(fp0);
7319             tcg_temp_free_i32(fp1);
7320             gen_store_fpr32(fp2, fd);
7321             tcg_temp_free_i32(fp2);
7322         }
7323         opn = "msub.s";
7324         break;
7325     case OPC_MSUB_D:
7326         check_cop1x(ctx);
7327         check_cp1_registers(ctx, fd | fs | ft | fr);
7328         {
7329             TCGv_i64 fp0 = tcg_temp_new_i64();
7330             TCGv_i64 fp1 = tcg_temp_new_i64();
7331             TCGv_i64 fp2 = tcg_temp_new_i64();
7332
7333             gen_load_fpr64(ctx, fp0, fs);
7334             gen_load_fpr64(ctx, fp1, ft);
7335             gen_load_fpr64(ctx, fp2, fr);
7336             gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7337             tcg_temp_free_i64(fp0);
7338             tcg_temp_free_i64(fp1);
7339             gen_store_fpr64(ctx, fp2, fd);
7340             tcg_temp_free_i64(fp2);
7341         }
7342         opn = "msub.d";
7343         break;
7344     case OPC_MSUB_PS:
7345         check_cp1_64bitmode(ctx);
7346         {
7347             TCGv_i64 fp0 = tcg_temp_new_i64();
7348             TCGv_i64 fp1 = tcg_temp_new_i64();
7349             TCGv_i64 fp2 = tcg_temp_new_i64();
7350
7351             gen_load_fpr64(ctx, fp0, fs);
7352             gen_load_fpr64(ctx, fp1, ft);
7353             gen_load_fpr64(ctx, fp2, fr);
7354             gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7355             tcg_temp_free_i64(fp0);
7356             tcg_temp_free_i64(fp1);
7357             gen_store_fpr64(ctx, fp2, fd);
7358             tcg_temp_free_i64(fp2);
7359         }
7360         opn = "msub.ps";
7361         break;
7362     case OPC_NMADD_S:
7363         check_cop1x(ctx);
7364         {
7365             TCGv_i32 fp0 = tcg_temp_new_i32();
7366             TCGv_i32 fp1 = tcg_temp_new_i32();
7367             TCGv_i32 fp2 = tcg_temp_new_i32();
7368
7369             gen_load_fpr32(fp0, fs);
7370             gen_load_fpr32(fp1, ft);
7371             gen_load_fpr32(fp2, fr);
7372             gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7373             tcg_temp_free_i32(fp0);
7374             tcg_temp_free_i32(fp1);
7375             gen_store_fpr32(fp2, fd);
7376             tcg_temp_free_i32(fp2);
7377         }
7378         opn = "nmadd.s";
7379         break;
7380     case OPC_NMADD_D:
7381         check_cop1x(ctx);
7382         check_cp1_registers(ctx, fd | fs | ft | fr);
7383         {
7384             TCGv_i64 fp0 = tcg_temp_new_i64();
7385             TCGv_i64 fp1 = tcg_temp_new_i64();
7386             TCGv_i64 fp2 = tcg_temp_new_i64();
7387
7388             gen_load_fpr64(ctx, fp0, fs);
7389             gen_load_fpr64(ctx, fp1, ft);
7390             gen_load_fpr64(ctx, fp2, fr);
7391             gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7392             tcg_temp_free_i64(fp0);
7393             tcg_temp_free_i64(fp1);
7394             gen_store_fpr64(ctx, fp2, fd);
7395             tcg_temp_free_i64(fp2);
7396         }
7397         opn = "nmadd.d";
7398         break;
7399     case OPC_NMADD_PS:
7400         check_cp1_64bitmode(ctx);
7401         {
7402             TCGv_i64 fp0 = tcg_temp_new_i64();
7403             TCGv_i64 fp1 = tcg_temp_new_i64();
7404             TCGv_i64 fp2 = tcg_temp_new_i64();
7405
7406             gen_load_fpr64(ctx, fp0, fs);
7407             gen_load_fpr64(ctx, fp1, ft);
7408             gen_load_fpr64(ctx, fp2, fr);
7409             gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7410             tcg_temp_free_i64(fp0);
7411             tcg_temp_free_i64(fp1);
7412             gen_store_fpr64(ctx, fp2, fd);
7413             tcg_temp_free_i64(fp2);
7414         }
7415         opn = "nmadd.ps";
7416         break;
7417     case OPC_NMSUB_S:
7418         check_cop1x(ctx);
7419         {
7420             TCGv_i32 fp0 = tcg_temp_new_i32();
7421             TCGv_i32 fp1 = tcg_temp_new_i32();
7422             TCGv_i32 fp2 = tcg_temp_new_i32();
7423
7424             gen_load_fpr32(fp0, fs);
7425             gen_load_fpr32(fp1, ft);
7426             gen_load_fpr32(fp2, fr);
7427             gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7428             tcg_temp_free_i32(fp0);
7429             tcg_temp_free_i32(fp1);
7430             gen_store_fpr32(fp2, fd);
7431             tcg_temp_free_i32(fp2);
7432         }
7433         opn = "nmsub.s";
7434         break;
7435     case OPC_NMSUB_D:
7436         check_cop1x(ctx);
7437         check_cp1_registers(ctx, fd | fs | ft | fr);
7438         {
7439             TCGv_i64 fp0 = tcg_temp_new_i64();
7440             TCGv_i64 fp1 = tcg_temp_new_i64();
7441             TCGv_i64 fp2 = tcg_temp_new_i64();
7442
7443             gen_load_fpr64(ctx, fp0, fs);
7444             gen_load_fpr64(ctx, fp1, ft);
7445             gen_load_fpr64(ctx, fp2, fr);
7446             gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7447             tcg_temp_free_i64(fp0);
7448             tcg_temp_free_i64(fp1);
7449             gen_store_fpr64(ctx, fp2, fd);
7450             tcg_temp_free_i64(fp2);
7451         }
7452         opn = "nmsub.d";
7453         break;
7454     case OPC_NMSUB_PS:
7455         check_cp1_64bitmode(ctx);
7456         {
7457             TCGv_i64 fp0 = tcg_temp_new_i64();
7458             TCGv_i64 fp1 = tcg_temp_new_i64();
7459             TCGv_i64 fp2 = tcg_temp_new_i64();
7460
7461             gen_load_fpr64(ctx, fp0, fs);
7462             gen_load_fpr64(ctx, fp1, ft);
7463             gen_load_fpr64(ctx, fp2, fr);
7464             gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
7465             tcg_temp_free_i64(fp0);
7466             tcg_temp_free_i64(fp1);
7467             gen_store_fpr64(ctx, fp2, fd);
7468             tcg_temp_free_i64(fp2);
7469         }
7470         opn = "nmsub.ps";
7471         break;
7472     default:
7473         MIPS_INVAL(opn);
7474         generate_exception (ctx, EXCP_RI);
7475         return;
7476     }
7477     MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7478                fregnames[fs], fregnames[ft]);
7479 }
7480
7481 /* ISA extensions (ASEs) */
7482 /* MIPS16 extension to MIPS32 */
7483 /* SmartMIPS extension to MIPS32 */
7484
7485 #if defined(TARGET_MIPS64)
7486
7487 /* MDMX extension to MIPS64 */
7488
7489 #endif
7490
7491 static void decode_opc (CPUState *env, DisasContext *ctx)
7492 {
7493     int32_t offset;
7494     int rs, rt, rd, sa;
7495     uint32_t op, op1, op2;
7496     int16_t imm;
7497
7498     /* make sure instructions are on a word boundary */
7499     if (ctx->pc & 0x3) {
7500         env->CP0_BadVAddr = ctx->pc;
7501         generate_exception(ctx, EXCP_AdEL);
7502         return;
7503     }
7504
7505     /* Handle blikely not taken case */
7506     if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7507         int l1 = gen_new_label();
7508
7509         MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7510         tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
7511         tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
7512         gen_goto_tb(ctx, 1, ctx->pc + 4);
7513         gen_set_label(l1);
7514     }
7515     op = MASK_OP_MAJOR(ctx->opcode);
7516     rs = (ctx->opcode >> 21) & 0x1f;
7517     rt = (ctx->opcode >> 16) & 0x1f;
7518     rd = (ctx->opcode >> 11) & 0x1f;
7519     sa = (ctx->opcode >> 6) & 0x1f;
7520     imm = (int16_t)ctx->opcode;
7521     switch (op) {
7522     case OPC_SPECIAL:
7523         op1 = MASK_SPECIAL(ctx->opcode);
7524         switch (op1) {
7525         case OPC_SLL:          /* Arithmetic with immediate */
7526         case OPC_SRL ... OPC_SRA:
7527             gen_arith_imm(env, ctx, op1, rd, rt, sa);
7528             break;
7529         case OPC_MOVZ ... OPC_MOVN:
7530             check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7531         case OPC_SLLV:         /* Arithmetic */
7532         case OPC_SRLV ... OPC_SRAV:
7533         case OPC_ADD ... OPC_NOR:
7534         case OPC_SLT ... OPC_SLTU:
7535             gen_arith(env, ctx, op1, rd, rs, rt);
7536             break;
7537         case OPC_MULT ... OPC_DIVU:
7538             if (sa) {
7539                 check_insn(env, ctx, INSN_VR54XX);
7540                 op1 = MASK_MUL_VR54XX(ctx->opcode);
7541                 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7542             } else
7543                 gen_muldiv(ctx, op1, rs, rt);
7544             break;
7545         case OPC_JR ... OPC_JALR:
7546             gen_compute_branch(ctx, op1, rs, rd, sa);
7547             return;
7548         case OPC_TGE ... OPC_TEQ: /* Traps */
7549         case OPC_TNE:
7550             gen_trap(ctx, op1, rs, rt, -1);
7551             break;
7552         case OPC_MFHI:          /* Move from HI/LO */
7553         case OPC_MFLO:
7554             gen_HILO(ctx, op1, rd);
7555             break;
7556         case OPC_MTHI:
7557         case OPC_MTLO:          /* Move to HI/LO */
7558             gen_HILO(ctx, op1, rs);
7559             break;
7560         case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
7561 #ifdef MIPS_STRICT_STANDARD
7562             MIPS_INVAL("PMON / selsl");
7563             generate_exception(ctx, EXCP_RI);
7564 #else
7565             gen_helper_0i(pmon, sa);
7566 #endif
7567             break;
7568         case OPC_SYSCALL:
7569             generate_exception(ctx, EXCP_SYSCALL);
7570             break;
7571         case OPC_BREAK:
7572             generate_exception(ctx, EXCP_BREAK);
7573             break;
7574         case OPC_SPIM:
7575 #ifdef MIPS_STRICT_STANDARD
7576             MIPS_INVAL("SPIM");
7577             generate_exception(ctx, EXCP_RI);
7578 #else
7579            /* Implemented as RI exception for now. */
7580             MIPS_INVAL("spim (unofficial)");
7581             generate_exception(ctx, EXCP_RI);
7582 #endif
7583             break;
7584         case OPC_SYNC:
7585             /* Treat as NOP. */
7586             break;
7587
7588         case OPC_MOVCI:
7589             check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7590             if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7591                 save_cpu_state(ctx, 1);
7592                 check_cp1_enabled(ctx);
7593                 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7594                           (ctx->opcode >> 16) & 1);
7595             } else {
7596                 generate_exception_err(ctx, EXCP_CpU, 1);
7597             }
7598             break;
7599
7600 #if defined(TARGET_MIPS64)
7601        /* MIPS64 specific opcodes */
7602         case OPC_DSLL:
7603         case OPC_DSRL ... OPC_DSRA:
7604         case OPC_DSLL32:
7605         case OPC_DSRL32 ... OPC_DSRA32:
7606             check_insn(env, ctx, ISA_MIPS3);
7607             check_mips_64(ctx);
7608             gen_arith_imm(env, ctx, op1, rd, rt, sa);
7609             break;
7610         case OPC_DSLLV:
7611         case OPC_DSRLV ... OPC_DSRAV:
7612         case OPC_DADD ... OPC_DSUBU:
7613             check_insn(env, ctx, ISA_MIPS3);
7614             check_mips_64(ctx);
7615             gen_arith(env, ctx, op1, rd, rs, rt);
7616             break;
7617         case OPC_DMULT ... OPC_DDIVU:
7618             check_insn(env, ctx, ISA_MIPS3);
7619             check_mips_64(ctx);
7620             gen_muldiv(ctx, op1, rs, rt);
7621             break;
7622 #endif
7623         default:            /* Invalid */
7624             MIPS_INVAL("special");
7625             generate_exception(ctx, EXCP_RI);
7626             break;
7627         }
7628         break;
7629     case OPC_SPECIAL2:
7630         op1 = MASK_SPECIAL2(ctx->opcode);
7631         switch (op1) {
7632         case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7633         case OPC_MSUB ... OPC_MSUBU:
7634             check_insn(env, ctx, ISA_MIPS32);
7635             gen_muldiv(ctx, op1, rs, rt);
7636             break;
7637         case OPC_MUL:
7638             gen_arith(env, ctx, op1, rd, rs, rt);
7639             break;
7640         case OPC_CLO:
7641         case OPC_CLZ:
7642             check_insn(env, ctx, ISA_MIPS32);
7643             gen_cl(ctx, op1, rd, rs);
7644             break;
7645         case OPC_SDBBP:
7646             /* XXX: not clear which exception should be raised
7647              *      when in debug mode...
7648              */
7649             check_insn(env, ctx, ISA_MIPS32);
7650             if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7651                 generate_exception(ctx, EXCP_DBp);
7652             } else {
7653                 generate_exception(ctx, EXCP_DBp);
7654             }
7655             /* Treat as NOP. */
7656             break;
7657 #if defined(TARGET_MIPS64)
7658         case OPC_DCLO:
7659         case OPC_DCLZ:
7660             check_insn(env, ctx, ISA_MIPS64);
7661             check_mips_64(ctx);
7662             gen_cl(ctx, op1, rd, rs);
7663             break;
7664 #endif
7665         default:            /* Invalid */
7666             MIPS_INVAL("special2");
7667             generate_exception(ctx, EXCP_RI);
7668             break;
7669         }
7670         break;
7671     case OPC_SPECIAL3:
7672         op1 = MASK_SPECIAL3(ctx->opcode);
7673         switch (op1) {
7674         case OPC_EXT:
7675         case OPC_INS:
7676             check_insn(env, ctx, ISA_MIPS32R2);
7677             gen_bitops(ctx, op1, rt, rs, sa, rd);
7678             break;
7679         case OPC_BSHFL:
7680             check_insn(env, ctx, ISA_MIPS32R2);
7681             op2 = MASK_BSHFL(ctx->opcode);
7682             gen_bshfl(ctx, op2, rt, rd);
7683             break;
7684         case OPC_RDHWR:
7685             check_insn(env, ctx, ISA_MIPS32R2);
7686             {
7687                 TCGv t0 = tcg_temp_local_new();
7688
7689                 switch (rd) {
7690                 case 0:
7691                     save_cpu_state(ctx, 1);
7692                     gen_helper_rdhwr_cpunum(t0);
7693                     break;
7694                 case 1:
7695                     save_cpu_state(ctx, 1);
7696                     gen_helper_rdhwr_synci_step(t0);
7697                     break;
7698                 case 2:
7699                     save_cpu_state(ctx, 1);
7700                     gen_helper_rdhwr_cc(t0);
7701                     break;
7702                 case 3:
7703                     save_cpu_state(ctx, 1);
7704                     gen_helper_rdhwr_ccres(t0);
7705                     break;
7706                 case 29:
7707 #if defined(CONFIG_USER_ONLY)
7708                     tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7709                     break;
7710 #else
7711                     /* XXX: Some CPUs implement this in hardware.
7712                        Not supported yet. */
7713 #endif
7714                 default:            /* Invalid */
7715                     MIPS_INVAL("rdhwr");
7716                     generate_exception(ctx, EXCP_RI);
7717                     break;
7718                 }
7719                 gen_store_gpr(t0, rt);
7720                 tcg_temp_free(t0);
7721             }
7722             break;
7723         case OPC_FORK:
7724             check_insn(env, ctx, ASE_MT);
7725             {
7726                 TCGv t0 = tcg_temp_local_new();
7727                 TCGv t1 = tcg_temp_local_new();
7728
7729                 gen_load_gpr(t0, rt);
7730                 gen_load_gpr(t1, rs);
7731                 gen_helper_fork(t0, t1);
7732                 tcg_temp_free(t0);
7733                 tcg_temp_free(t1);
7734             }
7735             break;
7736         case OPC_YIELD:
7737             check_insn(env, ctx, ASE_MT);
7738             {
7739                 TCGv t0 = tcg_temp_local_new();
7740
7741                 gen_load_gpr(t0, rs);
7742                 gen_helper_yield(t0, t0);
7743                 gen_store_gpr(t0, rd);
7744                 tcg_temp_free(t0);
7745             }
7746             break;
7747 #if defined(TARGET_MIPS64)
7748         case OPC_DEXTM ... OPC_DEXT:
7749         case OPC_DINSM ... OPC_DINS:
7750             check_insn(env, ctx, ISA_MIPS64R2);
7751             check_mips_64(ctx);
7752             gen_bitops(ctx, op1, rt, rs, sa, rd);
7753             break;
7754         case OPC_DBSHFL:
7755             check_insn(env, ctx, ISA_MIPS64R2);
7756             check_mips_64(ctx);
7757             op2 = MASK_DBSHFL(ctx->opcode);
7758             gen_bshfl(ctx, op2, rt, rd);
7759             break;
7760 #endif
7761         default:            /* Invalid */
7762             MIPS_INVAL("special3");
7763             generate_exception(ctx, EXCP_RI);
7764             break;
7765         }
7766         break;
7767     case OPC_REGIMM:
7768         op1 = MASK_REGIMM(ctx->opcode);
7769         switch (op1) {
7770         case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
7771         case OPC_BLTZAL ... OPC_BGEZALL:
7772             gen_compute_branch(ctx, op1, rs, -1, imm << 2);
7773             return;
7774         case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
7775         case OPC_TNEI:
7776             gen_trap(ctx, op1, rs, -1, imm);
7777             break;
7778         case OPC_SYNCI:
7779             check_insn(env, ctx, ISA_MIPS32R2);
7780             /* Treat as NOP. */
7781             break;
7782         default:            /* Invalid */
7783             MIPS_INVAL("regimm");
7784             generate_exception(ctx, EXCP_RI);
7785             break;
7786         }
7787         break;
7788     case OPC_CP0:
7789         check_cp0_enabled(ctx);
7790         op1 = MASK_CP0(ctx->opcode);
7791         switch (op1) {
7792         case OPC_MFC0:
7793         case OPC_MTC0:
7794         case OPC_MFTR:
7795         case OPC_MTTR:
7796 #if defined(TARGET_MIPS64)
7797         case OPC_DMFC0:
7798         case OPC_DMTC0:
7799 #endif
7800 #ifndef CONFIG_USER_ONLY
7801             gen_cp0(env, ctx, op1, rt, rd);
7802 #endif /* !CONFIG_USER_ONLY */
7803             break;
7804         case OPC_C0_FIRST ... OPC_C0_LAST:
7805 #ifndef CONFIG_USER_ONLY
7806             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
7807 #endif /* !CONFIG_USER_ONLY */
7808             break;
7809         case OPC_MFMC0:
7810 #ifndef CONFIG_USER_ONLY
7811             {
7812                 TCGv t0 = tcg_temp_local_new();
7813
7814                 op2 = MASK_MFMC0(ctx->opcode);
7815                 switch (op2) {
7816                 case OPC_DMT:
7817                     check_insn(env, ctx, ASE_MT);
7818                     gen_helper_dmt(t0, t0);
7819                     break;
7820                 case OPC_EMT:
7821                     check_insn(env, ctx, ASE_MT);
7822                     gen_helper_emt(t0, t0);
7823                     break;
7824                 case OPC_DVPE:
7825                     check_insn(env, ctx, ASE_MT);
7826                     gen_helper_dvpe(t0, t0);
7827                     break;
7828                 case OPC_EVPE:
7829                     check_insn(env, ctx, ASE_MT);
7830                     gen_helper_evpe(t0, t0);
7831                     break;
7832                 case OPC_DI:
7833                     check_insn(env, ctx, ISA_MIPS32R2);
7834                     save_cpu_state(ctx, 1);
7835                     gen_helper_di(t0);
7836                     /* Stop translation as we may have switched the execution mode */
7837                     ctx->bstate = BS_STOP;
7838                     break;
7839                 case OPC_EI:
7840                     check_insn(env, ctx, ISA_MIPS32R2);
7841                     save_cpu_state(ctx, 1);
7842                     gen_helper_ei(t0);
7843                     /* Stop translation as we may have switched the execution mode */
7844                     ctx->bstate = BS_STOP;
7845                     break;
7846                 default:            /* Invalid */
7847                     MIPS_INVAL("mfmc0");
7848                     generate_exception(ctx, EXCP_RI);
7849                     break;
7850                 }
7851                 gen_store_gpr(t0, rt);
7852                 tcg_temp_free(t0);
7853             }
7854 #endif /* !CONFIG_USER_ONLY */
7855             break;
7856         case OPC_RDPGPR:
7857             check_insn(env, ctx, ISA_MIPS32R2);
7858             gen_load_srsgpr(rt, rd);
7859             break;
7860         case OPC_WRPGPR:
7861             check_insn(env, ctx, ISA_MIPS32R2);
7862             gen_store_srsgpr(rt, rd);
7863             break;
7864         default:
7865             MIPS_INVAL("cp0");
7866             generate_exception(ctx, EXCP_RI);
7867             break;
7868         }
7869         break;
7870     case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
7871          gen_arith_imm(env, ctx, op, rt, rs, imm);
7872          break;
7873     case OPC_J ... OPC_JAL: /* Jump */
7874          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
7875          gen_compute_branch(ctx, op, rs, rt, offset);
7876          return;
7877     case OPC_BEQ ... OPC_BGTZ: /* Branch */
7878     case OPC_BEQL ... OPC_BGTZL:
7879          gen_compute_branch(ctx, op, rs, rt, imm << 2);
7880          return;
7881     case OPC_LB ... OPC_LWR: /* Load and stores */
7882     case OPC_SB ... OPC_SW:
7883     case OPC_SWR:
7884     case OPC_LL:
7885     case OPC_SC:
7886          gen_ldst(ctx, op, rt, rs, imm);
7887          break;
7888     case OPC_CACHE:
7889         check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
7890         /* Treat as NOP. */
7891         break;
7892     case OPC_PREF:
7893         check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7894         /* Treat as NOP. */
7895         break;
7896
7897     /* Floating point (COP1). */
7898     case OPC_LWC1:
7899     case OPC_LDC1:
7900     case OPC_SWC1:
7901     case OPC_SDC1:
7902         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7903             save_cpu_state(ctx, 1);
7904             check_cp1_enabled(ctx);
7905             gen_flt_ldst(ctx, op, rt, rs, imm);
7906         } else {
7907             generate_exception_err(ctx, EXCP_CpU, 1);
7908         }
7909         break;
7910
7911     case OPC_CP1:
7912         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7913             save_cpu_state(ctx, 1);
7914             check_cp1_enabled(ctx);
7915             op1 = MASK_CP1(ctx->opcode);
7916             switch (op1) {
7917             case OPC_MFHC1:
7918             case OPC_MTHC1:
7919                 check_insn(env, ctx, ISA_MIPS32R2);
7920             case OPC_MFC1:
7921             case OPC_CFC1:
7922             case OPC_MTC1:
7923             case OPC_CTC1:
7924                 gen_cp1(ctx, op1, rt, rd);
7925                 break;
7926 #if defined(TARGET_MIPS64)
7927             case OPC_DMFC1:
7928             case OPC_DMTC1:
7929                 check_insn(env, ctx, ISA_MIPS3);
7930                 gen_cp1(ctx, op1, rt, rd);
7931                 break;
7932 #endif
7933             case OPC_BC1ANY2:
7934             case OPC_BC1ANY4:
7935                 check_cop1x(ctx);
7936                 check_insn(env, ctx, ASE_MIPS3D);
7937                 /* fall through */
7938             case OPC_BC1:
7939                 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
7940                                     (rt >> 2) & 0x7, imm << 2);
7941                 return;
7942             case OPC_S_FMT:
7943             case OPC_D_FMT:
7944             case OPC_W_FMT:
7945             case OPC_L_FMT:
7946             case OPC_PS_FMT:
7947                 gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
7948                            (imm >> 8) & 0x7);
7949                 break;
7950             default:
7951                 MIPS_INVAL("cp1");
7952                 generate_exception (ctx, EXCP_RI);
7953                 break;
7954             }
7955         } else {
7956             generate_exception_err(ctx, EXCP_CpU, 1);
7957         }
7958         break;
7959
7960     /* COP2.  */
7961     case OPC_LWC2:
7962     case OPC_LDC2:
7963     case OPC_SWC2:
7964     case OPC_SDC2:
7965     case OPC_CP2:
7966         /* COP2: Not implemented. */
7967         generate_exception_err(ctx, EXCP_CpU, 2);
7968         break;
7969
7970     case OPC_CP3:
7971         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7972             save_cpu_state(ctx, 1);
7973             check_cp1_enabled(ctx);
7974             op1 = MASK_CP3(ctx->opcode);
7975             switch (op1) {
7976             case OPC_LWXC1:
7977             case OPC_LDXC1:
7978             case OPC_LUXC1:
7979             case OPC_SWXC1:
7980             case OPC_SDXC1:
7981             case OPC_SUXC1:
7982                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
7983                 break;
7984             case OPC_PREFX:
7985                 /* Treat as NOP. */
7986                 break;
7987             case OPC_ALNV_PS:
7988             case OPC_MADD_S:
7989             case OPC_MADD_D:
7990             case OPC_MADD_PS:
7991             case OPC_MSUB_S:
7992             case OPC_MSUB_D:
7993             case OPC_MSUB_PS:
7994             case OPC_NMADD_S:
7995             case OPC_NMADD_D:
7996             case OPC_NMADD_PS:
7997             case OPC_NMSUB_S:
7998             case OPC_NMSUB_D:
7999             case OPC_NMSUB_PS:
8000                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
8001                 break;
8002             default:
8003                 MIPS_INVAL("cp3");
8004                 generate_exception (ctx, EXCP_RI);
8005                 break;
8006             }
8007         } else {
8008             generate_exception_err(ctx, EXCP_CpU, 1);
8009         }
8010         break;
8011
8012 #if defined(TARGET_MIPS64)
8013     /* MIPS64 opcodes */
8014     case OPC_LWU:
8015     case OPC_LDL ... OPC_LDR:
8016     case OPC_SDL ... OPC_SDR:
8017     case OPC_LLD:
8018     case OPC_LD:
8019     case OPC_SCD:
8020     case OPC_SD:
8021         check_insn(env, ctx, ISA_MIPS3);
8022         check_mips_64(ctx);
8023         gen_ldst(ctx, op, rt, rs, imm);
8024         break;
8025     case OPC_DADDI ... OPC_DADDIU:
8026         check_insn(env, ctx, ISA_MIPS3);
8027         check_mips_64(ctx);
8028         gen_arith_imm(env, ctx, op, rt, rs, imm);
8029         break;
8030 #endif
8031     case OPC_JALX:
8032         check_insn(env, ctx, ASE_MIPS16);
8033         /* MIPS16: Not implemented. */
8034     case OPC_MDMX:
8035         check_insn(env, ctx, ASE_MDMX);
8036         /* MDMX: Not implemented. */
8037     default:            /* Invalid */
8038         MIPS_INVAL("major opcode");
8039         generate_exception(ctx, EXCP_RI);
8040         break;
8041     }
8042     if (ctx->hflags & MIPS_HFLAG_BMASK) {
8043         int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8044         /* Branches completion */
8045         ctx->hflags &= ~MIPS_HFLAG_BMASK;
8046         ctx->bstate = BS_BRANCH;
8047         save_cpu_state(ctx, 0);
8048         /* FIXME: Need to clear can_do_io.  */
8049         switch (hflags) {
8050         case MIPS_HFLAG_B:
8051             /* unconditional branch */
8052             MIPS_DEBUG("unconditional branch");
8053             gen_goto_tb(ctx, 0, ctx->btarget);
8054             break;
8055         case MIPS_HFLAG_BL:
8056             /* blikely taken case */
8057             MIPS_DEBUG("blikely branch taken");
8058             gen_goto_tb(ctx, 0, ctx->btarget);
8059             break;
8060         case MIPS_HFLAG_BC:
8061             /* Conditional branch */
8062             MIPS_DEBUG("conditional branch");
8063             {
8064                 int l1 = gen_new_label();
8065
8066                 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8067                 gen_goto_tb(ctx, 1, ctx->pc + 4);
8068                 gen_set_label(l1);
8069                 gen_goto_tb(ctx, 0, ctx->btarget);
8070             }
8071             break;
8072         case MIPS_HFLAG_BR:
8073             /* unconditional branch to register */
8074             MIPS_DEBUG("branch to register");
8075             tcg_gen_mov_tl(cpu_PC, btarget);
8076             tcg_gen_exit_tb(0);
8077             break;
8078         default:
8079             MIPS_DEBUG("unknown branch");
8080             break;
8081         }
8082     }
8083 }
8084
8085 static inline void
8086 gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8087                                 int search_pc)
8088 {
8089     DisasContext ctx;
8090     target_ulong pc_start;
8091     uint16_t *gen_opc_end;
8092     CPUBreakpoint *bp;
8093     int j, lj = -1;
8094     int num_insns;
8095     int max_insns;
8096
8097     if (search_pc)
8098         qemu_log("search pc %d\n", search_pc);
8099
8100     pc_start = tb->pc;
8101     /* Leave some spare opc slots for branch handling. */
8102     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
8103     ctx.pc = pc_start;
8104     ctx.saved_pc = -1;
8105     ctx.tb = tb;
8106     ctx.bstate = BS_NONE;
8107     /* Restore delay slot state from the tb context.  */
8108     ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
8109     restore_cpu_state(env, &ctx);
8110 #ifdef CONFIG_USER_ONLY
8111         ctx.mem_idx = MIPS_HFLAG_UM;
8112 #else
8113         ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
8114 #endif
8115     num_insns = 0;
8116     max_insns = tb->cflags & CF_COUNT_MASK;
8117     if (max_insns == 0)
8118         max_insns = CF_COUNT_MASK;
8119 #ifdef DEBUG_DISAS
8120     qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n");
8121     /* FIXME: This may print out stale hflags from env... */
8122     log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
8123 #endif
8124     LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
8125     gen_icount_start();
8126     while (ctx.bstate == BS_NONE) {
8127         if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
8128             TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8129                 if (bp->pc == ctx.pc) {
8130                     save_cpu_state(&ctx, 1);
8131                     ctx.bstate = BS_BRANCH;
8132                     gen_helper_0i(raise_exception, EXCP_DEBUG);
8133                     /* Include the breakpoint location or the tb won't
8134                      * be flushed when it must be.  */
8135                     ctx.pc += 4;
8136                     goto done_generating;
8137                 }
8138             }
8139         }
8140
8141         if (search_pc) {
8142             j = gen_opc_ptr - gen_opc_buf;
8143             if (lj < j) {
8144                 lj++;
8145                 while (lj < j)
8146                     gen_opc_instr_start[lj++] = 0;
8147             }
8148             gen_opc_pc[lj] = ctx.pc;
8149             gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
8150             gen_opc_instr_start[lj] = 1;
8151             gen_opc_icount[lj] = num_insns;
8152         }
8153         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8154             gen_io_start();
8155         ctx.opcode = ldl_code(ctx.pc);
8156         decode_opc(env, &ctx);
8157         ctx.pc += 4;
8158         num_insns++;
8159
8160         if (env->singlestep_enabled)
8161             break;
8162
8163         if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8164             break;
8165
8166         if (gen_opc_ptr >= gen_opc_end)
8167             break;
8168
8169         if (num_insns >= max_insns)
8170             break;
8171 #if defined (MIPS_SINGLE_STEP)
8172         break;
8173 #endif
8174     }
8175     if (tb->cflags & CF_LAST_IO)
8176         gen_io_end();
8177     if (env->singlestep_enabled) {
8178         save_cpu_state(&ctx, ctx.bstate == BS_NONE);
8179         gen_helper_0i(raise_exception, EXCP_DEBUG);
8180     } else {
8181         switch (ctx.bstate) {
8182         case BS_STOP:
8183             gen_helper_interrupt_restart();
8184             gen_goto_tb(&ctx, 0, ctx.pc);
8185             break;
8186         case BS_NONE:
8187             save_cpu_state(&ctx, 0);
8188             gen_goto_tb(&ctx, 0, ctx.pc);
8189             break;
8190         case BS_EXCP:
8191             gen_helper_interrupt_restart();
8192             tcg_gen_exit_tb(0);
8193             break;
8194         case BS_BRANCH:
8195         default:
8196             break;
8197         }
8198     }
8199 done_generating:
8200     gen_icount_end(tb, num_insns);
8201     *gen_opc_ptr = INDEX_op_end;
8202     if (search_pc) {
8203         j = gen_opc_ptr - gen_opc_buf;
8204         lj++;
8205         while (lj <= j)
8206             gen_opc_instr_start[lj++] = 0;
8207     } else {
8208         tb->size = ctx.pc - pc_start;
8209         tb->icount = num_insns;
8210     }
8211 #ifdef DEBUG_DISAS
8212     LOG_DISAS("\n");
8213     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8214         qemu_log("IN: %s\n", lookup_symbol(pc_start));
8215         log_target_disas(pc_start, ctx.pc - pc_start, 0);
8216         qemu_log("\n");
8217     }
8218     qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
8219 #endif
8220 }
8221
8222 void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8223 {
8224     gen_intermediate_code_internal(env, tb, 0);
8225 }
8226
8227 void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8228 {
8229     gen_intermediate_code_internal(env, tb, 1);
8230 }
8231
8232 static void fpu_dump_state(CPUState *env, FILE *f,
8233                            int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8234                            int flags)
8235 {
8236     int i;
8237     int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8238
8239 #define printfpr(fp)                                                        \
8240     do {                                                                    \
8241         if (is_fpu64)                                                       \
8242             fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
8243                         (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
8244                         (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8245         else {                                                              \
8246             fpr_t tmp;                                                      \
8247             tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
8248             tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
8249             fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
8250                         tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
8251                         tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
8252         }                                                                   \
8253     } while(0)
8254
8255
8256     fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
8257                 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
8258                 get_float_exception_flags(&env->active_fpu.fp_status));
8259     for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8260         fpu_fprintf(f, "%3s: ", fregnames[i]);
8261         printfpr(&env->active_fpu.fpr[i]);
8262     }
8263
8264 #undef printfpr
8265 }
8266
8267 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8268 /* Debug help: The architecture requires 32bit code to maintain proper
8269    sign-extended values on 64bit machines.  */
8270
8271 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8272
8273 static void
8274 cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8275                                 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8276                                 int flags)
8277 {
8278     int i;
8279
8280     if (!SIGN_EXT_P(env->active_tc.PC))
8281         cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8282     if (!SIGN_EXT_P(env->active_tc.HI[0]))
8283         cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8284     if (!SIGN_EXT_P(env->active_tc.LO[0]))
8285         cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8286     if (!SIGN_EXT_P(env->btarget))
8287         cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8288
8289     for (i = 0; i < 32; i++) {
8290         if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8291             cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8292     }
8293
8294     if (!SIGN_EXT_P(env->CP0_EPC))
8295         cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8296     if (!SIGN_EXT_P(env->CP0_LLAddr))
8297         cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8298 }
8299 #endif
8300
8301 void cpu_dump_state (CPUState *env, FILE *f,
8302                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8303                      int flags)
8304 {
8305     int i;
8306
8307     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",
8308                 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8309                 env->hflags, env->btarget, env->bcond);
8310     for (i = 0; i < 32; i++) {
8311         if ((i & 3) == 0)
8312             cpu_fprintf(f, "GPR%02d:", i);
8313         cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8314         if ((i & 3) == 3)
8315             cpu_fprintf(f, "\n");
8316     }
8317
8318     cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
8319                 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8320     cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8321                 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8322     if (env->hflags & MIPS_HFLAG_FPU)
8323         fpu_dump_state(env, f, cpu_fprintf, flags);
8324 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8325     cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8326 #endif
8327 }
8328
8329 static void mips_tcg_init(void)
8330 {
8331     int i;
8332     static int inited;
8333
8334     /* Initialize various static tables. */
8335     if (inited)
8336         return;
8337
8338     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8339     for (i = 0; i < 32; i++)
8340         cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
8341                                         offsetof(CPUState, active_tc.gpr[i]),
8342                                         regnames[i]);
8343     cpu_PC = tcg_global_mem_new(TCG_AREG0,
8344                                 offsetof(CPUState, active_tc.PC), "PC");
8345     for (i = 0; i < MIPS_DSP_ACC; i++) {
8346         cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
8347                                        offsetof(CPUState, active_tc.HI[i]),
8348                                        regnames_HI[i]);
8349         cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
8350                                        offsetof(CPUState, active_tc.LO[i]),
8351                                        regnames_LO[i]);
8352         cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
8353                                         offsetof(CPUState, active_tc.ACX[i]),
8354                                         regnames_ACX[i]);
8355     }
8356     cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
8357                                      offsetof(CPUState, active_tc.DSPControl),
8358                                      "DSPControl");
8359     bcond = tcg_global_mem_new(TCG_AREG0,
8360                                offsetof(CPUState, bcond), "bcond");
8361     btarget = tcg_global_mem_new(TCG_AREG0,
8362                                  offsetof(CPUState, btarget), "btarget");
8363     hflags = tcg_global_mem_new_i32(TCG_AREG0,
8364                                     offsetof(CPUState, hflags), "hflags");
8365
8366     fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
8367                                       offsetof(CPUState, active_fpu.fcr0),
8368                                       "fcr0");
8369     fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
8370                                        offsetof(CPUState, active_fpu.fcr31),
8371                                        "fcr31");
8372
8373     /* register helpers */
8374 #define GEN_HELPER 2
8375 #include "helper.h"
8376
8377     inited = 1;
8378 }
8379
8380 #include "translate_init.c"
8381
8382 CPUMIPSState *cpu_mips_init (const char *cpu_model)
8383 {
8384     CPUMIPSState *env;
8385     const mips_def_t *def;
8386
8387     def = cpu_mips_find_by_name(cpu_model);
8388     if (!def)
8389         return NULL;
8390     env = qemu_mallocz(sizeof(CPUMIPSState));
8391     env->cpu_model = def;
8392
8393     cpu_exec_init(env);
8394     env->cpu_model_str = cpu_model;
8395     mips_tcg_init();
8396     cpu_reset(env);
8397     return env;
8398 }
8399
8400 void cpu_reset (CPUMIPSState *env)
8401 {
8402     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
8403         qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
8404         log_cpu_state(env, 0);
8405     }
8406
8407     memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8408
8409     tlb_flush(env, 1);
8410
8411     /* Minimal init */
8412 #if defined(CONFIG_USER_ONLY)
8413     env->hflags = MIPS_HFLAG_UM;
8414 #else
8415     if (env->hflags & MIPS_HFLAG_BMASK) {
8416         /* If the exception was raised from a delay slot,
8417            come back to the jump.  */
8418         env->CP0_ErrorEPC = env->active_tc.PC - 4;
8419     } else {
8420         env->CP0_ErrorEPC = env->active_tc.PC;
8421     }
8422     env->active_tc.PC = (int32_t)0xBFC00000;
8423     env->CP0_Wired = 0;
8424     /* SMP not implemented */
8425     env->CP0_EBase = 0x80000000;
8426     env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8427     /* vectored interrupts not implemented, timer on int 7,
8428        no performance counters. */
8429     env->CP0_IntCtl = 0xe0000000;
8430     {
8431         int i;
8432
8433         for (i = 0; i < 7; i++) {
8434             env->CP0_WatchLo[i] = 0;
8435             env->CP0_WatchHi[i] = 0x80000000;
8436         }
8437         env->CP0_WatchLo[7] = 0;
8438         env->CP0_WatchHi[7] = 0;
8439     }
8440     /* Count register increments in debug mode, EJTAG version 1 */
8441     env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8442     env->hflags = MIPS_HFLAG_CP0;
8443 #endif
8444     env->exception_index = EXCP_NONE;
8445     cpu_mips_register(env, env->cpu_model);
8446 }
8447
8448 void gen_pc_load(CPUState *env, TranslationBlock *tb,
8449                 unsigned long searched_pc, int pc_pos, void *puc)
8450 {
8451     env->active_tc.PC = gen_opc_pc[pc_pos];
8452     env->hflags &= ~MIPS_HFLAG_BMASK;
8453     env->hflags |= gen_opc_hflags[pc_pos];
8454 }