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