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