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