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