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