target-mips: optimize movc*()
[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_local_new(TCG_TYPE_TL);
5638     TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
5639
5640     if (cc != 0)
5641         check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5642
5643     btarget = ctx->pc + 4 + offset;
5644
5645     switch (op) {
5646     case OPC_BC1F:
5647         {
5648             int l1 = gen_new_label();
5649             int l2 = gen_new_label();
5650             TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5651
5652             get_fp_cond(r_tmp1);
5653             tcg_gen_ext_i32_tl(t0, r_tmp1);
5654             tcg_temp_free(r_tmp1);
5655             tcg_gen_not_tl(t0, t0);
5656             tcg_gen_movi_tl(t1, 0x1 << cc);
5657             tcg_gen_and_tl(t0, t0, t1);
5658             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5659             tcg_gen_movi_tl(t0, 0);
5660             tcg_gen_br(l2);
5661             gen_set_label(l1);
5662             tcg_gen_movi_tl(t0, 1);
5663             gen_set_label(l2);
5664         }
5665         opn = "bc1f";
5666         goto not_likely;
5667     case OPC_BC1FL:
5668         {
5669             int l1 = gen_new_label();
5670             int l2 = gen_new_label();
5671             TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5672
5673             get_fp_cond(r_tmp1);
5674             tcg_gen_ext_i32_tl(t0, r_tmp1);
5675             tcg_temp_free(r_tmp1);
5676             tcg_gen_not_tl(t0, t0);
5677             tcg_gen_movi_tl(t1, 0x1 << cc);
5678             tcg_gen_and_tl(t0, t0, t1);
5679             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5680             tcg_gen_movi_tl(t0, 0);
5681             tcg_gen_br(l2);
5682             gen_set_label(l1);
5683             tcg_gen_movi_tl(t0, 1);
5684             gen_set_label(l2);
5685         }
5686         opn = "bc1fl";
5687         goto likely;
5688     case OPC_BC1T:
5689         {
5690             int l1 = gen_new_label();
5691             int l2 = gen_new_label();
5692             TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5693
5694             get_fp_cond(r_tmp1);
5695             tcg_gen_ext_i32_tl(t0, r_tmp1);
5696             tcg_temp_free(r_tmp1);
5697             tcg_gen_movi_tl(t1, 0x1 << cc);
5698             tcg_gen_and_tl(t0, t0, t1);
5699             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5700             tcg_gen_movi_tl(t0, 0);
5701             tcg_gen_br(l2);
5702             gen_set_label(l1);
5703             tcg_gen_movi_tl(t0, 1);
5704             gen_set_label(l2);
5705         }
5706         opn = "bc1t";
5707         goto not_likely;
5708     case OPC_BC1TL:
5709         {
5710             int l1 = gen_new_label();
5711             int l2 = gen_new_label();
5712             TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5713
5714             get_fp_cond(r_tmp1);
5715             tcg_gen_ext_i32_tl(t0, r_tmp1);
5716             tcg_temp_free(r_tmp1);
5717             tcg_gen_movi_tl(t1, 0x1 << cc);
5718             tcg_gen_and_tl(t0, t0, t1);
5719             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5720             tcg_gen_movi_tl(t0, 0);
5721             tcg_gen_br(l2);
5722             gen_set_label(l1);
5723             tcg_gen_movi_tl(t0, 1);
5724             gen_set_label(l2);
5725         }
5726         opn = "bc1tl";
5727     likely:
5728         ctx->hflags |= MIPS_HFLAG_BL;
5729         tcg_gen_trunc_tl_i32(bcond, t0);
5730         break;
5731     case OPC_BC1FANY2:
5732         {
5733             int l1 = gen_new_label();
5734             int l2 = gen_new_label();
5735             TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5736
5737             get_fp_cond(r_tmp1);
5738             tcg_gen_ext_i32_tl(t0, r_tmp1);
5739             tcg_temp_free(r_tmp1);
5740             tcg_gen_not_tl(t0, t0);
5741             tcg_gen_movi_tl(t1, 0x3 << cc);
5742             tcg_gen_and_tl(t0, t0, t1);
5743             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5744             tcg_gen_movi_tl(t0, 0);
5745             tcg_gen_br(l2);
5746             gen_set_label(l1);
5747             tcg_gen_movi_tl(t0, 1);
5748             gen_set_label(l2);
5749         }
5750         opn = "bc1any2f";
5751         goto not_likely;
5752     case OPC_BC1TANY2:
5753         {
5754             int l1 = gen_new_label();
5755             int l2 = gen_new_label();
5756             TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5757
5758             get_fp_cond(r_tmp1);
5759             tcg_gen_ext_i32_tl(t0, r_tmp1);
5760             tcg_temp_free(r_tmp1);
5761             tcg_gen_movi_tl(t1, 0x3 << cc);
5762             tcg_gen_and_tl(t0, t0, t1);
5763             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5764             tcg_gen_movi_tl(t0, 0);
5765             tcg_gen_br(l2);
5766             gen_set_label(l1);
5767             tcg_gen_movi_tl(t0, 1);
5768             gen_set_label(l2);
5769         }
5770         opn = "bc1any2t";
5771         goto not_likely;
5772     case OPC_BC1FANY4:
5773         {
5774             int l1 = gen_new_label();
5775             int l2 = gen_new_label();
5776             TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5777
5778             get_fp_cond(r_tmp1);
5779             tcg_gen_ext_i32_tl(t0, r_tmp1);
5780             tcg_temp_free(r_tmp1);
5781             tcg_gen_not_tl(t0, t0);
5782             tcg_gen_movi_tl(t1, 0xf << cc);
5783             tcg_gen_and_tl(t0, t0, t1);
5784             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5785             tcg_gen_movi_tl(t0, 0);
5786             tcg_gen_br(l2);
5787             gen_set_label(l1);
5788             tcg_gen_movi_tl(t0, 1);
5789             gen_set_label(l2);
5790         }
5791         opn = "bc1any4f";
5792         goto not_likely;
5793     case OPC_BC1TANY4:
5794         {
5795             int l1 = gen_new_label();
5796             int l2 = gen_new_label();
5797             TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5798
5799             get_fp_cond(r_tmp1);
5800             tcg_gen_ext_i32_tl(t0, r_tmp1);
5801             tcg_temp_free(r_tmp1);
5802             tcg_gen_movi_tl(t1, 0xf << cc);
5803             tcg_gen_and_tl(t0, t0, t1);
5804             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
5805             tcg_gen_movi_tl(t0, 0);
5806             tcg_gen_br(l2);
5807             gen_set_label(l1);
5808             tcg_gen_movi_tl(t0, 1);
5809             gen_set_label(l2);
5810         }
5811         opn = "bc1any4t";
5812     not_likely:
5813         ctx->hflags |= MIPS_HFLAG_BC;
5814         tcg_gen_trunc_tl_i32(bcond, t0);
5815         break;
5816     default:
5817         MIPS_INVAL(opn);
5818         generate_exception (ctx, EXCP_RI);
5819         goto out;
5820     }
5821     MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5822                ctx->hflags, btarget);
5823     ctx->btarget = btarget;
5824
5825  out:
5826     tcg_temp_free(t0);
5827     tcg_temp_free(t1);
5828 }
5829
5830 /* Coprocessor 1 (FPU) */
5831
5832 #define FOP(func, fmt) (((fmt) << 21) | (func))
5833
5834 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5835 {
5836     const char *opn = "cp1 move";
5837     TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5838
5839     switch (opc) {
5840     case OPC_MFC1:
5841         {
5842             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5843
5844             gen_load_fpr32(fp0, fs);
5845             tcg_gen_ext_i32_tl(t0, fp0);
5846             tcg_temp_free(fp0);
5847         }
5848         gen_store_gpr(t0, rt);
5849         opn = "mfc1";
5850         break;
5851     case OPC_MTC1:
5852         gen_load_gpr(t0, rt);
5853         {
5854             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5855
5856             tcg_gen_trunc_tl_i32(fp0, t0);
5857             gen_store_fpr32(fp0, fs);
5858             tcg_temp_free(fp0);
5859         }
5860         opn = "mtc1";
5861         break;
5862     case OPC_CFC1:
5863         tcg_gen_helper_1_i(do_cfc1, t0, fs);
5864         gen_store_gpr(t0, rt);
5865         opn = "cfc1";
5866         break;
5867     case OPC_CTC1:
5868         gen_load_gpr(t0, rt);
5869         tcg_gen_helper_0_1i(do_ctc1, t0, fs);
5870         opn = "ctc1";
5871         break;
5872     case OPC_DMFC1:
5873         {
5874             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
5875
5876             gen_load_fpr64(ctx, fp0, fs);
5877             tcg_gen_mov_tl(t0, fp0);
5878             tcg_temp_free(fp0);
5879         }
5880         gen_store_gpr(t0, rt);
5881         opn = "dmfc1";
5882         break;
5883     case OPC_DMTC1:
5884         gen_load_gpr(t0, rt);
5885         {
5886             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
5887
5888             tcg_gen_mov_tl(fp0, t0);
5889             gen_store_fpr64(ctx, fp0, fs);
5890             tcg_temp_free(fp0);
5891         }
5892         opn = "dmtc1";
5893         break;
5894     case OPC_MFHC1:
5895         {
5896             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5897
5898             gen_load_fpr32h(fp0, fs);
5899             tcg_gen_ext_i32_tl(t0, fp0);
5900             tcg_temp_free(fp0);
5901         }
5902         gen_store_gpr(t0, rt);
5903         opn = "mfhc1";
5904         break;
5905     case OPC_MTHC1:
5906         gen_load_gpr(t0, rt);
5907         {
5908             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
5909
5910             tcg_gen_trunc_tl_i32(fp0, t0);
5911             gen_store_fpr32h(fp0, fs);
5912             tcg_temp_free(fp0);
5913         }
5914         opn = "mthc1";
5915         break;
5916     default:
5917         MIPS_INVAL(opn);
5918         generate_exception (ctx, EXCP_RI);
5919         goto out;
5920     }
5921     MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5922
5923  out:
5924     tcg_temp_free(t0);
5925 }
5926
5927 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5928 {
5929     int l1 = gen_new_label();
5930     uint32_t ccbit;
5931     TCGCond cond;
5932     TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
5933     TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
5934
5935     if (cc)
5936         ccbit = 1 << (24 + cc);
5937     else
5938         ccbit = 1 << 23;
5939     if (tf)
5940         cond = TCG_COND_EQ;
5941     else
5942         cond = TCG_COND_NE;
5943
5944     gen_load_gpr(t0, rd);
5945     tcg_gen_andi_i32(r_tmp, fpu_fcr31, ccbit);
5946     tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
5947     gen_load_gpr(t0, rs);
5948     gen_set_label(l1);
5949     gen_store_gpr(t0, rd);
5950     tcg_temp_free(t0);
5951 }
5952
5953 static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
5954 {
5955     uint32_t ccbit;
5956     int cond;
5957     TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5958     TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
5959     int l1 = gen_new_label();
5960
5961     if (cc)
5962         ccbit = 1 << (24 + cc);
5963     else
5964         ccbit = 1 << 23;
5965
5966     if (tf)
5967         cond = TCG_COND_EQ;
5968     else
5969         cond = TCG_COND_NE;
5970
5971     gen_load_fpr32(fp0, fd);
5972     tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
5973     tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
5974     gen_load_fpr32(fp0, fs);
5975     gen_set_label(l1);
5976     gen_store_fpr32(fp0, fd);
5977     tcg_temp_free(fp0);
5978 }
5979
5980 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
5981 {
5982     uint32_t ccbit;
5983     int cond;
5984     TCGv r_tmp1 = tcg_temp_new(TCG_TYPE_I32);
5985     TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I64);
5986     int l1 = gen_new_label();
5987
5988     if (cc)
5989         ccbit = 1 << (24 + cc);
5990     else
5991         ccbit = 1 << 23;
5992
5993     if (tf)
5994         cond = TCG_COND_EQ;
5995     else
5996         cond = TCG_COND_NE;
5997
5998     gen_load_fpr64(ctx, fp0, fd);
5999     tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
6000     tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
6001     gen_load_fpr64(ctx, fp0, fs);
6002     gen_set_label(l1);
6003     gen_store_fpr64(ctx, fp0, fd);
6004     tcg_temp_free(fp0);
6005 }
6006
6007 static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
6008 {
6009     uint32_t ccbit1, ccbit2;
6010     int cond;
6011     TCGv r_tmp1 = tcg_temp_local_new(TCG_TYPE_I32);
6012     TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
6013     int l1 = gen_new_label();
6014     int l2 = gen_new_label();
6015
6016     if (cc) {
6017         ccbit1 = 1 << (24 + cc);
6018         ccbit2 = 1 << (25 + cc);
6019     } else {
6020         ccbit1 = 1 << 23;
6021         ccbit2 = 1 << 25;
6022     }
6023
6024     if (tf)
6025         cond = TCG_COND_EQ;
6026     else
6027         cond = TCG_COND_NE;
6028
6029     gen_load_fpr32(fp0, fd);
6030     tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit1);
6031     tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
6032     gen_load_fpr32(fp0, fs);
6033     gen_set_label(l1);
6034     gen_store_fpr32(fp0, fd);
6035
6036     gen_load_fpr32h(fp0, fd);
6037     tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit2);
6038     tcg_gen_brcondi_i32(cond, r_tmp1, 0, l2);
6039     gen_load_fpr32h(fp0, fs);
6040     gen_set_label(l2);
6041     gen_store_fpr32h(fp0, fd);
6042
6043     tcg_temp_free(r_tmp1);
6044     tcg_temp_free(fp0);
6045 }
6046
6047
6048 static void gen_farith (DisasContext *ctx, uint32_t op1,
6049                         int ft, int fs, int fd, int cc)
6050 {
6051     const char *opn = "farith";
6052     const char *condnames[] = {
6053             "c.f",
6054             "c.un",
6055             "c.eq",
6056             "c.ueq",
6057             "c.olt",
6058             "c.ult",
6059             "c.ole",
6060             "c.ule",
6061             "c.sf",
6062             "c.ngle",
6063             "c.seq",
6064             "c.ngl",
6065             "c.lt",
6066             "c.nge",
6067             "c.le",
6068             "c.ngt",
6069     };
6070     const char *condnames_abs[] = {
6071             "cabs.f",
6072             "cabs.un",
6073             "cabs.eq",
6074             "cabs.ueq",
6075             "cabs.olt",
6076             "cabs.ult",
6077             "cabs.ole",
6078             "cabs.ule",
6079             "cabs.sf",
6080             "cabs.ngle",
6081             "cabs.seq",
6082             "cabs.ngl",
6083             "cabs.lt",
6084             "cabs.nge",
6085             "cabs.le",
6086             "cabs.ngt",
6087     };
6088     enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6089     uint32_t func = ctx->opcode & 0x3f;
6090
6091     switch (ctx->opcode & FOP(0x3f, 0x1f)) {
6092     case FOP(0, 16):
6093         {
6094             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6095             TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6096
6097             gen_load_fpr32(fp0, fs);
6098             gen_load_fpr32(fp1, ft);
6099             tcg_gen_helper_1_2(do_float_add_s, fp0, fp0, fp1);
6100             tcg_temp_free(fp1);
6101             gen_store_fpr32(fp0, fd);
6102             tcg_temp_free(fp0);
6103         }
6104         opn = "add.s";
6105         optype = BINOP;
6106         break;
6107     case FOP(1, 16):
6108         {
6109             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6110             TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6111
6112             gen_load_fpr32(fp0, fs);
6113             gen_load_fpr32(fp1, ft);
6114             tcg_gen_helper_1_2(do_float_sub_s, fp0, fp0, fp1);
6115             tcg_temp_free(fp1);
6116             gen_store_fpr32(fp0, fd);
6117             tcg_temp_free(fp0);
6118         }
6119         opn = "sub.s";
6120         optype = BINOP;
6121         break;
6122     case FOP(2, 16):
6123         {
6124             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6125             TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6126
6127             gen_load_fpr32(fp0, fs);
6128             gen_load_fpr32(fp1, ft);
6129             tcg_gen_helper_1_2(do_float_mul_s, fp0, fp0, fp1);
6130             tcg_temp_free(fp1);
6131             gen_store_fpr32(fp0, fd);
6132             tcg_temp_free(fp0);
6133         }
6134         opn = "mul.s";
6135         optype = BINOP;
6136         break;
6137     case FOP(3, 16):
6138         {
6139             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6140             TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6141
6142             gen_load_fpr32(fp0, fs);
6143             gen_load_fpr32(fp1, ft);
6144             tcg_gen_helper_1_2(do_float_div_s, fp0, fp0, fp1);
6145             tcg_temp_free(fp1);
6146             gen_store_fpr32(fp0, fd);
6147             tcg_temp_free(fp0);
6148         }
6149         opn = "div.s";
6150         optype = BINOP;
6151         break;
6152     case FOP(4, 16):
6153         {
6154             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6155
6156             gen_load_fpr32(fp0, fs);
6157             tcg_gen_helper_1_1(do_float_sqrt_s, fp0, fp0);
6158             gen_store_fpr32(fp0, fd);
6159             tcg_temp_free(fp0);
6160         }
6161         opn = "sqrt.s";
6162         break;
6163     case FOP(5, 16):
6164         {
6165             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6166
6167             gen_load_fpr32(fp0, fs);
6168             tcg_gen_helper_1_1(do_float_abs_s, fp0, fp0);
6169             gen_store_fpr32(fp0, fd);
6170             tcg_temp_free(fp0);
6171         }
6172         opn = "abs.s";
6173         break;
6174     case FOP(6, 16):
6175         {
6176             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6177
6178             gen_load_fpr32(fp0, fs);
6179             gen_store_fpr32(fp0, fd);
6180             tcg_temp_free(fp0);
6181         }
6182         opn = "mov.s";
6183         break;
6184     case FOP(7, 16):
6185         {
6186             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6187
6188             gen_load_fpr32(fp0, fs);
6189             tcg_gen_helper_1_1(do_float_chs_s, fp0, fp0);
6190             gen_store_fpr32(fp0, fd);
6191             tcg_temp_free(fp0);
6192         }
6193         opn = "neg.s";
6194         break;
6195     case FOP(8, 16):
6196         check_cp1_64bitmode(ctx);
6197         {
6198             TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6199             TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6200
6201             gen_load_fpr32(fp32, fs);
6202             tcg_gen_helper_1_1(do_float_roundl_s, fp64, fp32);
6203             tcg_temp_free(fp32);
6204             gen_store_fpr64(ctx, fp64, fd);
6205             tcg_temp_free(fp64);
6206         }
6207         opn = "round.l.s";
6208         break;
6209     case FOP(9, 16):
6210         check_cp1_64bitmode(ctx);
6211         {
6212             TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6213             TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6214
6215             gen_load_fpr32(fp32, fs);
6216             tcg_gen_helper_1_1(do_float_truncl_s, fp64, fp32);
6217             tcg_temp_free(fp32);
6218             gen_store_fpr64(ctx, fp64, fd);
6219             tcg_temp_free(fp64);
6220         }
6221         opn = "trunc.l.s";
6222         break;
6223     case FOP(10, 16):
6224         check_cp1_64bitmode(ctx);
6225         {
6226             TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6227             TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6228
6229             gen_load_fpr32(fp32, fs);
6230             tcg_gen_helper_1_1(do_float_ceill_s, fp64, fp32);
6231             tcg_temp_free(fp32);
6232             gen_store_fpr64(ctx, fp64, fd);
6233             tcg_temp_free(fp64);
6234         }
6235         opn = "ceil.l.s";
6236         break;
6237     case FOP(11, 16):
6238         check_cp1_64bitmode(ctx);
6239         {
6240             TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6241             TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6242
6243             gen_load_fpr32(fp32, fs);
6244             tcg_gen_helper_1_1(do_float_floorl_s, fp64, fp32);
6245             tcg_temp_free(fp32);
6246             gen_store_fpr64(ctx, fp64, fd);
6247             tcg_temp_free(fp64);
6248         }
6249         opn = "floor.l.s";
6250         break;
6251     case FOP(12, 16):
6252         {
6253             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6254
6255             gen_load_fpr32(fp0, fs);
6256             tcg_gen_helper_1_1(do_float_roundw_s, fp0, fp0);
6257             gen_store_fpr32(fp0, fd);
6258             tcg_temp_free(fp0);
6259         }
6260         opn = "round.w.s";
6261         break;
6262     case FOP(13, 16):
6263         {
6264             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6265
6266             gen_load_fpr32(fp0, fs);
6267             tcg_gen_helper_1_1(do_float_truncw_s, fp0, fp0);
6268             gen_store_fpr32(fp0, fd);
6269             tcg_temp_free(fp0);
6270         }
6271         opn = "trunc.w.s";
6272         break;
6273     case FOP(14, 16):
6274         {
6275             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6276
6277             gen_load_fpr32(fp0, fs);
6278             tcg_gen_helper_1_1(do_float_ceilw_s, fp0, fp0);
6279             gen_store_fpr32(fp0, fd);
6280             tcg_temp_free(fp0);
6281         }
6282         opn = "ceil.w.s";
6283         break;
6284     case FOP(15, 16):
6285         {
6286             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6287
6288             gen_load_fpr32(fp0, fs);
6289             tcg_gen_helper_1_1(do_float_floorw_s, fp0, fp0);
6290             gen_store_fpr32(fp0, fd);
6291             tcg_temp_free(fp0);
6292         }
6293         opn = "floor.w.s";
6294         break;
6295     case FOP(17, 16):
6296         gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6297         opn = "movcf.s";
6298         break;
6299     case FOP(18, 16):
6300         {
6301             int l1 = gen_new_label();
6302             TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
6303             TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
6304
6305             gen_load_gpr(t0, ft);
6306             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6307             gen_load_fpr32(fp0, fs);
6308             gen_store_fpr32(fp0, fd);
6309             tcg_temp_free(fp0);
6310             gen_set_label(l1);
6311             tcg_temp_free(t0);
6312         }
6313         opn = "movz.s";
6314         break;
6315     case FOP(19, 16):
6316         {
6317             int l1 = gen_new_label();
6318             TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
6319             TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
6320
6321             gen_load_gpr(t0, ft);
6322             tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6323             gen_load_fpr32(fp0, fs);
6324             gen_store_fpr32(fp0, fd);
6325             tcg_temp_free(fp0);
6326             gen_set_label(l1);
6327             tcg_temp_free(t0);
6328         }
6329         opn = "movn.s";
6330         break;
6331     case FOP(21, 16):
6332         check_cop1x(ctx);
6333         {
6334             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6335
6336             gen_load_fpr32(fp0, fs);
6337             tcg_gen_helper_1_1(do_float_recip_s, fp0, fp0);
6338             gen_store_fpr32(fp0, fd);
6339             tcg_temp_free(fp0);
6340         }
6341         opn = "recip.s";
6342         break;
6343     case FOP(22, 16):
6344         check_cop1x(ctx);
6345         {
6346             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6347
6348             gen_load_fpr32(fp0, fs);
6349             tcg_gen_helper_1_1(do_float_rsqrt_s, fp0, fp0);
6350             gen_store_fpr32(fp0, fd);
6351             tcg_temp_free(fp0);
6352         }
6353         opn = "rsqrt.s";
6354         break;
6355     case FOP(28, 16):
6356         check_cp1_64bitmode(ctx);
6357         {
6358             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6359             TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6360
6361             gen_load_fpr32(fp0, fs);
6362             gen_load_fpr32(fp1, fd);
6363             tcg_gen_helper_1_2(do_float_recip2_s, fp0, fp0, fp1);
6364             tcg_temp_free(fp1);
6365             gen_store_fpr32(fp0, fd);
6366             tcg_temp_free(fp0);
6367         }
6368         opn = "recip2.s";
6369         break;
6370     case FOP(29, 16):
6371         check_cp1_64bitmode(ctx);
6372         {
6373             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6374
6375             gen_load_fpr32(fp0, fs);
6376             tcg_gen_helper_1_1(do_float_recip1_s, fp0, fp0);
6377             gen_store_fpr32(fp0, fd);
6378             tcg_temp_free(fp0);
6379         }
6380         opn = "recip1.s";
6381         break;
6382     case FOP(30, 16):
6383         check_cp1_64bitmode(ctx);
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_rsqrt1_s, fp0, fp0);
6389             gen_store_fpr32(fp0, fd);
6390             tcg_temp_free(fp0);
6391         }
6392         opn = "rsqrt1.s";
6393         break;
6394     case FOP(31, 16):
6395         check_cp1_64bitmode(ctx);
6396         {
6397             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6398             TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6399
6400             gen_load_fpr32(fp0, fs);
6401             gen_load_fpr32(fp1, ft);
6402             tcg_gen_helper_1_2(do_float_rsqrt2_s, fp0, fp0, fp1);
6403             tcg_temp_free(fp1);
6404             gen_store_fpr32(fp0, fd);
6405             tcg_temp_free(fp0);
6406         }
6407         opn = "rsqrt2.s";
6408         break;
6409     case FOP(33, 16):
6410         check_cp1_registers(ctx, fd);
6411         {
6412             TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6413             TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6414
6415             gen_load_fpr32(fp32, fs);
6416             tcg_gen_helper_1_1(do_float_cvtd_s, fp64, fp32);
6417             tcg_temp_free(fp32);
6418             gen_store_fpr64(ctx, fp64, fd);
6419             tcg_temp_free(fp64);
6420         }
6421         opn = "cvt.d.s";
6422         break;
6423     case FOP(36, 16):
6424         {
6425             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6426
6427             gen_load_fpr32(fp0, fs);
6428             tcg_gen_helper_1_1(do_float_cvtw_s, fp0, fp0);
6429             gen_store_fpr32(fp0, fd);
6430             tcg_temp_free(fp0);
6431         }
6432         opn = "cvt.w.s";
6433         break;
6434     case FOP(37, 16):
6435         check_cp1_64bitmode(ctx);
6436         {
6437             TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6438             TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6439
6440             gen_load_fpr32(fp32, fs);
6441             tcg_gen_helper_1_1(do_float_cvtl_s, fp64, fp32);
6442             tcg_temp_free(fp32);
6443             gen_store_fpr64(ctx, fp64, fd);
6444             tcg_temp_free(fp64);
6445         }
6446         opn = "cvt.l.s";
6447         break;
6448     case FOP(38, 16):
6449         check_cp1_64bitmode(ctx);
6450         {
6451             TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6452             TCGv fp32_0 = tcg_temp_new(TCG_TYPE_I32);
6453             TCGv fp32_1 = tcg_temp_new(TCG_TYPE_I32);
6454
6455             gen_load_fpr32(fp32_0, fs);
6456             gen_load_fpr32(fp32_1, ft);
6457             tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6458             tcg_temp_free(fp32_1);
6459             tcg_temp_free(fp32_0);
6460             gen_store_fpr64(ctx, fp64, fd);
6461             tcg_temp_free(fp64);
6462         }
6463         opn = "cvt.ps.s";
6464         break;
6465     case FOP(48, 16):
6466     case FOP(49, 16):
6467     case FOP(50, 16):
6468     case FOP(51, 16):
6469     case FOP(52, 16):
6470     case FOP(53, 16):
6471     case FOP(54, 16):
6472     case FOP(55, 16):
6473     case FOP(56, 16):
6474     case FOP(57, 16):
6475     case FOP(58, 16):
6476     case FOP(59, 16):
6477     case FOP(60, 16):
6478     case FOP(61, 16):
6479     case FOP(62, 16):
6480     case FOP(63, 16):
6481         {
6482             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6483             TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
6484
6485             gen_load_fpr32(fp0, fs);
6486             gen_load_fpr32(fp1, ft);
6487             if (ctx->opcode & (1 << 6)) {
6488                 check_cop1x(ctx);
6489                 gen_cmpabs_s(func-48, fp0, fp1, cc);
6490                 opn = condnames_abs[func-48];
6491             } else {
6492                 gen_cmp_s(func-48, fp0, fp1, cc);
6493                 opn = condnames[func-48];
6494             }
6495             tcg_temp_free(fp0);
6496             tcg_temp_free(fp1);
6497         }
6498         break;
6499     case FOP(0, 17):
6500         check_cp1_registers(ctx, fs | ft | fd);
6501         {
6502             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6503             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6504
6505             gen_load_fpr64(ctx, fp0, fs);
6506             gen_load_fpr64(ctx, fp1, ft);
6507             tcg_gen_helper_1_2(do_float_add_d, fp0, fp0, fp1);
6508             tcg_temp_free(fp1);
6509             gen_store_fpr64(ctx, fp0, fd);
6510             tcg_temp_free(fp0);
6511         }
6512         opn = "add.d";
6513         optype = BINOP;
6514         break;
6515     case FOP(1, 17):
6516         check_cp1_registers(ctx, fs | ft | fd);
6517         {
6518             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6519             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6520
6521             gen_load_fpr64(ctx, fp0, fs);
6522             gen_load_fpr64(ctx, fp1, ft);
6523             tcg_gen_helper_1_2(do_float_sub_d, fp0, fp0, fp1);
6524             tcg_temp_free(fp1);
6525             gen_store_fpr64(ctx, fp0, fd);
6526             tcg_temp_free(fp0);
6527         }
6528         opn = "sub.d";
6529         optype = BINOP;
6530         break;
6531     case FOP(2, 17):
6532         check_cp1_registers(ctx, fs | ft | fd);
6533         {
6534             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6535             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6536
6537             gen_load_fpr64(ctx, fp0, fs);
6538             gen_load_fpr64(ctx, fp1, ft);
6539             tcg_gen_helper_1_2(do_float_mul_d, fp0, fp0, fp1);
6540             tcg_temp_free(fp1);
6541             gen_store_fpr64(ctx, fp0, fd);
6542             tcg_temp_free(fp0);
6543         }
6544         opn = "mul.d";
6545         optype = BINOP;
6546         break;
6547     case FOP(3, 17):
6548         check_cp1_registers(ctx, fs | ft | fd);
6549         {
6550             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6551             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6552
6553             gen_load_fpr64(ctx, fp0, fs);
6554             gen_load_fpr64(ctx, fp1, ft);
6555             tcg_gen_helper_1_2(do_float_div_d, fp0, fp0, fp1);
6556             tcg_temp_free(fp1);
6557             gen_store_fpr64(ctx, fp0, fd);
6558             tcg_temp_free(fp0);
6559         }
6560         opn = "div.d";
6561         optype = BINOP;
6562         break;
6563     case FOP(4, 17):
6564         check_cp1_registers(ctx, fs | fd);
6565         {
6566             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6567
6568             gen_load_fpr64(ctx, fp0, fs);
6569             tcg_gen_helper_1_1(do_float_sqrt_d, fp0, fp0);
6570             gen_store_fpr64(ctx, fp0, fd);
6571             tcg_temp_free(fp0);
6572         }
6573         opn = "sqrt.d";
6574         break;
6575     case FOP(5, 17):
6576         check_cp1_registers(ctx, fs | fd);
6577         {
6578             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6579
6580             gen_load_fpr64(ctx, fp0, fs);
6581             tcg_gen_helper_1_1(do_float_abs_d, fp0, fp0);
6582             gen_store_fpr64(ctx, fp0, fd);
6583             tcg_temp_free(fp0);
6584         }
6585         opn = "abs.d";
6586         break;
6587     case FOP(6, 17):
6588         check_cp1_registers(ctx, fs | fd);
6589         {
6590             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6591
6592             gen_load_fpr64(ctx, fp0, fs);
6593             gen_store_fpr64(ctx, fp0, fd);
6594             tcg_temp_free(fp0);
6595         }
6596         opn = "mov.d";
6597         break;
6598     case FOP(7, 17):
6599         check_cp1_registers(ctx, fs | fd);
6600         {
6601             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6602
6603             gen_load_fpr64(ctx, fp0, fs);
6604             tcg_gen_helper_1_1(do_float_chs_d, fp0, fp0);
6605             gen_store_fpr64(ctx, fp0, fd);
6606             tcg_temp_free(fp0);
6607         }
6608         opn = "neg.d";
6609         break;
6610     case FOP(8, 17):
6611         check_cp1_64bitmode(ctx);
6612         {
6613             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6614
6615             gen_load_fpr64(ctx, fp0, fs);
6616             tcg_gen_helper_1_1(do_float_roundl_d, fp0, fp0);
6617             gen_store_fpr64(ctx, fp0, fd);
6618             tcg_temp_free(fp0);
6619         }
6620         opn = "round.l.d";
6621         break;
6622     case FOP(9, 17):
6623         check_cp1_64bitmode(ctx);
6624         {
6625             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6626
6627             gen_load_fpr64(ctx, fp0, fs);
6628             tcg_gen_helper_1_1(do_float_truncl_d, fp0, fp0);
6629             gen_store_fpr64(ctx, fp0, fd);
6630             tcg_temp_free(fp0);
6631         }
6632         opn = "trunc.l.d";
6633         break;
6634     case FOP(10, 17):
6635         check_cp1_64bitmode(ctx);
6636         {
6637             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6638
6639             gen_load_fpr64(ctx, fp0, fs);
6640             tcg_gen_helper_1_1(do_float_ceill_d, fp0, fp0);
6641             gen_store_fpr64(ctx, fp0, fd);
6642             tcg_temp_free(fp0);
6643         }
6644         opn = "ceil.l.d";
6645         break;
6646     case FOP(11, 17):
6647         check_cp1_64bitmode(ctx);
6648         {
6649             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6650
6651             gen_load_fpr64(ctx, fp0, fs);
6652             tcg_gen_helper_1_1(do_float_floorl_d, fp0, fp0);
6653             gen_store_fpr64(ctx, fp0, fd);
6654             tcg_temp_free(fp0);
6655         }
6656         opn = "floor.l.d";
6657         break;
6658     case FOP(12, 17):
6659         check_cp1_registers(ctx, fs);
6660         {
6661             TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6662             TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6663
6664             gen_load_fpr64(ctx, fp64, fs);
6665             tcg_gen_helper_1_1(do_float_roundw_d, fp32, fp64);
6666             tcg_temp_free(fp64);
6667             gen_store_fpr32(fp32, fd);
6668             tcg_temp_free(fp32);
6669         }
6670         opn = "round.w.d";
6671         break;
6672     case FOP(13, 17):
6673         check_cp1_registers(ctx, fs);
6674         {
6675             TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6676             TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6677
6678             gen_load_fpr64(ctx, fp64, fs);
6679             tcg_gen_helper_1_1(do_float_truncw_d, fp32, fp64);
6680             tcg_temp_free(fp64);
6681             gen_store_fpr32(fp32, fd);
6682             tcg_temp_free(fp32);
6683         }
6684         opn = "trunc.w.d";
6685         break;
6686     case FOP(14, 17):
6687         check_cp1_registers(ctx, fs);
6688         {
6689             TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6690             TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6691
6692             gen_load_fpr64(ctx, fp64, fs);
6693             tcg_gen_helper_1_1(do_float_ceilw_d, fp32, fp64);
6694             tcg_temp_free(fp64);
6695             gen_store_fpr32(fp32, fd);
6696             tcg_temp_free(fp32);
6697         }
6698         opn = "ceil.w.d";
6699         break;
6700     case FOP(15, 17):
6701         check_cp1_registers(ctx, fs);
6702         {
6703             TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6704             TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6705
6706             gen_load_fpr64(ctx, fp64, fs);
6707             tcg_gen_helper_1_1(do_float_floorw_d, fp32, fp64);
6708             tcg_temp_free(fp64);
6709             gen_store_fpr32(fp32, fd);
6710             tcg_temp_free(fp32);
6711         }
6712         opn = "floor.w.d";
6713         break;
6714     case FOP(17, 17):
6715         gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6716         opn = "movcf.d";
6717         break;
6718     case FOP(18, 17):
6719         {
6720             int l1 = gen_new_label();
6721             TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
6722             TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I64);
6723
6724             gen_load_gpr(t0, ft);
6725             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
6726             gen_load_fpr64(ctx, fp0, fs);
6727             gen_store_fpr64(ctx, fp0, fd);
6728             tcg_temp_free(fp0);
6729             gen_set_label(l1);
6730             tcg_temp_free(t0);
6731         }
6732         opn = "movz.d";
6733         break;
6734     case FOP(19, 17):
6735         {
6736             int l1 = gen_new_label();
6737             TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
6738             TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I64);
6739
6740             gen_load_gpr(t0, ft);
6741             tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
6742             gen_load_fpr64(ctx, fp0, fs);
6743             gen_store_fpr64(ctx, fp0, fd);
6744             tcg_temp_free(fp0);
6745             gen_set_label(l1);
6746             tcg_temp_free(t0);
6747         }
6748         opn = "movn.d";
6749         break;
6750     case FOP(21, 17):
6751         check_cp1_64bitmode(ctx);
6752         {
6753             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6754
6755             gen_load_fpr64(ctx, fp0, fs);
6756             tcg_gen_helper_1_1(do_float_recip_d, fp0, fp0);
6757             gen_store_fpr64(ctx, fp0, fd);
6758             tcg_temp_free(fp0);
6759         }
6760         opn = "recip.d";
6761         break;
6762     case FOP(22, 17):
6763         check_cp1_64bitmode(ctx);
6764         {
6765             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6766
6767             gen_load_fpr64(ctx, fp0, fs);
6768             tcg_gen_helper_1_1(do_float_rsqrt_d, fp0, fp0);
6769             gen_store_fpr64(ctx, fp0, fd);
6770             tcg_temp_free(fp0);
6771         }
6772         opn = "rsqrt.d";
6773         break;
6774     case FOP(28, 17):
6775         check_cp1_64bitmode(ctx);
6776         {
6777             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6778             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6779
6780             gen_load_fpr64(ctx, fp0, fs);
6781             gen_load_fpr64(ctx, fp1, ft);
6782             tcg_gen_helper_1_2(do_float_recip2_d, fp0, fp0, fp1);
6783             tcg_temp_free(fp1);
6784             gen_store_fpr64(ctx, fp0, fd);
6785             tcg_temp_free(fp0);
6786         }
6787         opn = "recip2.d";
6788         break;
6789     case FOP(29, 17):
6790         check_cp1_64bitmode(ctx);
6791         {
6792             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6793
6794             gen_load_fpr64(ctx, fp0, fs);
6795             tcg_gen_helper_1_1(do_float_recip1_d, fp0, fp0);
6796             gen_store_fpr64(ctx, fp0, fd);
6797             tcg_temp_free(fp0);
6798         }
6799         opn = "recip1.d";
6800         break;
6801     case FOP(30, 17):
6802         check_cp1_64bitmode(ctx);
6803         {
6804             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6805
6806             gen_load_fpr64(ctx, fp0, fs);
6807             tcg_gen_helper_1_1(do_float_rsqrt1_d, fp0, fp0);
6808             gen_store_fpr64(ctx, fp0, fd);
6809             tcg_temp_free(fp0);
6810         }
6811         opn = "rsqrt1.d";
6812         break;
6813     case FOP(31, 17):
6814         check_cp1_64bitmode(ctx);
6815         {
6816             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6817             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6818
6819             gen_load_fpr64(ctx, fp0, fs);
6820             gen_load_fpr64(ctx, fp1, ft);
6821             tcg_gen_helper_1_2(do_float_rsqrt2_d, fp0, fp0, fp1);
6822             tcg_temp_free(fp1);
6823             gen_store_fpr64(ctx, fp0, fd);
6824             tcg_temp_free(fp0);
6825         }
6826         opn = "rsqrt2.d";
6827         break;
6828     case FOP(48, 17):
6829     case FOP(49, 17):
6830     case FOP(50, 17):
6831     case FOP(51, 17):
6832     case FOP(52, 17):
6833     case FOP(53, 17):
6834     case FOP(54, 17):
6835     case FOP(55, 17):
6836     case FOP(56, 17):
6837     case FOP(57, 17):
6838     case FOP(58, 17):
6839     case FOP(59, 17):
6840     case FOP(60, 17):
6841     case FOP(61, 17):
6842     case FOP(62, 17):
6843     case FOP(63, 17):
6844         {
6845             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6846             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6847
6848             gen_load_fpr64(ctx, fp0, fs);
6849             gen_load_fpr64(ctx, fp1, ft);
6850             if (ctx->opcode & (1 << 6)) {
6851                 check_cop1x(ctx);
6852                 check_cp1_registers(ctx, fs | ft);
6853                 gen_cmpabs_d(func-48, fp0, fp1, cc);
6854                 opn = condnames_abs[func-48];
6855             } else {
6856                 check_cp1_registers(ctx, fs | ft);
6857                 gen_cmp_d(func-48, fp0, fp1, cc);
6858                 opn = condnames[func-48];
6859             }
6860             tcg_temp_free(fp0);
6861             tcg_temp_free(fp1);
6862         }
6863         break;
6864     case FOP(32, 17):
6865         check_cp1_registers(ctx, fs);
6866         {
6867             TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6868             TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6869
6870             gen_load_fpr64(ctx, fp64, fs);
6871             tcg_gen_helper_1_1(do_float_cvts_d, fp32, fp64);
6872             tcg_temp_free(fp64);
6873             gen_store_fpr32(fp32, fd);
6874             tcg_temp_free(fp32);
6875         }
6876         opn = "cvt.s.d";
6877         break;
6878     case FOP(36, 17):
6879         check_cp1_registers(ctx, fs);
6880         {
6881             TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6882             TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6883
6884             gen_load_fpr64(ctx, fp64, fs);
6885             tcg_gen_helper_1_1(do_float_cvtw_d, fp32, fp64);
6886             tcg_temp_free(fp64);
6887             gen_store_fpr32(fp32, fd);
6888             tcg_temp_free(fp32);
6889         }
6890         opn = "cvt.w.d";
6891         break;
6892     case FOP(37, 17):
6893         check_cp1_64bitmode(ctx);
6894         {
6895             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6896
6897             gen_load_fpr64(ctx, fp0, fs);
6898             tcg_gen_helper_1_1(do_float_cvtl_d, fp0, fp0);
6899             gen_store_fpr64(ctx, fp0, fd);
6900             tcg_temp_free(fp0);
6901         }
6902         opn = "cvt.l.d";
6903         break;
6904     case FOP(32, 20):
6905         {
6906             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
6907
6908             gen_load_fpr32(fp0, fs);
6909             tcg_gen_helper_1_1(do_float_cvts_w, fp0, fp0);
6910             gen_store_fpr32(fp0, fd);
6911             tcg_temp_free(fp0);
6912         }
6913         opn = "cvt.s.w";
6914         break;
6915     case FOP(33, 20):
6916         check_cp1_registers(ctx, fd);
6917         {
6918             TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6919             TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6920
6921             gen_load_fpr32(fp32, fs);
6922             tcg_gen_helper_1_1(do_float_cvtd_w, fp64, fp32);
6923             tcg_temp_free(fp32);
6924             gen_store_fpr64(ctx, fp64, fd);
6925             tcg_temp_free(fp64);
6926         }
6927         opn = "cvt.d.w";
6928         break;
6929     case FOP(32, 21):
6930         check_cp1_64bitmode(ctx);
6931         {
6932             TCGv fp32 = tcg_temp_new(TCG_TYPE_I32);
6933             TCGv fp64 = tcg_temp_new(TCG_TYPE_I64);
6934
6935             gen_load_fpr64(ctx, fp64, fs);
6936             tcg_gen_helper_1_1(do_float_cvts_l, fp32, fp64);
6937             tcg_temp_free(fp64);
6938             gen_store_fpr32(fp32, fd);
6939             tcg_temp_free(fp32);
6940         }
6941         opn = "cvt.s.l";
6942         break;
6943     case FOP(33, 21):
6944         check_cp1_64bitmode(ctx);
6945         {
6946             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6947
6948             gen_load_fpr64(ctx, fp0, fs);
6949             tcg_gen_helper_1_1(do_float_cvtd_l, fp0, fp0);
6950             gen_store_fpr64(ctx, fp0, fd);
6951             tcg_temp_free(fp0);
6952         }
6953         opn = "cvt.d.l";
6954         break;
6955     case FOP(38, 20):
6956         check_cp1_64bitmode(ctx);
6957         {
6958             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6959
6960             gen_load_fpr64(ctx, fp0, fs);
6961             tcg_gen_helper_1_1(do_float_cvtps_pw, fp0, fp0);
6962             gen_store_fpr64(ctx, fp0, fd);
6963             tcg_temp_free(fp0);
6964         }
6965         opn = "cvt.ps.pw";
6966         break;
6967     case FOP(0, 22):
6968         check_cp1_64bitmode(ctx);
6969         {
6970             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6971             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6972
6973             gen_load_fpr64(ctx, fp0, fs);
6974             gen_load_fpr64(ctx, fp1, ft);
6975             tcg_gen_helper_1_2(do_float_add_ps, fp0, fp0, fp1);
6976             tcg_temp_free(fp1);
6977             gen_store_fpr64(ctx, fp0, fd);
6978             tcg_temp_free(fp0);
6979         }
6980         opn = "add.ps";
6981         break;
6982     case FOP(1, 22):
6983         check_cp1_64bitmode(ctx);
6984         {
6985             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
6986             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
6987
6988             gen_load_fpr64(ctx, fp0, fs);
6989             gen_load_fpr64(ctx, fp1, ft);
6990             tcg_gen_helper_1_2(do_float_sub_ps, fp0, fp0, fp1);
6991             tcg_temp_free(fp1);
6992             gen_store_fpr64(ctx, fp0, fd);
6993             tcg_temp_free(fp0);
6994         }
6995         opn = "sub.ps";
6996         break;
6997     case FOP(2, 22):
6998         check_cp1_64bitmode(ctx);
6999         {
7000             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7001             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7002
7003             gen_load_fpr64(ctx, fp0, fs);
7004             gen_load_fpr64(ctx, fp1, ft);
7005             tcg_gen_helper_1_2(do_float_mul_ps, fp0, fp0, fp1);
7006             tcg_temp_free(fp1);
7007             gen_store_fpr64(ctx, fp0, fd);
7008             tcg_temp_free(fp0);
7009         }
7010         opn = "mul.ps";
7011         break;
7012     case FOP(5, 22):
7013         check_cp1_64bitmode(ctx);
7014         {
7015             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7016
7017             gen_load_fpr64(ctx, fp0, fs);
7018             tcg_gen_helper_1_1(do_float_abs_ps, fp0, fp0);
7019             gen_store_fpr64(ctx, fp0, fd);
7020             tcg_temp_free(fp0);
7021         }
7022         opn = "abs.ps";
7023         break;
7024     case FOP(6, 22):
7025         check_cp1_64bitmode(ctx);
7026         {
7027             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7028
7029             gen_load_fpr64(ctx, fp0, fs);
7030             gen_store_fpr64(ctx, fp0, fd);
7031             tcg_temp_free(fp0);
7032         }
7033         opn = "mov.ps";
7034         break;
7035     case FOP(7, 22):
7036         check_cp1_64bitmode(ctx);
7037         {
7038             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7039
7040             gen_load_fpr64(ctx, fp0, fs);
7041             tcg_gen_helper_1_1(do_float_chs_ps, fp0, fp0);
7042             gen_store_fpr64(ctx, fp0, fd);
7043             tcg_temp_free(fp0);
7044         }
7045         opn = "neg.ps";
7046         break;
7047     case FOP(17, 22):
7048         check_cp1_64bitmode(ctx);
7049         gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7050         opn = "movcf.ps";
7051         break;
7052     case FOP(18, 22):
7053         check_cp1_64bitmode(ctx);
7054         {
7055             int l1 = gen_new_label();
7056             TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
7057             TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
7058             TCGv fph0 = tcg_temp_local_new(TCG_TYPE_I32);
7059
7060             gen_load_gpr(t0, ft);
7061             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7062             gen_load_fpr32(fp0, fs);
7063             gen_load_fpr32h(fph0, fs);
7064             gen_store_fpr32(fp0, fd);
7065             gen_store_fpr32h(fph0, fd);
7066             tcg_temp_free(fp0);
7067             tcg_temp_free(fph0);
7068             gen_set_label(l1);
7069             tcg_temp_free(t0);
7070         }
7071         opn = "movz.ps";
7072         break;
7073     case FOP(19, 22):
7074         check_cp1_64bitmode(ctx);
7075         {
7076             int l1 = gen_new_label();
7077             TCGv t0 = tcg_temp_new(TCG_TYPE_TL);
7078             TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
7079             TCGv fph0 = tcg_temp_local_new(TCG_TYPE_I32);
7080
7081             gen_load_gpr(t0, ft);
7082             tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
7083             gen_load_fpr32(fp0, fs);
7084             gen_load_fpr32h(fph0, fs);
7085             gen_store_fpr32(fp0, fd);
7086             gen_store_fpr32h(fph0, fd);
7087             tcg_temp_free(fp0);
7088             tcg_temp_free(fph0);
7089             gen_set_label(l1);
7090             tcg_temp_free(t0);
7091         }
7092         opn = "movn.ps";
7093         break;
7094     case FOP(24, 22):
7095         check_cp1_64bitmode(ctx);
7096         {
7097             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7098             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7099
7100             gen_load_fpr64(ctx, fp0, ft);
7101             gen_load_fpr64(ctx, fp1, fs);
7102             tcg_gen_helper_1_2(do_float_addr_ps, fp0, fp0, fp1);
7103             tcg_temp_free(fp1);
7104             gen_store_fpr64(ctx, fp0, fd);
7105             tcg_temp_free(fp0);
7106         }
7107         opn = "addr.ps";
7108         break;
7109     case FOP(26, 22):
7110         check_cp1_64bitmode(ctx);
7111         {
7112             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7113             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7114
7115             gen_load_fpr64(ctx, fp0, ft);
7116             gen_load_fpr64(ctx, fp1, fs);
7117             tcg_gen_helper_1_2(do_float_mulr_ps, fp0, fp0, fp1);
7118             tcg_temp_free(fp1);
7119             gen_store_fpr64(ctx, fp0, fd);
7120             tcg_temp_free(fp0);
7121         }
7122         opn = "mulr.ps";
7123         break;
7124     case FOP(28, 22):
7125         check_cp1_64bitmode(ctx);
7126         {
7127             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7128             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7129
7130             gen_load_fpr64(ctx, fp0, fs);
7131             gen_load_fpr64(ctx, fp1, fd);
7132             tcg_gen_helper_1_2(do_float_recip2_ps, fp0, fp0, fp1);
7133             tcg_temp_free(fp1);
7134             gen_store_fpr64(ctx, fp0, fd);
7135             tcg_temp_free(fp0);
7136         }
7137         opn = "recip2.ps";
7138         break;
7139     case FOP(29, 22):
7140         check_cp1_64bitmode(ctx);
7141         {
7142             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7143
7144             gen_load_fpr64(ctx, fp0, fs);
7145             tcg_gen_helper_1_1(do_float_recip1_ps, fp0, fp0);
7146             gen_store_fpr64(ctx, fp0, fd);
7147             tcg_temp_free(fp0);
7148         }
7149         opn = "recip1.ps";
7150         break;
7151     case FOP(30, 22):
7152         check_cp1_64bitmode(ctx);
7153         {
7154             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7155
7156             gen_load_fpr64(ctx, fp0, fs);
7157             tcg_gen_helper_1_1(do_float_rsqrt1_ps, fp0, fp0);
7158             gen_store_fpr64(ctx, fp0, fd);
7159             tcg_temp_free(fp0);
7160         }
7161         opn = "rsqrt1.ps";
7162         break;
7163     case FOP(31, 22):
7164         check_cp1_64bitmode(ctx);
7165         {
7166             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7167             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7168
7169             gen_load_fpr64(ctx, fp0, fs);
7170             gen_load_fpr64(ctx, fp1, ft);
7171             tcg_gen_helper_1_2(do_float_rsqrt2_ps, fp0, fp0, fp1);
7172             tcg_temp_free(fp1);
7173             gen_store_fpr64(ctx, fp0, fd);
7174             tcg_temp_free(fp0);
7175         }
7176         opn = "rsqrt2.ps";
7177         break;
7178     case FOP(32, 22):
7179         check_cp1_64bitmode(ctx);
7180         {
7181             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7182
7183             gen_load_fpr32h(fp0, fs);
7184             tcg_gen_helper_1_1(do_float_cvts_pu, fp0, fp0);
7185             gen_store_fpr32(fp0, fd);
7186             tcg_temp_free(fp0);
7187         }
7188         opn = "cvt.s.pu";
7189         break;
7190     case FOP(36, 22):
7191         check_cp1_64bitmode(ctx);
7192         {
7193             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7194
7195             gen_load_fpr64(ctx, fp0, fs);
7196             tcg_gen_helper_1_1(do_float_cvtpw_ps, fp0, fp0);
7197             gen_store_fpr64(ctx, fp0, fd);
7198             tcg_temp_free(fp0);
7199         }
7200         opn = "cvt.pw.ps";
7201         break;
7202     case FOP(40, 22):
7203         check_cp1_64bitmode(ctx);
7204         {
7205             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7206
7207             gen_load_fpr32(fp0, fs);
7208             tcg_gen_helper_1_1(do_float_cvts_pl, fp0, fp0);
7209             gen_store_fpr32(fp0, fd);
7210             tcg_temp_free(fp0);
7211         }
7212         opn = "cvt.s.pl";
7213         break;
7214     case FOP(44, 22):
7215         check_cp1_64bitmode(ctx);
7216         {
7217             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7218             TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7219
7220             gen_load_fpr32(fp0, fs);
7221             gen_load_fpr32(fp1, ft);
7222             gen_store_fpr32h(fp0, fd);
7223             gen_store_fpr32(fp1, fd);
7224             tcg_temp_free(fp0);
7225             tcg_temp_free(fp1);
7226         }
7227         opn = "pll.ps";
7228         break;
7229     case FOP(45, 22):
7230         check_cp1_64bitmode(ctx);
7231         {
7232             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7233             TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7234
7235             gen_load_fpr32(fp0, fs);
7236             gen_load_fpr32h(fp1, ft);
7237             gen_store_fpr32(fp1, fd);
7238             gen_store_fpr32h(fp0, fd);
7239             tcg_temp_free(fp0);
7240             tcg_temp_free(fp1);
7241         }
7242         opn = "plu.ps";
7243         break;
7244     case FOP(46, 22):
7245         check_cp1_64bitmode(ctx);
7246         {
7247             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7248             TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7249
7250             gen_load_fpr32h(fp0, fs);
7251             gen_load_fpr32(fp1, ft);
7252             gen_store_fpr32(fp1, fd);
7253             gen_store_fpr32h(fp0, fd);
7254             tcg_temp_free(fp0);
7255             tcg_temp_free(fp1);
7256         }
7257         opn = "pul.ps";
7258         break;
7259     case FOP(47, 22):
7260         check_cp1_64bitmode(ctx);
7261         {
7262             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7263             TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7264
7265             gen_load_fpr32h(fp0, fs);
7266             gen_load_fpr32h(fp1, ft);
7267             gen_store_fpr32(fp1, fd);
7268             gen_store_fpr32h(fp0, fd);
7269             tcg_temp_free(fp0);
7270             tcg_temp_free(fp1);
7271         }
7272         opn = "puu.ps";
7273         break;
7274     case FOP(48, 22):
7275     case FOP(49, 22):
7276     case FOP(50, 22):
7277     case FOP(51, 22):
7278     case FOP(52, 22):
7279     case FOP(53, 22):
7280     case FOP(54, 22):
7281     case FOP(55, 22):
7282     case FOP(56, 22):
7283     case FOP(57, 22):
7284     case FOP(58, 22):
7285     case FOP(59, 22):
7286     case FOP(60, 22):
7287     case FOP(61, 22):
7288     case FOP(62, 22):
7289     case FOP(63, 22):
7290         check_cp1_64bitmode(ctx);
7291         {
7292             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7293             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7294
7295             gen_load_fpr64(ctx, fp0, fs);
7296             gen_load_fpr64(ctx, fp1, ft);
7297             if (ctx->opcode & (1 << 6)) {
7298                 gen_cmpabs_ps(func-48, fp0, fp1, cc);
7299                 opn = condnames_abs[func-48];
7300             } else {
7301                 gen_cmp_ps(func-48, fp0, fp1, cc);
7302                 opn = condnames[func-48];
7303             }
7304             tcg_temp_free(fp0);
7305             tcg_temp_free(fp1);
7306         }
7307         break;
7308     default:
7309         MIPS_INVAL(opn);
7310         generate_exception (ctx, EXCP_RI);
7311         return;
7312     }
7313     switch (optype) {
7314     case BINOP:
7315         MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7316         break;
7317     case CMPOP:
7318         MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7319         break;
7320     default:
7321         MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7322         break;
7323     }
7324 }
7325
7326 /* Coprocessor 3 (FPU) */
7327 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7328                            int fd, int fs, int base, int index)
7329 {
7330     const char *opn = "extended float load/store";
7331     int store = 0;
7332     TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7333     TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
7334
7335     if (base == 0) {
7336         gen_load_gpr(t0, index);
7337     } else if (index == 0) {
7338         gen_load_gpr(t0, base);
7339     } else {
7340         gen_load_gpr(t0, base);
7341         gen_load_gpr(t1, index);
7342         gen_op_addr_add(ctx, t0, t1);
7343     }
7344     /* Don't do NOP if destination is zero: we must perform the actual
7345        memory access. */
7346     switch (opc) {
7347     case OPC_LWXC1:
7348         check_cop1x(ctx);
7349         {
7350             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7351
7352             tcg_gen_qemu_ld32s(fp0, t0, ctx->mem_idx);
7353             gen_store_fpr32(fp0, fd);
7354             tcg_temp_free(fp0);
7355         }
7356         opn = "lwxc1";
7357         break;
7358     case OPC_LDXC1:
7359         check_cop1x(ctx);
7360         check_cp1_registers(ctx, fd);
7361         {
7362             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7363
7364             tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7365             gen_store_fpr64(ctx, fp0, fd);
7366             tcg_temp_free(fp0);
7367         }
7368         opn = "ldxc1";
7369         break;
7370     case OPC_LUXC1:
7371         check_cp1_64bitmode(ctx);
7372         tcg_gen_andi_tl(t0, t0, ~0x7);
7373         {
7374             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7375
7376             tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7377             gen_store_fpr64(ctx, fp0, fd);
7378             tcg_temp_free(fp0);
7379         }
7380         opn = "luxc1";
7381         break;
7382     case OPC_SWXC1:
7383         check_cop1x(ctx);
7384         {
7385             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7386
7387             gen_load_fpr32(fp0, fs);
7388             tcg_gen_qemu_st32(fp0, t0, ctx->mem_idx);
7389             tcg_temp_free(fp0);
7390         }
7391         opn = "swxc1";
7392         store = 1;
7393         break;
7394     case OPC_SDXC1:
7395         check_cop1x(ctx);
7396         check_cp1_registers(ctx, fs);
7397         {
7398             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7399
7400             gen_load_fpr64(ctx, fp0, fs);
7401             tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7402             tcg_temp_free(fp0);
7403         }
7404         opn = "sdxc1";
7405         store = 1;
7406         break;
7407     case OPC_SUXC1:
7408         check_cp1_64bitmode(ctx);
7409         tcg_gen_andi_tl(t0, t0, ~0x7);
7410         {
7411             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7412
7413             gen_load_fpr64(ctx, fp0, fs);
7414             tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7415             tcg_temp_free(fp0);
7416         }
7417         opn = "suxc1";
7418         store = 1;
7419         break;
7420     default:
7421         MIPS_INVAL(opn);
7422         generate_exception(ctx, EXCP_RI);
7423         tcg_temp_free(t0);
7424         tcg_temp_free(t1);
7425         return;
7426     }
7427     tcg_temp_free(t0);
7428     tcg_temp_free(t1);
7429     MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7430                regnames[index], regnames[base]);
7431 }
7432
7433 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7434                             int fd, int fr, int fs, int ft)
7435 {
7436     const char *opn = "flt3_arith";
7437
7438     switch (opc) {
7439     case OPC_ALNV_PS:
7440         check_cp1_64bitmode(ctx);
7441         {
7442             TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7443             TCGv fp0 = tcg_temp_local_new(TCG_TYPE_I32);
7444             TCGv fph0 = tcg_temp_local_new(TCG_TYPE_I32);
7445             TCGv fp1 = tcg_temp_local_new(TCG_TYPE_I32);
7446             TCGv fph1 = tcg_temp_local_new(TCG_TYPE_I32);
7447             int l1 = gen_new_label();
7448             int l2 = gen_new_label();
7449
7450             gen_load_gpr(t0, fr);
7451             tcg_gen_andi_tl(t0, t0, 0x7);
7452             gen_load_fpr32(fp0, fs);
7453             gen_load_fpr32h(fph0, fs);
7454             gen_load_fpr32(fp1, ft);
7455             gen_load_fpr32h(fph1, ft);
7456
7457             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7458             gen_store_fpr32(fp0, fd);
7459             gen_store_fpr32h(fph0, fd);
7460             tcg_gen_br(l2);
7461             gen_set_label(l1);
7462             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7463             tcg_temp_free(t0);
7464 #ifdef TARGET_WORDS_BIGENDIAN
7465             gen_store_fpr32(fph1, fd);
7466             gen_store_fpr32h(fp0, fd);
7467 #else
7468             gen_store_fpr32(fph0, fd);
7469             gen_store_fpr32h(fp1, fd);
7470 #endif
7471             gen_set_label(l2);
7472             tcg_temp_free(fp0);
7473             tcg_temp_free(fph0);
7474             tcg_temp_free(fp1);
7475             tcg_temp_free(fph1);
7476         }
7477         opn = "alnv.ps";
7478         break;
7479     case OPC_MADD_S:
7480         check_cop1x(ctx);
7481         {
7482             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7483             TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7484             TCGv fp2 = tcg_temp_new(TCG_TYPE_I32);
7485
7486             gen_load_fpr32(fp0, fs);
7487             gen_load_fpr32(fp1, ft);
7488             gen_load_fpr32(fp2, fr);
7489             tcg_gen_helper_1_3(do_float_muladd_s, fp2, fp0, fp1, fp2);
7490             tcg_temp_free(fp0);
7491             tcg_temp_free(fp1);
7492             gen_store_fpr32(fp2, fd);
7493             tcg_temp_free(fp2);
7494         }
7495         opn = "madd.s";
7496         break;
7497     case OPC_MADD_D:
7498         check_cop1x(ctx);
7499         check_cp1_registers(ctx, fd | fs | ft | fr);
7500         {
7501             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7502             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7503             TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7504
7505             gen_load_fpr64(ctx, fp0, fs);
7506             gen_load_fpr64(ctx, fp1, ft);
7507             gen_load_fpr64(ctx, fp2, fr);
7508             tcg_gen_helper_1_3(do_float_muladd_d, fp2, fp0, fp1, fp2);
7509             tcg_temp_free(fp0);
7510             tcg_temp_free(fp1);
7511             gen_store_fpr64(ctx, fp2, fd);
7512             tcg_temp_free(fp2);
7513         }
7514         opn = "madd.d";
7515         break;
7516     case OPC_MADD_PS:
7517         check_cp1_64bitmode(ctx);
7518         {
7519             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7520             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7521             TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7522
7523             gen_load_fpr64(ctx, fp0, fs);
7524             gen_load_fpr64(ctx, fp1, ft);
7525             gen_load_fpr64(ctx, fp2, fr);
7526             tcg_gen_helper_1_3(do_float_muladd_ps, fp2, fp0, fp1, fp2);
7527             tcg_temp_free(fp0);
7528             tcg_temp_free(fp1);
7529             gen_store_fpr64(ctx, fp2, fd);
7530             tcg_temp_free(fp2);
7531         }
7532         opn = "madd.ps";
7533         break;
7534     case OPC_MSUB_S:
7535         check_cop1x(ctx);
7536         {
7537             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7538             TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7539             TCGv fp2 = tcg_temp_new(TCG_TYPE_I32);
7540
7541             gen_load_fpr32(fp0, fs);
7542             gen_load_fpr32(fp1, ft);
7543             gen_load_fpr32(fp2, fr);
7544             tcg_gen_helper_1_3(do_float_mulsub_s, fp2, fp0, fp1, fp2);
7545             tcg_temp_free(fp0);
7546             tcg_temp_free(fp1);
7547             gen_store_fpr32(fp2, fd);
7548             tcg_temp_free(fp2);
7549         }
7550         opn = "msub.s";
7551         break;
7552     case OPC_MSUB_D:
7553         check_cop1x(ctx);
7554         check_cp1_registers(ctx, fd | fs | ft | fr);
7555         {
7556             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7557             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7558             TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7559
7560             gen_load_fpr64(ctx, fp0, fs);
7561             gen_load_fpr64(ctx, fp1, ft);
7562             gen_load_fpr64(ctx, fp2, fr);
7563             tcg_gen_helper_1_3(do_float_mulsub_d, fp2, fp0, fp1, fp2);
7564             tcg_temp_free(fp0);
7565             tcg_temp_free(fp1);
7566             gen_store_fpr64(ctx, fp2, fd);
7567             tcg_temp_free(fp2);
7568         }
7569         opn = "msub.d";
7570         break;
7571     case OPC_MSUB_PS:
7572         check_cp1_64bitmode(ctx);
7573         {
7574             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7575             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7576             TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7577
7578             gen_load_fpr64(ctx, fp0, fs);
7579             gen_load_fpr64(ctx, fp1, ft);
7580             gen_load_fpr64(ctx, fp2, fr);
7581             tcg_gen_helper_1_3(do_float_mulsub_ps, fp2, fp0, fp1, fp2);
7582             tcg_temp_free(fp0);
7583             tcg_temp_free(fp1);
7584             gen_store_fpr64(ctx, fp2, fd);
7585             tcg_temp_free(fp2);
7586         }
7587         opn = "msub.ps";
7588         break;
7589     case OPC_NMADD_S:
7590         check_cop1x(ctx);
7591         {
7592             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7593             TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7594             TCGv fp2 = tcg_temp_new(TCG_TYPE_I32);
7595
7596             gen_load_fpr32(fp0, fs);
7597             gen_load_fpr32(fp1, ft);
7598             gen_load_fpr32(fp2, fr);
7599             tcg_gen_helper_1_3(do_float_nmuladd_s, fp2, fp0, fp1, fp2);
7600             tcg_temp_free(fp0);
7601             tcg_temp_free(fp1);
7602             gen_store_fpr32(fp2, fd);
7603             tcg_temp_free(fp2);
7604         }
7605         opn = "nmadd.s";
7606         break;
7607     case OPC_NMADD_D:
7608         check_cop1x(ctx);
7609         check_cp1_registers(ctx, fd | fs | ft | fr);
7610         {
7611             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7612             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7613             TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7614
7615             gen_load_fpr64(ctx, fp0, fs);
7616             gen_load_fpr64(ctx, fp1, ft);
7617             gen_load_fpr64(ctx, fp2, fr);
7618             tcg_gen_helper_1_3(do_float_nmuladd_d, fp2, fp0, fp1, fp2);
7619             tcg_temp_free(fp0);
7620             tcg_temp_free(fp1);
7621             gen_store_fpr64(ctx, fp2, fd);
7622             tcg_temp_free(fp2);
7623         }
7624         opn = "nmadd.d";
7625         break;
7626     case OPC_NMADD_PS:
7627         check_cp1_64bitmode(ctx);
7628         {
7629             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7630             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7631             TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7632
7633             gen_load_fpr64(ctx, fp0, fs);
7634             gen_load_fpr64(ctx, fp1, ft);
7635             gen_load_fpr64(ctx, fp2, fr);
7636             tcg_gen_helper_1_3(do_float_nmuladd_ps, fp2, fp0, fp1, fp2);
7637             tcg_temp_free(fp0);
7638             tcg_temp_free(fp1);
7639             gen_store_fpr64(ctx, fp2, fd);
7640             tcg_temp_free(fp2);
7641         }
7642         opn = "nmadd.ps";
7643         break;
7644     case OPC_NMSUB_S:
7645         check_cop1x(ctx);
7646         {
7647             TCGv fp0 = tcg_temp_new(TCG_TYPE_I32);
7648             TCGv fp1 = tcg_temp_new(TCG_TYPE_I32);
7649             TCGv fp2 = tcg_temp_new(TCG_TYPE_I32);
7650
7651             gen_load_fpr32(fp0, fs);
7652             gen_load_fpr32(fp1, ft);
7653             gen_load_fpr32(fp2, fr);
7654             tcg_gen_helper_1_3(do_float_nmulsub_s, fp2, fp0, fp1, fp2);
7655             tcg_temp_free(fp0);
7656             tcg_temp_free(fp1);
7657             gen_store_fpr32(fp2, fd);
7658             tcg_temp_free(fp2);
7659         }
7660         opn = "nmsub.s";
7661         break;
7662     case OPC_NMSUB_D:
7663         check_cop1x(ctx);
7664         check_cp1_registers(ctx, fd | fs | ft | fr);
7665         {
7666             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7667             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7668             TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7669
7670             gen_load_fpr64(ctx, fp0, fs);
7671             gen_load_fpr64(ctx, fp1, ft);
7672             gen_load_fpr64(ctx, fp2, fr);
7673             tcg_gen_helper_1_3(do_float_nmulsub_d, fp2, fp0, fp1, fp2);
7674             tcg_temp_free(fp0);
7675             tcg_temp_free(fp1);
7676             gen_store_fpr64(ctx, fp2, fd);
7677             tcg_temp_free(fp2);
7678         }
7679         opn = "nmsub.d";
7680         break;
7681     case OPC_NMSUB_PS:
7682         check_cp1_64bitmode(ctx);
7683         {
7684             TCGv fp0 = tcg_temp_new(TCG_TYPE_I64);
7685             TCGv fp1 = tcg_temp_new(TCG_TYPE_I64);
7686             TCGv fp2 = tcg_temp_new(TCG_TYPE_I64);
7687
7688             gen_load_fpr64(ctx, fp0, fs);
7689             gen_load_fpr64(ctx, fp1, ft);
7690             gen_load_fpr64(ctx, fp2, fr);
7691             tcg_gen_helper_1_3(do_float_nmulsub_ps, fp2, fp0, fp1, fp2);
7692             tcg_temp_free(fp0);
7693             tcg_temp_free(fp1);
7694             gen_store_fpr64(ctx, fp2, fd);
7695             tcg_temp_free(fp2);
7696         }
7697         opn = "nmsub.ps";
7698         break;
7699     default:
7700         MIPS_INVAL(opn);
7701         generate_exception (ctx, EXCP_RI);
7702         return;
7703     }
7704     MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7705                fregnames[fs], fregnames[ft]);
7706 }
7707
7708 /* ISA extensions (ASEs) */
7709 /* MIPS16 extension to MIPS32 */
7710 /* SmartMIPS extension to MIPS32 */
7711
7712 #if defined(TARGET_MIPS64)
7713
7714 /* MDMX extension to MIPS64 */
7715
7716 #endif
7717
7718 static void decode_opc (CPUState *env, DisasContext *ctx)
7719 {
7720     int32_t offset;
7721     int rs, rt, rd, sa;
7722     uint32_t op, op1, op2;
7723     int16_t imm;
7724
7725     /* make sure instructions are on a word boundary */
7726     if (ctx->pc & 0x3) {
7727         env->CP0_BadVAddr = ctx->pc;
7728         generate_exception(ctx, EXCP_AdEL);
7729         return;
7730     }
7731
7732     /* Handle blikely not taken case */
7733     if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7734         int l1 = gen_new_label();
7735
7736         MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7737         tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
7738         {
7739             TCGv r_tmp = tcg_temp_new(TCG_TYPE_I32);
7740
7741             tcg_gen_movi_i32(r_tmp, ctx->hflags & ~MIPS_HFLAG_BMASK);
7742             tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
7743             tcg_temp_free(r_tmp);
7744         }
7745         gen_goto_tb(ctx, 1, ctx->pc + 4);
7746         gen_set_label(l1);
7747     }
7748     op = MASK_OP_MAJOR(ctx->opcode);
7749     rs = (ctx->opcode >> 21) & 0x1f;
7750     rt = (ctx->opcode >> 16) & 0x1f;
7751     rd = (ctx->opcode >> 11) & 0x1f;
7752     sa = (ctx->opcode >> 6) & 0x1f;
7753     imm = (int16_t)ctx->opcode;
7754     switch (op) {
7755     case OPC_SPECIAL:
7756         op1 = MASK_SPECIAL(ctx->opcode);
7757         switch (op1) {
7758         case OPC_SLL:          /* Arithmetic with immediate */
7759         case OPC_SRL ... OPC_SRA:
7760             gen_arith_imm(env, ctx, op1, rd, rt, sa);
7761             break;
7762         case OPC_MOVZ ... OPC_MOVN:
7763             check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7764         case OPC_SLLV:         /* Arithmetic */
7765         case OPC_SRLV ... OPC_SRAV:
7766         case OPC_ADD ... OPC_NOR:
7767         case OPC_SLT ... OPC_SLTU:
7768             gen_arith(env, ctx, op1, rd, rs, rt);
7769             break;
7770         case OPC_MULT ... OPC_DIVU:
7771             if (sa) {
7772                 check_insn(env, ctx, INSN_VR54XX);
7773                 op1 = MASK_MUL_VR54XX(ctx->opcode);
7774                 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7775             } else
7776                 gen_muldiv(ctx, op1, rs, rt);
7777             break;
7778         case OPC_JR ... OPC_JALR:
7779             gen_compute_branch(ctx, op1, rs, rd, sa);
7780             return;
7781         case OPC_TGE ... OPC_TEQ: /* Traps */
7782         case OPC_TNE:
7783             gen_trap(ctx, op1, rs, rt, -1);
7784             break;
7785         case OPC_MFHI:          /* Move from HI/LO */
7786         case OPC_MFLO:
7787             gen_HILO(ctx, op1, rd);
7788             break;
7789         case OPC_MTHI:
7790         case OPC_MTLO:          /* Move to HI/LO */
7791             gen_HILO(ctx, op1, rs);
7792             break;
7793         case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
7794 #ifdef MIPS_STRICT_STANDARD
7795             MIPS_INVAL("PMON / selsl");
7796             generate_exception(ctx, EXCP_RI);
7797 #else
7798             tcg_gen_helper_0_i(do_pmon, sa);
7799 #endif
7800             break;
7801         case OPC_SYSCALL:
7802             generate_exception(ctx, EXCP_SYSCALL);
7803             break;
7804         case OPC_BREAK:
7805             generate_exception(ctx, EXCP_BREAK);
7806             break;
7807         case OPC_SPIM:
7808 #ifdef MIPS_STRICT_STANDARD
7809             MIPS_INVAL("SPIM");
7810             generate_exception(ctx, EXCP_RI);
7811 #else
7812            /* Implemented as RI exception for now. */
7813             MIPS_INVAL("spim (unofficial)");
7814             generate_exception(ctx, EXCP_RI);
7815 #endif
7816             break;
7817         case OPC_SYNC:
7818             /* Treat as NOP. */
7819             break;
7820
7821         case OPC_MOVCI:
7822             check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7823             if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7824                 save_cpu_state(ctx, 1);
7825                 check_cp1_enabled(ctx);
7826                 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7827                           (ctx->opcode >> 16) & 1);
7828             } else {
7829                 generate_exception_err(ctx, EXCP_CpU, 1);
7830             }
7831             break;
7832
7833 #if defined(TARGET_MIPS64)
7834        /* MIPS64 specific opcodes */
7835         case OPC_DSLL:
7836         case OPC_DSRL ... OPC_DSRA:
7837         case OPC_DSLL32:
7838         case OPC_DSRL32 ... OPC_DSRA32:
7839             check_insn(env, ctx, ISA_MIPS3);
7840             check_mips_64(ctx);
7841             gen_arith_imm(env, ctx, op1, rd, rt, sa);
7842             break;
7843         case OPC_DSLLV:
7844         case OPC_DSRLV ... OPC_DSRAV:
7845         case OPC_DADD ... OPC_DSUBU:
7846             check_insn(env, ctx, ISA_MIPS3);
7847             check_mips_64(ctx);
7848             gen_arith(env, ctx, op1, rd, rs, rt);
7849             break;
7850         case OPC_DMULT ... OPC_DDIVU:
7851             check_insn(env, ctx, ISA_MIPS3);
7852             check_mips_64(ctx);
7853             gen_muldiv(ctx, op1, rs, rt);
7854             break;
7855 #endif
7856         default:            /* Invalid */
7857             MIPS_INVAL("special");
7858             generate_exception(ctx, EXCP_RI);
7859             break;
7860         }
7861         break;
7862     case OPC_SPECIAL2:
7863         op1 = MASK_SPECIAL2(ctx->opcode);
7864         switch (op1) {
7865         case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7866         case OPC_MSUB ... OPC_MSUBU:
7867             check_insn(env, ctx, ISA_MIPS32);
7868             gen_muldiv(ctx, op1, rs, rt);
7869             break;
7870         case OPC_MUL:
7871             gen_arith(env, ctx, op1, rd, rs, rt);
7872             break;
7873         case OPC_CLZ ... OPC_CLO:
7874             check_insn(env, ctx, ISA_MIPS32);
7875             gen_cl(ctx, op1, rd, rs);
7876             break;
7877         case OPC_SDBBP:
7878             /* XXX: not clear which exception should be raised
7879              *      when in debug mode...
7880              */
7881             check_insn(env, ctx, ISA_MIPS32);
7882             if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7883                 generate_exception(ctx, EXCP_DBp);
7884             } else {
7885                 generate_exception(ctx, EXCP_DBp);
7886             }
7887             /* Treat as NOP. */
7888             break;
7889 #if defined(TARGET_MIPS64)
7890         case OPC_DCLZ ... OPC_DCLO:
7891             check_insn(env, ctx, ISA_MIPS64);
7892             check_mips_64(ctx);
7893             gen_cl(ctx, op1, rd, rs);
7894             break;
7895 #endif
7896         default:            /* Invalid */
7897             MIPS_INVAL("special2");
7898             generate_exception(ctx, EXCP_RI);
7899             break;
7900         }
7901         break;
7902     case OPC_SPECIAL3:
7903         op1 = MASK_SPECIAL3(ctx->opcode);
7904         switch (op1) {
7905         case OPC_EXT:
7906         case OPC_INS:
7907             check_insn(env, ctx, ISA_MIPS32R2);
7908             gen_bitops(ctx, op1, rt, rs, sa, rd);
7909             break;
7910         case OPC_BSHFL:
7911             check_insn(env, ctx, ISA_MIPS32R2);
7912             op2 = MASK_BSHFL(ctx->opcode);
7913             gen_bshfl(ctx, op2, rt, rd);
7914             break;
7915         case OPC_RDHWR:
7916             check_insn(env, ctx, ISA_MIPS32R2);
7917             {
7918                 TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7919
7920                 switch (rd) {
7921                 case 0:
7922                     save_cpu_state(ctx, 1);
7923                     tcg_gen_helper_1_0(do_rdhwr_cpunum, t0);
7924                     break;
7925                 case 1:
7926                     save_cpu_state(ctx, 1);
7927                     tcg_gen_helper_1_0(do_rdhwr_synci_step, t0);
7928                     break;
7929                 case 2:
7930                     save_cpu_state(ctx, 1);
7931                     tcg_gen_helper_1_0(do_rdhwr_cc, t0);
7932                     break;
7933                 case 3:
7934                     save_cpu_state(ctx, 1);
7935                     tcg_gen_helper_1_0(do_rdhwr_ccres, t0);
7936                     break;
7937                 case 29:
7938                     if (env->user_mode_only) {
7939                         tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7940                         break;
7941                     } else {
7942                         /* XXX: Some CPUs implement this in hardware.
7943                            Not supported yet. */
7944                     }
7945                 default:            /* Invalid */
7946                     MIPS_INVAL("rdhwr");
7947                     generate_exception(ctx, EXCP_RI);
7948                     break;
7949                 }
7950                 gen_store_gpr(t0, rt);
7951                 tcg_temp_free(t0);
7952             }
7953             break;
7954         case OPC_FORK:
7955             check_insn(env, ctx, ASE_MT);
7956             {
7957                 TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7958                 TCGv t1 = tcg_temp_local_new(TCG_TYPE_TL);
7959
7960                 gen_load_gpr(t0, rt);
7961                 gen_load_gpr(t1, rs);
7962                 tcg_gen_helper_0_2(do_fork, t0, t1);
7963                 tcg_temp_free(t0);
7964                 tcg_temp_free(t1);
7965             }
7966             break;
7967         case OPC_YIELD:
7968             check_insn(env, ctx, ASE_MT);
7969             {
7970                 TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
7971
7972                 gen_load_gpr(t0, rs);
7973                 tcg_gen_helper_1_1(do_yield, t0, t0);
7974                 gen_store_gpr(t0, rd);
7975                 tcg_temp_free(t0);
7976             }
7977             break;
7978 #if defined(TARGET_MIPS64)
7979         case OPC_DEXTM ... OPC_DEXT:
7980         case OPC_DINSM ... OPC_DINS:
7981             check_insn(env, ctx, ISA_MIPS64R2);
7982             check_mips_64(ctx);
7983             gen_bitops(ctx, op1, rt, rs, sa, rd);
7984             break;
7985         case OPC_DBSHFL:
7986             check_insn(env, ctx, ISA_MIPS64R2);
7987             check_mips_64(ctx);
7988             op2 = MASK_DBSHFL(ctx->opcode);
7989             gen_bshfl(ctx, op2, rt, rd);
7990             break;
7991 #endif
7992         default:            /* Invalid */
7993             MIPS_INVAL("special3");
7994             generate_exception(ctx, EXCP_RI);
7995             break;
7996         }
7997         break;
7998     case OPC_REGIMM:
7999         op1 = MASK_REGIMM(ctx->opcode);
8000         switch (op1) {
8001         case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
8002         case OPC_BLTZAL ... OPC_BGEZALL:
8003             gen_compute_branch(ctx, op1, rs, -1, imm << 2);
8004             return;
8005         case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
8006         case OPC_TNEI:
8007             gen_trap(ctx, op1, rs, -1, imm);
8008             break;
8009         case OPC_SYNCI:
8010             check_insn(env, ctx, ISA_MIPS32R2);
8011             /* Treat as NOP. */
8012             break;
8013         default:            /* Invalid */
8014             MIPS_INVAL("regimm");
8015             generate_exception(ctx, EXCP_RI);
8016             break;
8017         }
8018         break;
8019     case OPC_CP0:
8020         check_cp0_enabled(ctx);
8021         op1 = MASK_CP0(ctx->opcode);
8022         switch (op1) {
8023         case OPC_MFC0:
8024         case OPC_MTC0:
8025         case OPC_MFTR:
8026         case OPC_MTTR:
8027 #if defined(TARGET_MIPS64)
8028         case OPC_DMFC0:
8029         case OPC_DMTC0:
8030 #endif
8031 #ifndef CONFIG_USER_ONLY
8032             if (!env->user_mode_only)
8033                 gen_cp0(env, ctx, op1, rt, rd);
8034 #endif /* !CONFIG_USER_ONLY */
8035             break;
8036         case OPC_C0_FIRST ... OPC_C0_LAST:
8037 #ifndef CONFIG_USER_ONLY
8038             if (!env->user_mode_only)
8039                 gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
8040 #endif /* !CONFIG_USER_ONLY */
8041             break;
8042         case OPC_MFMC0:
8043 #ifndef CONFIG_USER_ONLY
8044             if (!env->user_mode_only) {
8045                 TCGv t0 = tcg_temp_local_new(TCG_TYPE_TL);
8046
8047                 op2 = MASK_MFMC0(ctx->opcode);
8048                 switch (op2) {
8049                 case OPC_DMT:
8050                     check_insn(env, ctx, ASE_MT);
8051                     tcg_gen_helper_1_1(do_dmt, t0, t0);
8052                     break;
8053                 case OPC_EMT:
8054                     check_insn(env, ctx, ASE_MT);
8055                     tcg_gen_helper_1_1(do_emt, t0, t0);
8056                      break;
8057                 case OPC_DVPE:
8058                     check_insn(env, ctx, ASE_MT);
8059                     tcg_gen_helper_1_1(do_dvpe, t0, t0);
8060                     break;
8061                 case OPC_EVPE:
8062                     check_insn(env, ctx, ASE_MT);
8063                     tcg_gen_helper_1_1(do_evpe, t0, t0);
8064                     break;
8065                 case OPC_DI:
8066                     check_insn(env, ctx, ISA_MIPS32R2);
8067                     save_cpu_state(ctx, 1);
8068                     tcg_gen_helper_1_0(do_di, t0);
8069                     /* Stop translation as we may have switched the execution mode */
8070                     ctx->bstate = BS_STOP;
8071                     break;
8072                 case OPC_EI:
8073                     check_insn(env, ctx, ISA_MIPS32R2);
8074                     save_cpu_state(ctx, 1);
8075                     tcg_gen_helper_1_0(do_ei, t0);
8076                     /* Stop translation as we may have switched the execution mode */
8077                     ctx->bstate = BS_STOP;
8078                     break;
8079                 default:            /* Invalid */
8080                     MIPS_INVAL("mfmc0");
8081                     generate_exception(ctx, EXCP_RI);
8082                     break;
8083                 }
8084                 gen_store_gpr(t0, rt);
8085                 tcg_temp_free(t0);
8086             }
8087 #endif /* !CONFIG_USER_ONLY */
8088             break;
8089         case OPC_RDPGPR:
8090             check_insn(env, ctx, ISA_MIPS32R2);
8091             gen_load_srsgpr(rt, rd);
8092             break;
8093         case OPC_WRPGPR:
8094             check_insn(env, ctx, ISA_MIPS32R2);
8095             gen_store_srsgpr(rt, rd);
8096             break;
8097         default:
8098             MIPS_INVAL("cp0");
8099             generate_exception(ctx, EXCP_RI);
8100             break;
8101         }
8102         break;
8103     case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
8104          gen_arith_imm(env, ctx, op, rt, rs, imm);
8105          break;
8106     case OPC_J ... OPC_JAL: /* Jump */
8107          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
8108          gen_compute_branch(ctx, op, rs, rt, offset);
8109          return;
8110     case OPC_BEQ ... OPC_BGTZ: /* Branch */
8111     case OPC_BEQL ... OPC_BGTZL:
8112          gen_compute_branch(ctx, op, rs, rt, imm << 2);
8113          return;
8114     case OPC_LB ... OPC_LWR: /* Load and stores */
8115     case OPC_SB ... OPC_SW:
8116     case OPC_SWR:
8117     case OPC_LL:
8118     case OPC_SC:
8119          gen_ldst(ctx, op, rt, rs, imm);
8120          break;
8121     case OPC_CACHE:
8122         check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
8123         /* Treat as NOP. */
8124         break;
8125     case OPC_PREF:
8126         check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
8127         /* Treat as NOP. */
8128         break;
8129
8130     /* Floating point (COP1). */
8131     case OPC_LWC1:
8132     case OPC_LDC1:
8133     case OPC_SWC1:
8134     case OPC_SDC1:
8135         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8136             save_cpu_state(ctx, 1);
8137             check_cp1_enabled(ctx);
8138             gen_flt_ldst(ctx, op, rt, rs, imm);
8139         } else {
8140             generate_exception_err(ctx, EXCP_CpU, 1);
8141         }
8142         break;
8143
8144     case OPC_CP1:
8145         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8146             save_cpu_state(ctx, 1);
8147             check_cp1_enabled(ctx);
8148             op1 = MASK_CP1(ctx->opcode);
8149             switch (op1) {
8150             case OPC_MFHC1:
8151             case OPC_MTHC1:
8152                 check_insn(env, ctx, ISA_MIPS32R2);
8153             case OPC_MFC1:
8154             case OPC_CFC1:
8155             case OPC_MTC1:
8156             case OPC_CTC1:
8157                 gen_cp1(ctx, op1, rt, rd);
8158                 break;
8159 #if defined(TARGET_MIPS64)
8160             case OPC_DMFC1:
8161             case OPC_DMTC1:
8162                 check_insn(env, ctx, ISA_MIPS3);
8163                 gen_cp1(ctx, op1, rt, rd);
8164                 break;
8165 #endif
8166             case OPC_BC1ANY2:
8167             case OPC_BC1ANY4:
8168                 check_cop1x(ctx);
8169                 check_insn(env, ctx, ASE_MIPS3D);
8170                 /* fall through */
8171             case OPC_BC1:
8172                 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
8173                                     (rt >> 2) & 0x7, imm << 2);
8174                 return;
8175             case OPC_S_FMT:
8176             case OPC_D_FMT:
8177             case OPC_W_FMT:
8178             case OPC_L_FMT:
8179             case OPC_PS_FMT:
8180                 gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
8181                            (imm >> 8) & 0x7);
8182                 break;
8183             default:
8184                 MIPS_INVAL("cp1");
8185                 generate_exception (ctx, EXCP_RI);
8186                 break;
8187             }
8188         } else {
8189             generate_exception_err(ctx, EXCP_CpU, 1);
8190         }
8191         break;
8192
8193     /* COP2.  */
8194     case OPC_LWC2:
8195     case OPC_LDC2:
8196     case OPC_SWC2:
8197     case OPC_SDC2:
8198     case OPC_CP2:
8199         /* COP2: Not implemented. */
8200         generate_exception_err(ctx, EXCP_CpU, 2);
8201         break;
8202
8203     case OPC_CP3:
8204         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8205             save_cpu_state(ctx, 1);
8206             check_cp1_enabled(ctx);
8207             op1 = MASK_CP3(ctx->opcode);
8208             switch (op1) {
8209             case OPC_LWXC1:
8210             case OPC_LDXC1:
8211             case OPC_LUXC1:
8212             case OPC_SWXC1:
8213             case OPC_SDXC1:
8214             case OPC_SUXC1:
8215                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
8216                 break;
8217             case OPC_PREFX:
8218                 /* Treat as NOP. */
8219                 break;
8220             case OPC_ALNV_PS:
8221             case OPC_MADD_S:
8222             case OPC_MADD_D:
8223             case OPC_MADD_PS:
8224             case OPC_MSUB_S:
8225             case OPC_MSUB_D:
8226             case OPC_MSUB_PS:
8227             case OPC_NMADD_S:
8228             case OPC_NMADD_D:
8229             case OPC_NMADD_PS:
8230             case OPC_NMSUB_S:
8231             case OPC_NMSUB_D:
8232             case OPC_NMSUB_PS:
8233                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
8234                 break;
8235             default:
8236                 MIPS_INVAL("cp3");
8237                 generate_exception (ctx, EXCP_RI);
8238                 break;
8239             }
8240         } else {
8241             generate_exception_err(ctx, EXCP_CpU, 1);
8242         }
8243         break;
8244
8245 #if defined(TARGET_MIPS64)
8246     /* MIPS64 opcodes */
8247     case OPC_LWU:
8248     case OPC_LDL ... OPC_LDR:
8249     case OPC_SDL ... OPC_SDR:
8250     case OPC_LLD:
8251     case OPC_LD:
8252     case OPC_SCD:
8253     case OPC_SD:
8254         check_insn(env, ctx, ISA_MIPS3);
8255         check_mips_64(ctx);
8256         gen_ldst(ctx, op, rt, rs, imm);
8257         break;
8258     case OPC_DADDI ... OPC_DADDIU:
8259         check_insn(env, ctx, ISA_MIPS3);
8260         check_mips_64(ctx);
8261         gen_arith_imm(env, ctx, op, rt, rs, imm);
8262         break;
8263 #endif
8264     case OPC_JALX:
8265         check_insn(env, ctx, ASE_MIPS16);
8266         /* MIPS16: Not implemented. */
8267     case OPC_MDMX:
8268         check_insn(env, ctx, ASE_MDMX);
8269         /* MDMX: Not implemented. */
8270     default:            /* Invalid */
8271         MIPS_INVAL("major opcode");
8272         generate_exception(ctx, EXCP_RI);
8273         break;
8274     }
8275     if (ctx->hflags & MIPS_HFLAG_BMASK) {
8276         int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8277         /* Branches completion */
8278         ctx->hflags &= ~MIPS_HFLAG_BMASK;
8279         ctx->bstate = BS_BRANCH;
8280         save_cpu_state(ctx, 0);
8281         /* FIXME: Need to clear can_do_io.  */
8282         switch (hflags) {
8283         case MIPS_HFLAG_B:
8284             /* unconditional branch */
8285             MIPS_DEBUG("unconditional branch");
8286             gen_goto_tb(ctx, 0, ctx->btarget);
8287             break;
8288         case MIPS_HFLAG_BL:
8289             /* blikely taken case */
8290             MIPS_DEBUG("blikely branch taken");
8291             gen_goto_tb(ctx, 0, ctx->btarget);
8292             break;
8293         case MIPS_HFLAG_BC:
8294             /* Conditional branch */
8295             MIPS_DEBUG("conditional branch");
8296             {
8297                 int l1 = gen_new_label();
8298
8299                 tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
8300                 gen_goto_tb(ctx, 1, ctx->pc + 4);
8301                 gen_set_label(l1);
8302                 gen_goto_tb(ctx, 0, ctx->btarget);
8303             }
8304             break;
8305         case MIPS_HFLAG_BR:
8306             /* unconditional branch to register */
8307             MIPS_DEBUG("branch to register");
8308             tcg_gen_mov_tl(cpu_PC, btarget);
8309             tcg_gen_exit_tb(0);
8310             break;
8311         default:
8312             MIPS_DEBUG("unknown branch");
8313             break;
8314         }
8315     }
8316 }
8317
8318 static inline void
8319 gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8320                                 int search_pc)
8321 {
8322     DisasContext ctx;
8323     target_ulong pc_start;
8324     uint16_t *gen_opc_end;
8325     int j, lj = -1;
8326     int num_insns;
8327     int max_insns;
8328
8329     if (search_pc && loglevel)
8330         fprintf (logfile, "search pc %d\n", search_pc);
8331
8332     pc_start = tb->pc;
8333     /* Leave some spare opc slots for branch handling. */
8334     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
8335     ctx.pc = pc_start;
8336     ctx.saved_pc = -1;
8337     ctx.tb = tb;
8338     ctx.bstate = BS_NONE;
8339     /* Restore delay slot state from the tb context.  */
8340     ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
8341     restore_cpu_state(env, &ctx);
8342     if (env->user_mode_only)
8343         ctx.mem_idx = MIPS_HFLAG_UM;
8344     else
8345         ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
8346     num_insns = 0;
8347     max_insns = tb->cflags & CF_COUNT_MASK;
8348     if (max_insns == 0)
8349         max_insns = CF_COUNT_MASK;
8350 #ifdef DEBUG_DISAS
8351     if (loglevel & CPU_LOG_TB_CPU) {
8352         fprintf(logfile, "------------------------------------------------\n");
8353         /* FIXME: This may print out stale hflags from env... */
8354         cpu_dump_state(env, logfile, fprintf, 0);
8355     }
8356 #endif
8357 #ifdef MIPS_DEBUG_DISAS
8358     if (loglevel & CPU_LOG_TB_IN_ASM)
8359         fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
8360                 tb, ctx.mem_idx, ctx.hflags);
8361 #endif
8362     gen_icount_start();
8363     while (ctx.bstate == BS_NONE) {
8364         if (env->nb_breakpoints > 0) {
8365             for(j = 0; j < env->nb_breakpoints; j++) {
8366                 if (env->breakpoints[j] == ctx.pc) {
8367                     save_cpu_state(&ctx, 1);
8368                     ctx.bstate = BS_BRANCH;
8369                     tcg_gen_helper_0_i(do_raise_exception, EXCP_DEBUG);
8370                     /* Include the breakpoint location or the tb won't
8371                      * be flushed when it must be.  */
8372                     ctx.pc += 4;
8373                     goto done_generating;
8374                 }
8375             }
8376         }
8377
8378         if (search_pc) {
8379             j = gen_opc_ptr - gen_opc_buf;
8380             if (lj < j) {
8381                 lj++;
8382                 while (lj < j)
8383                     gen_opc_instr_start[lj++] = 0;
8384             }
8385             gen_opc_pc[lj] = ctx.pc;
8386             gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
8387             gen_opc_instr_start[lj] = 1;
8388             gen_opc_icount[lj] = num_insns;
8389         }
8390         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8391             gen_io_start();
8392         ctx.opcode = ldl_code(ctx.pc);
8393         decode_opc(env, &ctx);
8394         ctx.pc += 4;
8395         num_insns++;
8396
8397         if (env->singlestep_enabled)
8398             break;
8399
8400         if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8401             break;
8402
8403         if (gen_opc_ptr >= gen_opc_end)
8404             break;
8405
8406         if (num_insns >= max_insns)
8407             break;
8408 #if defined (MIPS_SINGLE_STEP)
8409         break;
8410 #endif
8411     }
8412     if (tb->cflags & CF_LAST_IO)
8413         gen_io_end();
8414     if (env->singlestep_enabled) {
8415         save_cpu_state(&ctx, ctx.bstate == BS_NONE);
8416         tcg_gen_helper_0_i(do_raise_exception, EXCP_DEBUG);
8417     } else {
8418         switch (ctx.bstate) {
8419         case BS_STOP:
8420             tcg_gen_helper_0_0(do_interrupt_restart);
8421             gen_goto_tb(&ctx, 0, ctx.pc);
8422             break;
8423         case BS_NONE:
8424             save_cpu_state(&ctx, 0);
8425             gen_goto_tb(&ctx, 0, ctx.pc);
8426             break;
8427         case BS_EXCP:
8428             tcg_gen_helper_0_0(do_interrupt_restart);
8429             tcg_gen_exit_tb(0);
8430             break;
8431         case BS_BRANCH:
8432         default:
8433             break;
8434         }
8435     }
8436 done_generating:
8437     gen_icount_end(tb, num_insns);
8438     *gen_opc_ptr = INDEX_op_end;
8439     if (search_pc) {
8440         j = gen_opc_ptr - gen_opc_buf;
8441         lj++;
8442         while (lj <= j)
8443             gen_opc_instr_start[lj++] = 0;
8444     } else {
8445         tb->size = ctx.pc - pc_start;
8446         tb->icount = num_insns;
8447     }
8448 #ifdef DEBUG_DISAS
8449 #if defined MIPS_DEBUG_DISAS
8450     if (loglevel & CPU_LOG_TB_IN_ASM)
8451         fprintf(logfile, "\n");
8452 #endif
8453     if (loglevel & CPU_LOG_TB_IN_ASM) {
8454         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
8455         target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
8456         fprintf(logfile, "\n");
8457     }
8458     if (loglevel & CPU_LOG_TB_CPU) {
8459         fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
8460     }
8461 #endif
8462 }
8463
8464 void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8465 {
8466     gen_intermediate_code_internal(env, tb, 0);
8467 }
8468
8469 void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8470 {
8471     gen_intermediate_code_internal(env, tb, 1);
8472 }
8473
8474 static void fpu_dump_state(CPUState *env, FILE *f,
8475                            int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8476                            int flags)
8477 {
8478     int i;
8479     int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8480
8481 #define printfpr(fp)                                                        \
8482     do {                                                                    \
8483         if (is_fpu64)                                                       \
8484             fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
8485                         (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
8486                         (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8487         else {                                                              \
8488             fpr_t tmp;                                                      \
8489             tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
8490             tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
8491             fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
8492                         tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
8493                         tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
8494         }                                                                   \
8495     } while(0)
8496
8497
8498     fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
8499                 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
8500                 get_float_exception_flags(&env->active_fpu.fp_status));
8501     for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8502         fpu_fprintf(f, "%3s: ", fregnames[i]);
8503         printfpr(&env->active_fpu.fpr[i]);
8504     }
8505
8506 #undef printfpr
8507 }
8508
8509 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8510 /* Debug help: The architecture requires 32bit code to maintain proper
8511    sign-extended values on 64bit machines.  */
8512
8513 #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8514
8515 static void
8516 cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8517                                 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8518                                 int flags)
8519 {
8520     int i;
8521
8522     if (!SIGN_EXT_P(env->active_tc.PC))
8523         cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8524     if (!SIGN_EXT_P(env->active_tc.HI[0]))
8525         cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8526     if (!SIGN_EXT_P(env->active_tc.LO[0]))
8527         cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8528     if (!SIGN_EXT_P(env->btarget))
8529         cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8530
8531     for (i = 0; i < 32; i++) {
8532         if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8533             cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8534     }
8535
8536     if (!SIGN_EXT_P(env->CP0_EPC))
8537         cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8538     if (!SIGN_EXT_P(env->CP0_LLAddr))
8539         cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8540 }
8541 #endif
8542
8543 void cpu_dump_state (CPUState *env, FILE *f,
8544                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8545                      int flags)
8546 {
8547     int i;
8548
8549     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",
8550                 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8551                 env->hflags, env->btarget, env->bcond);
8552     for (i = 0; i < 32; i++) {
8553         if ((i & 3) == 0)
8554             cpu_fprintf(f, "GPR%02d:", i);
8555         cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8556         if ((i & 3) == 3)
8557             cpu_fprintf(f, "\n");
8558     }
8559
8560     cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
8561                 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8562     cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8563                 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8564     if (env->hflags & MIPS_HFLAG_FPU)
8565         fpu_dump_state(env, f, cpu_fprintf, flags);
8566 #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8567     cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8568 #endif
8569 }
8570
8571 static void mips_tcg_init(void)
8572 {
8573     int i;
8574     static int inited;
8575
8576     /* Initialize various static tables. */
8577     if (inited)
8578         return;
8579
8580     cpu_env = tcg_global_reg_new(TCG_TYPE_PTR, TCG_AREG0, "env");
8581     for (i = 0; i < 32; i++)
8582         cpu_gpr[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8583                                         offsetof(CPUState, active_tc.gpr[i]),
8584                                         regnames[i]);
8585     cpu_PC = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8586                                 offsetof(CPUState, active_tc.PC), "PC");
8587     for (i = 0; i < MIPS_DSP_ACC; i++) {
8588         cpu_HI[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8589                                        offsetof(CPUState, active_tc.HI[i]),
8590                                        regnames_HI[i]);
8591         cpu_LO[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8592                                        offsetof(CPUState, active_tc.LO[i]),
8593                                        regnames_LO[i]);
8594         cpu_ACX[i] = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8595                                         offsetof(CPUState, active_tc.ACX[i]),
8596                                         regnames_ACX[i]);
8597     }
8598     cpu_dspctrl = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8599                                      offsetof(CPUState, active_tc.DSPControl),
8600                                      "DSPControl");
8601     bcond = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8602                                offsetof(CPUState, bcond), "bcond");
8603     btarget = tcg_global_mem_new(TCG_TYPE_TL, TCG_AREG0,
8604                                  offsetof(CPUState, btarget), "btarget");
8605     for (i = 0; i < 32; i++)
8606         fpu_fpr32[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8607                                           offsetof(CPUState, active_fpu.fpr[i].w[FP_ENDIAN_IDX]),
8608                                           fregnames[i]);
8609     for (i = 0; i < 32; i++)
8610         fpu_fpr64[i] = tcg_global_mem_new(TCG_TYPE_I64, TCG_AREG0,
8611                                           offsetof(CPUState, active_fpu.fpr[i]),
8612                                           fregnames_64[i]);
8613     for (i = 0; i < 32; i++)
8614         fpu_fpr32h[i] = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8615                                            offsetof(CPUState, active_fpu.fpr[i].w[!FP_ENDIAN_IDX]),
8616                                            fregnames_h[i]);
8617     fpu_fcr0 = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8618                                    offsetof(CPUState, active_fpu.fcr0),
8619                                    "fcr0");
8620     fpu_fcr31 = tcg_global_mem_new(TCG_TYPE_I32, TCG_AREG0,
8621                                    offsetof(CPUState, active_fpu.fcr31),
8622                                    "fcr31");
8623
8624     /* register helpers */
8625 #undef DEF_HELPER
8626 #define DEF_HELPER(ret, name, params) tcg_register_helper(name, #name);
8627 #include "helper.h"
8628
8629     inited = 1;
8630 }
8631
8632 #include "translate_init.c"
8633
8634 CPUMIPSState *cpu_mips_init (const char *cpu_model)
8635 {
8636     CPUMIPSState *env;
8637     const mips_def_t *def;
8638
8639     def = cpu_mips_find_by_name(cpu_model);
8640     if (!def)
8641         return NULL;
8642     env = qemu_mallocz(sizeof(CPUMIPSState));
8643     if (!env)
8644         return NULL;
8645     env->cpu_model = def;
8646
8647     cpu_exec_init(env);
8648     env->cpu_model_str = cpu_model;
8649     mips_tcg_init();
8650     cpu_reset(env);
8651     return env;
8652 }
8653
8654 void cpu_reset (CPUMIPSState *env)
8655 {
8656     memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8657
8658     tlb_flush(env, 1);
8659
8660     /* Minimal init */
8661 #if defined(CONFIG_USER_ONLY)
8662     env->user_mode_only = 1;
8663 #endif
8664     if (env->user_mode_only) {
8665         env->hflags = MIPS_HFLAG_UM;
8666     } else {
8667         if (env->hflags & MIPS_HFLAG_BMASK) {
8668             /* If the exception was raised from a delay slot,
8669                come back to the jump.  */
8670             env->CP0_ErrorEPC = env->active_tc.PC - 4;
8671         } else {
8672             env->CP0_ErrorEPC = env->active_tc.PC;
8673         }
8674         env->active_tc.PC = (int32_t)0xBFC00000;
8675         env->CP0_Wired = 0;
8676         /* SMP not implemented */
8677         env->CP0_EBase = 0x80000000;
8678         env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8679         /* vectored interrupts not implemented, timer on int 7,
8680            no performance counters. */
8681         env->CP0_IntCtl = 0xe0000000;
8682         {
8683             int i;
8684
8685             for (i = 0; i < 7; i++) {
8686                 env->CP0_WatchLo[i] = 0;
8687                 env->CP0_WatchHi[i] = 0x80000000;
8688             }
8689             env->CP0_WatchLo[7] = 0;
8690             env->CP0_WatchHi[7] = 0;
8691         }
8692         /* Count register increments in debug mode, EJTAG version 1 */
8693         env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8694         env->hflags = MIPS_HFLAG_CP0;
8695     }
8696     env->exception_index = EXCP_NONE;
8697     cpu_mips_register(env, env->cpu_model);
8698 }
8699
8700 void gen_pc_load(CPUState *env, TranslationBlock *tb,
8701                 unsigned long searched_pc, int pc_pos, void *puc)
8702 {
8703     env->active_tc.PC = gen_opc_pc[pc_pos];
8704     env->hflags &= ~MIPS_HFLAG_BMASK;
8705     env->hflags |= gen_opc_hflags[pc_pos];
8706 }