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