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