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