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