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