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