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