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