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