]> Git Repo - qemu.git/blob - target/mips/translate.c
target/mips: Fix emulation of microMIPS R6 <SELEQZ|SELNEZ>.<D|S>
[qemu.git] / target / mips / translate.c
1 /*
2  *  MIPS32 emulation for qemu: main translation routines.
3  *
4  *  Copyright (c) 2004-2005 Jocelyn Mayer
5  *  Copyright (c) 2006 Marius Groeger (FPU operations)
6  *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
7  *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
8  *  Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
9  *
10  * This library is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU Lesser General Public
12  * License as published by the Free Software Foundation; either
13  * version 2 of the License, or (at your option) any later version.
14  *
15  * This library is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * Lesser General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public
21  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
22  */
23
24 #include "qemu/osdep.h"
25 #include "cpu.h"
26 #include "internal.h"
27 #include "disas/disas.h"
28 #include "exec/exec-all.h"
29 #include "tcg-op.h"
30 #include "exec/cpu_ldst.h"
31 #include "hw/mips/cpudevs.h"
32
33 #include "exec/helper-proto.h"
34 #include "exec/helper-gen.h"
35 #include "exec/semihost.h"
36
37 #include "target/mips/trace.h"
38 #include "trace-tcg.h"
39 #include "exec/translator.h"
40 #include "exec/log.h"
41
42 #define MIPS_DEBUG_DISAS 0
43
44 /* MIPS major opcodes */
45 #define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
46
47 enum {
48     /* indirect opcode tables */
49     OPC_SPECIAL  = (0x00 << 26),
50     OPC_REGIMM   = (0x01 << 26),
51     OPC_CP0      = (0x10 << 26),
52     OPC_CP1      = (0x11 << 26),
53     OPC_CP2      = (0x12 << 26),
54     OPC_CP3      = (0x13 << 26),
55     OPC_SPECIAL2 = (0x1C << 26),
56     OPC_SPECIAL3 = (0x1F << 26),
57     /* arithmetic with immediate */
58     OPC_ADDI     = (0x08 << 26),
59     OPC_ADDIU    = (0x09 << 26),
60     OPC_SLTI     = (0x0A << 26),
61     OPC_SLTIU    = (0x0B << 26),
62     /* logic with immediate */
63     OPC_ANDI     = (0x0C << 26),
64     OPC_ORI      = (0x0D << 26),
65     OPC_XORI     = (0x0E << 26),
66     OPC_LUI      = (0x0F << 26),
67     /* arithmetic with immediate */
68     OPC_DADDI    = (0x18 << 26),
69     OPC_DADDIU   = (0x19 << 26),
70     /* Jump and branches */
71     OPC_J        = (0x02 << 26),
72     OPC_JAL      = (0x03 << 26),
73     OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
74     OPC_BEQL     = (0x14 << 26),
75     OPC_BNE      = (0x05 << 26),
76     OPC_BNEL     = (0x15 << 26),
77     OPC_BLEZ     = (0x06 << 26),
78     OPC_BLEZL    = (0x16 << 26),
79     OPC_BGTZ     = (0x07 << 26),
80     OPC_BGTZL    = (0x17 << 26),
81     OPC_JALX     = (0x1D << 26),
82     OPC_DAUI     = (0x1D << 26),
83     /* Load and stores */
84     OPC_LDL      = (0x1A << 26),
85     OPC_LDR      = (0x1B << 26),
86     OPC_LB       = (0x20 << 26),
87     OPC_LH       = (0x21 << 26),
88     OPC_LWL      = (0x22 << 26),
89     OPC_LW       = (0x23 << 26),
90     OPC_LWPC     = OPC_LW | 0x5,
91     OPC_LBU      = (0x24 << 26),
92     OPC_LHU      = (0x25 << 26),
93     OPC_LWR      = (0x26 << 26),
94     OPC_LWU      = (0x27 << 26),
95     OPC_SB       = (0x28 << 26),
96     OPC_SH       = (0x29 << 26),
97     OPC_SWL      = (0x2A << 26),
98     OPC_SW       = (0x2B << 26),
99     OPC_SDL      = (0x2C << 26),
100     OPC_SDR      = (0x2D << 26),
101     OPC_SWR      = (0x2E << 26),
102     OPC_LL       = (0x30 << 26),
103     OPC_LLD      = (0x34 << 26),
104     OPC_LD       = (0x37 << 26),
105     OPC_LDPC     = OPC_LD | 0x5,
106     OPC_SC       = (0x38 << 26),
107     OPC_SCD      = (0x3C << 26),
108     OPC_SD       = (0x3F << 26),
109     /* Floating point load/store */
110     OPC_LWC1     = (0x31 << 26),
111     OPC_LWC2     = (0x32 << 26),
112     OPC_LDC1     = (0x35 << 26),
113     OPC_LDC2     = (0x36 << 26),
114     OPC_SWC1     = (0x39 << 26),
115     OPC_SWC2     = (0x3A << 26),
116     OPC_SDC1     = (0x3D << 26),
117     OPC_SDC2     = (0x3E << 26),
118     /* Compact Branches */
119     OPC_BLEZALC  = (0x06 << 26),
120     OPC_BGEZALC  = (0x06 << 26),
121     OPC_BGEUC    = (0x06 << 26),
122     OPC_BGTZALC  = (0x07 << 26),
123     OPC_BLTZALC  = (0x07 << 26),
124     OPC_BLTUC    = (0x07 << 26),
125     OPC_BOVC     = (0x08 << 26),
126     OPC_BEQZALC  = (0x08 << 26),
127     OPC_BEQC     = (0x08 << 26),
128     OPC_BLEZC    = (0x16 << 26),
129     OPC_BGEZC    = (0x16 << 26),
130     OPC_BGEC     = (0x16 << 26),
131     OPC_BGTZC    = (0x17 << 26),
132     OPC_BLTZC    = (0x17 << 26),
133     OPC_BLTC     = (0x17 << 26),
134     OPC_BNVC     = (0x18 << 26),
135     OPC_BNEZALC  = (0x18 << 26),
136     OPC_BNEC     = (0x18 << 26),
137     OPC_BC       = (0x32 << 26),
138     OPC_BEQZC    = (0x36 << 26),
139     OPC_JIC      = (0x36 << 26),
140     OPC_BALC     = (0x3A << 26),
141     OPC_BNEZC    = (0x3E << 26),
142     OPC_JIALC    = (0x3E << 26),
143     /* MDMX ASE specific */
144     OPC_MDMX     = (0x1E << 26),
145     /* MSA ASE, same as MDMX */
146     OPC_MSA      = OPC_MDMX,
147     /* Cache and prefetch */
148     OPC_CACHE    = (0x2F << 26),
149     OPC_PREF     = (0x33 << 26),
150     /* PC-relative address computation / loads */
151     OPC_PCREL    = (0x3B << 26),
152 };
153
154 /* PC-relative address computation / loads  */
155 #define MASK_OPC_PCREL_TOP2BITS(op)  (MASK_OP_MAJOR(op) | (op & (3 << 19)))
156 #define MASK_OPC_PCREL_TOP5BITS(op)  (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
157 enum {
158     /* Instructions determined by bits 19 and 20 */
159     OPC_ADDIUPC = OPC_PCREL | (0 << 19),
160     R6_OPC_LWPC = OPC_PCREL | (1 << 19),
161     OPC_LWUPC   = OPC_PCREL | (2 << 19),
162
163     /* Instructions determined by bits 16 ... 20 */
164     OPC_AUIPC   = OPC_PCREL | (0x1e << 16),
165     OPC_ALUIPC  = OPC_PCREL | (0x1f << 16),
166
167     /* Other */
168     R6_OPC_LDPC = OPC_PCREL | (6 << 18),
169 };
170
171 /* MIPS special opcodes */
172 #define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
173
174 enum {
175     /* Shifts */
176     OPC_SLL      = 0x00 | OPC_SPECIAL,
177     /* NOP is SLL r0, r0, 0   */
178     /* SSNOP is SLL r0, r0, 1 */
179     /* EHB is SLL r0, r0, 3 */
180     OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
181     OPC_ROTR     = OPC_SRL | (1 << 21),
182     OPC_SRA      = 0x03 | OPC_SPECIAL,
183     OPC_SLLV     = 0x04 | OPC_SPECIAL,
184     OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
185     OPC_ROTRV    = OPC_SRLV | (1 << 6),
186     OPC_SRAV     = 0x07 | OPC_SPECIAL,
187     OPC_DSLLV    = 0x14 | OPC_SPECIAL,
188     OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
189     OPC_DROTRV   = OPC_DSRLV | (1 << 6),
190     OPC_DSRAV    = 0x17 | OPC_SPECIAL,
191     OPC_DSLL     = 0x38 | OPC_SPECIAL,
192     OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
193     OPC_DROTR    = OPC_DSRL | (1 << 21),
194     OPC_DSRA     = 0x3B | OPC_SPECIAL,
195     OPC_DSLL32   = 0x3C | OPC_SPECIAL,
196     OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
197     OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
198     OPC_DSRA32   = 0x3F | OPC_SPECIAL,
199     /* Multiplication / division */
200     OPC_MULT     = 0x18 | OPC_SPECIAL,
201     OPC_MULTU    = 0x19 | OPC_SPECIAL,
202     OPC_DIV      = 0x1A | OPC_SPECIAL,
203     OPC_DIVU     = 0x1B | OPC_SPECIAL,
204     OPC_DMULT    = 0x1C | OPC_SPECIAL,
205     OPC_DMULTU   = 0x1D | OPC_SPECIAL,
206     OPC_DDIV     = 0x1E | OPC_SPECIAL,
207     OPC_DDIVU    = 0x1F | OPC_SPECIAL,
208
209     /* 2 registers arithmetic / logic */
210     OPC_ADD      = 0x20 | OPC_SPECIAL,
211     OPC_ADDU     = 0x21 | OPC_SPECIAL,
212     OPC_SUB      = 0x22 | OPC_SPECIAL,
213     OPC_SUBU     = 0x23 | OPC_SPECIAL,
214     OPC_AND      = 0x24 | OPC_SPECIAL,
215     OPC_OR       = 0x25 | OPC_SPECIAL,
216     OPC_XOR      = 0x26 | OPC_SPECIAL,
217     OPC_NOR      = 0x27 | OPC_SPECIAL,
218     OPC_SLT      = 0x2A | OPC_SPECIAL,
219     OPC_SLTU     = 0x2B | OPC_SPECIAL,
220     OPC_DADD     = 0x2C | OPC_SPECIAL,
221     OPC_DADDU    = 0x2D | OPC_SPECIAL,
222     OPC_DSUB     = 0x2E | OPC_SPECIAL,
223     OPC_DSUBU    = 0x2F | OPC_SPECIAL,
224     /* Jumps */
225     OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
226     OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
227     /* Traps */
228     OPC_TGE      = 0x30 | OPC_SPECIAL,
229     OPC_TGEU     = 0x31 | OPC_SPECIAL,
230     OPC_TLT      = 0x32 | OPC_SPECIAL,
231     OPC_TLTU     = 0x33 | OPC_SPECIAL,
232     OPC_TEQ      = 0x34 | OPC_SPECIAL,
233     OPC_TNE      = 0x36 | OPC_SPECIAL,
234     /* HI / LO registers load & stores */
235     OPC_MFHI     = 0x10 | OPC_SPECIAL,
236     OPC_MTHI     = 0x11 | OPC_SPECIAL,
237     OPC_MFLO     = 0x12 | OPC_SPECIAL,
238     OPC_MTLO     = 0x13 | OPC_SPECIAL,
239     /* Conditional moves */
240     OPC_MOVZ     = 0x0A | OPC_SPECIAL,
241     OPC_MOVN     = 0x0B | OPC_SPECIAL,
242
243     OPC_SELEQZ   = 0x35 | OPC_SPECIAL,
244     OPC_SELNEZ   = 0x37 | OPC_SPECIAL,
245
246     OPC_MOVCI    = 0x01 | OPC_SPECIAL,
247
248     /* Special */
249     OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
250     OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
251     OPC_BREAK    = 0x0D | OPC_SPECIAL,
252     OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
253     OPC_SYNC     = 0x0F | OPC_SPECIAL,
254
255     OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
256     OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
257     OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
258     OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
259 };
260
261 /* R6 Multiply and Divide instructions have the same Opcode
262    and function field as legacy OPC_MULT[U]/OPC_DIV[U] */
263 #define MASK_R6_MULDIV(op)   (MASK_SPECIAL(op) | (op & (0x7ff)))
264
265 enum {
266     R6_OPC_MUL   = OPC_MULT  | (2 << 6),
267     R6_OPC_MUH   = OPC_MULT  | (3 << 6),
268     R6_OPC_MULU  = OPC_MULTU | (2 << 6),
269     R6_OPC_MUHU  = OPC_MULTU | (3 << 6),
270     R6_OPC_DIV   = OPC_DIV   | (2 << 6),
271     R6_OPC_MOD   = OPC_DIV   | (3 << 6),
272     R6_OPC_DIVU  = OPC_DIVU  | (2 << 6),
273     R6_OPC_MODU  = OPC_DIVU  | (3 << 6),
274
275     R6_OPC_DMUL   = OPC_DMULT  | (2 << 6),
276     R6_OPC_DMUH   = OPC_DMULT  | (3 << 6),
277     R6_OPC_DMULU  = OPC_DMULTU | (2 << 6),
278     R6_OPC_DMUHU  = OPC_DMULTU | (3 << 6),
279     R6_OPC_DDIV   = OPC_DDIV   | (2 << 6),
280     R6_OPC_DMOD   = OPC_DDIV   | (3 << 6),
281     R6_OPC_DDIVU  = OPC_DDIVU  | (2 << 6),
282     R6_OPC_DMODU  = OPC_DDIVU  | (3 << 6),
283
284     R6_OPC_CLZ      = 0x10 | OPC_SPECIAL,
285     R6_OPC_CLO      = 0x11 | OPC_SPECIAL,
286     R6_OPC_DCLZ     = 0x12 | OPC_SPECIAL,
287     R6_OPC_DCLO     = 0x13 | OPC_SPECIAL,
288     R6_OPC_SDBBP    = 0x0e | OPC_SPECIAL,
289
290     OPC_LSA  = 0x05 | OPC_SPECIAL,
291     OPC_DLSA = 0x15 | OPC_SPECIAL,
292 };
293
294 /* Multiplication variants of the vr54xx. */
295 #define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
296
297 enum {
298     OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
299     OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
300     OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
301     OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
302     OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
303     OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
304     OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
305     OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
306     OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
307     OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
308     OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
309     OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
310     OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
311     OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
312 };
313
314 /* REGIMM (rt field) opcodes */
315 #define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
316
317 enum {
318     OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
319     OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
320     OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
321     OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
322     OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
323     OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
324     OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
325     OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
326     OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
327     OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
328     OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
329     OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
330     OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
331     OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
332     OPC_SIGRIE   = (0x17 << 16) | OPC_REGIMM,
333     OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
334
335     OPC_DAHI     = (0x06 << 16) | OPC_REGIMM,
336     OPC_DATI     = (0x1e << 16) | OPC_REGIMM,
337 };
338
339 /* Special2 opcodes */
340 #define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
341
342 enum {
343     /* Multiply & xxx operations */
344     OPC_MADD     = 0x00 | OPC_SPECIAL2,
345     OPC_MADDU    = 0x01 | OPC_SPECIAL2,
346     OPC_MUL      = 0x02 | OPC_SPECIAL2,
347     OPC_MSUB     = 0x04 | OPC_SPECIAL2,
348     OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
349     /* Loongson 2F */
350     OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
351     OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
352     OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
353     OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
354     OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
355     OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
356     OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
357     OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
358     OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
359     OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
360     OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
361     OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
362     /* Misc */
363     OPC_CLZ      = 0x20 | OPC_SPECIAL2,
364     OPC_CLO      = 0x21 | OPC_SPECIAL2,
365     OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
366     OPC_DCLO     = 0x25 | OPC_SPECIAL2,
367     /* Special */
368     OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
369 };
370
371 /* Special3 opcodes */
372 #define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
373
374 enum {
375     OPC_EXT      = 0x00 | OPC_SPECIAL3,
376     OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
377     OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
378     OPC_DEXT     = 0x03 | OPC_SPECIAL3,
379     OPC_INS      = 0x04 | OPC_SPECIAL3,
380     OPC_DINSM    = 0x05 | OPC_SPECIAL3,
381     OPC_DINSU    = 0x06 | OPC_SPECIAL3,
382     OPC_DINS     = 0x07 | OPC_SPECIAL3,
383     OPC_FORK     = 0x08 | OPC_SPECIAL3,
384     OPC_YIELD    = 0x09 | OPC_SPECIAL3,
385     OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
386     OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
387     OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
388
389     /* Loongson 2E */
390     OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
391     OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
392     OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
393     OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
394     OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
395     OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
396     OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
397     OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
398     OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
399     OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
400     OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
401     OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
402
403     /* MIPS DSP Load */
404     OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
405     /* MIPS DSP Arithmetic */
406     OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
407     OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
408     OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
409     OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
410     /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E.  */
411     /* OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,  */
412     OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
413     OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
414     /* MIPS DSP GPR-Based Shift Sub-class */
415     OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
416     OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
417     /* MIPS DSP Multiply Sub-class insns */
418     /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP.  */
419     /* OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,  */
420     OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
421     OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
422     /* DSP Bit/Manipulation Sub-class */
423     OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
424     OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
425     /* MIPS DSP Append Sub-class */
426     OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
427     OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
428     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
429     OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
430     OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
431
432     /* EVA */
433     OPC_LWLE           = 0x19 | OPC_SPECIAL3,
434     OPC_LWRE           = 0x1A | OPC_SPECIAL3,
435     OPC_CACHEE         = 0x1B | OPC_SPECIAL3,
436     OPC_SBE            = 0x1C | OPC_SPECIAL3,
437     OPC_SHE            = 0x1D | OPC_SPECIAL3,
438     OPC_SCE            = 0x1E | OPC_SPECIAL3,
439     OPC_SWE            = 0x1F | OPC_SPECIAL3,
440     OPC_SWLE           = 0x21 | OPC_SPECIAL3,
441     OPC_SWRE           = 0x22 | OPC_SPECIAL3,
442     OPC_PREFE          = 0x23 | OPC_SPECIAL3,
443     OPC_LBUE           = 0x28 | OPC_SPECIAL3,
444     OPC_LHUE           = 0x29 | OPC_SPECIAL3,
445     OPC_LBE            = 0x2C | OPC_SPECIAL3,
446     OPC_LHE            = 0x2D | OPC_SPECIAL3,
447     OPC_LLE            = 0x2E | OPC_SPECIAL3,
448     OPC_LWE            = 0x2F | OPC_SPECIAL3,
449
450     /* R6 */
451     R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
452     R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
453     R6_OPC_LL          = 0x36 | OPC_SPECIAL3,
454     R6_OPC_SC          = 0x26 | OPC_SPECIAL3,
455     R6_OPC_LLD         = 0x37 | OPC_SPECIAL3,
456     R6_OPC_SCD         = 0x27 | OPC_SPECIAL3,
457 };
458
459 /* BSHFL opcodes */
460 #define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
461
462 enum {
463     OPC_WSBH      = (0x02 << 6) | OPC_BSHFL,
464     OPC_SEB       = (0x10 << 6) | OPC_BSHFL,
465     OPC_SEH       = (0x18 << 6) | OPC_BSHFL,
466     OPC_ALIGN     = (0x08 << 6) | OPC_BSHFL, /* 010.bp */
467     OPC_ALIGN_END = (0x0B << 6) | OPC_BSHFL, /* 010.00 to 010.11 */
468     OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
469 };
470
471 /* DBSHFL opcodes */
472 #define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
473
474 enum {
475     OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
476     OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
477     OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp */
478     OPC_DALIGN_END = (0x0F << 6) | OPC_DBSHFL, /* 01.000 to 01.111 */
479     OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
480 };
481
482 /* MIPS DSP REGIMM opcodes */
483 enum {
484     OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
485     OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
486 };
487
488 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
489 /* MIPS DSP Load */
490 enum {
491     OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
492     OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
493     OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
494     OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
495 };
496
497 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
498 enum {
499     /* MIPS DSP Arithmetic Sub-class */
500     OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
501     OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
502     OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
503     OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
504     OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
505     OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
506     OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
507     OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
508     OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
509     OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
510     OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
511     OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
512     OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
513     OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
514     OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
515     OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
516     OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
517     OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
518     /* MIPS DSP Multiply Sub-class insns */
519     OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
520     OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
521     OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
522     OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
523     OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
524     OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
525 };
526
527 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
528 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
529 enum {
530     /* MIPS DSP Arithmetic Sub-class */
531     OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
532     OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
533     OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
534     OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
535     OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
536     OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
537     OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
538     OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
539     OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
540     OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
541     OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
542     OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
543     /* MIPS DSP Multiply Sub-class insns */
544     OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
545     OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
546     OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
547     OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
548 };
549
550 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
551 enum {
552     /* MIPS DSP Arithmetic Sub-class */
553     OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
554     OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
555     OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
556     OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
557     OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
558     OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
559     OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
560     OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
561     OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
562     OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
563     OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
564     OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
565     OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
566     /* DSP Bit/Manipulation Sub-class */
567     OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
568     OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
569     OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
570     OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
571     OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
572 };
573
574 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
575 enum {
576     /* MIPS DSP Arithmetic Sub-class */
577     OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
578     OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
579     OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
580     OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
581     OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
582     OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
583     OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
584     /* DSP Compare-Pick Sub-class */
585     OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
586     OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
587     OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
588     OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
589     OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
590     OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
591     OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
592     OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
593     OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
594     OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
595     OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
596     OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
597     OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
598     OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
599     OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
600 };
601
602 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
603 enum {
604     /* MIPS DSP GPR-Based Shift Sub-class */
605     OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
606     OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
607     OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
608     OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
609     OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
610     OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
611     OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
612     OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
613     OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
614     OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
615     OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
616     OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
617     OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
618     OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
619     OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
620     OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
621     OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
622     OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
623     OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
624     OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
625     OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
626     OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
627 };
628
629 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
630 enum {
631     /* MIPS DSP Multiply Sub-class insns */
632     OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
633     OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
634     OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
635     OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
636     OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
637     OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
638     OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
639     OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
640     OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
641     OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
642     OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
643     OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
644     OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
645     OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
646     OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
647     OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
648     OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
649     OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
650     OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
651     OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
652     OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
653     OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
654 };
655
656 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
657 enum {
658     /* DSP Bit/Manipulation Sub-class */
659     OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
660 };
661
662 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
663 enum {
664     /* MIPS DSP Append Sub-class */
665     OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
666     OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
667     OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
668 };
669
670 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
671 enum {
672     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
673     OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
674     OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
675     OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
676     OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
677     OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
678     OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
679     OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
680     OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
681     OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
682     OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
683     OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
684     OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
685     OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
686     OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
687     OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
688     OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
689     OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
690 };
691
692 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
693 enum {
694     /* MIPS DSP Arithmetic Sub-class */
695     OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
696     OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
697     OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
698     OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
699     OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
700     OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
701     OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
702     OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
703     OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
704     OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
705     OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
706     OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
707     OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
708     OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
709     OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
710     OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
711     OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
712     /* DSP Bit/Manipulation Sub-class */
713     OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
714     OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
715     OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
716     OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
717     OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
718     OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
719 };
720
721 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
722 enum {
723     /* MIPS DSP Multiply Sub-class insns */
724     OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
725     OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
726     OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
727     OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
728     OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
729     /* MIPS DSP Arithmetic Sub-class */
730     OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
731     OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
732     OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
733     OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
734     OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
735     OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
736     OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
737     OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
738     OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
739     OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
740     OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
741     OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
742     OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
743     OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
744     OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
745     OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
746     OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
747     OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
748     OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
749     OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
750     OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
751 };
752
753 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
754 enum {
755     /* DSP Compare-Pick Sub-class */
756     OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
757     OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
758     OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
759     OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
760     OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
761     OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
762     OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
763     OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
764     OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
765     OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
766     OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
767     OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
768     OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
769     OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
770     OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
771     OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
772     OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
773     OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
774     OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
775     /* MIPS DSP Arithmetic Sub-class */
776     OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
777     OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
778     OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
779     OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
780     OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
781     OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
782     OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
783     OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
784 };
785
786 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
787 enum {
788     /* DSP Append Sub-class */
789     OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
790     OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
791     OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
792     OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
793 };
794
795 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
796 enum {
797     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
798     OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
799     OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
800     OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
801     OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
802     OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
803     OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
804     OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
805     OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
806     OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
807     OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
808     OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
809     OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
810     OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
811     OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
812     OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
813     OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
814     OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
815     OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
816     OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
817     OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
818     OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
819 };
820
821 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
822 enum {
823     /* DSP Bit/Manipulation Sub-class */
824     OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
825 };
826
827 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
828 enum {
829     /* MIPS DSP Multiply Sub-class insns */
830     OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
831     OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
832     OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
833     OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
834     OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
835     OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
836     OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
837     OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
838     OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
839     OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
840     OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
841     OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
842     OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
843     OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
844     OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
845     OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
846     OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
847     OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
848     OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
849     OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
850     OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
851     OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
852     OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
853     OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
854     OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
855     OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
856 };
857
858 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
859 enum {
860     /* MIPS DSP GPR-Based Shift Sub-class */
861     OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
862     OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
863     OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
864     OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
865     OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
866     OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
867     OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
868     OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
869     OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
870     OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
871     OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
872     OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
873     OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
874     OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
875     OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
876     OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
877     OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
878     OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
879     OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
880     OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
881     OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
882     OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
883     OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
884     OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
885     OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
886     OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
887 };
888
889 /* Coprocessor 0 (rs field) */
890 #define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
891
892 enum {
893     OPC_MFC0     = (0x00 << 21) | OPC_CP0,
894     OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
895     OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
896     OPC_MTC0     = (0x04 << 21) | OPC_CP0,
897     OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
898     OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
899     OPC_MFTR     = (0x08 << 21) | OPC_CP0,
900     OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
901     OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
902     OPC_MTTR     = (0x0C << 21) | OPC_CP0,
903     OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
904     OPC_C0       = (0x10 << 21) | OPC_CP0,
905     OPC_C0_1     = (0x11 << 21) | OPC_CP0,
906     OPC_C0_2     = (0x12 << 21) | OPC_CP0,
907     OPC_C0_3     = (0x13 << 21) | OPC_CP0,
908     OPC_C0_4     = (0x14 << 21) | OPC_CP0,
909     OPC_C0_5     = (0x15 << 21) | OPC_CP0,
910     OPC_C0_6     = (0x16 << 21) | OPC_CP0,
911     OPC_C0_7     = (0x17 << 21) | OPC_CP0,
912     OPC_C0_8     = (0x18 << 21) | OPC_CP0,
913     OPC_C0_9     = (0x19 << 21) | OPC_CP0,
914     OPC_C0_A     = (0x1A << 21) | OPC_CP0,
915     OPC_C0_B     = (0x1B << 21) | OPC_CP0,
916     OPC_C0_C     = (0x1C << 21) | OPC_CP0,
917     OPC_C0_D     = (0x1D << 21) | OPC_CP0,
918     OPC_C0_E     = (0x1E << 21) | OPC_CP0,
919     OPC_C0_F     = (0x1F << 21) | OPC_CP0,
920 };
921
922 /* MFMC0 opcodes */
923 #define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
924
925 enum {
926     OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
927     OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
928     OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
929     OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
930     OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
931     OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
932     OPC_DVP      = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
933     OPC_EVP      = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
934 };
935
936 /* Coprocessor 0 (with rs == C0) */
937 #define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
938
939 enum {
940     OPC_TLBR     = 0x01 | OPC_C0,
941     OPC_TLBWI    = 0x02 | OPC_C0,
942     OPC_TLBINV   = 0x03 | OPC_C0,
943     OPC_TLBINVF  = 0x04 | OPC_C0,
944     OPC_TLBWR    = 0x06 | OPC_C0,
945     OPC_TLBP     = 0x08 | OPC_C0,
946     OPC_RFE      = 0x10 | OPC_C0,
947     OPC_ERET     = 0x18 | OPC_C0,
948     OPC_DERET    = 0x1F | OPC_C0,
949     OPC_WAIT     = 0x20 | OPC_C0,
950 };
951
952 /* Coprocessor 1 (rs field) */
953 #define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
954
955 /* Values for the fmt field in FP instructions */
956 enum {
957     /* 0 - 15 are reserved */
958     FMT_S = 16,          /* single fp */
959     FMT_D = 17,          /* double fp */
960     FMT_E = 18,          /* extended fp */
961     FMT_Q = 19,          /* quad fp */
962     FMT_W = 20,          /* 32-bit fixed */
963     FMT_L = 21,          /* 64-bit fixed */
964     FMT_PS = 22,         /* paired single fp */
965     /* 23 - 31 are reserved */
966 };
967
968 enum {
969     OPC_MFC1     = (0x00 << 21) | OPC_CP1,
970     OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
971     OPC_CFC1     = (0x02 << 21) | OPC_CP1,
972     OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
973     OPC_MTC1     = (0x04 << 21) | OPC_CP1,
974     OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
975     OPC_CTC1     = (0x06 << 21) | OPC_CP1,
976     OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
977     OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
978     OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
979     OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
980     OPC_BZ_V     = (0x0B << 21) | OPC_CP1,
981     OPC_BNZ_V    = (0x0F << 21) | OPC_CP1,
982     OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
983     OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
984     OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
985     OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
986     OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
987     OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
988     OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
989     OPC_BC1EQZ   = (0x09 << 21) | OPC_CP1,
990     OPC_BC1NEZ   = (0x0D << 21) | OPC_CP1,
991     OPC_BZ_B     = (0x18 << 21) | OPC_CP1,
992     OPC_BZ_H     = (0x19 << 21) | OPC_CP1,
993     OPC_BZ_W     = (0x1A << 21) | OPC_CP1,
994     OPC_BZ_D     = (0x1B << 21) | OPC_CP1,
995     OPC_BNZ_B    = (0x1C << 21) | OPC_CP1,
996     OPC_BNZ_H    = (0x1D << 21) | OPC_CP1,
997     OPC_BNZ_W    = (0x1E << 21) | OPC_CP1,
998     OPC_BNZ_D    = (0x1F << 21) | OPC_CP1,
999 };
1000
1001 #define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
1002 #define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
1003
1004 enum {
1005     OPC_BC1F     = (0x00 << 16) | OPC_BC1,
1006     OPC_BC1T     = (0x01 << 16) | OPC_BC1,
1007     OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
1008     OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
1009 };
1010
1011 enum {
1012     OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
1013     OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
1014 };
1015
1016 enum {
1017     OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
1018     OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
1019 };
1020
1021 #define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
1022
1023 enum {
1024     OPC_MFC2    = (0x00 << 21) | OPC_CP2,
1025     OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
1026     OPC_CFC2    = (0x02 << 21) | OPC_CP2,
1027     OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
1028     OPC_MTC2    = (0x04 << 21) | OPC_CP2,
1029     OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
1030     OPC_CTC2    = (0x06 << 21) | OPC_CP2,
1031     OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
1032     OPC_BC2     = (0x08 << 21) | OPC_CP2,
1033     OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
1034     OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
1035 };
1036
1037 #define MASK_LMI(op)  (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1038
1039 enum {
1040     OPC_PADDSH  = (24 << 21) | (0x00) | OPC_CP2,
1041     OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1042     OPC_PADDH   = (26 << 21) | (0x00) | OPC_CP2,
1043     OPC_PADDW   = (27 << 21) | (0x00) | OPC_CP2,
1044     OPC_PADDSB  = (28 << 21) | (0x00) | OPC_CP2,
1045     OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1046     OPC_PADDB   = (30 << 21) | (0x00) | OPC_CP2,
1047     OPC_PADDD   = (31 << 21) | (0x00) | OPC_CP2,
1048
1049     OPC_PSUBSH  = (24 << 21) | (0x01) | OPC_CP2,
1050     OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1051     OPC_PSUBH   = (26 << 21) | (0x01) | OPC_CP2,
1052     OPC_PSUBW   = (27 << 21) | (0x01) | OPC_CP2,
1053     OPC_PSUBSB  = (28 << 21) | (0x01) | OPC_CP2,
1054     OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1055     OPC_PSUBB   = (30 << 21) | (0x01) | OPC_CP2,
1056     OPC_PSUBD   = (31 << 21) | (0x01) | OPC_CP2,
1057
1058     OPC_PSHUFH   = (24 << 21) | (0x02) | OPC_CP2,
1059     OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1060     OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1061     OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1062     OPC_XOR_CP2  = (28 << 21) | (0x02) | OPC_CP2,
1063     OPC_NOR_CP2  = (29 << 21) | (0x02) | OPC_CP2,
1064     OPC_AND_CP2  = (30 << 21) | (0x02) | OPC_CP2,
1065     OPC_PANDN    = (31 << 21) | (0x02) | OPC_CP2,
1066
1067     OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1068     OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1069     OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1070     OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1071     OPC_PINSRH_0  = (28 << 21) | (0x03) | OPC_CP2,
1072     OPC_PINSRH_1  = (29 << 21) | (0x03) | OPC_CP2,
1073     OPC_PINSRH_2  = (30 << 21) | (0x03) | OPC_CP2,
1074     OPC_PINSRH_3  = (31 << 21) | (0x03) | OPC_CP2,
1075
1076     OPC_PAVGH   = (24 << 21) | (0x08) | OPC_CP2,
1077     OPC_PAVGB   = (25 << 21) | (0x08) | OPC_CP2,
1078     OPC_PMAXSH  = (26 << 21) | (0x08) | OPC_CP2,
1079     OPC_PMINSH  = (27 << 21) | (0x08) | OPC_CP2,
1080     OPC_PMAXUB  = (28 << 21) | (0x08) | OPC_CP2,
1081     OPC_PMINUB  = (29 << 21) | (0x08) | OPC_CP2,
1082
1083     OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1084     OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1085     OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1086     OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1087     OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1088     OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1089
1090     OPC_PSLLW   = (24 << 21) | (0x0A) | OPC_CP2,
1091     OPC_PSLLH   = (25 << 21) | (0x0A) | OPC_CP2,
1092     OPC_PMULLH  = (26 << 21) | (0x0A) | OPC_CP2,
1093     OPC_PMULHH  = (27 << 21) | (0x0A) | OPC_CP2,
1094     OPC_PMULUW  = (28 << 21) | (0x0A) | OPC_CP2,
1095     OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1096
1097     OPC_PSRLW     = (24 << 21) | (0x0B) | OPC_CP2,
1098     OPC_PSRLH     = (25 << 21) | (0x0B) | OPC_CP2,
1099     OPC_PSRAW     = (26 << 21) | (0x0B) | OPC_CP2,
1100     OPC_PSRAH     = (27 << 21) | (0x0B) | OPC_CP2,
1101     OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1102     OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1103
1104     OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1105     OPC_OR_CP2   = (25 << 21) | (0x0C) | OPC_CP2,
1106     OPC_ADD_CP2  = (26 << 21) | (0x0C) | OPC_CP2,
1107     OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1108     OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1109     OPC_SEQ_CP2  = (29 << 21) | (0x0C) | OPC_CP2,
1110
1111     OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1112     OPC_PASUBUB  = (25 << 21) | (0x0D) | OPC_CP2,
1113     OPC_SUB_CP2  = (26 << 21) | (0x0D) | OPC_CP2,
1114     OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1115     OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1116     OPC_SLT_CP2  = (29 << 21) | (0x0D) | OPC_CP2,
1117
1118     OPC_SLL_CP2  = (24 << 21) | (0x0E) | OPC_CP2,
1119     OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1120     OPC_PEXTRH   = (26 << 21) | (0x0E) | OPC_CP2,
1121     OPC_PMADDHW  = (27 << 21) | (0x0E) | OPC_CP2,
1122     OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1123     OPC_SLE_CP2  = (29 << 21) | (0x0E) | OPC_CP2,
1124
1125     OPC_SRL_CP2  = (24 << 21) | (0x0F) | OPC_CP2,
1126     OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1127     OPC_SRA_CP2  = (26 << 21) | (0x0F) | OPC_CP2,
1128     OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1129     OPC_BIADD    = (28 << 21) | (0x0F) | OPC_CP2,
1130     OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1131 };
1132
1133
1134 #define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
1135
1136 enum {
1137     OPC_LWXC1   = 0x00 | OPC_CP3,
1138     OPC_LDXC1   = 0x01 | OPC_CP3,
1139     OPC_LUXC1   = 0x05 | OPC_CP3,
1140     OPC_SWXC1   = 0x08 | OPC_CP3,
1141     OPC_SDXC1   = 0x09 | OPC_CP3,
1142     OPC_SUXC1   = 0x0D | OPC_CP3,
1143     OPC_PREFX   = 0x0F | OPC_CP3,
1144     OPC_ALNV_PS = 0x1E | OPC_CP3,
1145     OPC_MADD_S  = 0x20 | OPC_CP3,
1146     OPC_MADD_D  = 0x21 | OPC_CP3,
1147     OPC_MADD_PS = 0x26 | OPC_CP3,
1148     OPC_MSUB_S  = 0x28 | OPC_CP3,
1149     OPC_MSUB_D  = 0x29 | OPC_CP3,
1150     OPC_MSUB_PS = 0x2E | OPC_CP3,
1151     OPC_NMADD_S = 0x30 | OPC_CP3,
1152     OPC_NMADD_D = 0x31 | OPC_CP3,
1153     OPC_NMADD_PS= 0x36 | OPC_CP3,
1154     OPC_NMSUB_S = 0x38 | OPC_CP3,
1155     OPC_NMSUB_D = 0x39 | OPC_CP3,
1156     OPC_NMSUB_PS= 0x3E | OPC_CP3,
1157 };
1158
1159 /* MSA Opcodes */
1160 #define MASK_MSA_MINOR(op)    (MASK_OP_MAJOR(op) | (op & 0x3F))
1161 enum {
1162     OPC_MSA_I8_00   = 0x00 | OPC_MSA,
1163     OPC_MSA_I8_01   = 0x01 | OPC_MSA,
1164     OPC_MSA_I8_02   = 0x02 | OPC_MSA,
1165     OPC_MSA_I5_06   = 0x06 | OPC_MSA,
1166     OPC_MSA_I5_07   = 0x07 | OPC_MSA,
1167     OPC_MSA_BIT_09  = 0x09 | OPC_MSA,
1168     OPC_MSA_BIT_0A  = 0x0A | OPC_MSA,
1169     OPC_MSA_3R_0D   = 0x0D | OPC_MSA,
1170     OPC_MSA_3R_0E   = 0x0E | OPC_MSA,
1171     OPC_MSA_3R_0F   = 0x0F | OPC_MSA,
1172     OPC_MSA_3R_10   = 0x10 | OPC_MSA,
1173     OPC_MSA_3R_11   = 0x11 | OPC_MSA,
1174     OPC_MSA_3R_12   = 0x12 | OPC_MSA,
1175     OPC_MSA_3R_13   = 0x13 | OPC_MSA,
1176     OPC_MSA_3R_14   = 0x14 | OPC_MSA,
1177     OPC_MSA_3R_15   = 0x15 | OPC_MSA,
1178     OPC_MSA_ELM     = 0x19 | OPC_MSA,
1179     OPC_MSA_3RF_1A  = 0x1A | OPC_MSA,
1180     OPC_MSA_3RF_1B  = 0x1B | OPC_MSA,
1181     OPC_MSA_3RF_1C  = 0x1C | OPC_MSA,
1182     OPC_MSA_VEC     = 0x1E | OPC_MSA,
1183
1184     /* MI10 instruction */
1185     OPC_LD_B    = (0x20) | OPC_MSA,
1186     OPC_LD_H    = (0x21) | OPC_MSA,
1187     OPC_LD_W    = (0x22) | OPC_MSA,
1188     OPC_LD_D    = (0x23) | OPC_MSA,
1189     OPC_ST_B    = (0x24) | OPC_MSA,
1190     OPC_ST_H    = (0x25) | OPC_MSA,
1191     OPC_ST_W    = (0x26) | OPC_MSA,
1192     OPC_ST_D    = (0x27) | OPC_MSA,
1193 };
1194
1195 enum {
1196     /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1197     OPC_ADDVI_df    = (0x0 << 23) | OPC_MSA_I5_06,
1198     OPC_CEQI_df     = (0x0 << 23) | OPC_MSA_I5_07,
1199     OPC_SUBVI_df    = (0x1 << 23) | OPC_MSA_I5_06,
1200     OPC_MAXI_S_df   = (0x2 << 23) | OPC_MSA_I5_06,
1201     OPC_CLTI_S_df   = (0x2 << 23) | OPC_MSA_I5_07,
1202     OPC_MAXI_U_df   = (0x3 << 23) | OPC_MSA_I5_06,
1203     OPC_CLTI_U_df   = (0x3 << 23) | OPC_MSA_I5_07,
1204     OPC_MINI_S_df   = (0x4 << 23) | OPC_MSA_I5_06,
1205     OPC_CLEI_S_df   = (0x4 << 23) | OPC_MSA_I5_07,
1206     OPC_MINI_U_df   = (0x5 << 23) | OPC_MSA_I5_06,
1207     OPC_CLEI_U_df   = (0x5 << 23) | OPC_MSA_I5_07,
1208     OPC_LDI_df      = (0x6 << 23) | OPC_MSA_I5_07,
1209
1210     /* I8 instruction */
1211     OPC_ANDI_B  = (0x0 << 24) | OPC_MSA_I8_00,
1212     OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1213     OPC_SHF_B   = (0x0 << 24) | OPC_MSA_I8_02,
1214     OPC_ORI_B   = (0x1 << 24) | OPC_MSA_I8_00,
1215     OPC_BMZI_B  = (0x1 << 24) | OPC_MSA_I8_01,
1216     OPC_SHF_H   = (0x1 << 24) | OPC_MSA_I8_02,
1217     OPC_NORI_B  = (0x2 << 24) | OPC_MSA_I8_00,
1218     OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1219     OPC_SHF_W   = (0x2 << 24) | OPC_MSA_I8_02,
1220     OPC_XORI_B  = (0x3 << 24) | OPC_MSA_I8_00,
1221
1222     /* VEC/2R/2RF instruction */
1223     OPC_AND_V   = (0x00 << 21) | OPC_MSA_VEC,
1224     OPC_OR_V    = (0x01 << 21) | OPC_MSA_VEC,
1225     OPC_NOR_V   = (0x02 << 21) | OPC_MSA_VEC,
1226     OPC_XOR_V   = (0x03 << 21) | OPC_MSA_VEC,
1227     OPC_BMNZ_V  = (0x04 << 21) | OPC_MSA_VEC,
1228     OPC_BMZ_V   = (0x05 << 21) | OPC_MSA_VEC,
1229     OPC_BSEL_V  = (0x06 << 21) | OPC_MSA_VEC,
1230
1231     OPC_MSA_2R      = (0x18 << 21) | OPC_MSA_VEC,
1232     OPC_MSA_2RF     = (0x19 << 21) | OPC_MSA_VEC,
1233
1234     /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1235     OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1236     OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1237     OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1238     OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1239
1240     /* 2RF instruction df(bit 16) = _w, _d */
1241     OPC_FCLASS_df   = (0x00 << 17) | OPC_MSA_2RF,
1242     OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1243     OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1244     OPC_FSQRT_df    = (0x03 << 17) | OPC_MSA_2RF,
1245     OPC_FRSQRT_df   = (0x04 << 17) | OPC_MSA_2RF,
1246     OPC_FRCP_df     = (0x05 << 17) | OPC_MSA_2RF,
1247     OPC_FRINT_df    = (0x06 << 17) | OPC_MSA_2RF,
1248     OPC_FLOG2_df    = (0x07 << 17) | OPC_MSA_2RF,
1249     OPC_FEXUPL_df   = (0x08 << 17) | OPC_MSA_2RF,
1250     OPC_FEXUPR_df   = (0x09 << 17) | OPC_MSA_2RF,
1251     OPC_FFQL_df     = (0x0A << 17) | OPC_MSA_2RF,
1252     OPC_FFQR_df     = (0x0B << 17) | OPC_MSA_2RF,
1253     OPC_FTINT_S_df  = (0x0C << 17) | OPC_MSA_2RF,
1254     OPC_FTINT_U_df  = (0x0D << 17) | OPC_MSA_2RF,
1255     OPC_FFINT_S_df  = (0x0E << 17) | OPC_MSA_2RF,
1256     OPC_FFINT_U_df  = (0x0F << 17) | OPC_MSA_2RF,
1257
1258     /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1259     OPC_SLL_df      = (0x0 << 23) | OPC_MSA_3R_0D,
1260     OPC_ADDV_df     = (0x0 << 23) | OPC_MSA_3R_0E,
1261     OPC_CEQ_df      = (0x0 << 23) | OPC_MSA_3R_0F,
1262     OPC_ADD_A_df    = (0x0 << 23) | OPC_MSA_3R_10,
1263     OPC_SUBS_S_df   = (0x0 << 23) | OPC_MSA_3R_11,
1264     OPC_MULV_df     = (0x0 << 23) | OPC_MSA_3R_12,
1265     OPC_DOTP_S_df   = (0x0 << 23) | OPC_MSA_3R_13,
1266     OPC_SLD_df      = (0x0 << 23) | OPC_MSA_3R_14,
1267     OPC_VSHF_df     = (0x0 << 23) | OPC_MSA_3R_15,
1268     OPC_SRA_df      = (0x1 << 23) | OPC_MSA_3R_0D,
1269     OPC_SUBV_df     = (0x1 << 23) | OPC_MSA_3R_0E,
1270     OPC_ADDS_A_df   = (0x1 << 23) | OPC_MSA_3R_10,
1271     OPC_SUBS_U_df   = (0x1 << 23) | OPC_MSA_3R_11,
1272     OPC_MADDV_df    = (0x1 << 23) | OPC_MSA_3R_12,
1273     OPC_DOTP_U_df   = (0x1 << 23) | OPC_MSA_3R_13,
1274     OPC_SPLAT_df    = (0x1 << 23) | OPC_MSA_3R_14,
1275     OPC_SRAR_df     = (0x1 << 23) | OPC_MSA_3R_15,
1276     OPC_SRL_df      = (0x2 << 23) | OPC_MSA_3R_0D,
1277     OPC_MAX_S_df    = (0x2 << 23) | OPC_MSA_3R_0E,
1278     OPC_CLT_S_df    = (0x2 << 23) | OPC_MSA_3R_0F,
1279     OPC_ADDS_S_df   = (0x2 << 23) | OPC_MSA_3R_10,
1280     OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1281     OPC_MSUBV_df    = (0x2 << 23) | OPC_MSA_3R_12,
1282     OPC_DPADD_S_df  = (0x2 << 23) | OPC_MSA_3R_13,
1283     OPC_PCKEV_df    = (0x2 << 23) | OPC_MSA_3R_14,
1284     OPC_SRLR_df     = (0x2 << 23) | OPC_MSA_3R_15,
1285     OPC_BCLR_df     = (0x3 << 23) | OPC_MSA_3R_0D,
1286     OPC_MAX_U_df    = (0x3 << 23) | OPC_MSA_3R_0E,
1287     OPC_CLT_U_df    = (0x3 << 23) | OPC_MSA_3R_0F,
1288     OPC_ADDS_U_df   = (0x3 << 23) | OPC_MSA_3R_10,
1289     OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1290     OPC_DPADD_U_df  = (0x3 << 23) | OPC_MSA_3R_13,
1291     OPC_PCKOD_df    = (0x3 << 23) | OPC_MSA_3R_14,
1292     OPC_BSET_df     = (0x4 << 23) | OPC_MSA_3R_0D,
1293     OPC_MIN_S_df    = (0x4 << 23) | OPC_MSA_3R_0E,
1294     OPC_CLE_S_df    = (0x4 << 23) | OPC_MSA_3R_0F,
1295     OPC_AVE_S_df    = (0x4 << 23) | OPC_MSA_3R_10,
1296     OPC_ASUB_S_df   = (0x4 << 23) | OPC_MSA_3R_11,
1297     OPC_DIV_S_df    = (0x4 << 23) | OPC_MSA_3R_12,
1298     OPC_DPSUB_S_df  = (0x4 << 23) | OPC_MSA_3R_13,
1299     OPC_ILVL_df     = (0x4 << 23) | OPC_MSA_3R_14,
1300     OPC_HADD_S_df   = (0x4 << 23) | OPC_MSA_3R_15,
1301     OPC_BNEG_df     = (0x5 << 23) | OPC_MSA_3R_0D,
1302     OPC_MIN_U_df    = (0x5 << 23) | OPC_MSA_3R_0E,
1303     OPC_CLE_U_df    = (0x5 << 23) | OPC_MSA_3R_0F,
1304     OPC_AVE_U_df    = (0x5 << 23) | OPC_MSA_3R_10,
1305     OPC_ASUB_U_df   = (0x5 << 23) | OPC_MSA_3R_11,
1306     OPC_DIV_U_df    = (0x5 << 23) | OPC_MSA_3R_12,
1307     OPC_DPSUB_U_df  = (0x5 << 23) | OPC_MSA_3R_13,
1308     OPC_ILVR_df     = (0x5 << 23) | OPC_MSA_3R_14,
1309     OPC_HADD_U_df   = (0x5 << 23) | OPC_MSA_3R_15,
1310     OPC_BINSL_df    = (0x6 << 23) | OPC_MSA_3R_0D,
1311     OPC_MAX_A_df    = (0x6 << 23) | OPC_MSA_3R_0E,
1312     OPC_AVER_S_df   = (0x6 << 23) | OPC_MSA_3R_10,
1313     OPC_MOD_S_df    = (0x6 << 23) | OPC_MSA_3R_12,
1314     OPC_ILVEV_df    = (0x6 << 23) | OPC_MSA_3R_14,
1315     OPC_HSUB_S_df   = (0x6 << 23) | OPC_MSA_3R_15,
1316     OPC_BINSR_df    = (0x7 << 23) | OPC_MSA_3R_0D,
1317     OPC_MIN_A_df    = (0x7 << 23) | OPC_MSA_3R_0E,
1318     OPC_AVER_U_df   = (0x7 << 23) | OPC_MSA_3R_10,
1319     OPC_MOD_U_df    = (0x7 << 23) | OPC_MSA_3R_12,
1320     OPC_ILVOD_df    = (0x7 << 23) | OPC_MSA_3R_14,
1321     OPC_HSUB_U_df   = (0x7 << 23) | OPC_MSA_3R_15,
1322
1323     /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1324     OPC_SLDI_df     = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1325     OPC_CTCMSA      = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1326     OPC_SPLATI_df   = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1327     OPC_CFCMSA      = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1328     OPC_COPY_S_df   = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1329     OPC_MOVE_V      = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1330     OPC_COPY_U_df   = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1331     OPC_INSERT_df   = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1332     OPC_INSVE_df    = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1333
1334     /* 3RF instruction _df(bit 21) = _w, _d */
1335     OPC_FCAF_df     = (0x0 << 22) | OPC_MSA_3RF_1A,
1336     OPC_FADD_df     = (0x0 << 22) | OPC_MSA_3RF_1B,
1337     OPC_FCUN_df     = (0x1 << 22) | OPC_MSA_3RF_1A,
1338     OPC_FSUB_df     = (0x1 << 22) | OPC_MSA_3RF_1B,
1339     OPC_FCOR_df     = (0x1 << 22) | OPC_MSA_3RF_1C,
1340     OPC_FCEQ_df     = (0x2 << 22) | OPC_MSA_3RF_1A,
1341     OPC_FMUL_df     = (0x2 << 22) | OPC_MSA_3RF_1B,
1342     OPC_FCUNE_df    = (0x2 << 22) | OPC_MSA_3RF_1C,
1343     OPC_FCUEQ_df    = (0x3 << 22) | OPC_MSA_3RF_1A,
1344     OPC_FDIV_df     = (0x3 << 22) | OPC_MSA_3RF_1B,
1345     OPC_FCNE_df     = (0x3 << 22) | OPC_MSA_3RF_1C,
1346     OPC_FCLT_df     = (0x4 << 22) | OPC_MSA_3RF_1A,
1347     OPC_FMADD_df    = (0x4 << 22) | OPC_MSA_3RF_1B,
1348     OPC_MUL_Q_df    = (0x4 << 22) | OPC_MSA_3RF_1C,
1349     OPC_FCULT_df    = (0x5 << 22) | OPC_MSA_3RF_1A,
1350     OPC_FMSUB_df    = (0x5 << 22) | OPC_MSA_3RF_1B,
1351     OPC_MADD_Q_df   = (0x5 << 22) | OPC_MSA_3RF_1C,
1352     OPC_FCLE_df     = (0x6 << 22) | OPC_MSA_3RF_1A,
1353     OPC_MSUB_Q_df   = (0x6 << 22) | OPC_MSA_3RF_1C,
1354     OPC_FCULE_df    = (0x7 << 22) | OPC_MSA_3RF_1A,
1355     OPC_FEXP2_df    = (0x7 << 22) | OPC_MSA_3RF_1B,
1356     OPC_FSAF_df     = (0x8 << 22) | OPC_MSA_3RF_1A,
1357     OPC_FEXDO_df    = (0x8 << 22) | OPC_MSA_3RF_1B,
1358     OPC_FSUN_df     = (0x9 << 22) | OPC_MSA_3RF_1A,
1359     OPC_FSOR_df     = (0x9 << 22) | OPC_MSA_3RF_1C,
1360     OPC_FSEQ_df     = (0xA << 22) | OPC_MSA_3RF_1A,
1361     OPC_FTQ_df      = (0xA << 22) | OPC_MSA_3RF_1B,
1362     OPC_FSUNE_df    = (0xA << 22) | OPC_MSA_3RF_1C,
1363     OPC_FSUEQ_df    = (0xB << 22) | OPC_MSA_3RF_1A,
1364     OPC_FSNE_df     = (0xB << 22) | OPC_MSA_3RF_1C,
1365     OPC_FSLT_df     = (0xC << 22) | OPC_MSA_3RF_1A,
1366     OPC_FMIN_df     = (0xC << 22) | OPC_MSA_3RF_1B,
1367     OPC_MULR_Q_df   = (0xC << 22) | OPC_MSA_3RF_1C,
1368     OPC_FSULT_df    = (0xD << 22) | OPC_MSA_3RF_1A,
1369     OPC_FMIN_A_df   = (0xD << 22) | OPC_MSA_3RF_1B,
1370     OPC_MADDR_Q_df  = (0xD << 22) | OPC_MSA_3RF_1C,
1371     OPC_FSLE_df     = (0xE << 22) | OPC_MSA_3RF_1A,
1372     OPC_FMAX_df     = (0xE << 22) | OPC_MSA_3RF_1B,
1373     OPC_MSUBR_Q_df  = (0xE << 22) | OPC_MSA_3RF_1C,
1374     OPC_FSULE_df    = (0xF << 22) | OPC_MSA_3RF_1A,
1375     OPC_FMAX_A_df   = (0xF << 22) | OPC_MSA_3RF_1B,
1376
1377     /* BIT instruction df(bits 22..16) = _B _H _W _D */
1378     OPC_SLLI_df     = (0x0 << 23) | OPC_MSA_BIT_09,
1379     OPC_SAT_S_df    = (0x0 << 23) | OPC_MSA_BIT_0A,
1380     OPC_SRAI_df     = (0x1 << 23) | OPC_MSA_BIT_09,
1381     OPC_SAT_U_df    = (0x1 << 23) | OPC_MSA_BIT_0A,
1382     OPC_SRLI_df     = (0x2 << 23) | OPC_MSA_BIT_09,
1383     OPC_SRARI_df    = (0x2 << 23) | OPC_MSA_BIT_0A,
1384     OPC_BCLRI_df    = (0x3 << 23) | OPC_MSA_BIT_09,
1385     OPC_SRLRI_df    = (0x3 << 23) | OPC_MSA_BIT_0A,
1386     OPC_BSETI_df    = (0x4 << 23) | OPC_MSA_BIT_09,
1387     OPC_BNEGI_df    = (0x5 << 23) | OPC_MSA_BIT_09,
1388     OPC_BINSLI_df   = (0x6 << 23) | OPC_MSA_BIT_09,
1389     OPC_BINSRI_df   = (0x7 << 23) | OPC_MSA_BIT_09,
1390 };
1391
1392
1393 /*
1394  *    AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1395  *    ============================================
1396  *
1397  * MXU (full name: MIPS eXtension/enhanced Unit) is an SIMD extension of MIPS32
1398  * instructions set. It is designed to fit the needs of signal, graphical and
1399  * video processing applications. MXU instruction set is used in Xburst family
1400  * of microprocessors by Ingenic.
1401  *
1402  * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1403  * the control register.
1404  *
1405  * The notation used in MXU assembler mnemonics:
1406  *
1407  *   XRa, XRb, XRc, XRd - MXU registers
1408  *   Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1409  *   s12                - a subfield of an instruction code
1410  *   strd2              - a subfield of an instruction code
1411  *   eptn2              - a subfield of an instruction code
1412  *   eptn3              - a subfield of an instruction code
1413  *   optn2              - a subfield of an instruction code
1414  *   optn3              - a subfield of an instruction code
1415  *   sft4               - a subfield of an instruction code
1416  *
1417  * Load/Store instructions           Multiplication instructions
1418  * -----------------------           ---------------------------
1419  *
1420  *  S32LDD XRa, Rb, s12               S32MADD XRa, XRd, Rs, Rt
1421  *  S32STD XRa, Rb, s12               S32MADDU XRa, XRd, Rs, Rt
1422  *  S32LDDV XRa, Rb, rc, strd2        S32SUB XRa, XRd, Rs, Rt
1423  *  S32STDV XRa, Rb, rc, strd2        S32SUBU XRa, XRd, Rs, Rt
1424  *  S32LDI XRa, Rb, s12               S32MUL XRa, XRd, Rs, Rt
1425  *  S32SDI XRa, Rb, s12               S32MULU XRa, XRd, Rs, Rt
1426  *  S32LDIV XRa, Rb, rc, strd2        D16MUL XRa, XRb, XRc, XRd, optn2
1427  *  S32SDIV XRa, Rb, rc, strd2        D16MULE XRa, XRb, XRc, optn2
1428  *  S32LDDR XRa, Rb, s12              D16MULF XRa, XRb, XRc, optn2
1429  *  S32STDR XRa, Rb, s12              D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1430  *  S32LDDVR XRa, Rb, rc, strd2       D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1431  *  S32STDVR XRa, Rb, rc, strd2       D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1432  *  S32LDIR XRa, Rb, s12              D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1433  *  S32SDIR XRa, Rb, s12              S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1434  *  S32LDIVR XRa, Rb, rc, strd2       Q8MUL XRa, XRb, XRc, XRd
1435  *  S32SDIVR XRa, Rb, rc, strd2       Q8MULSU XRa, XRb, XRc, XRd
1436  *  S16LDD XRa, Rb, s10, eptn2        Q8MAC XRa, XRb, XRc, XRd, aptn2
1437  *  S16STD XRa, Rb, s10, eptn2        Q8MACSU XRa, XRb, XRc, XRd, aptn2
1438  *  S16LDI XRa, Rb, s10, eptn2        Q8MADL XRa, XRb, XRc, XRd, aptn2
1439  *  S16SDI XRa, Rb, s10, eptn2
1440  *  S8LDD XRa, Rb, s8, eptn3
1441  *  S8STD XRa, Rb, s8, eptn3         Addition and subtraction instructions
1442  *  S8LDI XRa, Rb, s8, eptn3         -------------------------------------
1443  *  S8SDI XRa, Rb, s8, eptn3
1444  *  LXW Rd, Rs, Rt, strd2             D32ADD XRa, XRb, XRc, XRd, eptn2
1445  *  LXH Rd, Rs, Rt, strd2             D32ADDC XRa, XRb, XRc, XRd
1446  *  LXHU Rd, Rs, Rt, strd2            D32ACC XRa, XRb, XRc, XRd, eptn2
1447  *  LXB Rd, Rs, Rt, strd2             D32ACCM XRa, XRb, XRc, XRd, eptn2
1448  *  LXBU Rd, Rs, Rt, strd2            D32ASUM XRa, XRb, XRc, XRd, eptn2
1449  *                                    S32CPS XRa, XRb, XRc
1450  *                                    Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1451  * Comparison instructions            Q16ACC XRa, XRb, XRc, XRd, eptn2
1452  * -----------------------            Q16ACCM XRa, XRb, XRc, XRd, eptn2
1453  *                                    D16ASUM XRa, XRb, XRc, XRd, eptn2
1454  *  S32MAX XRa, XRb, XRc              D16CPS XRa, XRb,
1455  *  S32MIN XRa, XRb, XRc              D16AVG XRa, XRb, XRc
1456  *  S32SLT XRa, XRb, XRc              D16AVGR XRa, XRb, XRc
1457  *  S32MOVZ XRa, XRb, XRc             Q8ADD XRa, XRb, XRc, eptn2
1458  *  S32MOVN XRa, XRb, XRc             Q8ADDE XRa, XRb, XRc, XRd, eptn2
1459  *  D16MAX XRa, XRb, XRc              Q8ACCE XRa, XRb, XRc, XRd, eptn2
1460  *  D16MIN XRa, XRb, XRc              Q8ABD XRa, XRb, XRc
1461  *  D16SLT XRa, XRb, XRc              Q8SAD XRa, XRb, XRc, XRd
1462  *  D16MOVZ XRa, XRb, XRc             Q8AVG XRa, XRb, XRc
1463  *  D16MOVN XRa, XRb, XRc             Q8AVGR XRa, XRb, XRc
1464  *  Q8MAX XRa, XRb, XRc               D8SUM XRa, XRb, XRc, XRd
1465  *  Q8MIN XRa, XRb, XRc               D8SUMC XRa, XRb, XRc, XRd
1466  *  Q8SLT XRa, XRb, XRc
1467  *  Q8SLTU XRa, XRb, XRc
1468  *  Q8MOVZ XRa, XRb, XRc             Shift instructions
1469  *  Q8MOVN XRa, XRb, XRc             ------------------
1470  *
1471  *                                    D32SLL XRa, XRb, XRc, XRd, sft4
1472  * Bitwise instructions               D32SLR XRa, XRb, XRc, XRd, sft4
1473  * --------------------               D32SAR XRa, XRb, XRc, XRd, sft4
1474  *                                    D32SARL XRa, XRb, XRc, sft4
1475  *  S32NOR XRa, XRb, XRc              D32SLLV XRa, XRb, Rb
1476  *  S32AND XRa, XRb, XRc              D32SLRV XRa, XRb, Rb
1477  *  S32XOR XRa, XRb, XRc              D32SARV XRa, XRb, Rb
1478  *  S32OR XRa, XRb, XRc               D32SARW XRa, XRb, XRc, Rb
1479  *                                    Q16SLL XRa, XRb, XRc, XRd, sft4
1480  *                                    Q16SLR XRa, XRb, XRc, XRd, sft4
1481  * Miscelaneous instructions          Q16SAR XRa, XRb, XRc, XRd, sft4
1482  * -------------------------          Q16SLLV XRa, XRb, Rb
1483  *                                    Q16SLRV XRa, XRb, Rb
1484  *  S32SFL XRa, XRb, XRc, XRd, optn2  Q16SARV XRa, XRb, Rb
1485  *  S32ALN XRa, XRb, XRc, Rb
1486  *  S32ALNI XRa, XRb, XRc, s3
1487  *  S32LUI XRa, s8, optn3            Move instructions
1488  *  S32EXTR XRa, XRb, Rb, bits5      -----------------
1489  *  S32EXTRV XRa, XRb, Rs, Rt
1490  *  Q16SCOP XRa, XRb, XRc, XRd        S32M2I XRa, Rb
1491  *  Q16SAT XRa, XRb, XRc              S32I2M XRa, Rb
1492  *
1493  *
1494  *              bits
1495  *             05..00
1496  *
1497  *          â”Œâ”€ 000000 â”€ OPC_MXU_S32MADD
1498  *          â”œâ”€ 000001 â”€ OPC_MXU_S32MADDU
1499  *          â”œâ”€ 000010 â”€ <not assigned>
1500  *          â”‚                               20..18
1501  *          â”œâ”€ 000011 â”€ OPC_MXU__POOL00 â”€â”¬â”€ 000 â”€ OPC_MXU_S32MAX
1502  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_S32MIN
1503  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_D16MAX
1504  *          â”‚                            â”œâ”€ 011 â”€ OPC_MXU_D16MIN
1505  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_Q8MAX
1506  *          â”‚                            â”œâ”€ 101 â”€ OPC_MXU_Q8MIN
1507  *          â”‚                            â”œâ”€ 110 â”€ OPC_MXU_Q8SLT
1508  *          â”‚                            â””─ 111 â”€ OPC_MXU_Q8SLTU
1509  *          â”œâ”€ 000100 â”€ OPC_MXU_S32MSUB
1510  *          â”œâ”€ 000101 â”€ OPC_MXU_S32MSUBU    20..18
1511  *          â”œâ”€ 000110 â”€ OPC_MXU__POOL01 â”€â”¬â”€ 000 â”€ OPC_MXU_S32SLT
1512  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_D16SLT
1513  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_D16AVG
1514  *          â”‚                            â”œâ”€ 011 â”€ OPC_MXU_D16AVGR
1515  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_Q8AVG
1516  *          â”‚                            â”œâ”€ 101 â”€ OPC_MXU_Q8AVGR
1517  *          â”‚                            â””─ 111 â”€ OPC_MXU_Q8ADD
1518  *          â”‚
1519  *          â”‚                               20..18
1520  *          â”œâ”€ 000111 â”€ OPC_MXU__POOL02 â”€â”¬â”€ 000 â”€ OPC_MXU_S32CPS
1521  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_D16CPS
1522  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_Q8ABD
1523  *          â”‚                            â””─ 110 â”€ OPC_MXU_Q16SAT
1524  *          â”œâ”€ 001000 â”€ OPC_MXU_D16MUL
1525  *          â”‚                               25..24
1526  *          â”œâ”€ 001001 â”€ OPC_MXU__POOL03 â”€â”¬â”€ 00 â”€ OPC_MXU_D16MULF
1527  *          â”‚                            â””─ 01 â”€ OPC_MXU_D16MULE
1528  *          â”œâ”€ 001010 â”€ OPC_MXU_D16MAC
1529  *          â”œâ”€ 001011 â”€ OPC_MXU_D16MACF
1530  *          â”œâ”€ 001100 â”€ OPC_MXU_D16MADL
1531  *          â”‚                               25..24
1532  *          â”œâ”€ 001101 â”€ OPC_MXU__POOL04 â”€â”¬â”€ 00 â”€ OPC_MXU_S16MAD
1533  *          â”‚                            â””─ 01 â”€ OPC_MXU_S16MAD_1
1534  *          â”œâ”€ 001110 â”€ OPC_MXU_Q16ADD
1535  *          â”œâ”€ 001111 â”€ OPC_MXU_D16MACE
1536  *          â”‚                               23
1537  *          â”œâ”€ 010000 â”€ OPC_MXU__POOL05 â”€â”¬â”€ 0 â”€ OPC_MXU_S32LDD
1538  *          â”‚                            â””─ 1 â”€ OPC_MXU_S32LDDR
1539  *          â”‚
1540  *          â”‚                               23
1541  *          â”œâ”€ 010001 â”€ OPC_MXU__POOL06 â”€â”¬â”€ 0 â”€ OPC_MXU_S32STD
1542  *          â”‚                            â””─ 1 â”€ OPC_MXU_S32STDR
1543  *          â”‚
1544  *          â”‚                               13..10
1545  *          â”œâ”€ 010010 â”€ OPC_MXU__POOL07 â”€â”¬â”€ 0000 â”€ OPC_MXU_S32LDDV
1546  *          â”‚                            â””─ 0001 â”€ OPC_MXU_S32LDDVR
1547  *          â”‚
1548  *          â”‚                               13..10
1549  *          â”œâ”€ 010011 â”€ OPC_MXU__POOL08 â”€â”¬â”€ 0000 â”€ OPC_MXU_S32STDV
1550  *          â”‚                            â””─ 0001 â”€ OPC_MXU_S32STDVR
1551  *          â”‚
1552  *          â”‚                               23
1553  *          â”œâ”€ 010100 â”€ OPC_MXU__POOL09 â”€â”¬â”€ 0 â”€ OPC_MXU_S32LDI
1554  *          â”‚                            â””─ 1 â”€ OPC_MXU_S32LDIR
1555  *          â”‚
1556  *          â”‚                               23
1557  *          â”œâ”€ 010101 â”€ OPC_MXU__POOL10 â”€â”¬â”€ 0 â”€ OPC_MXU_S32SDI
1558  *          â”‚                            â””─ 1 â”€ OPC_MXU_S32SDIR
1559  *          â”‚
1560  *          â”‚                               13..10
1561  *          â”œâ”€ 010110 â”€ OPC_MXU__POOL11 â”€â”¬â”€ 0000 â”€ OPC_MXU_S32LDIV
1562  *          â”‚                            â””─ 0001 â”€ OPC_MXU_S32LDIVR
1563  *          â”‚
1564  *          â”‚                               13..10
1565  *          â”œâ”€ 010111 â”€ OPC_MXU__POOL12 â”€â”¬â”€ 0000 â”€ OPC_MXU_S32SDIV
1566  *          â”‚                            â””─ 0001 â”€ OPC_MXU_S32SDIVR
1567  *          â”œâ”€ 011000 â”€ OPC_MXU_D32ADD
1568  *          â”‚                               23..22
1569  *   MXU    â”œâ”€ 011001 â”€ OPC_MXU__POOL13 â”€â”¬â”€ 00 â”€ OPC_MXU_D32ACC
1570  * opcodes â”€â”¤                            â”œâ”€ 01 â”€ OPC_MXU_D32ACCM
1571  *          â”‚                            â””─ 10 â”€ OPC_MXU_D32ASUM
1572  *          â”œâ”€ 011010 â”€ <not assigned>
1573  *          â”‚                               23..22
1574  *          â”œâ”€ 011011 â”€ OPC_MXU__POOL14 â”€â”¬â”€ 00 â”€ OPC_MXU_Q16ACC
1575  *          â”‚                            â”œâ”€ 01 â”€ OPC_MXU_Q16ACCM
1576  *          â”‚                            â””─ 10 â”€ OPC_MXU_Q16ASUM
1577  *          â”‚
1578  *          â”‚                               23..22
1579  *          â”œâ”€ 011100 â”€ OPC_MXU__POOL15 â”€â”¬â”€ 00 â”€ OPC_MXU_Q8ADDE
1580  *          â”‚                            â”œâ”€ 01 â”€ OPC_MXU_D8SUM
1581  *          â”œâ”€ 011101 â”€ OPC_MXU_Q8ACCE   â””─ 10 â”€ OPC_MXU_D8SUMC
1582  *          â”œâ”€ 011110 â”€ <not assigned>
1583  *          â”œâ”€ 011111 â”€ <not assigned>
1584  *          â”œâ”€ 100000 â”€ <not assigned>
1585  *          â”œâ”€ 100001 â”€ <not assigned>
1586  *          â”œâ”€ 100010 â”€ OPC_MXU_S8LDD
1587  *          â”œâ”€ 100011 â”€ OPC_MXU_S8STD
1588  *          â”œâ”€ 100100 â”€ OPC_MXU_S8LDI
1589  *          â”œâ”€ 100101 â”€ OPC_MXU_S8SDI
1590  *          â”‚                               15..14
1591  *          â”œâ”€ 100110 â”€ OPC_MXU__POOL16 â”€â”¬â”€ 00 â”€ OPC_MXU_S32MUL
1592  *          â”‚                            â”œâ”€ 00 â”€ OPC_MXU_S32MULU
1593  *          â”‚                            â”œâ”€ 00 â”€ OPC_MXU_S32EXTR
1594  *          â”‚                            â””─ 00 â”€ OPC_MXU_S32EXTRV
1595  *          â”‚
1596  *          â”‚                               20..18
1597  *          â”œâ”€ 100111 â”€ OPC_MXU__POOL17 â”€â”¬â”€ 000 â”€ OPC_MXU_D32SARW
1598  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_S32ALN
1599  *          â”œâ”€ 101000 â”€ OPC_MXU_LXB      â”œâ”€ 010 â”€ OPC_MXU_S32ALNI
1600  *          â”œâ”€ 101001 â”€ <not assigned>   â”œâ”€ 011 â”€ OPC_MXU_S32NOR
1601  *          â”œâ”€ 101010 â”€ OPC_MXU_S16LDD   â”œâ”€ 100 â”€ OPC_MXU_S32AND
1602  *          â”œâ”€ 101011 â”€ OPC_MXU_S16STD   â”œâ”€ 101 â”€ OPC_MXU_S32OR
1603  *          â”œâ”€ 101100 â”€ OPC_MXU_S16LDI   â”œâ”€ 110 â”€ OPC_MXU_S32XOR
1604  *          â”œâ”€ 101101 â”€ OPC_MXU_S16SDI   â””─ 111 â”€ OPC_MXU_S32LUI
1605  *          â”œâ”€ 101000 â”€ <not assigned>
1606  *          â”œâ”€ 101001 â”€ <not assigned>
1607  *          â”œâ”€ 101010 â”€ <not assigned>
1608  *          â”œâ”€ 101011 â”€ <not assigned>
1609  *          â”œâ”€ 101100 â”€ <not assigned>
1610  *          â”œâ”€ 101101 â”€ <not assigned>
1611  *          â”œâ”€ 101110 â”€ OPC_MXU_S32M2I
1612  *          â”œâ”€ 101111 â”€ OPC_MXU_S32I2M
1613  *          â”œâ”€ 110000 â”€ OPC_MXU_D32SLL
1614  *          â”œâ”€ 110001 â”€ OPC_MXU_D32SLR
1615  *          â”œâ”€ 110010 â”€ OPC_MXU_D32SARL
1616  *          â”œâ”€ 110011 â”€ OPC_MXU_D32SAR
1617  *          â”œâ”€ 110100 â”€ OPC_MXU_Q16SLL
1618  *          â”œâ”€ 110101 â”€ OPC_MXU_Q16SLR      20..18
1619  *          â”œâ”€ 110110 â”€ OPC_MXU__POOL18 â”€â”¬â”€ 000 â”€ OPC_MXU_D32SLLV
1620  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_D32SLRV
1621  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_D32SARV
1622  *          â”‚                            â”œâ”€ 011 â”€ OPC_MXU_Q16SLLV
1623  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_Q16SLRV
1624  *          â”‚                            â””─ 101 â”€ OPC_MXU_Q16SARV
1625  *          â”œâ”€ 110111 â”€ OPC_MXU_Q16SAR
1626  *          â”‚                               23..22
1627  *          â”œâ”€ 111000 â”€ OPC_MXU__POOL19 â”€â”¬â”€ 00 â”€ OPC_MXU_Q8MUL
1628  *          â”‚                            â””─ 01 â”€ OPC_MXU_Q8MULSU
1629  *          â”‚
1630  *          â”‚                               20..18
1631  *          â”œâ”€ 111001 â”€ OPC_MXU__POOL20 â”€â”¬â”€ 000 â”€ OPC_MXU_Q8MOVZ
1632  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_Q8MOVN
1633  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_D16MOVZ
1634  *          â”‚                            â”œâ”€ 011 â”€ OPC_MXU_D16MOVN
1635  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_S32MOVZ
1636  *          â”‚                            â””─ 101 â”€ OPC_MXU_S32MOV
1637  *          â”‚
1638  *          â”‚                               23..22
1639  *          â”œâ”€ 111010 â”€ OPC_MXU__POOL21 â”€â”¬â”€ 00 â”€ OPC_MXU_Q8MAC
1640  *          â”‚                            â””─ 10 â”€ OPC_MXU_Q8MACSU
1641  *          â”œâ”€ 111011 â”€ OPC_MXU_Q16SCOP
1642  *          â”œâ”€ 111100 â”€ OPC_MXU_Q8MADL
1643  *          â”œâ”€ 111101 â”€ OPC_MXU_S32SFL
1644  *          â”œâ”€ 111110 â”€ OPC_MXU_Q8SAD
1645  *          â””─ 111111 â”€ <not assigned>
1646  *
1647  *
1648  *   Compiled after:
1649  *
1650  *   "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1651  *   Programming Manual", Ingenic Semiconductor Co, Ltd., 2017
1652  */
1653
1654 enum {
1655     OPC_MXU_S32MADD  = 0x00,
1656     OPC_MXU_S32MADDU = 0x01,
1657     /* not assigned 0x02 */
1658     OPC_MXU__POOL00  = 0x03,
1659     OPC_MXU_S32MSUB  = 0x04,
1660     OPC_MXU_S32MSUBU = 0x05,
1661     OPC_MXU__POOL01  = 0x06,
1662     OPC_MXU__POOL02  = 0x07,
1663     OPC_MXU_D16MUL   = 0x08,
1664     OPC_MXU__POOL03  = 0x09,
1665     OPC_MXU_D16MAC   = 0x0A,
1666     OPC_MXU_D16MACF  = 0x0B,
1667     OPC_MXU_D16MADL  = 0x0C,
1668     OPC_MXU__POOL04  = 0x0D,
1669     OPC_MXU_Q16ADD   = 0x0E,
1670     OPC_MXU_D16MACE  = 0x0F,
1671     OPC_MXU__POOL05  = 0x10,
1672     OPC_MXU__POOL06  = 0x11,
1673     OPC_MXU__POOL07  = 0x12,
1674     OPC_MXU__POOL08  = 0x13,
1675     OPC_MXU__POOL09  = 0x14,
1676     OPC_MXU__POOL10  = 0x15,
1677     OPC_MXU__POOL11  = 0x16,
1678     OPC_MXU__POOL12  = 0x17,
1679     OPC_MXU_D32ADD   = 0x18,
1680     OPC_MXU__POOL13  = 0x19,
1681     /* not assigned 0x1A */
1682     OPC_MXU__POOL14  = 0x1B,
1683     OPC_MXU__POOL15  = 0x1C,
1684     OPC_MXU_Q8ACCE   = 0x1D,
1685     /* not assigned 0x1E */
1686     /* not assigned 0x1F */
1687     /* not assigned 0x20 */
1688     /* not assigned 0x21 */
1689     OPC_MXU_S8LDD    = 0x22,
1690     OPC_MXU_S8STD    = 0x23,
1691     OPC_MXU_S8LDI    = 0x24,
1692     OPC_MXU_S8SDI    = 0x25,
1693     OPC_MXU__POOL16  = 0x26,
1694     OPC_MXU__POOL17  = 0x27,
1695     OPC_MXU_LXB      = 0x28,
1696     /* not assigned 0x29 */
1697     OPC_MXU_S16LDD   = 0x2A,
1698     OPC_MXU_S16STD   = 0x2B,
1699     OPC_MXU_S16LDI   = 0x2C,
1700     OPC_MXU_S16SDI   = 0x2D,
1701     OPC_MXU_S32M2I   = 0x2E,
1702     OPC_MXU_S32I2M   = 0x2F,
1703     OPC_MXU_D32SLL   = 0x30,
1704     OPC_MXU_D32SLR   = 0x31,
1705     OPC_MXU_D32SARL  = 0x32,
1706     OPC_MXU_D32SAR   = 0x33,
1707     OPC_MXU_Q16SLL   = 0x34,
1708     OPC_MXU_Q16SLR   = 0x35,
1709     OPC_MXU__POOL18  = 0x36,
1710     OPC_MXU_Q16SAR   = 0x37,
1711     OPC_MXU__POOL19  = 0x38,
1712     OPC_MXU__POOL20  = 0x39,
1713     OPC_MXU__POOL21  = 0x3A,
1714     OPC_MXU_Q16SCOP  = 0x3B,
1715     OPC_MXU_Q8MADL   = 0x3C,
1716     OPC_MXU_S32SFL   = 0x3D,
1717     OPC_MXU_Q8SAD    = 0x3E,
1718     /* not assigned 0x3F */
1719 };
1720
1721
1722 /*
1723  * MXU pool 00
1724  */
1725 enum {
1726     OPC_MXU_S32MAX   = 0x00,
1727     OPC_MXU_S32MIN   = 0x01,
1728     OPC_MXU_D16MAX   = 0x02,
1729     OPC_MXU_D16MIN   = 0x03,
1730     OPC_MXU_Q8MAX    = 0x04,
1731     OPC_MXU_Q8MIN    = 0x05,
1732     OPC_MXU_Q8SLT    = 0x06,
1733     OPC_MXU_Q8SLTU   = 0x07,
1734 };
1735
1736 /*
1737  * MXU pool 01
1738  */
1739 enum {
1740     OPC_MXU_S32SLT   = 0x00,
1741     OPC_MXU_D16SLT   = 0x01,
1742     OPC_MXU_D16AVG   = 0x02,
1743     OPC_MXU_D16AVGR  = 0x03,
1744     OPC_MXU_Q8AVG    = 0x04,
1745     OPC_MXU_Q8AVGR   = 0x05,
1746     OPC_MXU_Q8ADD    = 0x07,
1747 };
1748
1749 /*
1750  * MXU pool 02
1751  */
1752 enum {
1753     OPC_MXU_S32CPS   = 0x00,
1754     OPC_MXU_D16CPS   = 0x02,
1755     OPC_MXU_Q8ABD    = 0x04,
1756     OPC_MXU_Q16SAT   = 0x06,
1757 };
1758
1759 /*
1760  * MXU pool 03
1761  */
1762 enum {
1763     OPC_MXU_D16MULF  = 0x00,
1764     OPC_MXU_D16MULE  = 0x01,
1765 };
1766
1767 /*
1768  * MXU pool 04
1769  */
1770 enum {
1771     OPC_MXU_S16MAD   = 0x00,
1772     OPC_MXU_S16MAD_1 = 0x01,
1773 };
1774
1775 /*
1776  * MXU pool 05
1777  */
1778 enum {
1779     OPC_MXU_S32LDD   = 0x00,
1780     OPC_MXU_S32LDDR  = 0x01,
1781 };
1782
1783 /*
1784  * MXU pool 06
1785  */
1786 enum {
1787     OPC_MXU_S32STD   = 0x00,
1788     OPC_MXU_S32STDR  = 0x01,
1789 };
1790
1791 /*
1792  * MXU pool 07
1793  */
1794 enum {
1795     OPC_MXU_S32LDDV  = 0x00,
1796     OPC_MXU_S32LDDVR = 0x01,
1797 };
1798
1799 /*
1800  * MXU pool 08
1801  */
1802 enum {
1803     OPC_MXU_S32STDV  = 0x00,
1804     OPC_MXU_S32STDVR = 0x01,
1805 };
1806
1807 /*
1808  * MXU pool 09
1809  */
1810 enum {
1811     OPC_MXU_S32LDI   = 0x00,
1812     OPC_MXU_S32LDIR  = 0x01,
1813 };
1814
1815 /*
1816  * MXU pool 10
1817  */
1818 enum {
1819     OPC_MXU_S32SDI   = 0x00,
1820     OPC_MXU_S32SDIR  = 0x01,
1821 };
1822
1823 /*
1824  * MXU pool 11
1825  */
1826 enum {
1827     OPC_MXU_S32LDIV  = 0x00,
1828     OPC_MXU_S32LDIVR = 0x01,
1829 };
1830
1831 /*
1832  * MXU pool 12
1833  */
1834 enum {
1835     OPC_MXU_S32SDIV  = 0x00,
1836     OPC_MXU_S32SDIVR = 0x01,
1837 };
1838
1839 /*
1840  * MXU pool 13
1841  */
1842 enum {
1843     OPC_MXU_D32ACC   = 0x00,
1844     OPC_MXU_D32ACCM  = 0x01,
1845     OPC_MXU_D32ASUM  = 0x02,
1846 };
1847
1848 /*
1849  * MXU pool 14
1850  */
1851 enum {
1852     OPC_MXU_Q16ACC   = 0x00,
1853     OPC_MXU_Q16ACCM  = 0x01,
1854     OPC_MXU_Q16ASUM  = 0x02,
1855 };
1856
1857 /*
1858  * MXU pool 15
1859  */
1860 enum {
1861     OPC_MXU_Q8ADDE   = 0x00,
1862     OPC_MXU_D8SUM    = 0x01,
1863     OPC_MXU_D8SUMC   = 0x02,
1864 };
1865
1866 /*
1867  * MXU pool 16
1868  */
1869 enum {
1870     OPC_MXU_S32MUL   = 0x00,
1871     OPC_MXU_S32MULU  = 0x01,
1872     OPC_MXU_S32EXTR  = 0x02,
1873     OPC_MXU_S32EXTRV = 0x03,
1874 };
1875
1876 /*
1877  * MXU pool 17
1878  */
1879 enum {
1880     OPC_MXU_D32SARW  = 0x00,
1881     OPC_MXU_S32ALN   = 0x01,
1882     OPC_MXU_S32ALNI  = 0x02,
1883     OPC_MXU_S32NOR   = 0x03,
1884     OPC_MXU_S32AND   = 0x04,
1885     OPC_MXU_S32OR    = 0x05,
1886     OPC_MXU_S32XOR   = 0x06,
1887     OPC_MXU_S32LUI   = 0x07,
1888 };
1889
1890 /*
1891  * MXU pool 18
1892  */
1893 enum {
1894     OPC_MXU_D32SLLV  = 0x00,
1895     OPC_MXU_D32SLRV  = 0x01,
1896     OPC_MXU_D32SARV  = 0x03,
1897     OPC_MXU_Q16SLLV  = 0x04,
1898     OPC_MXU_Q16SLRV  = 0x05,
1899     OPC_MXU_Q16SARV  = 0x07,
1900 };
1901
1902 /*
1903  * MXU pool 19
1904  */
1905 enum {
1906     OPC_MXU_Q8MUL    = 0x00,
1907     OPC_MXU_Q8MULSU  = 0x01,
1908 };
1909
1910 /*
1911  * MXU pool 20
1912  */
1913 enum {
1914     OPC_MXU_Q8MOVZ   = 0x00,
1915     OPC_MXU_Q8MOVN   = 0x01,
1916     OPC_MXU_D16MOVZ  = 0x02,
1917     OPC_MXU_D16MOVN  = 0x03,
1918     OPC_MXU_S32MOVZ  = 0x04,
1919     OPC_MXU_S32MOVN  = 0x05,
1920 };
1921
1922 /*
1923  * MXU pool 21
1924  */
1925 enum {
1926     OPC_MXU_Q8MAC    = 0x00,
1927     OPC_MXU_Q8MACSU  = 0x01,
1928 };
1929
1930
1931 /* global register indices */
1932 static TCGv cpu_gpr[32], cpu_PC;
1933 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1934 static TCGv cpu_dspctrl, btarget, bcond;
1935 static TCGv_i32 hflags;
1936 static TCGv_i32 fpu_fcr0, fpu_fcr31;
1937 static TCGv_i64 fpu_f64[32];
1938 static TCGv_i64 msa_wr_d[64];
1939
1940 #include "exec/gen-icount.h"
1941
1942 #define gen_helper_0e0i(name, arg) do {                           \
1943     TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
1944     gen_helper_##name(cpu_env, helper_tmp);                       \
1945     tcg_temp_free_i32(helper_tmp);                                \
1946     } while(0)
1947
1948 #define gen_helper_0e1i(name, arg1, arg2) do {                    \
1949     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
1950     gen_helper_##name(cpu_env, arg1, helper_tmp);                 \
1951     tcg_temp_free_i32(helper_tmp);                                \
1952     } while(0)
1953
1954 #define gen_helper_1e0i(name, ret, arg1) do {                     \
1955     TCGv_i32 helper_tmp = tcg_const_i32(arg1);                    \
1956     gen_helper_##name(ret, cpu_env, helper_tmp);                  \
1957     tcg_temp_free_i32(helper_tmp);                                \
1958     } while(0)
1959
1960 #define gen_helper_1e1i(name, ret, arg1, arg2) do {               \
1961     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
1962     gen_helper_##name(ret, cpu_env, arg1, helper_tmp);            \
1963     tcg_temp_free_i32(helper_tmp);                                \
1964     } while(0)
1965
1966 #define gen_helper_0e2i(name, arg1, arg2, arg3) do {              \
1967     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
1968     gen_helper_##name(cpu_env, arg1, arg2, helper_tmp);           \
1969     tcg_temp_free_i32(helper_tmp);                                \
1970     } while(0)
1971
1972 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do {         \
1973     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
1974     gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp);      \
1975     tcg_temp_free_i32(helper_tmp);                                \
1976     } while(0)
1977
1978 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do {        \
1979     TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
1980     gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp);     \
1981     tcg_temp_free_i32(helper_tmp);                                \
1982     } while(0)
1983
1984 typedef struct DisasContext {
1985     DisasContextBase base;
1986     target_ulong saved_pc;
1987     target_ulong page_start;
1988     uint32_t opcode;
1989     uint64_t insn_flags;
1990     int32_t CP0_Config1;
1991     int32_t CP0_Config2;
1992     int32_t CP0_Config3;
1993     int32_t CP0_Config5;
1994     /* Routine used to access memory */
1995     int mem_idx;
1996     TCGMemOp default_tcg_memop_mask;
1997     uint32_t hflags, saved_hflags;
1998     target_ulong btarget;
1999     bool ulri;
2000     int kscrexist;
2001     bool rxi;
2002     int ie;
2003     bool bi;
2004     bool bp;
2005     uint64_t PAMask;
2006     bool mvh;
2007     bool eva;
2008     bool sc;
2009     int CP0_LLAddr_shift;
2010     bool ps;
2011     bool vp;
2012     bool cmgcr;
2013     bool mrp;
2014     bool nan2008;
2015     bool abs2008;
2016 } DisasContext;
2017
2018 #define DISAS_STOP       DISAS_TARGET_0
2019 #define DISAS_EXIT       DISAS_TARGET_1
2020
2021 static const char * const regnames[] = {
2022     "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2023     "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2024     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2025     "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2026 };
2027
2028 static const char * const regnames_HI[] = {
2029     "HI0", "HI1", "HI2", "HI3",
2030 };
2031
2032 static const char * const regnames_LO[] = {
2033     "LO0", "LO1", "LO2", "LO3",
2034 };
2035
2036 static const char * const fregnames[] = {
2037     "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
2038     "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
2039     "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2040     "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2041 };
2042
2043 static const char * const msaregnames[] = {
2044     "w0.d0",  "w0.d1",  "w1.d0",  "w1.d1",
2045     "w2.d0",  "w2.d1",  "w3.d0",  "w3.d1",
2046     "w4.d0",  "w4.d1",  "w5.d0",  "w5.d1",
2047     "w6.d0",  "w6.d1",  "w7.d0",  "w7.d1",
2048     "w8.d0",  "w8.d1",  "w9.d0",  "w9.d1",
2049     "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2050     "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2051     "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2052     "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2053     "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2054     "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2055     "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2056     "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2057     "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2058     "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2059     "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2060 };
2061
2062 #define LOG_DISAS(...)                                                        \
2063     do {                                                                      \
2064         if (MIPS_DEBUG_DISAS) {                                               \
2065             qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
2066         }                                                                     \
2067     } while (0)
2068
2069 #define MIPS_INVAL(op)                                                        \
2070     do {                                                                      \
2071         if (MIPS_DEBUG_DISAS) {                                               \
2072             qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
2073                           TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2074                           ctx->base.pc_next, ctx->opcode, op,                 \
2075                           ctx->opcode >> 26, ctx->opcode & 0x3F,              \
2076                           ((ctx->opcode >> 16) & 0x1F));                      \
2077         }                                                                     \
2078     } while (0)
2079
2080 /* General purpose registers moves. */
2081 static inline void gen_load_gpr (TCGv t, int reg)
2082 {
2083     if (reg == 0)
2084         tcg_gen_movi_tl(t, 0);
2085     else
2086         tcg_gen_mov_tl(t, cpu_gpr[reg]);
2087 }
2088
2089 static inline void gen_store_gpr (TCGv t, int reg)
2090 {
2091     if (reg != 0)
2092         tcg_gen_mov_tl(cpu_gpr[reg], t);
2093 }
2094
2095 /* Moves to/from shadow registers. */
2096 static inline void gen_load_srsgpr (int from, int to)
2097 {
2098     TCGv t0 = tcg_temp_new();
2099
2100     if (from == 0)
2101         tcg_gen_movi_tl(t0, 0);
2102     else {
2103         TCGv_i32 t2 = tcg_temp_new_i32();
2104         TCGv_ptr addr = tcg_temp_new_ptr();
2105
2106         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2107         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2108         tcg_gen_andi_i32(t2, t2, 0xf);
2109         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2110         tcg_gen_ext_i32_ptr(addr, t2);
2111         tcg_gen_add_ptr(addr, cpu_env, addr);
2112
2113         tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2114         tcg_temp_free_ptr(addr);
2115         tcg_temp_free_i32(t2);
2116     }
2117     gen_store_gpr(t0, to);
2118     tcg_temp_free(t0);
2119 }
2120
2121 static inline void gen_store_srsgpr (int from, int to)
2122 {
2123     if (to != 0) {
2124         TCGv t0 = tcg_temp_new();
2125         TCGv_i32 t2 = tcg_temp_new_i32();
2126         TCGv_ptr addr = tcg_temp_new_ptr();
2127
2128         gen_load_gpr(t0, from);
2129         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2130         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2131         tcg_gen_andi_i32(t2, t2, 0xf);
2132         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2133         tcg_gen_ext_i32_ptr(addr, t2);
2134         tcg_gen_add_ptr(addr, cpu_env, addr);
2135
2136         tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2137         tcg_temp_free_ptr(addr);
2138         tcg_temp_free_i32(t2);
2139         tcg_temp_free(t0);
2140     }
2141 }
2142
2143 /* Tests */
2144 static inline void gen_save_pc(target_ulong pc)
2145 {
2146     tcg_gen_movi_tl(cpu_PC, pc);
2147 }
2148
2149 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2150 {
2151     LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2152     if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2153         gen_save_pc(ctx->base.pc_next);
2154         ctx->saved_pc = ctx->base.pc_next;
2155     }
2156     if (ctx->hflags != ctx->saved_hflags) {
2157         tcg_gen_movi_i32(hflags, ctx->hflags);
2158         ctx->saved_hflags = ctx->hflags;
2159         switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2160         case MIPS_HFLAG_BR:
2161             break;
2162         case MIPS_HFLAG_BC:
2163         case MIPS_HFLAG_BL:
2164         case MIPS_HFLAG_B:
2165             tcg_gen_movi_tl(btarget, ctx->btarget);
2166             break;
2167         }
2168     }
2169 }
2170
2171 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2172 {
2173     ctx->saved_hflags = ctx->hflags;
2174     switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2175     case MIPS_HFLAG_BR:
2176         break;
2177     case MIPS_HFLAG_BC:
2178     case MIPS_HFLAG_BL:
2179     case MIPS_HFLAG_B:
2180         ctx->btarget = env->btarget;
2181         break;
2182     }
2183 }
2184
2185 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2186 {
2187     TCGv_i32 texcp = tcg_const_i32(excp);
2188     TCGv_i32 terr = tcg_const_i32(err);
2189     save_cpu_state(ctx, 1);
2190     gen_helper_raise_exception_err(cpu_env, texcp, terr);
2191     tcg_temp_free_i32(terr);
2192     tcg_temp_free_i32(texcp);
2193     ctx->base.is_jmp = DISAS_NORETURN;
2194 }
2195
2196 static inline void generate_exception(DisasContext *ctx, int excp)
2197 {
2198     gen_helper_0e0i(raise_exception, excp);
2199 }
2200
2201 static inline void generate_exception_end(DisasContext *ctx, int excp)
2202 {
2203     generate_exception_err(ctx, excp, 0);
2204 }
2205
2206 /* Floating point register moves. */
2207 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2208 {
2209     if (ctx->hflags & MIPS_HFLAG_FRE) {
2210         generate_exception(ctx, EXCP_RI);
2211     }
2212     tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2213 }
2214
2215 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2216 {
2217     TCGv_i64 t64;
2218     if (ctx->hflags & MIPS_HFLAG_FRE) {
2219         generate_exception(ctx, EXCP_RI);
2220     }
2221     t64 = tcg_temp_new_i64();
2222     tcg_gen_extu_i32_i64(t64, t);
2223     tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2224     tcg_temp_free_i64(t64);
2225 }
2226
2227 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2228 {
2229     if (ctx->hflags & MIPS_HFLAG_F64) {
2230         tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2231     } else {
2232         gen_load_fpr32(ctx, t, reg | 1);
2233     }
2234 }
2235
2236 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2237 {
2238     if (ctx->hflags & MIPS_HFLAG_F64) {
2239         TCGv_i64 t64 = tcg_temp_new_i64();
2240         tcg_gen_extu_i32_i64(t64, t);
2241         tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2242         tcg_temp_free_i64(t64);
2243     } else {
2244         gen_store_fpr32(ctx, t, reg | 1);
2245     }
2246 }
2247
2248 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2249 {
2250     if (ctx->hflags & MIPS_HFLAG_F64) {
2251         tcg_gen_mov_i64(t, fpu_f64[reg]);
2252     } else {
2253         tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2254     }
2255 }
2256
2257 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2258 {
2259     if (ctx->hflags & MIPS_HFLAG_F64) {
2260         tcg_gen_mov_i64(fpu_f64[reg], t);
2261     } else {
2262         TCGv_i64 t0;
2263         tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2264         t0 = tcg_temp_new_i64();
2265         tcg_gen_shri_i64(t0, t, 32);
2266         tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2267         tcg_temp_free_i64(t0);
2268     }
2269 }
2270
2271 static inline int get_fp_bit (int cc)
2272 {
2273     if (cc)
2274         return 24 + cc;
2275     else
2276         return 23;
2277 }
2278
2279 /* Addresses computation */
2280 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
2281 {
2282     tcg_gen_add_tl(ret, arg0, arg1);
2283
2284 #if defined(TARGET_MIPS64)
2285     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2286         tcg_gen_ext32s_i64(ret, ret);
2287     }
2288 #endif
2289 }
2290
2291 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2292                                     target_long ofs)
2293 {
2294     tcg_gen_addi_tl(ret, base, ofs);
2295
2296 #if defined(TARGET_MIPS64)
2297     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2298         tcg_gen_ext32s_i64(ret, ret);
2299     }
2300 #endif
2301 }
2302
2303 /* Addresses computation (translation time) */
2304 static target_long addr_add(DisasContext *ctx, target_long base,
2305                             target_long offset)
2306 {
2307     target_long sum = base + offset;
2308
2309 #if defined(TARGET_MIPS64)
2310     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2311         sum = (int32_t)sum;
2312     }
2313 #endif
2314     return sum;
2315 }
2316
2317 /* Sign-extract the low 32-bits to a target_long.  */
2318 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2319 {
2320 #if defined(TARGET_MIPS64)
2321     tcg_gen_ext32s_i64(ret, arg);
2322 #else
2323     tcg_gen_extrl_i64_i32(ret, arg);
2324 #endif
2325 }
2326
2327 /* Sign-extract the high 32-bits to a target_long.  */
2328 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2329 {
2330 #if defined(TARGET_MIPS64)
2331     tcg_gen_sari_i64(ret, arg, 32);
2332 #else
2333     tcg_gen_extrh_i64_i32(ret, arg);
2334 #endif
2335 }
2336
2337 static inline void check_cp0_enabled(DisasContext *ctx)
2338 {
2339     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
2340         generate_exception_err(ctx, EXCP_CpU, 0);
2341 }
2342
2343 static inline void check_cp1_enabled(DisasContext *ctx)
2344 {
2345     if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
2346         generate_exception_err(ctx, EXCP_CpU, 1);
2347 }
2348
2349 /* Verify that the processor is running with COP1X instructions enabled.
2350    This is associated with the nabla symbol in the MIPS32 and MIPS64
2351    opcode tables.  */
2352
2353 static inline void check_cop1x(DisasContext *ctx)
2354 {
2355     if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
2356         generate_exception_end(ctx, EXCP_RI);
2357 }
2358
2359 /* Verify that the processor is running with 64-bit floating-point
2360    operations enabled.  */
2361
2362 static inline void check_cp1_64bitmode(DisasContext *ctx)
2363 {
2364     if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
2365         generate_exception_end(ctx, EXCP_RI);
2366 }
2367
2368 /*
2369  * Verify if floating point register is valid; an operation is not defined
2370  * if bit 0 of any register specification is set and the FR bit in the
2371  * Status register equals zero, since the register numbers specify an
2372  * even-odd pair of adjacent coprocessor general registers. When the FR bit
2373  * in the Status register equals one, both even and odd register numbers
2374  * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2375  *
2376  * Multiple 64 bit wide registers can be checked by calling
2377  * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2378  */
2379 static inline void check_cp1_registers(DisasContext *ctx, int regs)
2380 {
2381     if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
2382         generate_exception_end(ctx, EXCP_RI);
2383 }
2384
2385 /* Verify that the processor is running with DSP instructions enabled.
2386    This is enabled by CP0 Status register MX(24) bit.
2387  */
2388
2389 static inline void check_dsp(DisasContext *ctx)
2390 {
2391     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2392         if (ctx->insn_flags & ASE_DSP) {
2393             generate_exception_end(ctx, EXCP_DSPDIS);
2394         } else {
2395             generate_exception_end(ctx, EXCP_RI);
2396         }
2397     }
2398 }
2399
2400 static inline void check_dsp_r2(DisasContext *ctx)
2401 {
2402     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2403         if (ctx->insn_flags & ASE_DSP) {
2404             generate_exception_end(ctx, EXCP_DSPDIS);
2405         } else {
2406             generate_exception_end(ctx, EXCP_RI);
2407         }
2408     }
2409 }
2410
2411 static inline void check_dsp_r3(DisasContext *ctx)
2412 {
2413     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
2414         if (ctx->insn_flags & ASE_DSP) {
2415             generate_exception_end(ctx, EXCP_DSPDIS);
2416         } else {
2417             generate_exception_end(ctx, EXCP_RI);
2418         }
2419     }
2420 }
2421
2422 /* This code generates a "reserved instruction" exception if the
2423    CPU does not support the instruction set corresponding to flags. */
2424 static inline void check_insn(DisasContext *ctx, uint64_t flags)
2425 {
2426     if (unlikely(!(ctx->insn_flags & flags))) {
2427         generate_exception_end(ctx, EXCP_RI);
2428     }
2429 }
2430
2431 /* This code generates a "reserved instruction" exception if the
2432    CPU has corresponding flag set which indicates that the instruction
2433    has been removed. */
2434 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
2435 {
2436     if (unlikely(ctx->insn_flags & flags)) {
2437         generate_exception_end(ctx, EXCP_RI);
2438     }
2439 }
2440
2441 /* This code generates a "reserved instruction" exception if the
2442    CPU does not support 64-bit paired-single (PS) floating point data type */
2443 static inline void check_ps(DisasContext *ctx)
2444 {
2445     if (unlikely(!ctx->ps)) {
2446         generate_exception(ctx, EXCP_RI);
2447     }
2448     check_cp1_64bitmode(ctx);
2449 }
2450
2451 #ifdef TARGET_MIPS64
2452 /* This code generates a "reserved instruction" exception if 64-bit
2453    instructions are not enabled. */
2454 static inline void check_mips_64(DisasContext *ctx)
2455 {
2456     if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
2457         generate_exception_end(ctx, EXCP_RI);
2458 }
2459 #endif
2460
2461 #ifndef CONFIG_USER_ONLY
2462 static inline void check_mvh(DisasContext *ctx)
2463 {
2464     if (unlikely(!ctx->mvh)) {
2465         generate_exception(ctx, EXCP_RI);
2466     }
2467 }
2468 #endif
2469
2470 /*
2471  * This code generates a "reserved instruction" exception if the
2472  * Config5 XNP bit is set.
2473  */
2474 static inline void check_xnp(DisasContext *ctx)
2475 {
2476     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
2477         generate_exception_end(ctx, EXCP_RI);
2478     }
2479 }
2480
2481 #ifndef CONFIG_USER_ONLY
2482 /*
2483  * This code generates a "reserved instruction" exception if the
2484  * Config3 PW bit is NOT set.
2485  */
2486 static inline void check_pw(DisasContext *ctx)
2487 {
2488     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
2489         generate_exception_end(ctx, EXCP_RI);
2490     }
2491 }
2492 #endif
2493
2494 /*
2495  * This code generates a "reserved instruction" exception if the
2496  * Config3 MT bit is NOT set.
2497  */
2498 static inline void check_mt(DisasContext *ctx)
2499 {
2500     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2501         generate_exception_end(ctx, EXCP_RI);
2502     }
2503 }
2504
2505 #ifndef CONFIG_USER_ONLY
2506 /*
2507  * This code generates a "coprocessor unusable" exception if CP0 is not
2508  * available, and, if that is not the case, generates a "reserved instruction"
2509  * exception if the Config5 MT bit is NOT set. This is needed for availability
2510  * control of some of MT ASE instructions.
2511  */
2512 static inline void check_cp0_mt(DisasContext *ctx)
2513 {
2514     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
2515         generate_exception_err(ctx, EXCP_CpU, 0);
2516     } else {
2517         if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
2518             generate_exception_err(ctx, EXCP_RI, 0);
2519         }
2520     }
2521 }
2522 #endif
2523
2524 /*
2525  * This code generates a "reserved instruction" exception if the
2526  * Config5 NMS bit is set.
2527  */
2528 static inline void check_nms(DisasContext *ctx)
2529 {
2530     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
2531         generate_exception_end(ctx, EXCP_RI);
2532     }
2533 }
2534
2535
2536 /* Define small wrappers for gen_load_fpr* so that we have a uniform
2537    calling interface for 32 and 64-bit FPRs.  No sense in changing
2538    all callers for gen_load_fpr32 when we need the CTX parameter for
2539    this one use.  */
2540 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
2541 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
2542 #define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
2543 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
2544                                                int ft, int fs, int cc)        \
2545 {                                                                             \
2546     TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
2547     TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
2548     switch (ifmt) {                                                           \
2549     case FMT_PS:                                                              \
2550         check_ps(ctx);                                                        \
2551         break;                                                                \
2552     case FMT_D:                                                               \
2553         if (abs) {                                                            \
2554             check_cop1x(ctx);                                                 \
2555         }                                                                     \
2556         check_cp1_registers(ctx, fs | ft);                                    \
2557         break;                                                                \
2558     case FMT_S:                                                               \
2559         if (abs) {                                                            \
2560             check_cop1x(ctx);                                                 \
2561         }                                                                     \
2562         break;                                                                \
2563     }                                                                         \
2564     gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
2565     gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
2566     switch (n) {                                                              \
2567     case  0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
2568     case  1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
2569     case  2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
2570     case  3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
2571     case  4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
2572     case  5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
2573     case  6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
2574     case  7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
2575     case  8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
2576     case  9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
2577     case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
2578     case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
2579     case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
2580     case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
2581     case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
2582     case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
2583     default: abort();                                                         \
2584     }                                                                         \
2585     tcg_temp_free_i##bits (fp0);                                              \
2586     tcg_temp_free_i##bits (fp1);                                              \
2587 }
2588
2589 FOP_CONDS(, 0, d, FMT_D, 64)
2590 FOP_CONDS(abs, 1, d, FMT_D, 64)
2591 FOP_CONDS(, 0, s, FMT_S, 32)
2592 FOP_CONDS(abs, 1, s, FMT_S, 32)
2593 FOP_CONDS(, 0, ps, FMT_PS, 64)
2594 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
2595 #undef FOP_CONDS
2596
2597 #define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
2598 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n,        \
2599                                       int ft, int fs, int fd)           \
2600 {                                                                       \
2601     TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
2602     TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
2603     if (ifmt == FMT_D) {                                                \
2604         check_cp1_registers(ctx, fs | ft | fd);                         \
2605     }                                                                   \
2606     gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
2607     gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
2608     switch (n) {                                                        \
2609     case  0:                                                            \
2610         gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
2611         break;                                                          \
2612     case  1:                                                            \
2613         gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
2614         break;                                                          \
2615     case  2:                                                            \
2616         gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
2617         break;                                                          \
2618     case  3:                                                            \
2619         gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
2620         break;                                                          \
2621     case  4:                                                            \
2622         gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
2623         break;                                                          \
2624     case  5:                                                            \
2625         gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
2626         break;                                                          \
2627     case  6:                                                            \
2628         gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
2629         break;                                                          \
2630     case  7:                                                            \
2631         gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
2632         break;                                                          \
2633     case  8:                                                            \
2634         gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
2635         break;                                                          \
2636     case  9:                                                            \
2637         gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
2638         break;                                                          \
2639     case 10:                                                            \
2640         gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
2641         break;                                                          \
2642     case 11:                                                            \
2643         gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
2644         break;                                                          \
2645     case 12:                                                            \
2646         gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
2647         break;                                                          \
2648     case 13:                                                            \
2649         gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
2650         break;                                                          \
2651     case 14:                                                            \
2652         gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
2653         break;                                                          \
2654     case 15:                                                            \
2655         gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
2656         break;                                                          \
2657     case 17:                                                            \
2658         gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
2659         break;                                                          \
2660     case 18:                                                            \
2661         gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
2662         break;                                                          \
2663     case 19:                                                            \
2664         gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
2665         break;                                                          \
2666     case 25:                                                            \
2667         gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
2668         break;                                                          \
2669     case 26:                                                            \
2670         gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
2671         break;                                                          \
2672     case 27:                                                            \
2673         gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
2674         break;                                                          \
2675     default:                                                            \
2676         abort();                                                        \
2677     }                                                                   \
2678     STORE;                                                              \
2679     tcg_temp_free_i ## bits (fp0);                                      \
2680     tcg_temp_free_i ## bits (fp1);                                      \
2681 }
2682
2683 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
2684 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
2685 #undef FOP_CONDNS
2686 #undef gen_ldcmp_fpr32
2687 #undef gen_ldcmp_fpr64
2688
2689 /* load/store instructions. */
2690 #ifdef CONFIG_USER_ONLY
2691 #define OP_LD_ATOMIC(insn,fname)                                           \
2692 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
2693                                 DisasContext *ctx)                         \
2694 {                                                                          \
2695     TCGv t0 = tcg_temp_new();                                              \
2696     tcg_gen_mov_tl(t0, arg1);                                              \
2697     tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
2698     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                \
2699     tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));                \
2700     tcg_temp_free(t0);                                                     \
2701 }
2702 #else
2703 #define OP_LD_ATOMIC(insn,fname)                                           \
2704 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
2705                                 DisasContext *ctx)                         \
2706 {                                                                          \
2707     gen_helper_1e1i(insn, ret, arg1, mem_idx);                             \
2708 }
2709 #endif
2710 OP_LD_ATOMIC(ll,ld32s);
2711 #if defined(TARGET_MIPS64)
2712 OP_LD_ATOMIC(lld,ld64);
2713 #endif
2714 #undef OP_LD_ATOMIC
2715
2716 #ifdef CONFIG_USER_ONLY
2717 #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
2718 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx,   \
2719                                 DisasContext *ctx)                           \
2720 {                                                                            \
2721     TCGv t0 = tcg_temp_new();                                                \
2722     TCGLabel *l1 = gen_new_label();                                          \
2723     TCGLabel *l2 = gen_new_label();                                          \
2724                                                                              \
2725     tcg_gen_andi_tl(t0, arg2, almask);                                       \
2726     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
2727     tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));          \
2728     generate_exception(ctx, EXCP_AdES);                                      \
2729     gen_set_label(l1);                                                       \
2730     tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                  \
2731     tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
2732     tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
2733     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg));                   \
2734     tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval));              \
2735     generate_exception_end(ctx, EXCP_SC);                                    \
2736     gen_set_label(l2);                                                       \
2737     tcg_gen_movi_tl(t0, 0);                                                  \
2738     gen_store_gpr(t0, rt);                                                   \
2739     tcg_temp_free(t0);                                                       \
2740 }
2741 #else
2742 #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
2743 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx,   \
2744                                 DisasContext *ctx)                           \
2745 {                                                                            \
2746     TCGv t0 = tcg_temp_new();                                                \
2747     gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx);                          \
2748     gen_store_gpr(t0, rt);                                                   \
2749     tcg_temp_free(t0);                                                       \
2750 }
2751 #endif
2752 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
2753 #if defined(TARGET_MIPS64)
2754 OP_ST_ATOMIC(scd,st64,ld64,0x7);
2755 #endif
2756 #undef OP_ST_ATOMIC
2757
2758 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
2759                                   int base, int offset)
2760 {
2761     if (base == 0) {
2762         tcg_gen_movi_tl(addr, offset);
2763     } else if (offset == 0) {
2764         gen_load_gpr(addr, base);
2765     } else {
2766         tcg_gen_movi_tl(addr, offset);
2767         gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2768     }
2769 }
2770
2771 static target_ulong pc_relative_pc (DisasContext *ctx)
2772 {
2773     target_ulong pc = ctx->base.pc_next;
2774
2775     if (ctx->hflags & MIPS_HFLAG_BMASK) {
2776         int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2777
2778         pc -= branch_bytes;
2779     }
2780
2781     pc &= ~(target_ulong)3;
2782     return pc;
2783 }
2784
2785 /* Load */
2786 static void gen_ld(DisasContext *ctx, uint32_t opc,
2787                    int rt, int base, int offset)
2788 {
2789     TCGv t0, t1, t2;
2790     int mem_idx = ctx->mem_idx;
2791
2792     if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
2793         /* Loongson CPU uses a load to zero register for prefetch.
2794            We emulate it as a NOP. On other CPU we must perform the
2795            actual memory access. */
2796         return;
2797     }
2798
2799     t0 = tcg_temp_new();
2800     gen_base_offset_addr(ctx, t0, base, offset);
2801
2802     switch (opc) {
2803 #if defined(TARGET_MIPS64)
2804     case OPC_LWU:
2805         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
2806                            ctx->default_tcg_memop_mask);
2807         gen_store_gpr(t0, rt);
2808         break;
2809     case OPC_LD:
2810         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
2811                            ctx->default_tcg_memop_mask);
2812         gen_store_gpr(t0, rt);
2813         break;
2814     case OPC_LLD:
2815     case R6_OPC_LLD:
2816         op_ld_lld(t0, t0, mem_idx, ctx);
2817         gen_store_gpr(t0, rt);
2818         break;
2819     case OPC_LDL:
2820         t1 = tcg_temp_new();
2821         /* Do a byte access to possibly trigger a page
2822            fault with the unaligned address.  */
2823         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2824         tcg_gen_andi_tl(t1, t0, 7);
2825 #ifndef TARGET_WORDS_BIGENDIAN
2826         tcg_gen_xori_tl(t1, t1, 7);
2827 #endif
2828         tcg_gen_shli_tl(t1, t1, 3);
2829         tcg_gen_andi_tl(t0, t0, ~7);
2830         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2831         tcg_gen_shl_tl(t0, t0, t1);
2832         t2 = tcg_const_tl(-1);
2833         tcg_gen_shl_tl(t2, t2, t1);
2834         gen_load_gpr(t1, rt);
2835         tcg_gen_andc_tl(t1, t1, t2);
2836         tcg_temp_free(t2);
2837         tcg_gen_or_tl(t0, t0, t1);
2838         tcg_temp_free(t1);
2839         gen_store_gpr(t0, rt);
2840         break;
2841     case OPC_LDR:
2842         t1 = tcg_temp_new();
2843         /* Do a byte access to possibly trigger a page
2844            fault with the unaligned address.  */
2845         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2846         tcg_gen_andi_tl(t1, t0, 7);
2847 #ifdef TARGET_WORDS_BIGENDIAN
2848         tcg_gen_xori_tl(t1, t1, 7);
2849 #endif
2850         tcg_gen_shli_tl(t1, t1, 3);
2851         tcg_gen_andi_tl(t0, t0, ~7);
2852         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2853         tcg_gen_shr_tl(t0, t0, t1);
2854         tcg_gen_xori_tl(t1, t1, 63);
2855         t2 = tcg_const_tl(0xfffffffffffffffeull);
2856         tcg_gen_shl_tl(t2, t2, t1);
2857         gen_load_gpr(t1, rt);
2858         tcg_gen_and_tl(t1, t1, t2);
2859         tcg_temp_free(t2);
2860         tcg_gen_or_tl(t0, t0, t1);
2861         tcg_temp_free(t1);
2862         gen_store_gpr(t0, rt);
2863         break;
2864     case OPC_LDPC:
2865         t1 = tcg_const_tl(pc_relative_pc(ctx));
2866         gen_op_addr_add(ctx, t0, t0, t1);
2867         tcg_temp_free(t1);
2868         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2869         gen_store_gpr(t0, rt);
2870         break;
2871 #endif
2872     case OPC_LWPC:
2873         t1 = tcg_const_tl(pc_relative_pc(ctx));
2874         gen_op_addr_add(ctx, t0, t0, t1);
2875         tcg_temp_free(t1);
2876         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
2877         gen_store_gpr(t0, rt);
2878         break;
2879     case OPC_LWE:
2880         mem_idx = MIPS_HFLAG_UM;
2881         /* fall through */
2882     case OPC_LW:
2883         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
2884                            ctx->default_tcg_memop_mask);
2885         gen_store_gpr(t0, rt);
2886         break;
2887     case OPC_LHE:
2888         mem_idx = MIPS_HFLAG_UM;
2889         /* fall through */
2890     case OPC_LH:
2891         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
2892                            ctx->default_tcg_memop_mask);
2893         gen_store_gpr(t0, rt);
2894         break;
2895     case OPC_LHUE:
2896         mem_idx = MIPS_HFLAG_UM;
2897         /* fall through */
2898     case OPC_LHU:
2899         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
2900                            ctx->default_tcg_memop_mask);
2901         gen_store_gpr(t0, rt);
2902         break;
2903     case OPC_LBE:
2904         mem_idx = MIPS_HFLAG_UM;
2905         /* fall through */
2906     case OPC_LB:
2907         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
2908         gen_store_gpr(t0, rt);
2909         break;
2910     case OPC_LBUE:
2911         mem_idx = MIPS_HFLAG_UM;
2912         /* fall through */
2913     case OPC_LBU:
2914         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
2915         gen_store_gpr(t0, rt);
2916         break;
2917     case OPC_LWLE:
2918         mem_idx = MIPS_HFLAG_UM;
2919         /* fall through */
2920     case OPC_LWL:
2921         t1 = tcg_temp_new();
2922         /* Do a byte access to possibly trigger a page
2923            fault with the unaligned address.  */
2924         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2925         tcg_gen_andi_tl(t1, t0, 3);
2926 #ifndef TARGET_WORDS_BIGENDIAN
2927         tcg_gen_xori_tl(t1, t1, 3);
2928 #endif
2929         tcg_gen_shli_tl(t1, t1, 3);
2930         tcg_gen_andi_tl(t0, t0, ~3);
2931         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2932         tcg_gen_shl_tl(t0, t0, t1);
2933         t2 = tcg_const_tl(-1);
2934         tcg_gen_shl_tl(t2, t2, t1);
2935         gen_load_gpr(t1, rt);
2936         tcg_gen_andc_tl(t1, t1, t2);
2937         tcg_temp_free(t2);
2938         tcg_gen_or_tl(t0, t0, t1);
2939         tcg_temp_free(t1);
2940         tcg_gen_ext32s_tl(t0, t0);
2941         gen_store_gpr(t0, rt);
2942         break;
2943     case OPC_LWRE:
2944         mem_idx = MIPS_HFLAG_UM;
2945         /* fall through */
2946     case OPC_LWR:
2947         t1 = tcg_temp_new();
2948         /* Do a byte access to possibly trigger a page
2949            fault with the unaligned address.  */
2950         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2951         tcg_gen_andi_tl(t1, t0, 3);
2952 #ifdef TARGET_WORDS_BIGENDIAN
2953         tcg_gen_xori_tl(t1, t1, 3);
2954 #endif
2955         tcg_gen_shli_tl(t1, t1, 3);
2956         tcg_gen_andi_tl(t0, t0, ~3);
2957         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2958         tcg_gen_shr_tl(t0, t0, t1);
2959         tcg_gen_xori_tl(t1, t1, 31);
2960         t2 = tcg_const_tl(0xfffffffeull);
2961         tcg_gen_shl_tl(t2, t2, t1);
2962         gen_load_gpr(t1, rt);
2963         tcg_gen_and_tl(t1, t1, t2);
2964         tcg_temp_free(t2);
2965         tcg_gen_or_tl(t0, t0, t1);
2966         tcg_temp_free(t1);
2967         tcg_gen_ext32s_tl(t0, t0);
2968         gen_store_gpr(t0, rt);
2969         break;
2970     case OPC_LLE:
2971         mem_idx = MIPS_HFLAG_UM;
2972         /* fall through */
2973     case OPC_LL:
2974     case R6_OPC_LL:
2975         op_ld_ll(t0, t0, mem_idx, ctx);
2976         gen_store_gpr(t0, rt);
2977         break;
2978     }
2979     tcg_temp_free(t0);
2980 }
2981
2982 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
2983                     uint32_t reg1, uint32_t reg2)
2984 {
2985     TCGv taddr = tcg_temp_new();
2986     TCGv_i64 tval = tcg_temp_new_i64();
2987     TCGv tmp1 = tcg_temp_new();
2988     TCGv tmp2 = tcg_temp_new();
2989
2990     gen_base_offset_addr(ctx, taddr, base, offset);
2991     tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
2992 #ifdef TARGET_WORDS_BIGENDIAN
2993     tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
2994 #else
2995     tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
2996 #endif
2997     gen_store_gpr(tmp1, reg1);
2998     tcg_temp_free(tmp1);
2999     gen_store_gpr(tmp2, reg2);
3000     tcg_temp_free(tmp2);
3001     tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3002     tcg_temp_free_i64(tval);
3003     tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3004     tcg_temp_free(taddr);
3005 }
3006
3007 /* Store */
3008 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
3009                     int base, int offset)
3010 {
3011     TCGv t0 = tcg_temp_new();
3012     TCGv t1 = tcg_temp_new();
3013     int mem_idx = ctx->mem_idx;
3014
3015     gen_base_offset_addr(ctx, t0, base, offset);
3016     gen_load_gpr(t1, rt);
3017     switch (opc) {
3018 #if defined(TARGET_MIPS64)
3019     case OPC_SD:
3020         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3021                            ctx->default_tcg_memop_mask);
3022         break;
3023     case OPC_SDL:
3024         gen_helper_0e2i(sdl, t1, t0, mem_idx);
3025         break;
3026     case OPC_SDR:
3027         gen_helper_0e2i(sdr, t1, t0, mem_idx);
3028         break;
3029 #endif
3030     case OPC_SWE:
3031         mem_idx = MIPS_HFLAG_UM;
3032         /* fall through */
3033     case OPC_SW:
3034         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3035                            ctx->default_tcg_memop_mask);
3036         break;
3037     case OPC_SHE:
3038         mem_idx = MIPS_HFLAG_UM;
3039         /* fall through */
3040     case OPC_SH:
3041         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3042                            ctx->default_tcg_memop_mask);
3043         break;
3044     case OPC_SBE:
3045         mem_idx = MIPS_HFLAG_UM;
3046         /* fall through */
3047     case OPC_SB:
3048         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3049         break;
3050     case OPC_SWLE:
3051         mem_idx = MIPS_HFLAG_UM;
3052         /* fall through */
3053     case OPC_SWL:
3054         gen_helper_0e2i(swl, t1, t0, mem_idx);
3055         break;
3056     case OPC_SWRE:
3057         mem_idx = MIPS_HFLAG_UM;
3058         /* fall through */
3059     case OPC_SWR:
3060         gen_helper_0e2i(swr, t1, t0, mem_idx);
3061         break;
3062     }
3063     tcg_temp_free(t0);
3064     tcg_temp_free(t1);
3065 }
3066
3067
3068 /* Store conditional */
3069 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
3070                          int base, int16_t offset)
3071 {
3072     TCGv t0, t1;
3073     int mem_idx = ctx->mem_idx;
3074
3075 #ifdef CONFIG_USER_ONLY
3076     t0 = tcg_temp_local_new();
3077     t1 = tcg_temp_local_new();
3078 #else
3079     t0 = tcg_temp_new();
3080     t1 = tcg_temp_new();
3081 #endif
3082     gen_base_offset_addr(ctx, t0, base, offset);
3083     gen_load_gpr(t1, rt);
3084     switch (opc) {
3085 #if defined(TARGET_MIPS64)
3086     case OPC_SCD:
3087     case R6_OPC_SCD:
3088         op_st_scd(t1, t0, rt, mem_idx, ctx);
3089         break;
3090 #endif
3091     case OPC_SCE:
3092         mem_idx = MIPS_HFLAG_UM;
3093         /* fall through */
3094     case OPC_SC:
3095     case R6_OPC_SC:
3096         op_st_sc(t1, t0, rt, mem_idx, ctx);
3097         break;
3098     }
3099     tcg_temp_free(t1);
3100     tcg_temp_free(t0);
3101 }
3102
3103 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3104                     uint32_t reg1, uint32_t reg2)
3105 {
3106     TCGv taddr = tcg_temp_local_new();
3107     TCGv lladdr = tcg_temp_local_new();
3108     TCGv_i64 tval = tcg_temp_new_i64();
3109     TCGv_i64 llval = tcg_temp_new_i64();
3110     TCGv_i64 val = tcg_temp_new_i64();
3111     TCGv tmp1 = tcg_temp_new();
3112     TCGv tmp2 = tcg_temp_new();
3113     TCGLabel *lab_fail = gen_new_label();
3114     TCGLabel *lab_done = gen_new_label();
3115
3116     gen_base_offset_addr(ctx, taddr, base, offset);
3117
3118     tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3119     tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3120
3121     gen_load_gpr(tmp1, reg1);
3122     gen_load_gpr(tmp2, reg2);
3123
3124 #ifdef TARGET_WORDS_BIGENDIAN
3125     tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3126 #else
3127     tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3128 #endif
3129
3130     tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3131     tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3132                                ctx->mem_idx, MO_64);
3133     if (reg1 != 0) {
3134         tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3135     }
3136     tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3137
3138     gen_set_label(lab_fail);
3139
3140     if (reg1 != 0) {
3141         tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3142     }
3143     gen_set_label(lab_done);
3144     tcg_gen_movi_tl(lladdr, -1);
3145     tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3146 }
3147
3148 /* Load and store */
3149 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
3150                           TCGv t0)
3151 {
3152     /* Don't do NOP if destination is zero: we must perform the actual
3153        memory access. */
3154     switch (opc) {
3155     case OPC_LWC1:
3156         {
3157             TCGv_i32 fp0 = tcg_temp_new_i32();
3158             tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3159                                 ctx->default_tcg_memop_mask);
3160             gen_store_fpr32(ctx, fp0, ft);
3161             tcg_temp_free_i32(fp0);
3162         }
3163         break;
3164     case OPC_SWC1:
3165         {
3166             TCGv_i32 fp0 = tcg_temp_new_i32();
3167             gen_load_fpr32(ctx, fp0, ft);
3168             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3169                                 ctx->default_tcg_memop_mask);
3170             tcg_temp_free_i32(fp0);
3171         }
3172         break;
3173     case OPC_LDC1:
3174         {
3175             TCGv_i64 fp0 = tcg_temp_new_i64();
3176             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3177                                 ctx->default_tcg_memop_mask);
3178             gen_store_fpr64(ctx, fp0, ft);
3179             tcg_temp_free_i64(fp0);
3180         }
3181         break;
3182     case OPC_SDC1:
3183         {
3184             TCGv_i64 fp0 = tcg_temp_new_i64();
3185             gen_load_fpr64(ctx, fp0, ft);
3186             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3187                                 ctx->default_tcg_memop_mask);
3188             tcg_temp_free_i64(fp0);
3189         }
3190         break;
3191     default:
3192         MIPS_INVAL("flt_ldst");
3193         generate_exception_end(ctx, EXCP_RI);
3194         break;
3195     }
3196 }
3197
3198 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3199                           int rs, int16_t imm)
3200 {
3201     TCGv t0 = tcg_temp_new();
3202
3203     if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3204         check_cp1_enabled(ctx);
3205         switch (op) {
3206         case OPC_LDC1:
3207         case OPC_SDC1:
3208             check_insn(ctx, ISA_MIPS2);
3209             /* Fallthrough */
3210         default:
3211             gen_base_offset_addr(ctx, t0, rs, imm);
3212             gen_flt_ldst(ctx, op, rt, t0);
3213         }
3214     } else {
3215         generate_exception_err(ctx, EXCP_CpU, 1);
3216     }
3217     tcg_temp_free(t0);
3218 }
3219
3220 /* Arithmetic with immediate operand */
3221 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3222                           int rt, int rs, int imm)
3223 {
3224     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3225
3226     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3227         /* If no destination, treat it as a NOP.
3228            For addi, we must generate the overflow exception when needed. */
3229         return;
3230     }
3231     switch (opc) {
3232     case OPC_ADDI:
3233         {
3234             TCGv t0 = tcg_temp_local_new();
3235             TCGv t1 = tcg_temp_new();
3236             TCGv t2 = tcg_temp_new();
3237             TCGLabel *l1 = gen_new_label();
3238
3239             gen_load_gpr(t1, rs);
3240             tcg_gen_addi_tl(t0, t1, uimm);
3241             tcg_gen_ext32s_tl(t0, t0);
3242
3243             tcg_gen_xori_tl(t1, t1, ~uimm);
3244             tcg_gen_xori_tl(t2, t0, uimm);
3245             tcg_gen_and_tl(t1, t1, t2);
3246             tcg_temp_free(t2);
3247             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3248             tcg_temp_free(t1);
3249             /* operands of same sign, result different sign */
3250             generate_exception(ctx, EXCP_OVERFLOW);
3251             gen_set_label(l1);
3252             tcg_gen_ext32s_tl(t0, t0);
3253             gen_store_gpr(t0, rt);
3254             tcg_temp_free(t0);
3255         }
3256         break;
3257     case OPC_ADDIU:
3258         if (rs != 0) {
3259             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3260             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3261         } else {
3262             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3263         }
3264         break;
3265 #if defined(TARGET_MIPS64)
3266     case OPC_DADDI:
3267         {
3268             TCGv t0 = tcg_temp_local_new();
3269             TCGv t1 = tcg_temp_new();
3270             TCGv t2 = tcg_temp_new();
3271             TCGLabel *l1 = gen_new_label();
3272
3273             gen_load_gpr(t1, rs);
3274             tcg_gen_addi_tl(t0, t1, uimm);
3275
3276             tcg_gen_xori_tl(t1, t1, ~uimm);
3277             tcg_gen_xori_tl(t2, t0, uimm);
3278             tcg_gen_and_tl(t1, t1, t2);
3279             tcg_temp_free(t2);
3280             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3281             tcg_temp_free(t1);
3282             /* operands of same sign, result different sign */
3283             generate_exception(ctx, EXCP_OVERFLOW);
3284             gen_set_label(l1);
3285             gen_store_gpr(t0, rt);
3286             tcg_temp_free(t0);
3287         }
3288         break;
3289     case OPC_DADDIU:
3290         if (rs != 0) {
3291             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3292         } else {
3293             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3294         }
3295         break;
3296 #endif
3297     }
3298 }
3299
3300 /* Logic with immediate operand */
3301 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3302                           int rt, int rs, int16_t imm)
3303 {
3304     target_ulong uimm;
3305
3306     if (rt == 0) {
3307         /* If no destination, treat it as a NOP. */
3308         return;
3309     }
3310     uimm = (uint16_t)imm;
3311     switch (opc) {
3312     case OPC_ANDI:
3313         if (likely(rs != 0))
3314             tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3315         else
3316             tcg_gen_movi_tl(cpu_gpr[rt], 0);
3317         break;
3318     case OPC_ORI:
3319         if (rs != 0)
3320             tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3321         else
3322             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3323         break;
3324     case OPC_XORI:
3325         if (likely(rs != 0))
3326             tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3327         else
3328             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3329         break;
3330     case OPC_LUI:
3331         if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3332             /* OPC_AUI */
3333             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3334             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3335         } else {
3336             tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3337         }
3338         break;
3339
3340     default:
3341         break;
3342     }
3343 }
3344
3345 /* Set on less than with immediate operand */
3346 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3347                         int rt, int rs, int16_t imm)
3348 {
3349     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3350     TCGv t0;
3351
3352     if (rt == 0) {
3353         /* If no destination, treat it as a NOP. */
3354         return;
3355     }
3356     t0 = tcg_temp_new();
3357     gen_load_gpr(t0, rs);
3358     switch (opc) {
3359     case OPC_SLTI:
3360         tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
3361         break;
3362     case OPC_SLTIU:
3363         tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
3364         break;
3365     }
3366     tcg_temp_free(t0);
3367 }
3368
3369 /* Shifts with immediate operand */
3370 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
3371                           int rt, int rs, int16_t imm)
3372 {
3373     target_ulong uimm = ((uint16_t)imm) & 0x1f;
3374     TCGv t0;
3375
3376     if (rt == 0) {
3377         /* If no destination, treat it as a NOP. */
3378         return;
3379     }
3380
3381     t0 = tcg_temp_new();
3382     gen_load_gpr(t0, rs);
3383     switch (opc) {
3384     case OPC_SLL:
3385         tcg_gen_shli_tl(t0, t0, uimm);
3386         tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3387         break;
3388     case OPC_SRA:
3389         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3390         break;
3391     case OPC_SRL:
3392         if (uimm != 0) {
3393             tcg_gen_ext32u_tl(t0, t0);
3394             tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3395         } else {
3396             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3397         }
3398         break;
3399     case OPC_ROTR:
3400         if (uimm != 0) {
3401             TCGv_i32 t1 = tcg_temp_new_i32();
3402
3403             tcg_gen_trunc_tl_i32(t1, t0);
3404             tcg_gen_rotri_i32(t1, t1, uimm);
3405             tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
3406             tcg_temp_free_i32(t1);
3407         } else {
3408             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3409         }
3410         break;
3411 #if defined(TARGET_MIPS64)
3412     case OPC_DSLL:
3413         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
3414         break;
3415     case OPC_DSRA:
3416         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3417         break;
3418     case OPC_DSRL:
3419         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3420         break;
3421     case OPC_DROTR:
3422         if (uimm != 0) {
3423             tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3424         } else {
3425             tcg_gen_mov_tl(cpu_gpr[rt], t0);
3426         }
3427         break;
3428     case OPC_DSLL32:
3429         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
3430         break;
3431     case OPC_DSRA32:
3432         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
3433         break;
3434     case OPC_DSRL32:
3435         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
3436         break;
3437     case OPC_DROTR32:
3438         tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
3439         break;
3440 #endif
3441     }
3442     tcg_temp_free(t0);
3443 }
3444
3445 /* Arithmetic */
3446 static void gen_arith(DisasContext *ctx, uint32_t opc,
3447                       int rd, int rs, int rt)
3448 {
3449     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
3450        && opc != OPC_DADD && opc != OPC_DSUB) {
3451         /* If no destination, treat it as a NOP.
3452            For add & sub, we must generate the overflow exception when needed. */
3453         return;
3454     }
3455
3456     switch (opc) {
3457     case OPC_ADD:
3458         {
3459             TCGv t0 = tcg_temp_local_new();
3460             TCGv t1 = tcg_temp_new();
3461             TCGv t2 = tcg_temp_new();
3462             TCGLabel *l1 = gen_new_label();
3463
3464             gen_load_gpr(t1, rs);
3465             gen_load_gpr(t2, rt);
3466             tcg_gen_add_tl(t0, t1, t2);
3467             tcg_gen_ext32s_tl(t0, t0);
3468             tcg_gen_xor_tl(t1, t1, t2);
3469             tcg_gen_xor_tl(t2, t0, t2);
3470             tcg_gen_andc_tl(t1, t2, t1);
3471             tcg_temp_free(t2);
3472             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3473             tcg_temp_free(t1);
3474             /* operands of same sign, result different sign */
3475             generate_exception(ctx, EXCP_OVERFLOW);
3476             gen_set_label(l1);
3477             gen_store_gpr(t0, rd);
3478             tcg_temp_free(t0);
3479         }
3480         break;
3481     case OPC_ADDU:
3482         if (rs != 0 && rt != 0) {
3483             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3484             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3485         } else if (rs == 0 && rt != 0) {
3486             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3487         } else if (rs != 0 && rt == 0) {
3488             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3489         } else {
3490             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3491         }
3492         break;
3493     case OPC_SUB:
3494         {
3495             TCGv t0 = tcg_temp_local_new();
3496             TCGv t1 = tcg_temp_new();
3497             TCGv t2 = tcg_temp_new();
3498             TCGLabel *l1 = gen_new_label();
3499
3500             gen_load_gpr(t1, rs);
3501             gen_load_gpr(t2, rt);
3502             tcg_gen_sub_tl(t0, t1, t2);
3503             tcg_gen_ext32s_tl(t0, t0);
3504             tcg_gen_xor_tl(t2, t1, t2);
3505             tcg_gen_xor_tl(t1, t0, t1);
3506             tcg_gen_and_tl(t1, t1, t2);
3507             tcg_temp_free(t2);
3508             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3509             tcg_temp_free(t1);
3510             /* operands of different sign, first operand and result different sign */
3511             generate_exception(ctx, EXCP_OVERFLOW);
3512             gen_set_label(l1);
3513             gen_store_gpr(t0, rd);
3514             tcg_temp_free(t0);
3515         }
3516         break;
3517     case OPC_SUBU:
3518         if (rs != 0 && rt != 0) {
3519             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3520             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3521         } else if (rs == 0 && rt != 0) {
3522             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
3523             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3524         } else if (rs != 0 && rt == 0) {
3525             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3526         } else {
3527             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3528         }
3529         break;
3530 #if defined(TARGET_MIPS64)
3531     case OPC_DADD:
3532         {
3533             TCGv t0 = tcg_temp_local_new();
3534             TCGv t1 = tcg_temp_new();
3535             TCGv t2 = tcg_temp_new();
3536             TCGLabel *l1 = gen_new_label();
3537
3538             gen_load_gpr(t1, rs);
3539             gen_load_gpr(t2, rt);
3540             tcg_gen_add_tl(t0, t1, t2);
3541             tcg_gen_xor_tl(t1, t1, t2);
3542             tcg_gen_xor_tl(t2, t0, t2);
3543             tcg_gen_andc_tl(t1, t2, t1);
3544             tcg_temp_free(t2);
3545             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3546             tcg_temp_free(t1);
3547             /* operands of same sign, result different sign */
3548             generate_exception(ctx, EXCP_OVERFLOW);
3549             gen_set_label(l1);
3550             gen_store_gpr(t0, rd);
3551             tcg_temp_free(t0);
3552         }
3553         break;
3554     case OPC_DADDU:
3555         if (rs != 0 && rt != 0) {
3556             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3557         } else if (rs == 0 && rt != 0) {
3558             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3559         } else if (rs != 0 && rt == 0) {
3560             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3561         } else {
3562             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3563         }
3564         break;
3565     case OPC_DSUB:
3566         {
3567             TCGv t0 = tcg_temp_local_new();
3568             TCGv t1 = tcg_temp_new();
3569             TCGv t2 = tcg_temp_new();
3570             TCGLabel *l1 = gen_new_label();
3571
3572             gen_load_gpr(t1, rs);
3573             gen_load_gpr(t2, rt);
3574             tcg_gen_sub_tl(t0, t1, t2);
3575             tcg_gen_xor_tl(t2, t1, t2);
3576             tcg_gen_xor_tl(t1, t0, t1);
3577             tcg_gen_and_tl(t1, t1, t2);
3578             tcg_temp_free(t2);
3579             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3580             tcg_temp_free(t1);
3581             /* operands of different sign, first operand and result different sign */
3582             generate_exception(ctx, EXCP_OVERFLOW);
3583             gen_set_label(l1);
3584             gen_store_gpr(t0, rd);
3585             tcg_temp_free(t0);
3586         }
3587         break;
3588     case OPC_DSUBU:
3589         if (rs != 0 && rt != 0) {
3590             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3591         } else if (rs == 0 && rt != 0) {
3592             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
3593         } else if (rs != 0 && rt == 0) {
3594             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3595         } else {
3596             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3597         }
3598         break;
3599 #endif
3600     case OPC_MUL:
3601         if (likely(rs != 0 && rt != 0)) {
3602             tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3603             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3604         } else {
3605             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3606         }
3607         break;
3608     }
3609 }
3610
3611 /* Conditional move */
3612 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
3613                           int rd, int rs, int rt)
3614 {
3615     TCGv t0, t1, t2;
3616
3617     if (rd == 0) {
3618         /* If no destination, treat it as a NOP. */
3619         return;
3620     }
3621
3622     t0 = tcg_temp_new();
3623     gen_load_gpr(t0, rt);
3624     t1 = tcg_const_tl(0);
3625     t2 = tcg_temp_new();
3626     gen_load_gpr(t2, rs);
3627     switch (opc) {
3628     case OPC_MOVN:
3629         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
3630         break;
3631     case OPC_MOVZ:
3632         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
3633         break;
3634     case OPC_SELNEZ:
3635         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
3636         break;
3637     case OPC_SELEQZ:
3638         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
3639         break;
3640     }
3641     tcg_temp_free(t2);
3642     tcg_temp_free(t1);
3643     tcg_temp_free(t0);
3644 }
3645
3646 /* Logic */
3647 static void gen_logic(DisasContext *ctx, uint32_t opc,
3648                       int rd, int rs, int rt)
3649 {
3650     if (rd == 0) {
3651         /* If no destination, treat it as a NOP. */
3652         return;
3653     }
3654
3655     switch (opc) {
3656     case OPC_AND:
3657         if (likely(rs != 0 && rt != 0)) {
3658             tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3659         } else {
3660             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3661         }
3662         break;
3663     case OPC_NOR:
3664         if (rs != 0 && rt != 0) {
3665             tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3666         } else if (rs == 0 && rt != 0) {
3667             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
3668         } else if (rs != 0 && rt == 0) {
3669             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
3670         } else {
3671             tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
3672         }
3673         break;
3674     case OPC_OR:
3675         if (likely(rs != 0 && rt != 0)) {
3676             tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3677         } else if (rs == 0 && rt != 0) {
3678             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3679         } else if (rs != 0 && rt == 0) {
3680             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3681         } else {
3682             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3683         }
3684         break;
3685     case OPC_XOR:
3686         if (likely(rs != 0 && rt != 0)) {
3687             tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
3688         } else if (rs == 0 && rt != 0) {
3689             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3690         } else if (rs != 0 && rt == 0) {
3691             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3692         } else {
3693             tcg_gen_movi_tl(cpu_gpr[rd], 0);
3694         }
3695         break;
3696     }
3697 }
3698
3699 /* Set on lower than */
3700 static void gen_slt(DisasContext *ctx, uint32_t opc,
3701                     int rd, int rs, int rt)
3702 {
3703     TCGv t0, t1;
3704
3705     if (rd == 0) {
3706         /* If no destination, treat it as a NOP. */
3707         return;
3708     }
3709
3710     t0 = tcg_temp_new();
3711     t1 = tcg_temp_new();
3712     gen_load_gpr(t0, rs);
3713     gen_load_gpr(t1, rt);
3714     switch (opc) {
3715     case OPC_SLT:
3716         tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
3717         break;
3718     case OPC_SLTU:
3719         tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
3720         break;
3721     }
3722     tcg_temp_free(t0);
3723     tcg_temp_free(t1);
3724 }
3725
3726 /* Shifts */
3727 static void gen_shift(DisasContext *ctx, uint32_t opc,
3728                       int rd, int rs, int rt)
3729 {
3730     TCGv t0, t1;
3731
3732     if (rd == 0) {
3733         /* If no destination, treat it as a NOP.
3734            For add & sub, we must generate the overflow exception when needed. */
3735         return;
3736     }
3737
3738     t0 = tcg_temp_new();
3739     t1 = tcg_temp_new();
3740     gen_load_gpr(t0, rs);
3741     gen_load_gpr(t1, rt);
3742     switch (opc) {
3743     case OPC_SLLV:
3744         tcg_gen_andi_tl(t0, t0, 0x1f);
3745         tcg_gen_shl_tl(t0, t1, t0);
3746         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3747         break;
3748     case OPC_SRAV:
3749         tcg_gen_andi_tl(t0, t0, 0x1f);
3750         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
3751         break;
3752     case OPC_SRLV:
3753         tcg_gen_ext32u_tl(t1, t1);
3754         tcg_gen_andi_tl(t0, t0, 0x1f);
3755         tcg_gen_shr_tl(t0, t1, t0);
3756         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3757         break;
3758     case OPC_ROTRV:
3759         {
3760             TCGv_i32 t2 = tcg_temp_new_i32();
3761             TCGv_i32 t3 = tcg_temp_new_i32();
3762
3763             tcg_gen_trunc_tl_i32(t2, t0);
3764             tcg_gen_trunc_tl_i32(t3, t1);
3765             tcg_gen_andi_i32(t2, t2, 0x1f);
3766             tcg_gen_rotr_i32(t2, t3, t2);
3767             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3768             tcg_temp_free_i32(t2);
3769             tcg_temp_free_i32(t3);
3770         }
3771         break;
3772 #if defined(TARGET_MIPS64)
3773     case OPC_DSLLV:
3774         tcg_gen_andi_tl(t0, t0, 0x3f);
3775         tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
3776         break;
3777     case OPC_DSRAV:
3778         tcg_gen_andi_tl(t0, t0, 0x3f);
3779         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
3780         break;
3781     case OPC_DSRLV:
3782         tcg_gen_andi_tl(t0, t0, 0x3f);
3783         tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3784         break;
3785     case OPC_DROTRV:
3786         tcg_gen_andi_tl(t0, t0, 0x3f);
3787         tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3788         break;
3789 #endif
3790     }
3791     tcg_temp_free(t0);
3792     tcg_temp_free(t1);
3793 }
3794
3795 /* Arithmetic on HI/LO registers */
3796 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
3797 {
3798     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
3799         /* Treat as NOP. */
3800         return;
3801     }
3802
3803     if (acc != 0) {
3804         check_dsp(ctx);
3805     }
3806
3807     switch (opc) {
3808     case OPC_MFHI:
3809 #if defined(TARGET_MIPS64)
3810         if (acc != 0) {
3811             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3812         } else
3813 #endif
3814         {
3815             tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3816         }
3817         break;
3818     case OPC_MFLO:
3819 #if defined(TARGET_MIPS64)
3820         if (acc != 0) {
3821             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3822         } else
3823 #endif
3824         {
3825             tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3826         }
3827         break;
3828     case OPC_MTHI:
3829         if (reg != 0) {
3830 #if defined(TARGET_MIPS64)
3831             if (acc != 0) {
3832                 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3833             } else
3834 #endif
3835             {
3836                 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3837             }
3838         } else {
3839             tcg_gen_movi_tl(cpu_HI[acc], 0);
3840         }
3841         break;
3842     case OPC_MTLO:
3843         if (reg != 0) {
3844 #if defined(TARGET_MIPS64)
3845             if (acc != 0) {
3846                 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3847             } else
3848 #endif
3849             {
3850                 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3851             }
3852         } else {
3853             tcg_gen_movi_tl(cpu_LO[acc], 0);
3854         }
3855         break;
3856     }
3857 }
3858
3859 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3860                              TCGMemOp memop)
3861 {
3862     TCGv t0 = tcg_const_tl(addr);
3863     tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3864     gen_store_gpr(t0, reg);
3865     tcg_temp_free(t0);
3866 }
3867
3868 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3869                              int rs)
3870 {
3871     target_long offset;
3872     target_long addr;
3873
3874     switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3875     case OPC_ADDIUPC:
3876         if (rs != 0) {
3877             offset = sextract32(ctx->opcode << 2, 0, 21);
3878             addr = addr_add(ctx, pc, offset);
3879             tcg_gen_movi_tl(cpu_gpr[rs], addr);
3880         }
3881         break;
3882     case R6_OPC_LWPC:
3883         offset = sextract32(ctx->opcode << 2, 0, 21);
3884         addr = addr_add(ctx, pc, offset);
3885         gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3886         break;
3887 #if defined(TARGET_MIPS64)
3888     case OPC_LWUPC:
3889         check_mips_64(ctx);
3890         offset = sextract32(ctx->opcode << 2, 0, 21);
3891         addr = addr_add(ctx, pc, offset);
3892         gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3893         break;
3894 #endif
3895     default:
3896         switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3897         case OPC_AUIPC:
3898             if (rs != 0) {
3899                 offset = sextract32(ctx->opcode, 0, 16) << 16;
3900                 addr = addr_add(ctx, pc, offset);
3901                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3902             }
3903             break;
3904         case OPC_ALUIPC:
3905             if (rs != 0) {
3906                 offset = sextract32(ctx->opcode, 0, 16) << 16;
3907                 addr = ~0xFFFF & addr_add(ctx, pc, offset);
3908                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
3909             }
3910             break;
3911 #if defined(TARGET_MIPS64)
3912         case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3913         case R6_OPC_LDPC + (1 << 16):
3914         case R6_OPC_LDPC + (2 << 16):
3915         case R6_OPC_LDPC + (3 << 16):
3916             check_mips_64(ctx);
3917             offset = sextract32(ctx->opcode << 3, 0, 21);
3918             addr = addr_add(ctx, (pc & ~0x7), offset);
3919             gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3920             break;
3921 #endif
3922         default:
3923             MIPS_INVAL("OPC_PCREL");
3924             generate_exception_end(ctx, EXCP_RI);
3925             break;
3926         }
3927         break;
3928     }
3929 }
3930
3931 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3932 {
3933     TCGv t0, t1;
3934
3935     if (rd == 0) {
3936         /* Treat as NOP. */
3937         return;
3938     }
3939
3940     t0 = tcg_temp_new();
3941     t1 = tcg_temp_new();
3942
3943     gen_load_gpr(t0, rs);
3944     gen_load_gpr(t1, rt);
3945
3946     switch (opc) {
3947     case R6_OPC_DIV:
3948         {
3949             TCGv t2 = tcg_temp_new();
3950             TCGv t3 = tcg_temp_new();
3951             tcg_gen_ext32s_tl(t0, t0);
3952             tcg_gen_ext32s_tl(t1, t1);
3953             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3954             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3955             tcg_gen_and_tl(t2, t2, t3);
3956             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3957             tcg_gen_or_tl(t2, t2, t3);
3958             tcg_gen_movi_tl(t3, 0);
3959             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3960             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3961             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3962             tcg_temp_free(t3);
3963             tcg_temp_free(t2);
3964         }
3965         break;
3966     case R6_OPC_MOD:
3967         {
3968             TCGv t2 = tcg_temp_new();
3969             TCGv t3 = tcg_temp_new();
3970             tcg_gen_ext32s_tl(t0, t0);
3971             tcg_gen_ext32s_tl(t1, t1);
3972             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3973             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3974             tcg_gen_and_tl(t2, t2, t3);
3975             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3976             tcg_gen_or_tl(t2, t2, t3);
3977             tcg_gen_movi_tl(t3, 0);
3978             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3979             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3980             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3981             tcg_temp_free(t3);
3982             tcg_temp_free(t2);
3983         }
3984         break;
3985     case R6_OPC_DIVU:
3986         {
3987             TCGv t2 = tcg_const_tl(0);
3988             TCGv t3 = tcg_const_tl(1);
3989             tcg_gen_ext32u_tl(t0, t0);
3990             tcg_gen_ext32u_tl(t1, t1);
3991             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3992             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3993             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3994             tcg_temp_free(t3);
3995             tcg_temp_free(t2);
3996         }
3997         break;
3998     case R6_OPC_MODU:
3999         {
4000             TCGv t2 = tcg_const_tl(0);
4001             TCGv t3 = tcg_const_tl(1);
4002             tcg_gen_ext32u_tl(t0, t0);
4003             tcg_gen_ext32u_tl(t1, t1);
4004             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4005             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4006             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4007             tcg_temp_free(t3);
4008             tcg_temp_free(t2);
4009         }
4010         break;
4011     case R6_OPC_MUL:
4012         {
4013             TCGv_i32 t2 = tcg_temp_new_i32();
4014             TCGv_i32 t3 = tcg_temp_new_i32();
4015             tcg_gen_trunc_tl_i32(t2, t0);
4016             tcg_gen_trunc_tl_i32(t3, t1);
4017             tcg_gen_mul_i32(t2, t2, t3);
4018             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4019             tcg_temp_free_i32(t2);
4020             tcg_temp_free_i32(t3);
4021         }
4022         break;
4023     case R6_OPC_MUH:
4024         {
4025             TCGv_i32 t2 = tcg_temp_new_i32();
4026             TCGv_i32 t3 = tcg_temp_new_i32();
4027             tcg_gen_trunc_tl_i32(t2, t0);
4028             tcg_gen_trunc_tl_i32(t3, t1);
4029             tcg_gen_muls2_i32(t2, t3, t2, t3);
4030             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4031             tcg_temp_free_i32(t2);
4032             tcg_temp_free_i32(t3);
4033         }
4034         break;
4035     case R6_OPC_MULU:
4036         {
4037             TCGv_i32 t2 = tcg_temp_new_i32();
4038             TCGv_i32 t3 = tcg_temp_new_i32();
4039             tcg_gen_trunc_tl_i32(t2, t0);
4040             tcg_gen_trunc_tl_i32(t3, t1);
4041             tcg_gen_mul_i32(t2, t2, t3);
4042             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4043             tcg_temp_free_i32(t2);
4044             tcg_temp_free_i32(t3);
4045         }
4046         break;
4047     case R6_OPC_MUHU:
4048         {
4049             TCGv_i32 t2 = tcg_temp_new_i32();
4050             TCGv_i32 t3 = tcg_temp_new_i32();
4051             tcg_gen_trunc_tl_i32(t2, t0);
4052             tcg_gen_trunc_tl_i32(t3, t1);
4053             tcg_gen_mulu2_i32(t2, t3, t2, t3);
4054             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4055             tcg_temp_free_i32(t2);
4056             tcg_temp_free_i32(t3);
4057         }
4058         break;
4059 #if defined(TARGET_MIPS64)
4060     case R6_OPC_DDIV:
4061         {
4062             TCGv t2 = tcg_temp_new();
4063             TCGv t3 = tcg_temp_new();
4064             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4065             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4066             tcg_gen_and_tl(t2, t2, t3);
4067             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4068             tcg_gen_or_tl(t2, t2, t3);
4069             tcg_gen_movi_tl(t3, 0);
4070             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4071             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4072             tcg_temp_free(t3);
4073             tcg_temp_free(t2);
4074         }
4075         break;
4076     case R6_OPC_DMOD:
4077         {
4078             TCGv t2 = tcg_temp_new();
4079             TCGv t3 = tcg_temp_new();
4080             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4081             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4082             tcg_gen_and_tl(t2, t2, t3);
4083             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4084             tcg_gen_or_tl(t2, t2, t3);
4085             tcg_gen_movi_tl(t3, 0);
4086             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4087             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4088             tcg_temp_free(t3);
4089             tcg_temp_free(t2);
4090         }
4091         break;
4092     case R6_OPC_DDIVU:
4093         {
4094             TCGv t2 = tcg_const_tl(0);
4095             TCGv t3 = tcg_const_tl(1);
4096             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4097             tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4098             tcg_temp_free(t3);
4099             tcg_temp_free(t2);
4100         }
4101         break;
4102     case R6_OPC_DMODU:
4103         {
4104             TCGv t2 = tcg_const_tl(0);
4105             TCGv t3 = tcg_const_tl(1);
4106             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4107             tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4108             tcg_temp_free(t3);
4109             tcg_temp_free(t2);
4110         }
4111         break;
4112     case R6_OPC_DMUL:
4113         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4114         break;
4115     case R6_OPC_DMUH:
4116         {
4117             TCGv t2 = tcg_temp_new();
4118             tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4119             tcg_temp_free(t2);
4120         }
4121         break;
4122     case R6_OPC_DMULU:
4123         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4124         break;
4125     case R6_OPC_DMUHU:
4126         {
4127             TCGv t2 = tcg_temp_new();
4128             tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4129             tcg_temp_free(t2);
4130         }
4131         break;
4132 #endif
4133     default:
4134         MIPS_INVAL("r6 mul/div");
4135         generate_exception_end(ctx, EXCP_RI);
4136         goto out;
4137     }
4138  out:
4139     tcg_temp_free(t0);
4140     tcg_temp_free(t1);
4141 }
4142
4143 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4144                        int acc, int rs, int rt)
4145 {
4146     TCGv t0, t1;
4147
4148     t0 = tcg_temp_new();
4149     t1 = tcg_temp_new();
4150
4151     gen_load_gpr(t0, rs);
4152     gen_load_gpr(t1, rt);
4153
4154     if (acc != 0) {
4155         check_dsp(ctx);
4156     }
4157
4158     switch (opc) {
4159     case OPC_DIV:
4160         {
4161             TCGv t2 = tcg_temp_new();
4162             TCGv t3 = tcg_temp_new();
4163             tcg_gen_ext32s_tl(t0, t0);
4164             tcg_gen_ext32s_tl(t1, t1);
4165             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4166             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4167             tcg_gen_and_tl(t2, t2, t3);
4168             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4169             tcg_gen_or_tl(t2, t2, t3);
4170             tcg_gen_movi_tl(t3, 0);
4171             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4172             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4173             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4174             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4175             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4176             tcg_temp_free(t3);
4177             tcg_temp_free(t2);
4178         }
4179         break;
4180     case OPC_DIVU:
4181         {
4182             TCGv t2 = tcg_const_tl(0);
4183             TCGv t3 = tcg_const_tl(1);
4184             tcg_gen_ext32u_tl(t0, t0);
4185             tcg_gen_ext32u_tl(t1, t1);
4186             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4187             tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4188             tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4189             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4190             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4191             tcg_temp_free(t3);
4192             tcg_temp_free(t2);
4193         }
4194         break;
4195     case OPC_MULT:
4196         {
4197             TCGv_i32 t2 = tcg_temp_new_i32();
4198             TCGv_i32 t3 = tcg_temp_new_i32();
4199             tcg_gen_trunc_tl_i32(t2, t0);
4200             tcg_gen_trunc_tl_i32(t3, t1);
4201             tcg_gen_muls2_i32(t2, t3, t2, t3);
4202             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4203             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4204             tcg_temp_free_i32(t2);
4205             tcg_temp_free_i32(t3);
4206         }
4207         break;
4208     case OPC_MULTU:
4209         {
4210             TCGv_i32 t2 = tcg_temp_new_i32();
4211             TCGv_i32 t3 = tcg_temp_new_i32();
4212             tcg_gen_trunc_tl_i32(t2, t0);
4213             tcg_gen_trunc_tl_i32(t3, t1);
4214             tcg_gen_mulu2_i32(t2, t3, t2, t3);
4215             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4216             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4217             tcg_temp_free_i32(t2);
4218             tcg_temp_free_i32(t3);
4219         }
4220         break;
4221 #if defined(TARGET_MIPS64)
4222     case OPC_DDIV:
4223         {
4224             TCGv t2 = tcg_temp_new();
4225             TCGv t3 = tcg_temp_new();
4226             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4227             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4228             tcg_gen_and_tl(t2, t2, t3);
4229             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4230             tcg_gen_or_tl(t2, t2, t3);
4231             tcg_gen_movi_tl(t3, 0);
4232             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4233             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4234             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4235             tcg_temp_free(t3);
4236             tcg_temp_free(t2);
4237         }
4238         break;
4239     case OPC_DDIVU:
4240         {
4241             TCGv t2 = tcg_const_tl(0);
4242             TCGv t3 = tcg_const_tl(1);
4243             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4244             tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4245             tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4246             tcg_temp_free(t3);
4247             tcg_temp_free(t2);
4248         }
4249         break;
4250     case OPC_DMULT:
4251         tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4252         break;
4253     case OPC_DMULTU:
4254         tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4255         break;
4256 #endif
4257     case OPC_MADD:
4258         {
4259             TCGv_i64 t2 = tcg_temp_new_i64();
4260             TCGv_i64 t3 = tcg_temp_new_i64();
4261
4262             tcg_gen_ext_tl_i64(t2, t0);
4263             tcg_gen_ext_tl_i64(t3, t1);
4264             tcg_gen_mul_i64(t2, t2, t3);
4265             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4266             tcg_gen_add_i64(t2, t2, t3);
4267             tcg_temp_free_i64(t3);
4268             gen_move_low32(cpu_LO[acc], t2);
4269             gen_move_high32(cpu_HI[acc], t2);
4270             tcg_temp_free_i64(t2);
4271         }
4272         break;
4273     case OPC_MADDU:
4274         {
4275             TCGv_i64 t2 = tcg_temp_new_i64();
4276             TCGv_i64 t3 = tcg_temp_new_i64();
4277
4278             tcg_gen_ext32u_tl(t0, t0);
4279             tcg_gen_ext32u_tl(t1, t1);
4280             tcg_gen_extu_tl_i64(t2, t0);
4281             tcg_gen_extu_tl_i64(t3, t1);
4282             tcg_gen_mul_i64(t2, t2, t3);
4283             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4284             tcg_gen_add_i64(t2, t2, t3);
4285             tcg_temp_free_i64(t3);
4286             gen_move_low32(cpu_LO[acc], t2);
4287             gen_move_high32(cpu_HI[acc], t2);
4288             tcg_temp_free_i64(t2);
4289         }
4290         break;
4291     case OPC_MSUB:
4292         {
4293             TCGv_i64 t2 = tcg_temp_new_i64();
4294             TCGv_i64 t3 = tcg_temp_new_i64();
4295
4296             tcg_gen_ext_tl_i64(t2, t0);
4297             tcg_gen_ext_tl_i64(t3, t1);
4298             tcg_gen_mul_i64(t2, t2, t3);
4299             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4300             tcg_gen_sub_i64(t2, t3, t2);
4301             tcg_temp_free_i64(t3);
4302             gen_move_low32(cpu_LO[acc], t2);
4303             gen_move_high32(cpu_HI[acc], t2);
4304             tcg_temp_free_i64(t2);
4305         }
4306         break;
4307     case OPC_MSUBU:
4308         {
4309             TCGv_i64 t2 = tcg_temp_new_i64();
4310             TCGv_i64 t3 = tcg_temp_new_i64();
4311
4312             tcg_gen_ext32u_tl(t0, t0);
4313             tcg_gen_ext32u_tl(t1, t1);
4314             tcg_gen_extu_tl_i64(t2, t0);
4315             tcg_gen_extu_tl_i64(t3, t1);
4316             tcg_gen_mul_i64(t2, t2, t3);
4317             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4318             tcg_gen_sub_i64(t2, t3, t2);
4319             tcg_temp_free_i64(t3);
4320             gen_move_low32(cpu_LO[acc], t2);
4321             gen_move_high32(cpu_HI[acc], t2);
4322             tcg_temp_free_i64(t2);
4323         }
4324         break;
4325     default:
4326         MIPS_INVAL("mul/div");
4327         generate_exception_end(ctx, EXCP_RI);
4328         goto out;
4329     }
4330  out:
4331     tcg_temp_free(t0);
4332     tcg_temp_free(t1);
4333 }
4334
4335 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
4336                             int rd, int rs, int rt)
4337 {
4338     TCGv t0 = tcg_temp_new();
4339     TCGv t1 = tcg_temp_new();
4340
4341     gen_load_gpr(t0, rs);
4342     gen_load_gpr(t1, rt);
4343
4344     switch (opc) {
4345     case OPC_VR54XX_MULS:
4346         gen_helper_muls(t0, cpu_env, t0, t1);
4347         break;
4348     case OPC_VR54XX_MULSU:
4349         gen_helper_mulsu(t0, cpu_env, t0, t1);
4350         break;
4351     case OPC_VR54XX_MACC:
4352         gen_helper_macc(t0, cpu_env, t0, t1);
4353         break;
4354     case OPC_VR54XX_MACCU:
4355         gen_helper_maccu(t0, cpu_env, t0, t1);
4356         break;
4357     case OPC_VR54XX_MSAC:
4358         gen_helper_msac(t0, cpu_env, t0, t1);
4359         break;
4360     case OPC_VR54XX_MSACU:
4361         gen_helper_msacu(t0, cpu_env, t0, t1);
4362         break;
4363     case OPC_VR54XX_MULHI:
4364         gen_helper_mulhi(t0, cpu_env, t0, t1);
4365         break;
4366     case OPC_VR54XX_MULHIU:
4367         gen_helper_mulhiu(t0, cpu_env, t0, t1);
4368         break;
4369     case OPC_VR54XX_MULSHI:
4370         gen_helper_mulshi(t0, cpu_env, t0, t1);
4371         break;
4372     case OPC_VR54XX_MULSHIU:
4373         gen_helper_mulshiu(t0, cpu_env, t0, t1);
4374         break;
4375     case OPC_VR54XX_MACCHI:
4376         gen_helper_macchi(t0, cpu_env, t0, t1);
4377         break;
4378     case OPC_VR54XX_MACCHIU:
4379         gen_helper_macchiu(t0, cpu_env, t0, t1);
4380         break;
4381     case OPC_VR54XX_MSACHI:
4382         gen_helper_msachi(t0, cpu_env, t0, t1);
4383         break;
4384     case OPC_VR54XX_MSACHIU:
4385         gen_helper_msachiu(t0, cpu_env, t0, t1);
4386         break;
4387     default:
4388         MIPS_INVAL("mul vr54xx");
4389         generate_exception_end(ctx, EXCP_RI);
4390         goto out;
4391     }
4392     gen_store_gpr(t0, rd);
4393
4394  out:
4395     tcg_temp_free(t0);
4396     tcg_temp_free(t1);
4397 }
4398
4399 static void gen_cl (DisasContext *ctx, uint32_t opc,
4400                     int rd, int rs)
4401 {
4402     TCGv t0;
4403
4404     if (rd == 0) {
4405         /* Treat as NOP. */
4406         return;
4407     }
4408     t0 = cpu_gpr[rd];
4409     gen_load_gpr(t0, rs);
4410
4411     switch (opc) {
4412     case OPC_CLO:
4413     case R6_OPC_CLO:
4414 #if defined(TARGET_MIPS64)
4415     case OPC_DCLO:
4416     case R6_OPC_DCLO:
4417 #endif
4418         tcg_gen_not_tl(t0, t0);
4419         break;
4420     }
4421
4422     switch (opc) {
4423     case OPC_CLO:
4424     case R6_OPC_CLO:
4425     case OPC_CLZ:
4426     case R6_OPC_CLZ:
4427         tcg_gen_ext32u_tl(t0, t0);
4428         tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
4429         tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
4430         break;
4431 #if defined(TARGET_MIPS64)
4432     case OPC_DCLO:
4433     case R6_OPC_DCLO:
4434     case OPC_DCLZ:
4435     case R6_OPC_DCLZ:
4436         tcg_gen_clzi_i64(t0, t0, 64);
4437         break;
4438 #endif
4439     }
4440 }
4441
4442 /* Godson integer instructions */
4443 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
4444                                  int rd, int rs, int rt)
4445 {
4446     TCGv t0, t1;
4447
4448     if (rd == 0) {
4449         /* Treat as NOP. */
4450         return;
4451     }
4452
4453     switch (opc) {
4454     case OPC_MULT_G_2E:
4455     case OPC_MULT_G_2F:
4456     case OPC_MULTU_G_2E:
4457     case OPC_MULTU_G_2F:
4458 #if defined(TARGET_MIPS64)
4459     case OPC_DMULT_G_2E:
4460     case OPC_DMULT_G_2F:
4461     case OPC_DMULTU_G_2E:
4462     case OPC_DMULTU_G_2F:
4463 #endif
4464         t0 = tcg_temp_new();
4465         t1 = tcg_temp_new();
4466         break;
4467     default:
4468         t0 = tcg_temp_local_new();
4469         t1 = tcg_temp_local_new();
4470         break;
4471     }
4472
4473     gen_load_gpr(t0, rs);
4474     gen_load_gpr(t1, rt);
4475
4476     switch (opc) {
4477     case OPC_MULT_G_2E:
4478     case OPC_MULT_G_2F:
4479         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4480         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4481         break;
4482     case OPC_MULTU_G_2E:
4483     case OPC_MULTU_G_2F:
4484         tcg_gen_ext32u_tl(t0, t0);
4485         tcg_gen_ext32u_tl(t1, t1);
4486         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4487         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4488         break;
4489     case OPC_DIV_G_2E:
4490     case OPC_DIV_G_2F:
4491         {
4492             TCGLabel *l1 = gen_new_label();
4493             TCGLabel *l2 = gen_new_label();
4494             TCGLabel *l3 = gen_new_label();
4495             tcg_gen_ext32s_tl(t0, t0);
4496             tcg_gen_ext32s_tl(t1, t1);
4497             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4498             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4499             tcg_gen_br(l3);
4500             gen_set_label(l1);
4501             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
4502             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
4503             tcg_gen_mov_tl(cpu_gpr[rd], t0);
4504             tcg_gen_br(l3);
4505             gen_set_label(l2);
4506             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4507             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4508             gen_set_label(l3);
4509         }
4510         break;
4511     case OPC_DIVU_G_2E:
4512     case OPC_DIVU_G_2F:
4513         {
4514             TCGLabel *l1 = gen_new_label();
4515             TCGLabel *l2 = gen_new_label();
4516             tcg_gen_ext32u_tl(t0, t0);
4517             tcg_gen_ext32u_tl(t1, t1);
4518             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4519             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4520             tcg_gen_br(l2);
4521             gen_set_label(l1);
4522             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4523             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4524             gen_set_label(l2);
4525         }
4526         break;
4527     case OPC_MOD_G_2E:
4528     case OPC_MOD_G_2F:
4529         {
4530             TCGLabel *l1 = gen_new_label();
4531             TCGLabel *l2 = gen_new_label();
4532             TCGLabel *l3 = gen_new_label();
4533             tcg_gen_ext32u_tl(t0, t0);
4534             tcg_gen_ext32u_tl(t1, t1);
4535             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4536             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
4537             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
4538             gen_set_label(l1);
4539             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4540             tcg_gen_br(l3);
4541             gen_set_label(l2);
4542             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4543             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4544             gen_set_label(l3);
4545         }
4546         break;
4547     case OPC_MODU_G_2E:
4548     case OPC_MODU_G_2F:
4549         {
4550             TCGLabel *l1 = gen_new_label();
4551             TCGLabel *l2 = gen_new_label();
4552             tcg_gen_ext32u_tl(t0, t0);
4553             tcg_gen_ext32u_tl(t1, t1);
4554             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4555             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4556             tcg_gen_br(l2);
4557             gen_set_label(l1);
4558             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4559             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4560             gen_set_label(l2);
4561         }
4562         break;
4563 #if defined(TARGET_MIPS64)
4564     case OPC_DMULT_G_2E:
4565     case OPC_DMULT_G_2F:
4566         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4567         break;
4568     case OPC_DMULTU_G_2E:
4569     case OPC_DMULTU_G_2F:
4570         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4571         break;
4572     case OPC_DDIV_G_2E:
4573     case OPC_DDIV_G_2F:
4574         {
4575             TCGLabel *l1 = gen_new_label();
4576             TCGLabel *l2 = gen_new_label();
4577             TCGLabel *l3 = gen_new_label();
4578             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4579             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4580             tcg_gen_br(l3);
4581             gen_set_label(l1);
4582             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
4583             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
4584             tcg_gen_mov_tl(cpu_gpr[rd], t0);
4585             tcg_gen_br(l3);
4586             gen_set_label(l2);
4587             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4588             gen_set_label(l3);
4589         }
4590         break;
4591     case OPC_DDIVU_G_2E:
4592     case OPC_DDIVU_G_2F:
4593         {
4594             TCGLabel *l1 = gen_new_label();
4595             TCGLabel *l2 = gen_new_label();
4596             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4597             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4598             tcg_gen_br(l2);
4599             gen_set_label(l1);
4600             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4601             gen_set_label(l2);
4602         }
4603         break;
4604     case OPC_DMOD_G_2E:
4605     case OPC_DMOD_G_2F:
4606         {
4607             TCGLabel *l1 = gen_new_label();
4608             TCGLabel *l2 = gen_new_label();
4609             TCGLabel *l3 = gen_new_label();
4610             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4611             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
4612             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
4613             gen_set_label(l1);
4614             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4615             tcg_gen_br(l3);
4616             gen_set_label(l2);
4617             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4618             gen_set_label(l3);
4619         }
4620         break;
4621     case OPC_DMODU_G_2E:
4622     case OPC_DMODU_G_2F:
4623         {
4624             TCGLabel *l1 = gen_new_label();
4625             TCGLabel *l2 = gen_new_label();
4626             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4627             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4628             tcg_gen_br(l2);
4629             gen_set_label(l1);
4630             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4631             gen_set_label(l2);
4632         }
4633         break;
4634 #endif
4635     }
4636
4637     tcg_temp_free(t0);
4638     tcg_temp_free(t1);
4639 }
4640
4641 /* Loongson multimedia instructions */
4642 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
4643 {
4644     uint32_t opc, shift_max;
4645     TCGv_i64 t0, t1;
4646
4647     opc = MASK_LMI(ctx->opcode);
4648     switch (opc) {
4649     case OPC_ADD_CP2:
4650     case OPC_SUB_CP2:
4651     case OPC_DADD_CP2:
4652     case OPC_DSUB_CP2:
4653         t0 = tcg_temp_local_new_i64();
4654         t1 = tcg_temp_local_new_i64();
4655         break;
4656     default:
4657         t0 = tcg_temp_new_i64();
4658         t1 = tcg_temp_new_i64();
4659         break;
4660     }
4661
4662     check_cp1_enabled(ctx);
4663     gen_load_fpr64(ctx, t0, rs);
4664     gen_load_fpr64(ctx, t1, rt);
4665
4666 #define LMI_HELPER(UP, LO) \
4667     case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
4668 #define LMI_HELPER_1(UP, LO) \
4669     case OPC_##UP: gen_helper_##LO(t0, t0); break
4670 #define LMI_DIRECT(UP, LO, OP) \
4671     case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
4672
4673     switch (opc) {
4674     LMI_HELPER(PADDSH, paddsh);
4675     LMI_HELPER(PADDUSH, paddush);
4676     LMI_HELPER(PADDH, paddh);
4677     LMI_HELPER(PADDW, paddw);
4678     LMI_HELPER(PADDSB, paddsb);
4679     LMI_HELPER(PADDUSB, paddusb);
4680     LMI_HELPER(PADDB, paddb);
4681
4682     LMI_HELPER(PSUBSH, psubsh);
4683     LMI_HELPER(PSUBUSH, psubush);
4684     LMI_HELPER(PSUBH, psubh);
4685     LMI_HELPER(PSUBW, psubw);
4686     LMI_HELPER(PSUBSB, psubsb);
4687     LMI_HELPER(PSUBUSB, psubusb);
4688     LMI_HELPER(PSUBB, psubb);
4689
4690     LMI_HELPER(PSHUFH, pshufh);
4691     LMI_HELPER(PACKSSWH, packsswh);
4692     LMI_HELPER(PACKSSHB, packsshb);
4693     LMI_HELPER(PACKUSHB, packushb);
4694
4695     LMI_HELPER(PUNPCKLHW, punpcklhw);
4696     LMI_HELPER(PUNPCKHHW, punpckhhw);
4697     LMI_HELPER(PUNPCKLBH, punpcklbh);
4698     LMI_HELPER(PUNPCKHBH, punpckhbh);
4699     LMI_HELPER(PUNPCKLWD, punpcklwd);
4700     LMI_HELPER(PUNPCKHWD, punpckhwd);
4701
4702     LMI_HELPER(PAVGH, pavgh);
4703     LMI_HELPER(PAVGB, pavgb);
4704     LMI_HELPER(PMAXSH, pmaxsh);
4705     LMI_HELPER(PMINSH, pminsh);
4706     LMI_HELPER(PMAXUB, pmaxub);
4707     LMI_HELPER(PMINUB, pminub);
4708
4709     LMI_HELPER(PCMPEQW, pcmpeqw);
4710     LMI_HELPER(PCMPGTW, pcmpgtw);
4711     LMI_HELPER(PCMPEQH, pcmpeqh);
4712     LMI_HELPER(PCMPGTH, pcmpgth);
4713     LMI_HELPER(PCMPEQB, pcmpeqb);
4714     LMI_HELPER(PCMPGTB, pcmpgtb);
4715
4716     LMI_HELPER(PSLLW, psllw);
4717     LMI_HELPER(PSLLH, psllh);
4718     LMI_HELPER(PSRLW, psrlw);
4719     LMI_HELPER(PSRLH, psrlh);
4720     LMI_HELPER(PSRAW, psraw);
4721     LMI_HELPER(PSRAH, psrah);
4722
4723     LMI_HELPER(PMULLH, pmullh);
4724     LMI_HELPER(PMULHH, pmulhh);
4725     LMI_HELPER(PMULHUH, pmulhuh);
4726     LMI_HELPER(PMADDHW, pmaddhw);
4727
4728     LMI_HELPER(PASUBUB, pasubub);
4729     LMI_HELPER_1(BIADD, biadd);
4730     LMI_HELPER_1(PMOVMSKB, pmovmskb);
4731
4732     LMI_DIRECT(PADDD, paddd, add);
4733     LMI_DIRECT(PSUBD, psubd, sub);
4734     LMI_DIRECT(XOR_CP2, xor, xor);
4735     LMI_DIRECT(NOR_CP2, nor, nor);
4736     LMI_DIRECT(AND_CP2, and, and);
4737     LMI_DIRECT(OR_CP2, or, or);
4738
4739     case OPC_PANDN:
4740         tcg_gen_andc_i64(t0, t1, t0);
4741         break;
4742
4743     case OPC_PINSRH_0:
4744         tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4745         break;
4746     case OPC_PINSRH_1:
4747         tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4748         break;
4749     case OPC_PINSRH_2:
4750         tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4751         break;
4752     case OPC_PINSRH_3:
4753         tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4754         break;
4755
4756     case OPC_PEXTRH:
4757         tcg_gen_andi_i64(t1, t1, 3);
4758         tcg_gen_shli_i64(t1, t1, 4);
4759         tcg_gen_shr_i64(t0, t0, t1);
4760         tcg_gen_ext16u_i64(t0, t0);
4761         break;
4762
4763     case OPC_ADDU_CP2:
4764         tcg_gen_add_i64(t0, t0, t1);
4765         tcg_gen_ext32s_i64(t0, t0);
4766         break;
4767     case OPC_SUBU_CP2:
4768         tcg_gen_sub_i64(t0, t0, t1);
4769         tcg_gen_ext32s_i64(t0, t0);
4770         break;
4771
4772     case OPC_SLL_CP2:
4773         shift_max = 32;
4774         goto do_shift;
4775     case OPC_SRL_CP2:
4776         shift_max = 32;
4777         goto do_shift;
4778     case OPC_SRA_CP2:
4779         shift_max = 32;
4780         goto do_shift;
4781     case OPC_DSLL_CP2:
4782         shift_max = 64;
4783         goto do_shift;
4784     case OPC_DSRL_CP2:
4785         shift_max = 64;
4786         goto do_shift;
4787     case OPC_DSRA_CP2:
4788         shift_max = 64;
4789         goto do_shift;
4790     do_shift:
4791         /* Make sure shift count isn't TCG undefined behaviour.  */
4792         tcg_gen_andi_i64(t1, t1, shift_max - 1);
4793
4794         switch (opc) {
4795         case OPC_SLL_CP2:
4796         case OPC_DSLL_CP2:
4797             tcg_gen_shl_i64(t0, t0, t1);
4798             break;
4799         case OPC_SRA_CP2:
4800         case OPC_DSRA_CP2:
4801             /* Since SRA is UndefinedResult without sign-extended inputs,
4802                we can treat SRA and DSRA the same.  */
4803             tcg_gen_sar_i64(t0, t0, t1);
4804             break;
4805         case OPC_SRL_CP2:
4806             /* We want to shift in zeros for SRL; zero-extend first.  */
4807             tcg_gen_ext32u_i64(t0, t0);
4808             /* FALLTHRU */
4809         case OPC_DSRL_CP2:
4810             tcg_gen_shr_i64(t0, t0, t1);
4811             break;
4812         }
4813
4814         if (shift_max == 32) {
4815             tcg_gen_ext32s_i64(t0, t0);
4816         }
4817
4818         /* Shifts larger than MAX produce zero.  */
4819         tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4820         tcg_gen_neg_i64(t1, t1);
4821         tcg_gen_and_i64(t0, t0, t1);
4822         break;
4823
4824     case OPC_ADD_CP2:
4825     case OPC_DADD_CP2:
4826         {
4827             TCGv_i64 t2 = tcg_temp_new_i64();
4828             TCGLabel *lab = gen_new_label();
4829
4830             tcg_gen_mov_i64(t2, t0);
4831             tcg_gen_add_i64(t0, t1, t2);
4832             if (opc == OPC_ADD_CP2) {
4833                 tcg_gen_ext32s_i64(t0, t0);
4834             }
4835             tcg_gen_xor_i64(t1, t1, t2);
4836             tcg_gen_xor_i64(t2, t2, t0);
4837             tcg_gen_andc_i64(t1, t2, t1);
4838             tcg_temp_free_i64(t2);
4839             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4840             generate_exception(ctx, EXCP_OVERFLOW);
4841             gen_set_label(lab);
4842             break;
4843         }
4844
4845     case OPC_SUB_CP2:
4846     case OPC_DSUB_CP2:
4847         {
4848             TCGv_i64 t2 = tcg_temp_new_i64();
4849             TCGLabel *lab = gen_new_label();
4850
4851             tcg_gen_mov_i64(t2, t0);
4852             tcg_gen_sub_i64(t0, t1, t2);
4853             if (opc == OPC_SUB_CP2) {
4854                 tcg_gen_ext32s_i64(t0, t0);
4855             }
4856             tcg_gen_xor_i64(t1, t1, t2);
4857             tcg_gen_xor_i64(t2, t2, t0);
4858             tcg_gen_and_i64(t1, t1, t2);
4859             tcg_temp_free_i64(t2);
4860             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4861             generate_exception(ctx, EXCP_OVERFLOW);
4862             gen_set_label(lab);
4863             break;
4864         }
4865
4866     case OPC_PMULUW:
4867         tcg_gen_ext32u_i64(t0, t0);
4868         tcg_gen_ext32u_i64(t1, t1);
4869         tcg_gen_mul_i64(t0, t0, t1);
4870         break;
4871
4872     case OPC_SEQU_CP2:
4873     case OPC_SEQ_CP2:
4874     case OPC_SLTU_CP2:
4875     case OPC_SLT_CP2:
4876     case OPC_SLEU_CP2:
4877     case OPC_SLE_CP2:
4878         /* ??? Document is unclear: Set FCC[CC].  Does that mean the
4879            FD field is the CC field?  */
4880     default:
4881         MIPS_INVAL("loongson_cp2");
4882         generate_exception_end(ctx, EXCP_RI);
4883         return;
4884     }
4885
4886 #undef LMI_HELPER
4887 #undef LMI_DIRECT
4888
4889     gen_store_fpr64(ctx, t0, rd);
4890
4891     tcg_temp_free_i64(t0);
4892     tcg_temp_free_i64(t1);
4893 }
4894
4895 /* Traps */
4896 static void gen_trap (DisasContext *ctx, uint32_t opc,
4897                       int rs, int rt, int16_t imm)
4898 {
4899     int cond;
4900     TCGv t0 = tcg_temp_new();
4901     TCGv t1 = tcg_temp_new();
4902
4903     cond = 0;
4904     /* Load needed operands */
4905     switch (opc) {
4906     case OPC_TEQ:
4907     case OPC_TGE:
4908     case OPC_TGEU:
4909     case OPC_TLT:
4910     case OPC_TLTU:
4911     case OPC_TNE:
4912         /* Compare two registers */
4913         if (rs != rt) {
4914             gen_load_gpr(t0, rs);
4915             gen_load_gpr(t1, rt);
4916             cond = 1;
4917         }
4918         break;
4919     case OPC_TEQI:
4920     case OPC_TGEI:
4921     case OPC_TGEIU:
4922     case OPC_TLTI:
4923     case OPC_TLTIU:
4924     case OPC_TNEI:
4925         /* Compare register to immediate */
4926         if (rs != 0 || imm != 0) {
4927             gen_load_gpr(t0, rs);
4928             tcg_gen_movi_tl(t1, (int32_t)imm);
4929             cond = 1;
4930         }
4931         break;
4932     }
4933     if (cond == 0) {
4934         switch (opc) {
4935         case OPC_TEQ:   /* rs == rs */
4936         case OPC_TEQI:  /* r0 == 0  */
4937         case OPC_TGE:   /* rs >= rs */
4938         case OPC_TGEI:  /* r0 >= 0  */
4939         case OPC_TGEU:  /* rs >= rs unsigned */
4940         case OPC_TGEIU: /* r0 >= 0  unsigned */
4941             /* Always trap */
4942             generate_exception_end(ctx, EXCP_TRAP);
4943             break;
4944         case OPC_TLT:   /* rs < rs           */
4945         case OPC_TLTI:  /* r0 < 0            */
4946         case OPC_TLTU:  /* rs < rs unsigned  */
4947         case OPC_TLTIU: /* r0 < 0  unsigned  */
4948         case OPC_TNE:   /* rs != rs          */
4949         case OPC_TNEI:  /* r0 != 0           */
4950             /* Never trap: treat as NOP. */
4951             break;
4952         }
4953     } else {
4954         TCGLabel *l1 = gen_new_label();
4955
4956         switch (opc) {
4957         case OPC_TEQ:
4958         case OPC_TEQI:
4959             tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4960             break;
4961         case OPC_TGE:
4962         case OPC_TGEI:
4963             tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4964             break;
4965         case OPC_TGEU:
4966         case OPC_TGEIU:
4967             tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4968             break;
4969         case OPC_TLT:
4970         case OPC_TLTI:
4971             tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4972             break;
4973         case OPC_TLTU:
4974         case OPC_TLTIU:
4975             tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4976             break;
4977         case OPC_TNE:
4978         case OPC_TNEI:
4979             tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4980             break;
4981         }
4982         generate_exception(ctx, EXCP_TRAP);
4983         gen_set_label(l1);
4984     }
4985     tcg_temp_free(t0);
4986     tcg_temp_free(t1);
4987 }
4988
4989 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
4990 {
4991     if (unlikely(ctx->base.singlestep_enabled)) {
4992         return false;
4993     }
4994
4995 #ifndef CONFIG_USER_ONLY
4996     return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
4997 #else
4998     return true;
4999 #endif
5000 }
5001
5002 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
5003 {
5004     if (use_goto_tb(ctx, dest)) {
5005         tcg_gen_goto_tb(n);
5006         gen_save_pc(dest);
5007         tcg_gen_exit_tb(ctx->base.tb, n);
5008     } else {
5009         gen_save_pc(dest);
5010         if (ctx->base.singlestep_enabled) {
5011             save_cpu_state(ctx, 0);
5012             gen_helper_raise_exception_debug(cpu_env);
5013         }
5014         tcg_gen_lookup_and_goto_ptr();
5015     }
5016 }
5017
5018 /* Branches (before delay slot) */
5019 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
5020                                 int insn_bytes,
5021                                 int rs, int rt, int32_t offset,
5022                                 int delayslot_size)
5023 {
5024     target_ulong btgt = -1;
5025     int blink = 0;
5026     int bcond_compute = 0;
5027     TCGv t0 = tcg_temp_new();
5028     TCGv t1 = tcg_temp_new();
5029
5030     if (ctx->hflags & MIPS_HFLAG_BMASK) {
5031 #ifdef MIPS_DEBUG_DISAS
5032         LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5033                   TARGET_FMT_lx "\n", ctx->base.pc_next);
5034 #endif
5035         generate_exception_end(ctx, EXCP_RI);
5036         goto out;
5037     }
5038
5039     /* Load needed operands */
5040     switch (opc) {
5041     case OPC_BEQ:
5042     case OPC_BEQL:
5043     case OPC_BNE:
5044     case OPC_BNEL:
5045         /* Compare two registers */
5046         if (rs != rt) {
5047             gen_load_gpr(t0, rs);
5048             gen_load_gpr(t1, rt);
5049             bcond_compute = 1;
5050         }
5051         btgt = ctx->base.pc_next + insn_bytes + offset;
5052         break;
5053     case OPC_BGEZ:
5054     case OPC_BGEZAL:
5055     case OPC_BGEZALL:
5056     case OPC_BGEZL:
5057     case OPC_BGTZ:
5058     case OPC_BGTZL:
5059     case OPC_BLEZ:
5060     case OPC_BLEZL:
5061     case OPC_BLTZ:
5062     case OPC_BLTZAL:
5063     case OPC_BLTZALL:
5064     case OPC_BLTZL:
5065         /* Compare to zero */
5066         if (rs != 0) {
5067             gen_load_gpr(t0, rs);
5068             bcond_compute = 1;
5069         }
5070         btgt = ctx->base.pc_next + insn_bytes + offset;
5071         break;
5072     case OPC_BPOSGE32:
5073 #if defined(TARGET_MIPS64)
5074     case OPC_BPOSGE64:
5075         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5076 #else
5077         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5078 #endif
5079         bcond_compute = 1;
5080         btgt = ctx->base.pc_next + insn_bytes + offset;
5081         break;
5082     case OPC_J:
5083     case OPC_JAL:
5084     case OPC_JALX:
5085         /* Jump to immediate */
5086         btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5087             (uint32_t)offset;
5088         break;
5089     case OPC_JR:
5090     case OPC_JALR:
5091         /* Jump to register */
5092         if (offset != 0 && offset != 16) {
5093             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5094                others are reserved. */
5095             MIPS_INVAL("jump hint");
5096             generate_exception_end(ctx, EXCP_RI);
5097             goto out;
5098         }
5099         gen_load_gpr(btarget, rs);
5100         break;
5101     default:
5102         MIPS_INVAL("branch/jump");
5103         generate_exception_end(ctx, EXCP_RI);
5104         goto out;
5105     }
5106     if (bcond_compute == 0) {
5107         /* No condition to be computed */
5108         switch (opc) {
5109         case OPC_BEQ:     /* rx == rx        */
5110         case OPC_BEQL:    /* rx == rx likely */
5111         case OPC_BGEZ:    /* 0 >= 0          */
5112         case OPC_BGEZL:   /* 0 >= 0 likely   */
5113         case OPC_BLEZ:    /* 0 <= 0          */
5114         case OPC_BLEZL:   /* 0 <= 0 likely   */
5115             /* Always take */
5116             ctx->hflags |= MIPS_HFLAG_B;
5117             break;
5118         case OPC_BGEZAL:  /* 0 >= 0          */
5119         case OPC_BGEZALL: /* 0 >= 0 likely   */
5120             /* Always take and link */
5121             blink = 31;
5122             ctx->hflags |= MIPS_HFLAG_B;
5123             break;
5124         case OPC_BNE:     /* rx != rx        */
5125         case OPC_BGTZ:    /* 0 > 0           */
5126         case OPC_BLTZ:    /* 0 < 0           */
5127             /* Treat as NOP. */
5128             goto out;
5129         case OPC_BLTZAL:  /* 0 < 0           */
5130             /* Handle as an unconditional branch to get correct delay
5131                slot checking.  */
5132             blink = 31;
5133             btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
5134             ctx->hflags |= MIPS_HFLAG_B;
5135             break;
5136         case OPC_BLTZALL: /* 0 < 0 likely */
5137             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5138             /* Skip the instruction in the delay slot */
5139             ctx->base.pc_next += 4;
5140             goto out;
5141         case OPC_BNEL:    /* rx != rx likely */
5142         case OPC_BGTZL:   /* 0 > 0 likely */
5143         case OPC_BLTZL:   /* 0 < 0 likely */
5144             /* Skip the instruction in the delay slot */
5145             ctx->base.pc_next += 4;
5146             goto out;
5147         case OPC_J:
5148             ctx->hflags |= MIPS_HFLAG_B;
5149             break;
5150         case OPC_JALX:
5151             ctx->hflags |= MIPS_HFLAG_BX;
5152             /* Fallthrough */
5153         case OPC_JAL:
5154             blink = 31;
5155             ctx->hflags |= MIPS_HFLAG_B;
5156             break;
5157         case OPC_JR:
5158             ctx->hflags |= MIPS_HFLAG_BR;
5159             break;
5160         case OPC_JALR:
5161             blink = rt;
5162             ctx->hflags |= MIPS_HFLAG_BR;
5163             break;
5164         default:
5165             MIPS_INVAL("branch/jump");
5166             generate_exception_end(ctx, EXCP_RI);
5167             goto out;
5168         }
5169     } else {
5170         switch (opc) {
5171         case OPC_BEQ:
5172             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5173             goto not_likely;
5174         case OPC_BEQL:
5175             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5176             goto likely;
5177         case OPC_BNE:
5178             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5179             goto not_likely;
5180         case OPC_BNEL:
5181             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5182             goto likely;
5183         case OPC_BGEZ:
5184             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5185             goto not_likely;
5186         case OPC_BGEZL:
5187             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5188             goto likely;
5189         case OPC_BGEZAL:
5190             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5191             blink = 31;
5192             goto not_likely;
5193         case OPC_BGEZALL:
5194             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5195             blink = 31;
5196             goto likely;
5197         case OPC_BGTZ:
5198             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5199             goto not_likely;
5200         case OPC_BGTZL:
5201             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5202             goto likely;
5203         case OPC_BLEZ:
5204             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5205             goto not_likely;
5206         case OPC_BLEZL:
5207             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5208             goto likely;
5209         case OPC_BLTZ:
5210             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5211             goto not_likely;
5212         case OPC_BLTZL:
5213             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5214             goto likely;
5215         case OPC_BPOSGE32:
5216             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5217             goto not_likely;
5218 #if defined(TARGET_MIPS64)
5219         case OPC_BPOSGE64:
5220             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
5221             goto not_likely;
5222 #endif
5223         case OPC_BLTZAL:
5224             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5225             blink = 31;
5226         not_likely:
5227             ctx->hflags |= MIPS_HFLAG_BC;
5228             break;
5229         case OPC_BLTZALL:
5230             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5231             blink = 31;
5232         likely:
5233             ctx->hflags |= MIPS_HFLAG_BL;
5234             break;
5235         default:
5236             MIPS_INVAL("conditional branch/jump");
5237             generate_exception_end(ctx, EXCP_RI);
5238             goto out;
5239         }
5240     }
5241
5242     ctx->btarget = btgt;
5243
5244     switch (delayslot_size) {
5245     case 2:
5246         ctx->hflags |= MIPS_HFLAG_BDS16;
5247         break;
5248     case 4:
5249         ctx->hflags |= MIPS_HFLAG_BDS32;
5250         break;
5251     }
5252
5253     if (blink > 0) {
5254         int post_delay = insn_bytes + delayslot_size;
5255         int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5256
5257         tcg_gen_movi_tl(cpu_gpr[blink],
5258                         ctx->base.pc_next + post_delay + lowbit);
5259     }
5260
5261  out:
5262     if (insn_bytes == 2)
5263         ctx->hflags |= MIPS_HFLAG_B16;
5264     tcg_temp_free(t0);
5265     tcg_temp_free(t1);
5266 }
5267
5268
5269 /* nanoMIPS Branches */
5270 static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
5271                                 int insn_bytes,
5272                                 int rs, int rt, int32_t offset)
5273 {
5274     target_ulong btgt = -1;
5275     int bcond_compute = 0;
5276     TCGv t0 = tcg_temp_new();
5277     TCGv t1 = tcg_temp_new();
5278
5279     /* Load needed operands */
5280     switch (opc) {
5281     case OPC_BEQ:
5282     case OPC_BNE:
5283         /* Compare two registers */
5284         if (rs != rt) {
5285             gen_load_gpr(t0, rs);
5286             gen_load_gpr(t1, rt);
5287             bcond_compute = 1;
5288         }
5289         btgt = ctx->base.pc_next + insn_bytes + offset;
5290         break;
5291     case OPC_BGEZAL:
5292         /* Compare to zero */
5293         if (rs != 0) {
5294             gen_load_gpr(t0, rs);
5295             bcond_compute = 1;
5296         }
5297         btgt = ctx->base.pc_next + insn_bytes + offset;
5298         break;
5299     case OPC_BPOSGE32:
5300         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5301         bcond_compute = 1;
5302         btgt = ctx->base.pc_next + insn_bytes + offset;
5303         break;
5304     case OPC_JR:
5305     case OPC_JALR:
5306         /* Jump to register */
5307         if (offset != 0 && offset != 16) {
5308             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5309                others are reserved. */
5310             MIPS_INVAL("jump hint");
5311             generate_exception_end(ctx, EXCP_RI);
5312             goto out;
5313         }
5314         gen_load_gpr(btarget, rs);
5315         break;
5316     default:
5317         MIPS_INVAL("branch/jump");
5318         generate_exception_end(ctx, EXCP_RI);
5319         goto out;
5320     }
5321     if (bcond_compute == 0) {
5322         /* No condition to be computed */
5323         switch (opc) {
5324         case OPC_BEQ:     /* rx == rx        */
5325             /* Always take */
5326             ctx->hflags |= MIPS_HFLAG_B;
5327             break;
5328         case OPC_BGEZAL:  /* 0 >= 0          */
5329             /* Always take and link */
5330             tcg_gen_movi_tl(cpu_gpr[31],
5331                             ctx->base.pc_next + insn_bytes);
5332             ctx->hflags |= MIPS_HFLAG_B;
5333             break;
5334         case OPC_BNE:     /* rx != rx        */
5335             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5336             /* Skip the instruction in the delay slot */
5337             ctx->base.pc_next += 4;
5338             goto out;
5339         case OPC_JR:
5340             ctx->hflags |= MIPS_HFLAG_BR;
5341             break;
5342         case OPC_JALR:
5343             if (rt > 0) {
5344                 tcg_gen_movi_tl(cpu_gpr[rt],
5345                                 ctx->base.pc_next + insn_bytes);
5346             }
5347             ctx->hflags |= MIPS_HFLAG_BR;
5348             break;
5349         default:
5350             MIPS_INVAL("branch/jump");
5351             generate_exception_end(ctx, EXCP_RI);
5352             goto out;
5353         }
5354     } else {
5355         switch (opc) {
5356         case OPC_BEQ:
5357             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5358             goto not_likely;
5359         case OPC_BNE:
5360             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5361             goto not_likely;
5362         case OPC_BGEZAL:
5363             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5364             tcg_gen_movi_tl(cpu_gpr[31],
5365                             ctx->base.pc_next + insn_bytes);
5366             goto not_likely;
5367         case OPC_BPOSGE32:
5368             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5369         not_likely:
5370             ctx->hflags |= MIPS_HFLAG_BC;
5371             break;
5372         default:
5373             MIPS_INVAL("conditional branch/jump");
5374             generate_exception_end(ctx, EXCP_RI);
5375             goto out;
5376         }
5377     }
5378
5379     ctx->btarget = btgt;
5380
5381  out:
5382     if (insn_bytes == 2) {
5383         ctx->hflags |= MIPS_HFLAG_B16;
5384     }
5385     tcg_temp_free(t0);
5386     tcg_temp_free(t1);
5387 }
5388
5389
5390 /* special3 bitfield operations */
5391 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
5392                         int rs, int lsb, int msb)
5393 {
5394     TCGv t0 = tcg_temp_new();
5395     TCGv t1 = tcg_temp_new();
5396
5397     gen_load_gpr(t1, rs);
5398     switch (opc) {
5399     case OPC_EXT:
5400         if (lsb + msb > 31) {
5401             goto fail;
5402         }
5403         if (msb != 31) {
5404             tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5405         } else {
5406             /* The two checks together imply that lsb == 0,
5407                so this is a simple sign-extension.  */
5408             tcg_gen_ext32s_tl(t0, t1);
5409         }
5410         break;
5411 #if defined(TARGET_MIPS64)
5412     case OPC_DEXTU:
5413         lsb += 32;
5414         goto do_dext;
5415     case OPC_DEXTM:
5416         msb += 32;
5417         goto do_dext;
5418     case OPC_DEXT:
5419     do_dext:
5420         if (lsb + msb > 63) {
5421             goto fail;
5422         }
5423         tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5424         break;
5425 #endif
5426     case OPC_INS:
5427         if (lsb > msb) {
5428             goto fail;
5429         }
5430         gen_load_gpr(t0, rt);
5431         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5432         tcg_gen_ext32s_tl(t0, t0);
5433         break;
5434 #if defined(TARGET_MIPS64)
5435     case OPC_DINSU:
5436         lsb += 32;
5437         /* FALLTHRU */
5438     case OPC_DINSM:
5439         msb += 32;
5440         /* FALLTHRU */
5441     case OPC_DINS:
5442         if (lsb > msb) {
5443             goto fail;
5444         }
5445         gen_load_gpr(t0, rt);
5446         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5447         break;
5448 #endif
5449     default:
5450 fail:
5451         MIPS_INVAL("bitops");
5452         generate_exception_end(ctx, EXCP_RI);
5453         tcg_temp_free(t0);
5454         tcg_temp_free(t1);
5455         return;
5456     }
5457     gen_store_gpr(t0, rt);
5458     tcg_temp_free(t0);
5459     tcg_temp_free(t1);
5460 }
5461
5462 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
5463 {
5464     TCGv t0;
5465
5466     if (rd == 0) {
5467         /* If no destination, treat it as a NOP. */
5468         return;
5469     }
5470
5471     t0 = tcg_temp_new();
5472     gen_load_gpr(t0, rt);
5473     switch (op2) {
5474     case OPC_WSBH:
5475         {
5476             TCGv t1 = tcg_temp_new();
5477             TCGv t2 = tcg_const_tl(0x00FF00FF);
5478
5479             tcg_gen_shri_tl(t1, t0, 8);
5480             tcg_gen_and_tl(t1, t1, t2);
5481             tcg_gen_and_tl(t0, t0, t2);
5482             tcg_gen_shli_tl(t0, t0, 8);
5483             tcg_gen_or_tl(t0, t0, t1);
5484             tcg_temp_free(t2);
5485             tcg_temp_free(t1);
5486             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5487         }
5488         break;
5489     case OPC_SEB:
5490         tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
5491         break;
5492     case OPC_SEH:
5493         tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
5494         break;
5495 #if defined(TARGET_MIPS64)
5496     case OPC_DSBH:
5497         {
5498             TCGv t1 = tcg_temp_new();
5499             TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
5500
5501             tcg_gen_shri_tl(t1, t0, 8);
5502             tcg_gen_and_tl(t1, t1, t2);
5503             tcg_gen_and_tl(t0, t0, t2);
5504             tcg_gen_shli_tl(t0, t0, 8);
5505             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5506             tcg_temp_free(t2);
5507             tcg_temp_free(t1);
5508         }
5509         break;
5510     case OPC_DSHD:
5511         {
5512             TCGv t1 = tcg_temp_new();
5513             TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
5514
5515             tcg_gen_shri_tl(t1, t0, 16);
5516             tcg_gen_and_tl(t1, t1, t2);
5517             tcg_gen_and_tl(t0, t0, t2);
5518             tcg_gen_shli_tl(t0, t0, 16);
5519             tcg_gen_or_tl(t0, t0, t1);
5520             tcg_gen_shri_tl(t1, t0, 32);
5521             tcg_gen_shli_tl(t0, t0, 32);
5522             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5523             tcg_temp_free(t2);
5524             tcg_temp_free(t1);
5525         }
5526         break;
5527 #endif
5528     default:
5529         MIPS_INVAL("bsfhl");
5530         generate_exception_end(ctx, EXCP_RI);
5531         tcg_temp_free(t0);
5532         return;
5533     }
5534     tcg_temp_free(t0);
5535 }
5536
5537 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
5538                     int imm2)
5539 {
5540     TCGv t0;
5541     TCGv t1;
5542     if (rd == 0) {
5543         /* Treat as NOP. */
5544         return;
5545     }
5546     t0 = tcg_temp_new();
5547     t1 = tcg_temp_new();
5548     gen_load_gpr(t0, rs);
5549     gen_load_gpr(t1, rt);
5550     tcg_gen_shli_tl(t0, t0, imm2 + 1);
5551     tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
5552     if (opc == OPC_LSA) {
5553         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5554     }
5555
5556     tcg_temp_free(t1);
5557     tcg_temp_free(t0);
5558
5559     return;
5560 }
5561
5562 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
5563                            int rt, int bits)
5564 {
5565     TCGv t0;
5566     if (rd == 0) {
5567         /* Treat as NOP. */
5568         return;
5569     }
5570     t0 = tcg_temp_new();
5571     if (bits == 0 || bits == wordsz) {
5572         if (bits == 0) {
5573             gen_load_gpr(t0, rt);
5574         } else {
5575             gen_load_gpr(t0, rs);
5576         }
5577         switch (wordsz) {
5578         case 32:
5579             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5580             break;
5581 #if defined(TARGET_MIPS64)
5582         case 64:
5583             tcg_gen_mov_tl(cpu_gpr[rd], t0);
5584             break;
5585 #endif
5586         }
5587     } else {
5588         TCGv t1 = tcg_temp_new();
5589         gen_load_gpr(t0, rt);
5590         gen_load_gpr(t1, rs);
5591         switch (wordsz) {
5592         case 32:
5593             {
5594                 TCGv_i64 t2 = tcg_temp_new_i64();
5595                 tcg_gen_concat_tl_i64(t2, t1, t0);
5596                 tcg_gen_shri_i64(t2, t2, 32 - bits);
5597                 gen_move_low32(cpu_gpr[rd], t2);
5598                 tcg_temp_free_i64(t2);
5599             }
5600             break;
5601 #if defined(TARGET_MIPS64)
5602         case 64:
5603             tcg_gen_shli_tl(t0, t0, bits);
5604             tcg_gen_shri_tl(t1, t1, 64 - bits);
5605             tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
5606             break;
5607 #endif
5608         }
5609         tcg_temp_free(t1);
5610     }
5611
5612     tcg_temp_free(t0);
5613 }
5614
5615 static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
5616                       int bp)
5617 {
5618     gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
5619 }
5620
5621 static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
5622                     int shift)
5623 {
5624     gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
5625 }
5626
5627 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
5628 {
5629     TCGv t0;
5630     if (rd == 0) {
5631         /* Treat as NOP. */
5632         return;
5633     }
5634     t0 = tcg_temp_new();
5635     gen_load_gpr(t0, rt);
5636     switch (opc) {
5637     case OPC_BITSWAP:
5638         gen_helper_bitswap(cpu_gpr[rd], t0);
5639         break;
5640 #if defined(TARGET_MIPS64)
5641     case OPC_DBITSWAP:
5642         gen_helper_dbitswap(cpu_gpr[rd], t0);
5643         break;
5644 #endif
5645     }
5646     tcg_temp_free(t0);
5647 }
5648
5649 #ifndef CONFIG_USER_ONLY
5650 /* CP0 (MMU and control) */
5651 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
5652 {
5653     TCGv_i64 t0 = tcg_temp_new_i64();
5654     TCGv_i64 t1 = tcg_temp_new_i64();
5655
5656     tcg_gen_ext_tl_i64(t0, arg);
5657     tcg_gen_ld_i64(t1, cpu_env, off);
5658 #if defined(TARGET_MIPS64)
5659     tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
5660 #else
5661     tcg_gen_concat32_i64(t1, t1, t0);
5662 #endif
5663     tcg_gen_st_i64(t1, cpu_env, off);
5664     tcg_temp_free_i64(t1);
5665     tcg_temp_free_i64(t0);
5666 }
5667
5668 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
5669 {
5670     TCGv_i64 t0 = tcg_temp_new_i64();
5671     TCGv_i64 t1 = tcg_temp_new_i64();
5672
5673     tcg_gen_ext_tl_i64(t0, arg);
5674     tcg_gen_ld_i64(t1, cpu_env, off);
5675     tcg_gen_concat32_i64(t1, t1, t0);
5676     tcg_gen_st_i64(t1, cpu_env, off);
5677     tcg_temp_free_i64(t1);
5678     tcg_temp_free_i64(t0);
5679 }
5680
5681 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
5682 {
5683     TCGv_i64 t0 = tcg_temp_new_i64();
5684
5685     tcg_gen_ld_i64(t0, cpu_env, off);
5686 #if defined(TARGET_MIPS64)
5687     tcg_gen_shri_i64(t0, t0, 30);
5688 #else
5689     tcg_gen_shri_i64(t0, t0, 32);
5690 #endif
5691     gen_move_low32(arg, t0);
5692     tcg_temp_free_i64(t0);
5693 }
5694
5695 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
5696 {
5697     TCGv_i64 t0 = tcg_temp_new_i64();
5698
5699     tcg_gen_ld_i64(t0, cpu_env, off);
5700     tcg_gen_shri_i64(t0, t0, 32 + shift);
5701     gen_move_low32(arg, t0);
5702     tcg_temp_free_i64(t0);
5703 }
5704
5705 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
5706 {
5707     TCGv_i32 t0 = tcg_temp_new_i32();
5708
5709     tcg_gen_ld_i32(t0, cpu_env, off);
5710     tcg_gen_ext_i32_tl(arg, t0);
5711     tcg_temp_free_i32(t0);
5712 }
5713
5714 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
5715 {
5716     tcg_gen_ld_tl(arg, cpu_env, off);
5717     tcg_gen_ext32s_tl(arg, arg);
5718 }
5719
5720 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
5721 {
5722     TCGv_i32 t0 = tcg_temp_new_i32();
5723
5724     tcg_gen_trunc_tl_i32(t0, arg);
5725     tcg_gen_st_i32(t0, cpu_env, off);
5726     tcg_temp_free_i32(t0);
5727 }
5728
5729 #define CP0_CHECK(c)                            \
5730     do {                                        \
5731         if (!(c)) {                             \
5732             goto cp0_unimplemented;             \
5733         }                                       \
5734     } while (0)
5735
5736 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5737 {
5738     const char *rn = "invalid";
5739
5740     switch (reg) {
5741     case 2:
5742         switch (sel) {
5743         case 0:
5744             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5745             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5746             rn = "EntryLo0";
5747             break;
5748         default:
5749             goto cp0_unimplemented;
5750         }
5751         break;
5752     case 3:
5753         switch (sel) {
5754         case 0:
5755             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5756             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5757             rn = "EntryLo1";
5758             break;
5759         default:
5760             goto cp0_unimplemented;
5761         }
5762         break;
5763     case 17:
5764         switch (sel) {
5765         case 0:
5766             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
5767                              ctx->CP0_LLAddr_shift);
5768             rn = "LLAddr";
5769             break;
5770         case 1:
5771             CP0_CHECK(ctx->mrp);
5772             gen_helper_mfhc0_maar(arg, cpu_env);
5773             rn = "MAAR";
5774             break;
5775         default:
5776             goto cp0_unimplemented;
5777         }
5778         break;
5779     case 28:
5780         switch (sel) {
5781         case 0:
5782         case 2:
5783         case 4:
5784         case 6:
5785             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
5786             rn = "TagLo";
5787             break;
5788         default:
5789             goto cp0_unimplemented;
5790         }
5791         break;
5792     default:
5793         goto cp0_unimplemented;
5794     }
5795     trace_mips_translate_c0("mfhc0", rn, reg, sel);
5796     return;
5797
5798 cp0_unimplemented:
5799     qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n", rn, reg, sel);
5800     tcg_gen_movi_tl(arg, 0);
5801 }
5802
5803 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5804 {
5805     const char *rn = "invalid";
5806     uint64_t mask = ctx->PAMask >> 36;
5807
5808     switch (reg) {
5809     case 2:
5810         switch (sel) {
5811         case 0:
5812             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5813             tcg_gen_andi_tl(arg, arg, mask);
5814             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5815             rn = "EntryLo0";
5816             break;
5817         default:
5818             goto cp0_unimplemented;
5819         }
5820         break;
5821     case 3:
5822         switch (sel) {
5823         case 0:
5824             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5825             tcg_gen_andi_tl(arg, arg, mask);
5826             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5827             rn = "EntryLo1";
5828             break;
5829         default:
5830             goto cp0_unimplemented;
5831         }
5832         break;
5833     case 17:
5834         switch (sel) {
5835         case 0:
5836             /* LLAddr is read-only (the only exception is bit 0 if LLB is
5837                supported); the CP0_LLAddr_rw_bitmask does not seem to be
5838                relevant for modern MIPS cores supporting MTHC0, therefore
5839                treating MTHC0 to LLAddr as NOP. */
5840             rn = "LLAddr";
5841             break;
5842         case 1:
5843             CP0_CHECK(ctx->mrp);
5844             gen_helper_mthc0_maar(cpu_env, arg);
5845             rn = "MAAR";
5846             break;
5847         default:
5848             goto cp0_unimplemented;
5849         }
5850         break;
5851     case 28:
5852         switch (sel) {
5853         case 0:
5854         case 2:
5855         case 4:
5856         case 6:
5857             tcg_gen_andi_tl(arg, arg, mask);
5858             gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5859             rn = "TagLo";
5860             break;
5861         default:
5862             goto cp0_unimplemented;
5863         }
5864         break;
5865     default:
5866         goto cp0_unimplemented;
5867     }
5868     trace_mips_translate_c0("mthc0", rn, reg, sel);
5869
5870 cp0_unimplemented:
5871     qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n", rn, reg, sel);
5872 }
5873
5874 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5875 {
5876     if (ctx->insn_flags & ISA_MIPS32R6) {
5877         tcg_gen_movi_tl(arg, 0);
5878     } else {
5879         tcg_gen_movi_tl(arg, ~0);
5880     }
5881 }
5882
5883 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5884 {
5885     const char *rn = "invalid";
5886
5887     if (sel != 0)
5888         check_insn(ctx, ISA_MIPS32);
5889
5890     switch (reg) {
5891     case 0:
5892         switch (sel) {
5893         case 0:
5894             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5895             rn = "Index";
5896             break;
5897         case 1:
5898             CP0_CHECK(ctx->insn_flags & ASE_MT);
5899             gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5900             rn = "MVPControl";
5901             break;
5902         case 2:
5903             CP0_CHECK(ctx->insn_flags & ASE_MT);
5904             gen_helper_mfc0_mvpconf0(arg, cpu_env);
5905             rn = "MVPConf0";
5906             break;
5907         case 3:
5908             CP0_CHECK(ctx->insn_flags & ASE_MT);
5909             gen_helper_mfc0_mvpconf1(arg, cpu_env);
5910             rn = "MVPConf1";
5911             break;
5912         case 4:
5913             CP0_CHECK(ctx->vp);
5914             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5915             rn = "VPControl";
5916             break;
5917         default:
5918             goto cp0_unimplemented;
5919         }
5920         break;
5921     case 1:
5922         switch (sel) {
5923         case 0:
5924             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
5925             gen_helper_mfc0_random(arg, cpu_env);
5926             rn = "Random";
5927             break;
5928         case 1:
5929             CP0_CHECK(ctx->insn_flags & ASE_MT);
5930             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5931             rn = "VPEControl";
5932             break;
5933         case 2:
5934             CP0_CHECK(ctx->insn_flags & ASE_MT);
5935             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5936             rn = "VPEConf0";
5937             break;
5938         case 3:
5939             CP0_CHECK(ctx->insn_flags & ASE_MT);
5940             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5941             rn = "VPEConf1";
5942             break;
5943         case 4:
5944             CP0_CHECK(ctx->insn_flags & ASE_MT);
5945             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5946             rn = "YQMask";
5947             break;
5948         case 5:
5949             CP0_CHECK(ctx->insn_flags & ASE_MT);
5950             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5951             rn = "VPESchedule";
5952             break;
5953         case 6:
5954             CP0_CHECK(ctx->insn_flags & ASE_MT);
5955             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5956             rn = "VPEScheFBack";
5957             break;
5958         case 7:
5959             CP0_CHECK(ctx->insn_flags & ASE_MT);
5960             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5961             rn = "VPEOpt";
5962             break;
5963         default:
5964             goto cp0_unimplemented;
5965         }
5966         break;
5967     case 2:
5968         switch (sel) {
5969         case 0:
5970             {
5971                 TCGv_i64 tmp = tcg_temp_new_i64();
5972                 tcg_gen_ld_i64(tmp, cpu_env,
5973                                offsetof(CPUMIPSState, CP0_EntryLo0));
5974 #if defined(TARGET_MIPS64)
5975                 if (ctx->rxi) {
5976                     /* Move RI/XI fields to bits 31:30 */
5977                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5978                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5979                 }
5980 #endif
5981                 gen_move_low32(arg, tmp);
5982                 tcg_temp_free_i64(tmp);
5983             }
5984             rn = "EntryLo0";
5985             break;
5986         case 1:
5987             CP0_CHECK(ctx->insn_flags & ASE_MT);
5988             gen_helper_mfc0_tcstatus(arg, cpu_env);
5989             rn = "TCStatus";
5990             break;
5991         case 2:
5992             CP0_CHECK(ctx->insn_flags & ASE_MT);
5993             gen_helper_mfc0_tcbind(arg, cpu_env);
5994             rn = "TCBind";
5995             break;
5996         case 3:
5997             CP0_CHECK(ctx->insn_flags & ASE_MT);
5998             gen_helper_mfc0_tcrestart(arg, cpu_env);
5999             rn = "TCRestart";
6000             break;
6001         case 4:
6002             CP0_CHECK(ctx->insn_flags & ASE_MT);
6003             gen_helper_mfc0_tchalt(arg, cpu_env);
6004             rn = "TCHalt";
6005             break;
6006         case 5:
6007             CP0_CHECK(ctx->insn_flags & ASE_MT);
6008             gen_helper_mfc0_tccontext(arg, cpu_env);
6009             rn = "TCContext";
6010             break;
6011         case 6:
6012             CP0_CHECK(ctx->insn_flags & ASE_MT);
6013             gen_helper_mfc0_tcschedule(arg, cpu_env);
6014             rn = "TCSchedule";
6015             break;
6016         case 7:
6017             CP0_CHECK(ctx->insn_flags & ASE_MT);
6018             gen_helper_mfc0_tcschefback(arg, cpu_env);
6019             rn = "TCScheFBack";
6020             break;
6021         default:
6022             goto cp0_unimplemented;
6023         }
6024         break;
6025     case 3:
6026         switch (sel) {
6027         case 0:
6028             {
6029                 TCGv_i64 tmp = tcg_temp_new_i64();
6030                 tcg_gen_ld_i64(tmp, cpu_env,
6031                                offsetof(CPUMIPSState, CP0_EntryLo1));
6032 #if defined(TARGET_MIPS64)
6033                 if (ctx->rxi) {
6034                     /* Move RI/XI fields to bits 31:30 */
6035                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6036                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6037                 }
6038 #endif
6039                 gen_move_low32(arg, tmp);
6040                 tcg_temp_free_i64(tmp);
6041             }
6042             rn = "EntryLo1";
6043             break;
6044         case 1:
6045             CP0_CHECK(ctx->vp);
6046             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6047             rn = "GlobalNumber";
6048             break;
6049         default:
6050             goto cp0_unimplemented;
6051         }
6052         break;
6053     case 4:
6054         switch (sel) {
6055         case 0:
6056             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6057             tcg_gen_ext32s_tl(arg, arg);
6058             rn = "Context";
6059             break;
6060         case 1:
6061 //            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
6062             rn = "ContextConfig";
6063             goto cp0_unimplemented;
6064         case 2:
6065             CP0_CHECK(ctx->ulri);
6066             tcg_gen_ld_tl(arg, cpu_env,
6067                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6068             tcg_gen_ext32s_tl(arg, arg);
6069             rn = "UserLocal";
6070             break;
6071         default:
6072             goto cp0_unimplemented;
6073         }
6074         break;
6075     case 5:
6076         switch (sel) {
6077         case 0:
6078             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6079             rn = "PageMask";
6080             break;
6081         case 1:
6082             check_insn(ctx, ISA_MIPS32R2);
6083             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6084             rn = "PageGrain";
6085             break;
6086         case 2:
6087             CP0_CHECK(ctx->sc);
6088             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6089             tcg_gen_ext32s_tl(arg, arg);
6090             rn = "SegCtl0";
6091             break;
6092         case 3:
6093             CP0_CHECK(ctx->sc);
6094             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6095             tcg_gen_ext32s_tl(arg, arg);
6096             rn = "SegCtl1";
6097             break;
6098         case 4:
6099             CP0_CHECK(ctx->sc);
6100             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6101             tcg_gen_ext32s_tl(arg, arg);
6102             rn = "SegCtl2";
6103             break;
6104         case 5:
6105             check_pw(ctx);
6106             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6107             rn = "PWBase";
6108             break;
6109         case 6:
6110             check_pw(ctx);
6111             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
6112             rn = "PWField";
6113             break;
6114         case 7:
6115             check_pw(ctx);
6116             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
6117             rn = "PWSize";
6118             break;
6119         default:
6120             goto cp0_unimplemented;
6121         }
6122         break;
6123     case 6:
6124         switch (sel) {
6125         case 0:
6126             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6127             rn = "Wired";
6128             break;
6129         case 1:
6130             check_insn(ctx, ISA_MIPS32R2);
6131             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6132             rn = "SRSConf0";
6133             break;
6134         case 2:
6135             check_insn(ctx, ISA_MIPS32R2);
6136             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6137             rn = "SRSConf1";
6138             break;
6139         case 3:
6140             check_insn(ctx, ISA_MIPS32R2);
6141             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6142             rn = "SRSConf2";
6143             break;
6144         case 4:
6145             check_insn(ctx, ISA_MIPS32R2);
6146             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6147             rn = "SRSConf3";
6148             break;
6149         case 5:
6150             check_insn(ctx, ISA_MIPS32R2);
6151             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6152             rn = "SRSConf4";
6153             break;
6154         case 6:
6155             check_pw(ctx);
6156             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6157             rn = "PWCtl";
6158             break;
6159         default:
6160             goto cp0_unimplemented;
6161         }
6162         break;
6163     case 7:
6164         switch (sel) {
6165         case 0:
6166             check_insn(ctx, ISA_MIPS32R2);
6167             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6168             rn = "HWREna";
6169             break;
6170         default:
6171             goto cp0_unimplemented;
6172         }
6173         break;
6174     case 8:
6175         switch (sel) {
6176         case 0:
6177             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6178             tcg_gen_ext32s_tl(arg, arg);
6179             rn = "BadVAddr";
6180             break;
6181         case 1:
6182             CP0_CHECK(ctx->bi);
6183             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6184             rn = "BadInstr";
6185             break;
6186         case 2:
6187             CP0_CHECK(ctx->bp);
6188             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6189             rn = "BadInstrP";
6190             break;
6191         case 3:
6192             CP0_CHECK(ctx->bi);
6193             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
6194             tcg_gen_andi_tl(arg, arg, ~0xffff);
6195             rn = "BadInstrX";
6196             break;
6197        default:
6198             goto cp0_unimplemented;
6199         }
6200         break;
6201     case 9:
6202         switch (sel) {
6203         case 0:
6204             /* Mark as an IO operation because we read the time.  */
6205             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6206                 gen_io_start();
6207             }
6208             gen_helper_mfc0_count(arg, cpu_env);
6209             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6210                 gen_io_end();
6211             }
6212             /* Break the TB to be able to take timer interrupts immediately
6213                after reading count. DISAS_STOP isn't sufficient, we need to
6214                ensure we break completely out of translated code.  */
6215             gen_save_pc(ctx->base.pc_next + 4);
6216             ctx->base.is_jmp = DISAS_EXIT;
6217             rn = "Count";
6218             break;
6219         /* 6,7 are implementation dependent */
6220         default:
6221             goto cp0_unimplemented;
6222         }
6223         break;
6224     case 10:
6225         switch (sel) {
6226         case 0:
6227             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6228             tcg_gen_ext32s_tl(arg, arg);
6229             rn = "EntryHi";
6230             break;
6231         default:
6232             goto cp0_unimplemented;
6233         }
6234         break;
6235     case 11:
6236         switch (sel) {
6237         case 0:
6238             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6239             rn = "Compare";
6240             break;
6241         /* 6,7 are implementation dependent */
6242         default:
6243             goto cp0_unimplemented;
6244         }
6245         break;
6246     case 12:
6247         switch (sel) {
6248         case 0:
6249             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6250             rn = "Status";
6251             break;
6252         case 1:
6253             check_insn(ctx, ISA_MIPS32R2);
6254             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6255             rn = "IntCtl";
6256             break;
6257         case 2:
6258             check_insn(ctx, ISA_MIPS32R2);
6259             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6260             rn = "SRSCtl";
6261             break;
6262         case 3:
6263             check_insn(ctx, ISA_MIPS32R2);
6264             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6265             rn = "SRSMap";
6266             break;
6267         default:
6268             goto cp0_unimplemented;
6269        }
6270         break;
6271     case 13:
6272         switch (sel) {
6273         case 0:
6274             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6275             rn = "Cause";
6276             break;
6277         default:
6278             goto cp0_unimplemented;
6279        }
6280         break;
6281     case 14:
6282         switch (sel) {
6283         case 0:
6284             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6285             tcg_gen_ext32s_tl(arg, arg);
6286             rn = "EPC";
6287             break;
6288         default:
6289             goto cp0_unimplemented;
6290         }
6291         break;
6292     case 15:
6293         switch (sel) {
6294         case 0:
6295             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6296             rn = "PRid";
6297             break;
6298         case 1:
6299             check_insn(ctx, ISA_MIPS32R2);
6300             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6301             tcg_gen_ext32s_tl(arg, arg);
6302             rn = "EBase";
6303             break;
6304         case 3:
6305             check_insn(ctx, ISA_MIPS32R2);
6306             CP0_CHECK(ctx->cmgcr);
6307             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6308             tcg_gen_ext32s_tl(arg, arg);
6309             rn = "CMGCRBase";
6310             break;
6311         default:
6312             goto cp0_unimplemented;
6313        }
6314         break;
6315     case 16:
6316         switch (sel) {
6317         case 0:
6318             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6319             rn = "Config";
6320             break;
6321         case 1:
6322             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6323             rn = "Config1";
6324             break;
6325         case 2:
6326             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6327             rn = "Config2";
6328             break;
6329         case 3:
6330             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6331             rn = "Config3";
6332             break;
6333         case 4:
6334             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6335             rn = "Config4";
6336             break;
6337         case 5:
6338             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6339             rn = "Config5";
6340             break;
6341         /* 6,7 are implementation dependent */
6342         case 6:
6343             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6344             rn = "Config6";
6345             break;
6346         case 7:
6347             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6348             rn = "Config7";
6349             break;
6350         default:
6351             goto cp0_unimplemented;
6352         }
6353         break;
6354     case 17:
6355         switch (sel) {
6356         case 0:
6357             gen_helper_mfc0_lladdr(arg, cpu_env);
6358             rn = "LLAddr";
6359             break;
6360         case 1:
6361             CP0_CHECK(ctx->mrp);
6362             gen_helper_mfc0_maar(arg, cpu_env);
6363             rn = "MAAR";
6364             break;
6365         case 2:
6366             CP0_CHECK(ctx->mrp);
6367             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6368             rn = "MAARI";
6369             break;
6370         default:
6371             goto cp0_unimplemented;
6372         }
6373         break;
6374     case 18:
6375         switch (sel) {
6376         case 0:
6377         case 1:
6378         case 2:
6379         case 3:
6380         case 4:
6381         case 5:
6382         case 6:
6383         case 7:
6384             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6385             gen_helper_1e0i(mfc0_watchlo, arg, sel);
6386             rn = "WatchLo";
6387             break;
6388         default:
6389             goto cp0_unimplemented;
6390         }
6391         break;
6392     case 19:
6393         switch (sel) {
6394         case 0:
6395         case 1:
6396         case 2:
6397         case 3:
6398         case 4:
6399         case 5:
6400         case 6:
6401         case 7:
6402             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6403             gen_helper_1e0i(mfc0_watchhi, arg, sel);
6404             rn = "WatchHi";
6405             break;
6406         default:
6407             goto cp0_unimplemented;
6408         }
6409         break;
6410     case 20:
6411         switch (sel) {
6412         case 0:
6413 #if defined(TARGET_MIPS64)
6414             check_insn(ctx, ISA_MIPS3);
6415             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6416             tcg_gen_ext32s_tl(arg, arg);
6417             rn = "XContext";
6418             break;
6419 #endif
6420         default:
6421             goto cp0_unimplemented;
6422         }
6423         break;
6424     case 21:
6425        /* Officially reserved, but sel 0 is used for R1x000 framemask */
6426         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6427         switch (sel) {
6428         case 0:
6429             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6430             rn = "Framemask";
6431             break;
6432         default:
6433             goto cp0_unimplemented;
6434         }
6435         break;
6436     case 22:
6437         tcg_gen_movi_tl(arg, 0); /* unimplemented */
6438         rn = "'Diagnostic"; /* implementation dependent */
6439         break;
6440     case 23:
6441         switch (sel) {
6442         case 0:
6443             gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6444             rn = "Debug";
6445             break;
6446         case 1:
6447 //            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
6448             rn = "TraceControl";
6449             goto cp0_unimplemented;
6450         case 2:
6451 //            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
6452             rn = "TraceControl2";
6453             goto cp0_unimplemented;
6454         case 3:
6455 //            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
6456             rn = "UserTraceData";
6457             goto cp0_unimplemented;
6458         case 4:
6459 //            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
6460             rn = "TraceBPC";
6461             goto cp0_unimplemented;
6462         default:
6463             goto cp0_unimplemented;
6464         }
6465         break;
6466     case 24:
6467         switch (sel) {
6468         case 0:
6469             /* EJTAG support */
6470             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6471             tcg_gen_ext32s_tl(arg, arg);
6472             rn = "DEPC";
6473             break;
6474         default:
6475             goto cp0_unimplemented;
6476         }
6477         break;
6478     case 25:
6479         switch (sel) {
6480         case 0:
6481             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6482             rn = "Performance0";
6483             break;
6484         case 1:
6485 //            gen_helper_mfc0_performance1(arg);
6486             rn = "Performance1";
6487             goto cp0_unimplemented;
6488         case 2:
6489 //            gen_helper_mfc0_performance2(arg);
6490             rn = "Performance2";
6491             goto cp0_unimplemented;
6492         case 3:
6493 //            gen_helper_mfc0_performance3(arg);
6494             rn = "Performance3";
6495             goto cp0_unimplemented;
6496         case 4:
6497 //            gen_helper_mfc0_performance4(arg);
6498             rn = "Performance4";
6499             goto cp0_unimplemented;
6500         case 5:
6501 //            gen_helper_mfc0_performance5(arg);
6502             rn = "Performance5";
6503             goto cp0_unimplemented;
6504         case 6:
6505 //            gen_helper_mfc0_performance6(arg);
6506             rn = "Performance6";
6507             goto cp0_unimplemented;
6508         case 7:
6509 //            gen_helper_mfc0_performance7(arg);
6510             rn = "Performance7";
6511             goto cp0_unimplemented;
6512         default:
6513             goto cp0_unimplemented;
6514         }
6515         break;
6516     case 26:
6517         switch (sel) {
6518         case 0:
6519             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6520             rn = "ErrCtl";
6521             break;
6522         default:
6523             goto cp0_unimplemented;
6524         }
6525         break;
6526     case 27:
6527         switch (sel) {
6528         case 0:
6529         case 1:
6530         case 2:
6531         case 3:
6532             tcg_gen_movi_tl(arg, 0); /* unimplemented */
6533             rn = "CacheErr";
6534             break;
6535         default:
6536             goto cp0_unimplemented;
6537         }
6538         break;
6539     case 28:
6540         switch (sel) {
6541         case 0:
6542         case 2:
6543         case 4:
6544         case 6:
6545             {
6546                 TCGv_i64 tmp = tcg_temp_new_i64();
6547                 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
6548                 gen_move_low32(arg, tmp);
6549                 tcg_temp_free_i64(tmp);
6550             }
6551             rn = "TagLo";
6552             break;
6553         case 1:
6554         case 3:
6555         case 5:
6556         case 7:
6557             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6558             rn = "DataLo";
6559             break;
6560         default:
6561             goto cp0_unimplemented;
6562         }
6563         break;
6564     case 29:
6565         switch (sel) {
6566         case 0:
6567         case 2:
6568         case 4:
6569         case 6:
6570             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6571             rn = "TagHi";
6572             break;
6573         case 1:
6574         case 3:
6575         case 5:
6576         case 7:
6577             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6578             rn = "DataHi";
6579             break;
6580         default:
6581             goto cp0_unimplemented;
6582         }
6583         break;
6584     case 30:
6585         switch (sel) {
6586         case 0:
6587             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6588             tcg_gen_ext32s_tl(arg, arg);
6589             rn = "ErrorEPC";
6590             break;
6591         default:
6592             goto cp0_unimplemented;
6593         }
6594         break;
6595     case 31:
6596         switch (sel) {
6597         case 0:
6598             /* EJTAG support */
6599             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6600             rn = "DESAVE";
6601             break;
6602         case 2:
6603         case 3:
6604         case 4:
6605         case 5:
6606         case 6:
6607         case 7:
6608             CP0_CHECK(ctx->kscrexist & (1 << sel));
6609             tcg_gen_ld_tl(arg, cpu_env,
6610                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
6611             tcg_gen_ext32s_tl(arg, arg);
6612             rn = "KScratch";
6613             break;
6614         default:
6615             goto cp0_unimplemented;
6616         }
6617         break;
6618     default:
6619        goto cp0_unimplemented;
6620     }
6621     trace_mips_translate_c0("mfc0", rn, reg, sel);
6622     return;
6623
6624 cp0_unimplemented:
6625     qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
6626     gen_mfc0_unimplemented(ctx, arg);
6627 }
6628
6629 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6630 {
6631     const char *rn = "invalid";
6632
6633     if (sel != 0)
6634         check_insn(ctx, ISA_MIPS32);
6635
6636     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6637         gen_io_start();
6638     }
6639
6640     switch (reg) {
6641     case 0:
6642         switch (sel) {
6643         case 0:
6644             gen_helper_mtc0_index(cpu_env, arg);
6645             rn = "Index";
6646             break;
6647         case 1:
6648             CP0_CHECK(ctx->insn_flags & ASE_MT);
6649             gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6650             rn = "MVPControl";
6651             break;
6652         case 2:
6653             CP0_CHECK(ctx->insn_flags & ASE_MT);
6654             /* ignored */
6655             rn = "MVPConf0";
6656             break;
6657         case 3:
6658             CP0_CHECK(ctx->insn_flags & ASE_MT);
6659             /* ignored */
6660             rn = "MVPConf1";
6661             break;
6662         case 4:
6663             CP0_CHECK(ctx->vp);
6664             /* ignored */
6665             rn = "VPControl";
6666             break;
6667         default:
6668             goto cp0_unimplemented;
6669         }
6670         break;
6671     case 1:
6672         switch (sel) {
6673         case 0:
6674             /* ignored */
6675             rn = "Random";
6676             break;
6677         case 1:
6678             CP0_CHECK(ctx->insn_flags & ASE_MT);
6679             gen_helper_mtc0_vpecontrol(cpu_env, arg);
6680             rn = "VPEControl";
6681             break;
6682         case 2:
6683             CP0_CHECK(ctx->insn_flags & ASE_MT);
6684             gen_helper_mtc0_vpeconf0(cpu_env, arg);
6685             rn = "VPEConf0";
6686             break;
6687         case 3:
6688             CP0_CHECK(ctx->insn_flags & ASE_MT);
6689             gen_helper_mtc0_vpeconf1(cpu_env, arg);
6690             rn = "VPEConf1";
6691             break;
6692         case 4:
6693             CP0_CHECK(ctx->insn_flags & ASE_MT);
6694             gen_helper_mtc0_yqmask(cpu_env, arg);
6695             rn = "YQMask";
6696             break;
6697         case 5:
6698             CP0_CHECK(ctx->insn_flags & ASE_MT);
6699             tcg_gen_st_tl(arg, cpu_env,
6700                           offsetof(CPUMIPSState, CP0_VPESchedule));
6701             rn = "VPESchedule";
6702             break;
6703         case 6:
6704             CP0_CHECK(ctx->insn_flags & ASE_MT);
6705             tcg_gen_st_tl(arg, cpu_env,
6706                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
6707             rn = "VPEScheFBack";
6708             break;
6709         case 7:
6710             CP0_CHECK(ctx->insn_flags & ASE_MT);
6711             gen_helper_mtc0_vpeopt(cpu_env, arg);
6712             rn = "VPEOpt";
6713             break;
6714         default:
6715             goto cp0_unimplemented;
6716         }
6717         break;
6718     case 2:
6719         switch (sel) {
6720         case 0:
6721             gen_helper_mtc0_entrylo0(cpu_env, arg);
6722             rn = "EntryLo0";
6723             break;
6724         case 1:
6725             CP0_CHECK(ctx->insn_flags & ASE_MT);
6726             gen_helper_mtc0_tcstatus(cpu_env, arg);
6727             rn = "TCStatus";
6728             break;
6729         case 2:
6730             CP0_CHECK(ctx->insn_flags & ASE_MT);
6731             gen_helper_mtc0_tcbind(cpu_env, arg);
6732             rn = "TCBind";
6733             break;
6734         case 3:
6735             CP0_CHECK(ctx->insn_flags & ASE_MT);
6736             gen_helper_mtc0_tcrestart(cpu_env, arg);
6737             rn = "TCRestart";
6738             break;
6739         case 4:
6740             CP0_CHECK(ctx->insn_flags & ASE_MT);
6741             gen_helper_mtc0_tchalt(cpu_env, arg);
6742             rn = "TCHalt";
6743             break;
6744         case 5:
6745             CP0_CHECK(ctx->insn_flags & ASE_MT);
6746             gen_helper_mtc0_tccontext(cpu_env, arg);
6747             rn = "TCContext";
6748             break;
6749         case 6:
6750             CP0_CHECK(ctx->insn_flags & ASE_MT);
6751             gen_helper_mtc0_tcschedule(cpu_env, arg);
6752             rn = "TCSchedule";
6753             break;
6754         case 7:
6755             CP0_CHECK(ctx->insn_flags & ASE_MT);
6756             gen_helper_mtc0_tcschefback(cpu_env, arg);
6757             rn = "TCScheFBack";
6758             break;
6759         default:
6760             goto cp0_unimplemented;
6761         }
6762         break;
6763     case 3:
6764         switch (sel) {
6765         case 0:
6766             gen_helper_mtc0_entrylo1(cpu_env, arg);
6767             rn = "EntryLo1";
6768             break;
6769         case 1:
6770             CP0_CHECK(ctx->vp);
6771             /* ignored */
6772             rn = "GlobalNumber";
6773             break;
6774         default:
6775             goto cp0_unimplemented;
6776         }
6777         break;
6778     case 4:
6779         switch (sel) {
6780         case 0:
6781             gen_helper_mtc0_context(cpu_env, arg);
6782             rn = "Context";
6783             break;
6784         case 1:
6785 //            gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
6786             rn = "ContextConfig";
6787             goto cp0_unimplemented;
6788         case 2:
6789             CP0_CHECK(ctx->ulri);
6790             tcg_gen_st_tl(arg, cpu_env,
6791                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6792             rn = "UserLocal";
6793             break;
6794         default:
6795             goto cp0_unimplemented;
6796         }
6797         break;
6798     case 5:
6799         switch (sel) {
6800         case 0:
6801             gen_helper_mtc0_pagemask(cpu_env, arg);
6802             rn = "PageMask";
6803             break;
6804         case 1:
6805             check_insn(ctx, ISA_MIPS32R2);
6806             gen_helper_mtc0_pagegrain(cpu_env, arg);
6807             rn = "PageGrain";
6808             ctx->base.is_jmp = DISAS_STOP;
6809             break;
6810         case 2:
6811             CP0_CHECK(ctx->sc);
6812             gen_helper_mtc0_segctl0(cpu_env, arg);
6813             rn = "SegCtl0";
6814             break;
6815         case 3:
6816             CP0_CHECK(ctx->sc);
6817             gen_helper_mtc0_segctl1(cpu_env, arg);
6818             rn = "SegCtl1";
6819             break;
6820         case 4:
6821             CP0_CHECK(ctx->sc);
6822             gen_helper_mtc0_segctl2(cpu_env, arg);
6823             rn = "SegCtl2";
6824             break;
6825         case 5:
6826             check_pw(ctx);
6827             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6828             rn = "PWBase";
6829             break;
6830         case 6:
6831             check_pw(ctx);
6832             gen_helper_mtc0_pwfield(cpu_env, arg);
6833             rn = "PWField";
6834             break;
6835         case 7:
6836             check_pw(ctx);
6837             gen_helper_mtc0_pwsize(cpu_env, arg);
6838             rn = "PWSize";
6839             break;
6840         default:
6841             goto cp0_unimplemented;
6842         }
6843         break;
6844     case 6:
6845         switch (sel) {
6846         case 0:
6847             gen_helper_mtc0_wired(cpu_env, arg);
6848             rn = "Wired";
6849             break;
6850         case 1:
6851             check_insn(ctx, ISA_MIPS32R2);
6852             gen_helper_mtc0_srsconf0(cpu_env, arg);
6853             rn = "SRSConf0";
6854             break;
6855         case 2:
6856             check_insn(ctx, ISA_MIPS32R2);
6857             gen_helper_mtc0_srsconf1(cpu_env, arg);
6858             rn = "SRSConf1";
6859             break;
6860         case 3:
6861             check_insn(ctx, ISA_MIPS32R2);
6862             gen_helper_mtc0_srsconf2(cpu_env, arg);
6863             rn = "SRSConf2";
6864             break;
6865         case 4:
6866             check_insn(ctx, ISA_MIPS32R2);
6867             gen_helper_mtc0_srsconf3(cpu_env, arg);
6868             rn = "SRSConf3";
6869             break;
6870         case 5:
6871             check_insn(ctx, ISA_MIPS32R2);
6872             gen_helper_mtc0_srsconf4(cpu_env, arg);
6873             rn = "SRSConf4";
6874             break;
6875         case 6:
6876             check_pw(ctx);
6877             gen_helper_mtc0_pwctl(cpu_env, arg);
6878             rn = "PWCtl";
6879             break;
6880         default:
6881             goto cp0_unimplemented;
6882         }
6883         break;
6884     case 7:
6885         switch (sel) {
6886         case 0:
6887             check_insn(ctx, ISA_MIPS32R2);
6888             gen_helper_mtc0_hwrena(cpu_env, arg);
6889             ctx->base.is_jmp = DISAS_STOP;
6890             rn = "HWREna";
6891             break;
6892         default:
6893             goto cp0_unimplemented;
6894         }
6895         break;
6896     case 8:
6897         switch (sel) {
6898         case 0:
6899             /* ignored */
6900             rn = "BadVAddr";
6901             break;
6902         case 1:
6903             /* ignored */
6904             rn = "BadInstr";
6905             break;
6906         case 2:
6907             /* ignored */
6908             rn = "BadInstrP";
6909             break;
6910         case 3:
6911             /* ignored */
6912             rn = "BadInstrX";
6913             break;
6914         default:
6915             goto cp0_unimplemented;
6916         }
6917         break;
6918     case 9:
6919         switch (sel) {
6920         case 0:
6921             gen_helper_mtc0_count(cpu_env, arg);
6922             rn = "Count";
6923             break;
6924         /* 6,7 are implementation dependent */
6925         default:
6926             goto cp0_unimplemented;
6927         }
6928         break;
6929     case 10:
6930         switch (sel) {
6931         case 0:
6932             gen_helper_mtc0_entryhi(cpu_env, arg);
6933             rn = "EntryHi";
6934             break;
6935         default:
6936             goto cp0_unimplemented;
6937         }
6938         break;
6939     case 11:
6940         switch (sel) {
6941         case 0:
6942             gen_helper_mtc0_compare(cpu_env, arg);
6943             rn = "Compare";
6944             break;
6945         /* 6,7 are implementation dependent */
6946         default:
6947             goto cp0_unimplemented;
6948         }
6949         break;
6950     case 12:
6951         switch (sel) {
6952         case 0:
6953             save_cpu_state(ctx, 1);
6954             gen_helper_mtc0_status(cpu_env, arg);
6955             /* DISAS_STOP isn't good enough here, hflags may have changed. */
6956             gen_save_pc(ctx->base.pc_next + 4);
6957             ctx->base.is_jmp = DISAS_EXIT;
6958             rn = "Status";
6959             break;
6960         case 1:
6961             check_insn(ctx, ISA_MIPS32R2);
6962             gen_helper_mtc0_intctl(cpu_env, arg);
6963             /* Stop translation as we may have switched the execution mode */
6964             ctx->base.is_jmp = DISAS_STOP;
6965             rn = "IntCtl";
6966             break;
6967         case 2:
6968             check_insn(ctx, ISA_MIPS32R2);
6969             gen_helper_mtc0_srsctl(cpu_env, arg);
6970             /* Stop translation as we may have switched the execution mode */
6971             ctx->base.is_jmp = DISAS_STOP;
6972             rn = "SRSCtl";
6973             break;
6974         case 3:
6975             check_insn(ctx, ISA_MIPS32R2);
6976             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6977             /* Stop translation as we may have switched the execution mode */
6978             ctx->base.is_jmp = DISAS_STOP;
6979             rn = "SRSMap";
6980             break;
6981         default:
6982             goto cp0_unimplemented;
6983         }
6984         break;
6985     case 13:
6986         switch (sel) {
6987         case 0:
6988             save_cpu_state(ctx, 1);
6989             gen_helper_mtc0_cause(cpu_env, arg);
6990             /* Stop translation as we may have triggered an interrupt.
6991              * DISAS_STOP isn't sufficient, we need to ensure we break out of
6992              * translated code to check for pending interrupts.  */
6993             gen_save_pc(ctx->base.pc_next + 4);
6994             ctx->base.is_jmp = DISAS_EXIT;
6995             rn = "Cause";
6996             break;
6997         default:
6998             goto cp0_unimplemented;
6999         }
7000         break;
7001     case 14:
7002         switch (sel) {
7003         case 0:
7004             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7005             rn = "EPC";
7006             break;
7007         default:
7008             goto cp0_unimplemented;
7009         }
7010         break;
7011     case 15:
7012         switch (sel) {
7013         case 0:
7014             /* ignored */
7015             rn = "PRid";
7016             break;
7017         case 1:
7018             check_insn(ctx, ISA_MIPS32R2);
7019             gen_helper_mtc0_ebase(cpu_env, arg);
7020             rn = "EBase";
7021             break;
7022         default:
7023             goto cp0_unimplemented;
7024         }
7025         break;
7026     case 16:
7027         switch (sel) {
7028         case 0:
7029             gen_helper_mtc0_config0(cpu_env, arg);
7030             rn = "Config";
7031             /* Stop translation as we may have switched the execution mode */
7032             ctx->base.is_jmp = DISAS_STOP;
7033             break;
7034         case 1:
7035             /* ignored, read only */
7036             rn = "Config1";
7037             break;
7038         case 2:
7039             gen_helper_mtc0_config2(cpu_env, arg);
7040             rn = "Config2";
7041             /* Stop translation as we may have switched the execution mode */
7042             ctx->base.is_jmp = DISAS_STOP;
7043             break;
7044         case 3:
7045             gen_helper_mtc0_config3(cpu_env, arg);
7046             rn = "Config3";
7047             /* Stop translation as we may have switched the execution mode */
7048             ctx->base.is_jmp = DISAS_STOP;
7049             break;
7050         case 4:
7051             gen_helper_mtc0_config4(cpu_env, arg);
7052             rn = "Config4";
7053             ctx->base.is_jmp = DISAS_STOP;
7054             break;
7055         case 5:
7056             gen_helper_mtc0_config5(cpu_env, arg);
7057             rn = "Config5";
7058             /* Stop translation as we may have switched the execution mode */
7059             ctx->base.is_jmp = DISAS_STOP;
7060             break;
7061         /* 6,7 are implementation dependent */
7062         case 6:
7063             /* ignored */
7064             rn = "Config6";
7065             break;
7066         case 7:
7067             /* ignored */
7068             rn = "Config7";
7069             break;
7070         default:
7071             rn = "Invalid config selector";
7072             goto cp0_unimplemented;
7073         }
7074         break;
7075     case 17:
7076         switch (sel) {
7077         case 0:
7078             gen_helper_mtc0_lladdr(cpu_env, arg);
7079             rn = "LLAddr";
7080             break;
7081         case 1:
7082             CP0_CHECK(ctx->mrp);
7083             gen_helper_mtc0_maar(cpu_env, arg);
7084             rn = "MAAR";
7085             break;
7086         case 2:
7087             CP0_CHECK(ctx->mrp);
7088             gen_helper_mtc0_maari(cpu_env, arg);
7089             rn = "MAARI";
7090             break;
7091         default:
7092             goto cp0_unimplemented;
7093         }
7094         break;
7095     case 18:
7096         switch (sel) {
7097         case 0:
7098         case 1:
7099         case 2:
7100         case 3:
7101         case 4:
7102         case 5:
7103         case 6:
7104         case 7:
7105             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7106             gen_helper_0e1i(mtc0_watchlo, arg, sel);
7107             rn = "WatchLo";
7108             break;
7109         default:
7110             goto cp0_unimplemented;
7111         }
7112         break;
7113     case 19:
7114         switch (sel) {
7115         case 0:
7116         case 1:
7117         case 2:
7118         case 3:
7119         case 4:
7120         case 5:
7121         case 6:
7122         case 7:
7123             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7124             gen_helper_0e1i(mtc0_watchhi, arg, sel);
7125             rn = "WatchHi";
7126             break;
7127         default:
7128             goto cp0_unimplemented;
7129         }
7130         break;
7131     case 20:
7132         switch (sel) {
7133         case 0:
7134 #if defined(TARGET_MIPS64)
7135             check_insn(ctx, ISA_MIPS3);
7136             gen_helper_mtc0_xcontext(cpu_env, arg);
7137             rn = "XContext";
7138             break;
7139 #endif
7140         default:
7141             goto cp0_unimplemented;
7142         }
7143         break;
7144     case 21:
7145        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7146         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7147         switch (sel) {
7148         case 0:
7149             gen_helper_mtc0_framemask(cpu_env, arg);
7150             rn = "Framemask";
7151             break;
7152         default:
7153             goto cp0_unimplemented;
7154         }
7155         break;
7156     case 22:
7157         /* ignored */
7158         rn = "Diagnostic"; /* implementation dependent */
7159         break;
7160     case 23:
7161         switch (sel) {
7162         case 0:
7163             gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7164             /* DISAS_STOP isn't good enough here, hflags may have changed. */
7165             gen_save_pc(ctx->base.pc_next + 4);
7166             ctx->base.is_jmp = DISAS_EXIT;
7167             rn = "Debug";
7168             break;
7169         case 1:
7170 //            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
7171             rn = "TraceControl";
7172             /* Stop translation as we may have switched the execution mode */
7173             ctx->base.is_jmp = DISAS_STOP;
7174             goto cp0_unimplemented;
7175         case 2:
7176 //            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
7177             rn = "TraceControl2";
7178             /* Stop translation as we may have switched the execution mode */
7179             ctx->base.is_jmp = DISAS_STOP;
7180             goto cp0_unimplemented;
7181         case 3:
7182             /* Stop translation as we may have switched the execution mode */
7183             ctx->base.is_jmp = DISAS_STOP;
7184 //            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
7185             rn = "UserTraceData";
7186             /* Stop translation as we may have switched the execution mode */
7187             ctx->base.is_jmp = DISAS_STOP;
7188             goto cp0_unimplemented;
7189         case 4:
7190 //            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
7191             /* Stop translation as we may have switched the execution mode */
7192             ctx->base.is_jmp = DISAS_STOP;
7193             rn = "TraceBPC";
7194             goto cp0_unimplemented;
7195         default:
7196             goto cp0_unimplemented;
7197         }
7198         break;
7199     case 24:
7200         switch (sel) {
7201         case 0:
7202             /* EJTAG support */
7203             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7204             rn = "DEPC";
7205             break;
7206         default:
7207             goto cp0_unimplemented;
7208         }
7209         break;
7210     case 25:
7211         switch (sel) {
7212         case 0:
7213             gen_helper_mtc0_performance0(cpu_env, arg);
7214             rn = "Performance0";
7215             break;
7216         case 1:
7217 //            gen_helper_mtc0_performance1(arg);
7218             rn = "Performance1";
7219             goto cp0_unimplemented;
7220         case 2:
7221 //            gen_helper_mtc0_performance2(arg);
7222             rn = "Performance2";
7223             goto cp0_unimplemented;
7224         case 3:
7225 //            gen_helper_mtc0_performance3(arg);
7226             rn = "Performance3";
7227             goto cp0_unimplemented;
7228         case 4:
7229 //            gen_helper_mtc0_performance4(arg);
7230             rn = "Performance4";
7231             goto cp0_unimplemented;
7232         case 5:
7233 //            gen_helper_mtc0_performance5(arg);
7234             rn = "Performance5";
7235             goto cp0_unimplemented;
7236         case 6:
7237 //            gen_helper_mtc0_performance6(arg);
7238             rn = "Performance6";
7239             goto cp0_unimplemented;
7240         case 7:
7241 //            gen_helper_mtc0_performance7(arg);
7242             rn = "Performance7";
7243             goto cp0_unimplemented;
7244         default:
7245             goto cp0_unimplemented;
7246         }
7247        break;
7248     case 26:
7249         switch (sel) {
7250         case 0:
7251             gen_helper_mtc0_errctl(cpu_env, arg);
7252             ctx->base.is_jmp = DISAS_STOP;
7253             rn = "ErrCtl";
7254             break;
7255         default:
7256             goto cp0_unimplemented;
7257         }
7258         break;
7259     case 27:
7260         switch (sel) {
7261         case 0:
7262         case 1:
7263         case 2:
7264         case 3:
7265             /* ignored */
7266             rn = "CacheErr";
7267             break;
7268         default:
7269             goto cp0_unimplemented;
7270         }
7271        break;
7272     case 28:
7273         switch (sel) {
7274         case 0:
7275         case 2:
7276         case 4:
7277         case 6:
7278             gen_helper_mtc0_taglo(cpu_env, arg);
7279             rn = "TagLo";
7280             break;
7281         case 1:
7282         case 3:
7283         case 5:
7284         case 7:
7285             gen_helper_mtc0_datalo(cpu_env, arg);
7286             rn = "DataLo";
7287             break;
7288         default:
7289             goto cp0_unimplemented;
7290         }
7291         break;
7292     case 29:
7293         switch (sel) {
7294         case 0:
7295         case 2:
7296         case 4:
7297         case 6:
7298             gen_helper_mtc0_taghi(cpu_env, arg);
7299             rn = "TagHi";
7300             break;
7301         case 1:
7302         case 3:
7303         case 5:
7304         case 7:
7305             gen_helper_mtc0_datahi(cpu_env, arg);
7306             rn = "DataHi";
7307             break;
7308         default:
7309             rn = "invalid sel";
7310             goto cp0_unimplemented;
7311         }
7312        break;
7313     case 30:
7314         switch (sel) {
7315         case 0:
7316             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7317             rn = "ErrorEPC";
7318             break;
7319         default:
7320             goto cp0_unimplemented;
7321         }
7322         break;
7323     case 31:
7324         switch (sel) {
7325         case 0:
7326             /* EJTAG support */
7327             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7328             rn = "DESAVE";
7329             break;
7330         case 2:
7331         case 3:
7332         case 4:
7333         case 5:
7334         case 6:
7335         case 7:
7336             CP0_CHECK(ctx->kscrexist & (1 << sel));
7337             tcg_gen_st_tl(arg, cpu_env,
7338                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7339             rn = "KScratch";
7340             break;
7341         default:
7342             goto cp0_unimplemented;
7343         }
7344         break;
7345     default:
7346        goto cp0_unimplemented;
7347     }
7348     trace_mips_translate_c0("mtc0", rn, reg, sel);
7349
7350     /* For simplicity assume that all writes can cause interrupts.  */
7351     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7352         gen_io_end();
7353         /* DISAS_STOP isn't sufficient, we need to ensure we break out of
7354          * translated code to check for pending interrupts.  */
7355         gen_save_pc(ctx->base.pc_next + 4);
7356         ctx->base.is_jmp = DISAS_EXIT;
7357     }
7358     return;
7359
7360 cp0_unimplemented:
7361     qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
7362 }
7363
7364 #if defined(TARGET_MIPS64)
7365 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7366 {
7367     const char *rn = "invalid";
7368
7369     if (sel != 0)
7370         check_insn(ctx, ISA_MIPS64);
7371
7372     switch (reg) {
7373     case 0:
7374         switch (sel) {
7375         case 0:
7376             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7377             rn = "Index";
7378             break;
7379         case 1:
7380             CP0_CHECK(ctx->insn_flags & ASE_MT);
7381             gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7382             rn = "MVPControl";
7383             break;
7384         case 2:
7385             CP0_CHECK(ctx->insn_flags & ASE_MT);
7386             gen_helper_mfc0_mvpconf0(arg, cpu_env);
7387             rn = "MVPConf0";
7388             break;
7389         case 3:
7390             CP0_CHECK(ctx->insn_flags & ASE_MT);
7391             gen_helper_mfc0_mvpconf1(arg, cpu_env);
7392             rn = "MVPConf1";
7393             break;
7394         case 4:
7395             CP0_CHECK(ctx->vp);
7396             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
7397             rn = "VPControl";
7398             break;
7399         default:
7400             goto cp0_unimplemented;
7401         }
7402         break;
7403     case 1:
7404         switch (sel) {
7405         case 0:
7406             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7407             gen_helper_mfc0_random(arg, cpu_env);
7408             rn = "Random";
7409             break;
7410         case 1:
7411             CP0_CHECK(ctx->insn_flags & ASE_MT);
7412             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7413             rn = "VPEControl";
7414             break;
7415         case 2:
7416             CP0_CHECK(ctx->insn_flags & ASE_MT);
7417             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7418             rn = "VPEConf0";
7419             break;
7420         case 3:
7421             CP0_CHECK(ctx->insn_flags & ASE_MT);
7422             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7423             rn = "VPEConf1";
7424             break;
7425         case 4:
7426             CP0_CHECK(ctx->insn_flags & ASE_MT);
7427             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
7428             rn = "YQMask";
7429             break;
7430         case 5:
7431             CP0_CHECK(ctx->insn_flags & ASE_MT);
7432             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
7433             rn = "VPESchedule";
7434             break;
7435         case 6:
7436             CP0_CHECK(ctx->insn_flags & ASE_MT);
7437             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
7438             rn = "VPEScheFBack";
7439             break;
7440         case 7:
7441             CP0_CHECK(ctx->insn_flags & ASE_MT);
7442             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7443             rn = "VPEOpt";
7444             break;
7445         default:
7446             goto cp0_unimplemented;
7447         }
7448         break;
7449     case 2:
7450         switch (sel) {
7451         case 0:
7452             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
7453             rn = "EntryLo0";
7454             break;
7455         case 1:
7456             CP0_CHECK(ctx->insn_flags & ASE_MT);
7457             gen_helper_mfc0_tcstatus(arg, cpu_env);
7458             rn = "TCStatus";
7459             break;
7460         case 2:
7461             CP0_CHECK(ctx->insn_flags & ASE_MT);
7462             gen_helper_mfc0_tcbind(arg, cpu_env);
7463             rn = "TCBind";
7464             break;
7465         case 3:
7466             CP0_CHECK(ctx->insn_flags & ASE_MT);
7467             gen_helper_dmfc0_tcrestart(arg, cpu_env);
7468             rn = "TCRestart";
7469             break;
7470         case 4:
7471             CP0_CHECK(ctx->insn_flags & ASE_MT);
7472             gen_helper_dmfc0_tchalt(arg, cpu_env);
7473             rn = "TCHalt";
7474             break;
7475         case 5:
7476             CP0_CHECK(ctx->insn_flags & ASE_MT);
7477             gen_helper_dmfc0_tccontext(arg, cpu_env);
7478             rn = "TCContext";
7479             break;
7480         case 6:
7481             CP0_CHECK(ctx->insn_flags & ASE_MT);
7482             gen_helper_dmfc0_tcschedule(arg, cpu_env);
7483             rn = "TCSchedule";
7484             break;
7485         case 7:
7486             CP0_CHECK(ctx->insn_flags & ASE_MT);
7487             gen_helper_dmfc0_tcschefback(arg, cpu_env);
7488             rn = "TCScheFBack";
7489             break;
7490         default:
7491             goto cp0_unimplemented;
7492         }
7493         break;
7494     case 3:
7495         switch (sel) {
7496         case 0:
7497             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
7498             rn = "EntryLo1";
7499             break;
7500         case 1:
7501             CP0_CHECK(ctx->vp);
7502             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
7503             rn = "GlobalNumber";
7504             break;
7505         default:
7506             goto cp0_unimplemented;
7507         }
7508         break;
7509     case 4:
7510         switch (sel) {
7511         case 0:
7512             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
7513             rn = "Context";
7514             break;
7515         case 1:
7516 //            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
7517             rn = "ContextConfig";
7518             goto cp0_unimplemented;
7519         case 2:
7520             CP0_CHECK(ctx->ulri);
7521             tcg_gen_ld_tl(arg, cpu_env,
7522                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7523             rn = "UserLocal";
7524             break;
7525         default:
7526             goto cp0_unimplemented;
7527         }
7528         break;
7529     case 5:
7530         switch (sel) {
7531         case 0:
7532             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
7533             rn = "PageMask";
7534             break;
7535         case 1:
7536             check_insn(ctx, ISA_MIPS32R2);
7537             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7538             rn = "PageGrain";
7539             break;
7540         case 2:
7541             CP0_CHECK(ctx->sc);
7542             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7543             rn = "SegCtl0";
7544             break;
7545         case 3:
7546             CP0_CHECK(ctx->sc);
7547             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7548             rn = "SegCtl1";
7549             break;
7550         case 4:
7551             CP0_CHECK(ctx->sc);
7552             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7553             rn = "SegCtl2";
7554             break;
7555         case 5:
7556             check_pw(ctx);
7557             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
7558             rn = "PWBase";
7559             break;
7560         case 6:
7561             check_pw(ctx);
7562             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
7563             rn = "PWField";
7564             break;
7565         case 7:
7566             check_pw(ctx);
7567             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
7568             rn = "PWSize";
7569             break;
7570         default:
7571             goto cp0_unimplemented;
7572         }
7573         break;
7574     case 6:
7575         switch (sel) {
7576         case 0:
7577             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
7578             rn = "Wired";
7579             break;
7580         case 1:
7581             check_insn(ctx, ISA_MIPS32R2);
7582             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
7583             rn = "SRSConf0";
7584             break;
7585         case 2:
7586             check_insn(ctx, ISA_MIPS32R2);
7587             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
7588             rn = "SRSConf1";
7589             break;
7590         case 3:
7591             check_insn(ctx, ISA_MIPS32R2);
7592             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7593             rn = "SRSConf2";
7594             break;
7595         case 4:
7596             check_insn(ctx, ISA_MIPS32R2);
7597             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7598             rn = "SRSConf3";
7599             break;
7600         case 5:
7601             check_insn(ctx, ISA_MIPS32R2);
7602             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7603             rn = "SRSConf4";
7604             break;
7605         case 6:
7606             check_pw(ctx);
7607             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7608             rn = "PWCtl";
7609             break;
7610         default:
7611             goto cp0_unimplemented;
7612         }
7613         break;
7614     case 7:
7615         switch (sel) {
7616         case 0:
7617             check_insn(ctx, ISA_MIPS32R2);
7618             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7619             rn = "HWREna";
7620             break;
7621         default:
7622             goto cp0_unimplemented;
7623         }
7624         break;
7625     case 8:
7626         switch (sel) {
7627         case 0:
7628             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7629             rn = "BadVAddr";
7630             break;
7631         case 1:
7632             CP0_CHECK(ctx->bi);
7633             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7634             rn = "BadInstr";
7635             break;
7636         case 2:
7637             CP0_CHECK(ctx->bp);
7638             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7639             rn = "BadInstrP";
7640             break;
7641         case 3:
7642             CP0_CHECK(ctx->bi);
7643             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7644             tcg_gen_andi_tl(arg, arg, ~0xffff);
7645             rn = "BadInstrX";
7646             break;
7647         default:
7648             goto cp0_unimplemented;
7649         }
7650         break;
7651     case 9:
7652         switch (sel) {
7653         case 0:
7654             /* Mark as an IO operation because we read the time.  */
7655             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7656                 gen_io_start();
7657             }
7658             gen_helper_mfc0_count(arg, cpu_env);
7659             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7660                 gen_io_end();
7661             }
7662             /* Break the TB to be able to take timer interrupts immediately
7663                after reading count. DISAS_STOP isn't sufficient, we need to
7664                ensure we break completely out of translated code.  */
7665             gen_save_pc(ctx->base.pc_next + 4);
7666             ctx->base.is_jmp = DISAS_EXIT;
7667             rn = "Count";
7668             break;
7669         /* 6,7 are implementation dependent */
7670         default:
7671             goto cp0_unimplemented;
7672         }
7673         break;
7674     case 10:
7675         switch (sel) {
7676         case 0:
7677             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7678             rn = "EntryHi";
7679             break;
7680         default:
7681             goto cp0_unimplemented;
7682         }
7683         break;
7684     case 11:
7685         switch (sel) {
7686         case 0:
7687             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7688             rn = "Compare";
7689             break;
7690         /* 6,7 are implementation dependent */
7691         default:
7692             goto cp0_unimplemented;
7693         }
7694         break;
7695     case 12:
7696         switch (sel) {
7697         case 0:
7698             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7699             rn = "Status";
7700             break;
7701         case 1:
7702             check_insn(ctx, ISA_MIPS32R2);
7703             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7704             rn = "IntCtl";
7705             break;
7706         case 2:
7707             check_insn(ctx, ISA_MIPS32R2);
7708             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7709             rn = "SRSCtl";
7710             break;
7711         case 3:
7712             check_insn(ctx, ISA_MIPS32R2);
7713             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7714             rn = "SRSMap";
7715             break;
7716         default:
7717             goto cp0_unimplemented;
7718         }
7719         break;
7720     case 13:
7721         switch (sel) {
7722         case 0:
7723             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7724             rn = "Cause";
7725             break;
7726         default:
7727             goto cp0_unimplemented;
7728         }
7729         break;
7730     case 14:
7731         switch (sel) {
7732         case 0:
7733             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7734             rn = "EPC";
7735             break;
7736         default:
7737             goto cp0_unimplemented;
7738         }
7739         break;
7740     case 15:
7741         switch (sel) {
7742         case 0:
7743             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7744             rn = "PRid";
7745             break;
7746         case 1:
7747             check_insn(ctx, ISA_MIPS32R2);
7748             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7749             rn = "EBase";
7750             break;
7751         case 3:
7752             check_insn(ctx, ISA_MIPS32R2);
7753             CP0_CHECK(ctx->cmgcr);
7754             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7755             rn = "CMGCRBase";
7756             break;
7757         default:
7758             goto cp0_unimplemented;
7759         }
7760         break;
7761     case 16:
7762         switch (sel) {
7763         case 0:
7764             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7765             rn = "Config";
7766             break;
7767         case 1:
7768             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7769             rn = "Config1";
7770             break;
7771         case 2:
7772             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7773             rn = "Config2";
7774             break;
7775         case 3:
7776             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7777             rn = "Config3";
7778             break;
7779         case 4:
7780             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7781             rn = "Config4";
7782             break;
7783         case 5:
7784             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7785             rn = "Config5";
7786             break;
7787        /* 6,7 are implementation dependent */
7788         case 6:
7789             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7790             rn = "Config6";
7791             break;
7792         case 7:
7793             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7794             rn = "Config7";
7795             break;
7796         default:
7797             goto cp0_unimplemented;
7798         }
7799         break;
7800     case 17:
7801         switch (sel) {
7802         case 0:
7803             gen_helper_dmfc0_lladdr(arg, cpu_env);
7804             rn = "LLAddr";
7805             break;
7806         case 1:
7807             CP0_CHECK(ctx->mrp);
7808             gen_helper_dmfc0_maar(arg, cpu_env);
7809             rn = "MAAR";
7810             break;
7811         case 2:
7812             CP0_CHECK(ctx->mrp);
7813             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7814             rn = "MAARI";
7815             break;
7816         default:
7817             goto cp0_unimplemented;
7818         }
7819         break;
7820     case 18:
7821         switch (sel) {
7822         case 0:
7823         case 1:
7824         case 2:
7825         case 3:
7826         case 4:
7827         case 5:
7828         case 6:
7829         case 7:
7830             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7831             gen_helper_1e0i(dmfc0_watchlo, arg, sel);
7832             rn = "WatchLo";
7833             break;
7834         default:
7835             goto cp0_unimplemented;
7836         }
7837         break;
7838     case 19:
7839         switch (sel) {
7840         case 0:
7841         case 1:
7842         case 2:
7843         case 3:
7844         case 4:
7845         case 5:
7846         case 6:
7847         case 7:
7848             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7849             gen_helper_1e0i(mfc0_watchhi, arg, sel);
7850             rn = "WatchHi";
7851             break;
7852         default:
7853             goto cp0_unimplemented;
7854         }
7855         break;
7856     case 20:
7857         switch (sel) {
7858         case 0:
7859             check_insn(ctx, ISA_MIPS3);
7860             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7861             rn = "XContext";
7862             break;
7863         default:
7864             goto cp0_unimplemented;
7865         }
7866         break;
7867     case 21:
7868        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7869         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7870         switch (sel) {
7871         case 0:
7872             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7873             rn = "Framemask";
7874             break;
7875         default:
7876             goto cp0_unimplemented;
7877         }
7878         break;
7879     case 22:
7880         tcg_gen_movi_tl(arg, 0); /* unimplemented */
7881         rn = "'Diagnostic"; /* implementation dependent */
7882         break;
7883     case 23:
7884         switch (sel) {
7885         case 0:
7886             gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7887             rn = "Debug";
7888             break;
7889         case 1:
7890 //            gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
7891             rn = "TraceControl";
7892             goto cp0_unimplemented;
7893         case 2:
7894 //            gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
7895             rn = "TraceControl2";
7896             goto cp0_unimplemented;
7897         case 3:
7898 //            gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
7899             rn = "UserTraceData";
7900             goto cp0_unimplemented;
7901         case 4:
7902 //            gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
7903             rn = "TraceBPC";
7904             goto cp0_unimplemented;
7905         default:
7906             goto cp0_unimplemented;
7907         }
7908         break;
7909     case 24:
7910         switch (sel) {
7911         case 0:
7912             /* EJTAG support */
7913             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7914             rn = "DEPC";
7915             break;
7916         default:
7917             goto cp0_unimplemented;
7918         }
7919         break;
7920     case 25:
7921         switch (sel) {
7922         case 0:
7923             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7924             rn = "Performance0";
7925             break;
7926         case 1:
7927 //            gen_helper_dmfc0_performance1(arg);
7928             rn = "Performance1";
7929             goto cp0_unimplemented;
7930         case 2:
7931 //            gen_helper_dmfc0_performance2(arg);
7932             rn = "Performance2";
7933             goto cp0_unimplemented;
7934         case 3:
7935 //            gen_helper_dmfc0_performance3(arg);
7936             rn = "Performance3";
7937             goto cp0_unimplemented;
7938         case 4:
7939 //            gen_helper_dmfc0_performance4(arg);
7940             rn = "Performance4";
7941             goto cp0_unimplemented;
7942         case 5:
7943 //            gen_helper_dmfc0_performance5(arg);
7944             rn = "Performance5";
7945             goto cp0_unimplemented;
7946         case 6:
7947 //            gen_helper_dmfc0_performance6(arg);
7948             rn = "Performance6";
7949             goto cp0_unimplemented;
7950         case 7:
7951 //            gen_helper_dmfc0_performance7(arg);
7952             rn = "Performance7";
7953             goto cp0_unimplemented;
7954         default:
7955             goto cp0_unimplemented;
7956         }
7957         break;
7958     case 26:
7959         switch (sel) {
7960         case 0:
7961             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7962             rn = "ErrCtl";
7963             break;
7964         default:
7965             goto cp0_unimplemented;
7966         }
7967         break;
7968     case 27:
7969         switch (sel) {
7970         /* ignored */
7971         case 0:
7972         case 1:
7973         case 2:
7974         case 3:
7975             tcg_gen_movi_tl(arg, 0); /* unimplemented */
7976             rn = "CacheErr";
7977             break;
7978         default:
7979             goto cp0_unimplemented;
7980         }
7981         break;
7982     case 28:
7983         switch (sel) {
7984         case 0:
7985         case 2:
7986         case 4:
7987         case 6:
7988             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
7989             rn = "TagLo";
7990             break;
7991         case 1:
7992         case 3:
7993         case 5:
7994         case 7:
7995             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7996             rn = "DataLo";
7997             break;
7998         default:
7999             goto cp0_unimplemented;
8000         }
8001         break;
8002     case 29:
8003         switch (sel) {
8004         case 0:
8005         case 2:
8006         case 4:
8007         case 6:
8008             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
8009             rn = "TagHi";
8010             break;
8011         case 1:
8012         case 3:
8013         case 5:
8014         case 7:
8015             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
8016             rn = "DataHi";
8017             break;
8018         default:
8019             goto cp0_unimplemented;
8020         }
8021         break;
8022     case 30:
8023         switch (sel) {
8024         case 0:
8025             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8026             rn = "ErrorEPC";
8027             break;
8028         default:
8029             goto cp0_unimplemented;
8030         }
8031         break;
8032     case 31:
8033         switch (sel) {
8034         case 0:
8035             /* EJTAG support */
8036             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8037             rn = "DESAVE";
8038             break;
8039         case 2:
8040         case 3:
8041         case 4:
8042         case 5:
8043         case 6:
8044         case 7:
8045             CP0_CHECK(ctx->kscrexist & (1 << sel));
8046             tcg_gen_ld_tl(arg, cpu_env,
8047                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8048             rn = "KScratch";
8049             break;
8050         default:
8051             goto cp0_unimplemented;
8052         }
8053         break;
8054     default:
8055         goto cp0_unimplemented;
8056     }
8057     trace_mips_translate_c0("dmfc0", rn, reg, sel);
8058     return;
8059
8060 cp0_unimplemented:
8061     qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
8062     gen_mfc0_unimplemented(ctx, arg);
8063 }
8064
8065 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8066 {
8067     const char *rn = "invalid";
8068
8069     if (sel != 0)
8070         check_insn(ctx, ISA_MIPS64);
8071
8072     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8073         gen_io_start();
8074     }
8075
8076     switch (reg) {
8077     case 0:
8078         switch (sel) {
8079         case 0:
8080             gen_helper_mtc0_index(cpu_env, arg);
8081             rn = "Index";
8082             break;
8083         case 1:
8084             CP0_CHECK(ctx->insn_flags & ASE_MT);
8085             gen_helper_mtc0_mvpcontrol(cpu_env, arg);
8086             rn = "MVPControl";
8087             break;
8088         case 2:
8089             CP0_CHECK(ctx->insn_flags & ASE_MT);
8090             /* ignored */
8091             rn = "MVPConf0";
8092             break;
8093         case 3:
8094             CP0_CHECK(ctx->insn_flags & ASE_MT);
8095             /* ignored */
8096             rn = "MVPConf1";
8097             break;
8098         case 4:
8099             CP0_CHECK(ctx->vp);
8100             /* ignored */
8101             rn = "VPControl";
8102             break;
8103         default:
8104             goto cp0_unimplemented;
8105         }
8106         break;
8107     case 1:
8108         switch (sel) {
8109         case 0:
8110             /* ignored */
8111             rn = "Random";
8112             break;
8113         case 1:
8114             CP0_CHECK(ctx->insn_flags & ASE_MT);
8115             gen_helper_mtc0_vpecontrol(cpu_env, arg);
8116             rn = "VPEControl";
8117             break;
8118         case 2:
8119             CP0_CHECK(ctx->insn_flags & ASE_MT);
8120             gen_helper_mtc0_vpeconf0(cpu_env, arg);
8121             rn = "VPEConf0";
8122             break;
8123         case 3:
8124             CP0_CHECK(ctx->insn_flags & ASE_MT);
8125             gen_helper_mtc0_vpeconf1(cpu_env, arg);
8126             rn = "VPEConf1";
8127             break;
8128         case 4:
8129             CP0_CHECK(ctx->insn_flags & ASE_MT);
8130             gen_helper_mtc0_yqmask(cpu_env, arg);
8131             rn = "YQMask";
8132             break;
8133         case 5:
8134             CP0_CHECK(ctx->insn_flags & ASE_MT);
8135             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8136             rn = "VPESchedule";
8137             break;
8138         case 6:
8139             CP0_CHECK(ctx->insn_flags & ASE_MT);
8140             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8141             rn = "VPEScheFBack";
8142             break;
8143         case 7:
8144             CP0_CHECK(ctx->insn_flags & ASE_MT);
8145             gen_helper_mtc0_vpeopt(cpu_env, arg);
8146             rn = "VPEOpt";
8147             break;
8148         default:
8149             goto cp0_unimplemented;
8150         }
8151         break;
8152     case 2:
8153         switch (sel) {
8154         case 0:
8155             gen_helper_dmtc0_entrylo0(cpu_env, arg);
8156             rn = "EntryLo0";
8157             break;
8158         case 1:
8159             CP0_CHECK(ctx->insn_flags & ASE_MT);
8160             gen_helper_mtc0_tcstatus(cpu_env, arg);
8161             rn = "TCStatus";
8162             break;
8163         case 2:
8164             CP0_CHECK(ctx->insn_flags & ASE_MT);
8165             gen_helper_mtc0_tcbind(cpu_env, arg);
8166             rn = "TCBind";
8167             break;
8168         case 3:
8169             CP0_CHECK(ctx->insn_flags & ASE_MT);
8170             gen_helper_mtc0_tcrestart(cpu_env, arg);
8171             rn = "TCRestart";
8172             break;
8173         case 4:
8174             CP0_CHECK(ctx->insn_flags & ASE_MT);
8175             gen_helper_mtc0_tchalt(cpu_env, arg);
8176             rn = "TCHalt";
8177             break;
8178         case 5:
8179             CP0_CHECK(ctx->insn_flags & ASE_MT);
8180             gen_helper_mtc0_tccontext(cpu_env, arg);
8181             rn = "TCContext";
8182             break;
8183         case 6:
8184             CP0_CHECK(ctx->insn_flags & ASE_MT);
8185             gen_helper_mtc0_tcschedule(cpu_env, arg);
8186             rn = "TCSchedule";
8187             break;
8188         case 7:
8189             CP0_CHECK(ctx->insn_flags & ASE_MT);
8190             gen_helper_mtc0_tcschefback(cpu_env, arg);
8191             rn = "TCScheFBack";
8192             break;
8193         default:
8194             goto cp0_unimplemented;
8195         }
8196         break;
8197     case 3:
8198         switch (sel) {
8199         case 0:
8200             gen_helper_dmtc0_entrylo1(cpu_env, arg);
8201             rn = "EntryLo1";
8202             break;
8203         case 1:
8204             CP0_CHECK(ctx->vp);
8205             /* ignored */
8206             rn = "GlobalNumber";
8207             break;
8208         default:
8209             goto cp0_unimplemented;
8210         }
8211         break;
8212     case 4:
8213         switch (sel) {
8214         case 0:
8215             gen_helper_mtc0_context(cpu_env, arg);
8216             rn = "Context";
8217             break;
8218         case 1:
8219 //           gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
8220             rn = "ContextConfig";
8221             goto cp0_unimplemented;
8222         case 2:
8223             CP0_CHECK(ctx->ulri);
8224             tcg_gen_st_tl(arg, cpu_env,
8225                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8226             rn = "UserLocal";
8227             break;
8228         default:
8229             goto cp0_unimplemented;
8230         }
8231         break;
8232     case 5:
8233         switch (sel) {
8234         case 0:
8235             gen_helper_mtc0_pagemask(cpu_env, arg);
8236             rn = "PageMask";
8237             break;
8238         case 1:
8239             check_insn(ctx, ISA_MIPS32R2);
8240             gen_helper_mtc0_pagegrain(cpu_env, arg);
8241             rn = "PageGrain";
8242             break;
8243         case 2:
8244             CP0_CHECK(ctx->sc);
8245             gen_helper_mtc0_segctl0(cpu_env, arg);
8246             rn = "SegCtl0";
8247             break;
8248         case 3:
8249             CP0_CHECK(ctx->sc);
8250             gen_helper_mtc0_segctl1(cpu_env, arg);
8251             rn = "SegCtl1";
8252             break;
8253         case 4:
8254             CP0_CHECK(ctx->sc);
8255             gen_helper_mtc0_segctl2(cpu_env, arg);
8256             rn = "SegCtl2";
8257             break;
8258         case 5:
8259             check_pw(ctx);
8260             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8261             rn = "PWBase";
8262             break;
8263         case 6:
8264             check_pw(ctx);
8265             gen_helper_mtc0_pwfield(cpu_env, arg);
8266             rn = "PWField";
8267             break;
8268         case 7:
8269             check_pw(ctx);
8270             gen_helper_mtc0_pwsize(cpu_env, arg);
8271             rn = "PWSize";
8272             break;
8273         default:
8274             goto cp0_unimplemented;
8275         }
8276         break;
8277     case 6:
8278         switch (sel) {
8279         case 0:
8280             gen_helper_mtc0_wired(cpu_env, arg);
8281             rn = "Wired";
8282             break;
8283         case 1:
8284             check_insn(ctx, ISA_MIPS32R2);
8285             gen_helper_mtc0_srsconf0(cpu_env, arg);
8286             rn = "SRSConf0";
8287             break;
8288         case 2:
8289             check_insn(ctx, ISA_MIPS32R2);
8290             gen_helper_mtc0_srsconf1(cpu_env, arg);
8291             rn = "SRSConf1";
8292             break;
8293         case 3:
8294             check_insn(ctx, ISA_MIPS32R2);
8295             gen_helper_mtc0_srsconf2(cpu_env, arg);
8296             rn = "SRSConf2";
8297             break;
8298         case 4:
8299             check_insn(ctx, ISA_MIPS32R2);
8300             gen_helper_mtc0_srsconf3(cpu_env, arg);
8301             rn = "SRSConf3";
8302             break;
8303         case 5:
8304             check_insn(ctx, ISA_MIPS32R2);
8305             gen_helper_mtc0_srsconf4(cpu_env, arg);
8306             rn = "SRSConf4";
8307             break;
8308         case 6:
8309             check_pw(ctx);
8310             gen_helper_mtc0_pwctl(cpu_env, arg);
8311             rn = "PWCtl";
8312             break;
8313         default:
8314             goto cp0_unimplemented;
8315         }
8316         break;
8317     case 7:
8318         switch (sel) {
8319         case 0:
8320             check_insn(ctx, ISA_MIPS32R2);
8321             gen_helper_mtc0_hwrena(cpu_env, arg);
8322             ctx->base.is_jmp = DISAS_STOP;
8323             rn = "HWREna";
8324             break;
8325         default:
8326             goto cp0_unimplemented;
8327         }
8328         break;
8329     case 8:
8330         switch (sel) {
8331         case 0:
8332             /* ignored */
8333             rn = "BadVAddr";
8334             break;
8335         case 1:
8336             /* ignored */
8337             rn = "BadInstr";
8338             break;
8339         case 2:
8340             /* ignored */
8341             rn = "BadInstrP";
8342             break;
8343         case 3:
8344             /* ignored */
8345             rn = "BadInstrX";
8346             break;
8347         default:
8348             goto cp0_unimplemented;
8349         }
8350         break;
8351     case 9:
8352         switch (sel) {
8353         case 0:
8354             gen_helper_mtc0_count(cpu_env, arg);
8355             rn = "Count";
8356             break;
8357         /* 6,7 are implementation dependent */
8358         default:
8359             goto cp0_unimplemented;
8360         }
8361         /* Stop translation as we may have switched the execution mode */
8362         ctx->base.is_jmp = DISAS_STOP;
8363         break;
8364     case 10:
8365         switch (sel) {
8366         case 0:
8367             gen_helper_mtc0_entryhi(cpu_env, arg);
8368             rn = "EntryHi";
8369             break;
8370         default:
8371             goto cp0_unimplemented;
8372         }
8373         break;
8374     case 11:
8375         switch (sel) {
8376         case 0:
8377             gen_helper_mtc0_compare(cpu_env, arg);
8378             rn = "Compare";
8379             break;
8380         /* 6,7 are implementation dependent */
8381         default:
8382             goto cp0_unimplemented;
8383         }
8384         /* Stop translation as we may have switched the execution mode */
8385         ctx->base.is_jmp = DISAS_STOP;
8386         break;
8387     case 12:
8388         switch (sel) {
8389         case 0:
8390             save_cpu_state(ctx, 1);
8391             gen_helper_mtc0_status(cpu_env, arg);
8392             /* DISAS_STOP isn't good enough here, hflags may have changed. */
8393             gen_save_pc(ctx->base.pc_next + 4);
8394             ctx->base.is_jmp = DISAS_EXIT;
8395             rn = "Status";
8396             break;
8397         case 1:
8398             check_insn(ctx, ISA_MIPS32R2);
8399             gen_helper_mtc0_intctl(cpu_env, arg);
8400             /* Stop translation as we may have switched the execution mode */
8401             ctx->base.is_jmp = DISAS_STOP;
8402             rn = "IntCtl";
8403             break;
8404         case 2:
8405             check_insn(ctx, ISA_MIPS32R2);
8406             gen_helper_mtc0_srsctl(cpu_env, arg);
8407             /* Stop translation as we may have switched the execution mode */
8408             ctx->base.is_jmp = DISAS_STOP;
8409             rn = "SRSCtl";
8410             break;
8411         case 3:
8412             check_insn(ctx, ISA_MIPS32R2);
8413             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8414             /* Stop translation as we may have switched the execution mode */
8415             ctx->base.is_jmp = DISAS_STOP;
8416             rn = "SRSMap";
8417             break;
8418         default:
8419             goto cp0_unimplemented;
8420         }
8421         break;
8422     case 13:
8423         switch (sel) {
8424         case 0:
8425             save_cpu_state(ctx, 1);
8426             gen_helper_mtc0_cause(cpu_env, arg);
8427             /* Stop translation as we may have triggered an interrupt.
8428              * DISAS_STOP isn't sufficient, we need to ensure we break out of
8429              * translated code to check for pending interrupts.  */
8430             gen_save_pc(ctx->base.pc_next + 4);
8431             ctx->base.is_jmp = DISAS_EXIT;
8432             rn = "Cause";
8433             break;
8434         default:
8435             goto cp0_unimplemented;
8436         }
8437         break;
8438     case 14:
8439         switch (sel) {
8440         case 0:
8441             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8442             rn = "EPC";
8443             break;
8444         default:
8445             goto cp0_unimplemented;
8446         }
8447         break;
8448     case 15:
8449         switch (sel) {
8450         case 0:
8451             /* ignored */
8452             rn = "PRid";
8453             break;
8454         case 1:
8455             check_insn(ctx, ISA_MIPS32R2);
8456             gen_helper_mtc0_ebase(cpu_env, arg);
8457             rn = "EBase";
8458             break;
8459         default:
8460             goto cp0_unimplemented;
8461         }
8462         break;
8463     case 16:
8464         switch (sel) {
8465         case 0:
8466             gen_helper_mtc0_config0(cpu_env, arg);
8467             rn = "Config";
8468             /* Stop translation as we may have switched the execution mode */
8469             ctx->base.is_jmp = DISAS_STOP;
8470             break;
8471         case 1:
8472             /* ignored, read only */
8473             rn = "Config1";
8474             break;
8475         case 2:
8476             gen_helper_mtc0_config2(cpu_env, arg);
8477             rn = "Config2";
8478             /* Stop translation as we may have switched the execution mode */
8479             ctx->base.is_jmp = DISAS_STOP;
8480             break;
8481         case 3:
8482             gen_helper_mtc0_config3(cpu_env, arg);
8483             rn = "Config3";
8484             /* Stop translation as we may have switched the execution mode */
8485             ctx->base.is_jmp = DISAS_STOP;
8486             break;
8487         case 4:
8488             /* currently ignored */
8489             rn = "Config4";
8490             break;
8491         case 5:
8492             gen_helper_mtc0_config5(cpu_env, arg);
8493             rn = "Config5";
8494             /* Stop translation as we may have switched the execution mode */
8495             ctx->base.is_jmp = DISAS_STOP;
8496             break;
8497         /* 6,7 are implementation dependent */
8498         default:
8499             rn = "Invalid config selector";
8500             goto cp0_unimplemented;
8501         }
8502         break;
8503     case 17:
8504         switch (sel) {
8505         case 0:
8506             gen_helper_mtc0_lladdr(cpu_env, arg);
8507             rn = "LLAddr";
8508             break;
8509         case 1:
8510             CP0_CHECK(ctx->mrp);
8511             gen_helper_mtc0_maar(cpu_env, arg);
8512             rn = "MAAR";
8513             break;
8514         case 2:
8515             CP0_CHECK(ctx->mrp);
8516             gen_helper_mtc0_maari(cpu_env, arg);
8517             rn = "MAARI";
8518             break;
8519         default:
8520             goto cp0_unimplemented;
8521         }
8522         break;
8523     case 18:
8524         switch (sel) {
8525         case 0:
8526         case 1:
8527         case 2:
8528         case 3:
8529         case 4:
8530         case 5:
8531         case 6:
8532         case 7:
8533             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8534             gen_helper_0e1i(mtc0_watchlo, arg, sel);
8535             rn = "WatchLo";
8536             break;
8537         default:
8538             goto cp0_unimplemented;
8539         }
8540         break;
8541     case 19:
8542         switch (sel) {
8543         case 0:
8544         case 1:
8545         case 2:
8546         case 3:
8547         case 4:
8548         case 5:
8549         case 6:
8550         case 7:
8551             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8552             gen_helper_0e1i(mtc0_watchhi, arg, sel);
8553             rn = "WatchHi";
8554             break;
8555         default:
8556             goto cp0_unimplemented;
8557         }
8558         break;
8559     case 20:
8560         switch (sel) {
8561         case 0:
8562             check_insn(ctx, ISA_MIPS3);
8563             gen_helper_mtc0_xcontext(cpu_env, arg);
8564             rn = "XContext";
8565             break;
8566         default:
8567             goto cp0_unimplemented;
8568         }
8569         break;
8570     case 21:
8571        /* Officially reserved, but sel 0 is used for R1x000 framemask */
8572         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8573         switch (sel) {
8574         case 0:
8575             gen_helper_mtc0_framemask(cpu_env, arg);
8576             rn = "Framemask";
8577             break;
8578         default:
8579             goto cp0_unimplemented;
8580         }
8581         break;
8582     case 22:
8583         /* ignored */
8584         rn = "Diagnostic"; /* implementation dependent */
8585         break;
8586     case 23:
8587         switch (sel) {
8588         case 0:
8589             gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8590             /* DISAS_STOP isn't good enough here, hflags may have changed. */
8591             gen_save_pc(ctx->base.pc_next + 4);
8592             ctx->base.is_jmp = DISAS_EXIT;
8593             rn = "Debug";
8594             break;
8595         case 1:
8596 //            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8597             /* Stop translation as we may have switched the execution mode */
8598             ctx->base.is_jmp = DISAS_STOP;
8599             rn = "TraceControl";
8600             goto cp0_unimplemented;
8601         case 2:
8602 //            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8603             /* Stop translation as we may have switched the execution mode */
8604             ctx->base.is_jmp = DISAS_STOP;
8605             rn = "TraceControl2";
8606             goto cp0_unimplemented;
8607         case 3:
8608 //            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8609             /* Stop translation as we may have switched the execution mode */
8610             ctx->base.is_jmp = DISAS_STOP;
8611             rn = "UserTraceData";
8612             goto cp0_unimplemented;
8613         case 4:
8614 //            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8615             /* Stop translation as we may have switched the execution mode */
8616             ctx->base.is_jmp = DISAS_STOP;
8617             rn = "TraceBPC";
8618             goto cp0_unimplemented;
8619         default:
8620             goto cp0_unimplemented;
8621         }
8622         break;
8623     case 24:
8624         switch (sel) {
8625         case 0:
8626             /* EJTAG support */
8627             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8628             rn = "DEPC";
8629             break;
8630         default:
8631             goto cp0_unimplemented;
8632         }
8633         break;
8634     case 25:
8635         switch (sel) {
8636         case 0:
8637             gen_helper_mtc0_performance0(cpu_env, arg);
8638             rn = "Performance0";
8639             break;
8640         case 1:
8641 //            gen_helper_mtc0_performance1(cpu_env, arg);
8642             rn = "Performance1";
8643             goto cp0_unimplemented;
8644         case 2:
8645 //            gen_helper_mtc0_performance2(cpu_env, arg);
8646             rn = "Performance2";
8647             goto cp0_unimplemented;
8648         case 3:
8649 //            gen_helper_mtc0_performance3(cpu_env, arg);
8650             rn = "Performance3";
8651             goto cp0_unimplemented;
8652         case 4:
8653 //            gen_helper_mtc0_performance4(cpu_env, arg);
8654             rn = "Performance4";
8655             goto cp0_unimplemented;
8656         case 5:
8657 //            gen_helper_mtc0_performance5(cpu_env, arg);
8658             rn = "Performance5";
8659             goto cp0_unimplemented;
8660         case 6:
8661 //            gen_helper_mtc0_performance6(cpu_env, arg);
8662             rn = "Performance6";
8663             goto cp0_unimplemented;
8664         case 7:
8665 //            gen_helper_mtc0_performance7(cpu_env, arg);
8666             rn = "Performance7";
8667             goto cp0_unimplemented;
8668         default:
8669             goto cp0_unimplemented;
8670         }
8671         break;
8672     case 26:
8673         switch (sel) {
8674         case 0:
8675             gen_helper_mtc0_errctl(cpu_env, arg);
8676             ctx->base.is_jmp = DISAS_STOP;
8677             rn = "ErrCtl";
8678             break;
8679         default:
8680             goto cp0_unimplemented;
8681         }
8682         break;
8683     case 27:
8684         switch (sel) {
8685         case 0:
8686         case 1:
8687         case 2:
8688         case 3:
8689             /* ignored */
8690             rn = "CacheErr";
8691             break;
8692         default:
8693             goto cp0_unimplemented;
8694         }
8695         break;
8696     case 28:
8697         switch (sel) {
8698         case 0:
8699         case 2:
8700         case 4:
8701         case 6:
8702             gen_helper_mtc0_taglo(cpu_env, arg);
8703             rn = "TagLo";
8704             break;
8705         case 1:
8706         case 3:
8707         case 5:
8708         case 7:
8709             gen_helper_mtc0_datalo(cpu_env, arg);
8710             rn = "DataLo";
8711             break;
8712         default:
8713             goto cp0_unimplemented;
8714         }
8715         break;
8716     case 29:
8717         switch (sel) {
8718         case 0:
8719         case 2:
8720         case 4:
8721         case 6:
8722             gen_helper_mtc0_taghi(cpu_env, arg);
8723             rn = "TagHi";
8724             break;
8725         case 1:
8726         case 3:
8727         case 5:
8728         case 7:
8729             gen_helper_mtc0_datahi(cpu_env, arg);
8730             rn = "DataHi";
8731             break;
8732         default:
8733             rn = "invalid sel";
8734             goto cp0_unimplemented;
8735         }
8736         break;
8737     case 30:
8738         switch (sel) {
8739         case 0:
8740             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8741             rn = "ErrorEPC";
8742             break;
8743         default:
8744             goto cp0_unimplemented;
8745         }
8746         break;
8747     case 31:
8748         switch (sel) {
8749         case 0:
8750             /* EJTAG support */
8751             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8752             rn = "DESAVE";
8753             break;
8754         case 2:
8755         case 3:
8756         case 4:
8757         case 5:
8758         case 6:
8759         case 7:
8760             CP0_CHECK(ctx->kscrexist & (1 << sel));
8761             tcg_gen_st_tl(arg, cpu_env,
8762                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8763             rn = "KScratch";
8764             break;
8765         default:
8766             goto cp0_unimplemented;
8767         }
8768         break;
8769     default:
8770         goto cp0_unimplemented;
8771     }
8772     trace_mips_translate_c0("dmtc0", rn, reg, sel);
8773
8774     /* For simplicity assume that all writes can cause interrupts.  */
8775     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8776         gen_io_end();
8777         /* DISAS_STOP isn't sufficient, we need to ensure we break out of
8778          * translated code to check for pending interrupts.  */
8779         gen_save_pc(ctx->base.pc_next + 4);
8780         ctx->base.is_jmp = DISAS_EXIT;
8781     }
8782     return;
8783
8784 cp0_unimplemented:
8785     qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
8786 }
8787 #endif /* TARGET_MIPS64 */
8788
8789 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
8790                      int u, int sel, int h)
8791 {
8792     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8793     TCGv t0 = tcg_temp_local_new();
8794
8795     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8796         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8797          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
8798         tcg_gen_movi_tl(t0, -1);
8799     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8800              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
8801         tcg_gen_movi_tl(t0, -1);
8802     else if (u == 0) {
8803         switch (rt) {
8804         case 1:
8805             switch (sel) {
8806             case 1:
8807                 gen_helper_mftc0_vpecontrol(t0, cpu_env);
8808                 break;
8809             case 2:
8810                 gen_helper_mftc0_vpeconf0(t0, cpu_env);
8811                 break;
8812             default:
8813                 goto die;
8814                 break;
8815             }
8816             break;
8817         case 2:
8818             switch (sel) {
8819             case 1:
8820                 gen_helper_mftc0_tcstatus(t0, cpu_env);
8821                 break;
8822             case 2:
8823                 gen_helper_mftc0_tcbind(t0, cpu_env);
8824                 break;
8825             case 3:
8826                 gen_helper_mftc0_tcrestart(t0, cpu_env);
8827                 break;
8828             case 4:
8829                 gen_helper_mftc0_tchalt(t0, cpu_env);
8830                 break;
8831             case 5:
8832                 gen_helper_mftc0_tccontext(t0, cpu_env);
8833                 break;
8834             case 6:
8835                 gen_helper_mftc0_tcschedule(t0, cpu_env);
8836                 break;
8837             case 7:
8838                 gen_helper_mftc0_tcschefback(t0, cpu_env);
8839                 break;
8840             default:
8841                 gen_mfc0(ctx, t0, rt, sel);
8842                 break;
8843             }
8844             break;
8845         case 10:
8846             switch (sel) {
8847             case 0:
8848                 gen_helper_mftc0_entryhi(t0, cpu_env);
8849                 break;
8850             default:
8851                 gen_mfc0(ctx, t0, rt, sel);
8852                 break;
8853             }
8854         case 12:
8855             switch (sel) {
8856             case 0:
8857                 gen_helper_mftc0_status(t0, cpu_env);
8858                 break;
8859             default:
8860                 gen_mfc0(ctx, t0, rt, sel);
8861                 break;
8862             }
8863         case 13:
8864             switch (sel) {
8865             case 0:
8866                 gen_helper_mftc0_cause(t0, cpu_env);
8867                 break;
8868             default:
8869                 goto die;
8870                 break;
8871             }
8872             break;
8873         case 14:
8874             switch (sel) {
8875             case 0:
8876                 gen_helper_mftc0_epc(t0, cpu_env);
8877                 break;
8878             default:
8879                 goto die;
8880                 break;
8881             }
8882             break;
8883         case 15:
8884             switch (sel) {
8885             case 1:
8886                 gen_helper_mftc0_ebase(t0, cpu_env);
8887                 break;
8888             default:
8889                 goto die;
8890                 break;
8891             }
8892             break;
8893         case 16:
8894             switch (sel) {
8895             case 0:
8896             case 1:
8897             case 2:
8898             case 3:
8899             case 4:
8900             case 5:
8901             case 6:
8902             case 7:
8903                 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
8904                 break;
8905             default:
8906                 goto die;
8907                 break;
8908             }
8909             break;
8910         case 23:
8911             switch (sel) {
8912             case 0:
8913                 gen_helper_mftc0_debug(t0, cpu_env);
8914                 break;
8915             default:
8916                 gen_mfc0(ctx, t0, rt, sel);
8917                 break;
8918             }
8919             break;
8920         default:
8921             gen_mfc0(ctx, t0, rt, sel);
8922         }
8923     } else switch (sel) {
8924     /* GPR registers. */
8925     case 0:
8926         gen_helper_1e0i(mftgpr, t0, rt);
8927         break;
8928     /* Auxiliary CPU registers */
8929     case 1:
8930         switch (rt) {
8931         case 0:
8932             gen_helper_1e0i(mftlo, t0, 0);
8933             break;
8934         case 1:
8935             gen_helper_1e0i(mfthi, t0, 0);
8936             break;
8937         case 2:
8938             gen_helper_1e0i(mftacx, t0, 0);
8939             break;
8940         case 4:
8941             gen_helper_1e0i(mftlo, t0, 1);
8942             break;
8943         case 5:
8944             gen_helper_1e0i(mfthi, t0, 1);
8945             break;
8946         case 6:
8947             gen_helper_1e0i(mftacx, t0, 1);
8948             break;
8949         case 8:
8950             gen_helper_1e0i(mftlo, t0, 2);
8951             break;
8952         case 9:
8953             gen_helper_1e0i(mfthi, t0, 2);
8954             break;
8955         case 10:
8956             gen_helper_1e0i(mftacx, t0, 2);
8957             break;
8958         case 12:
8959             gen_helper_1e0i(mftlo, t0, 3);
8960             break;
8961         case 13:
8962             gen_helper_1e0i(mfthi, t0, 3);
8963             break;
8964         case 14:
8965             gen_helper_1e0i(mftacx, t0, 3);
8966             break;
8967         case 16:
8968             gen_helper_mftdsp(t0, cpu_env);
8969             break;
8970         default:
8971             goto die;
8972         }
8973         break;
8974     /* Floating point (COP1). */
8975     case 2:
8976         /* XXX: For now we support only a single FPU context. */
8977         if (h == 0) {
8978             TCGv_i32 fp0 = tcg_temp_new_i32();
8979
8980             gen_load_fpr32(ctx, fp0, rt);
8981             tcg_gen_ext_i32_tl(t0, fp0);
8982             tcg_temp_free_i32(fp0);
8983         } else {
8984             TCGv_i32 fp0 = tcg_temp_new_i32();
8985
8986             gen_load_fpr32h(ctx, fp0, rt);
8987             tcg_gen_ext_i32_tl(t0, fp0);
8988             tcg_temp_free_i32(fp0);
8989         }
8990         break;
8991     case 3:
8992         /* XXX: For now we support only a single FPU context. */
8993         gen_helper_1e0i(cfc1, t0, rt);
8994         break;
8995     /* COP2: Not implemented. */
8996     case 4:
8997     case 5:
8998         /* fall through */
8999     default:
9000         goto die;
9001     }
9002     trace_mips_translate_tr("mftr", rt, u, sel, h);
9003     gen_store_gpr(t0, rd);
9004     tcg_temp_free(t0);
9005     return;
9006
9007 die:
9008     tcg_temp_free(t0);
9009     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9010     generate_exception_end(ctx, EXCP_RI);
9011 }
9012
9013 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
9014                      int u, int sel, int h)
9015 {
9016     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9017     TCGv t0 = tcg_temp_local_new();
9018
9019     gen_load_gpr(t0, rt);
9020     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9021         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9022          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9023         /* NOP */ ;
9024     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9025              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9026         /* NOP */ ;
9027     else if (u == 0) {
9028         switch (rd) {
9029         case 1:
9030             switch (sel) {
9031             case 1:
9032                 gen_helper_mttc0_vpecontrol(cpu_env, t0);
9033                 break;
9034             case 2:
9035                 gen_helper_mttc0_vpeconf0(cpu_env, t0);
9036                 break;
9037             default:
9038                 goto die;
9039                 break;
9040             }
9041             break;
9042         case 2:
9043             switch (sel) {
9044             case 1:
9045                 gen_helper_mttc0_tcstatus(cpu_env, t0);
9046                 break;
9047             case 2:
9048                 gen_helper_mttc0_tcbind(cpu_env, t0);
9049                 break;
9050             case 3:
9051                 gen_helper_mttc0_tcrestart(cpu_env, t0);
9052                 break;
9053             case 4:
9054                 gen_helper_mttc0_tchalt(cpu_env, t0);
9055                 break;
9056             case 5:
9057                 gen_helper_mttc0_tccontext(cpu_env, t0);
9058                 break;
9059             case 6:
9060                 gen_helper_mttc0_tcschedule(cpu_env, t0);
9061                 break;
9062             case 7:
9063                 gen_helper_mttc0_tcschefback(cpu_env, t0);
9064                 break;
9065             default:
9066                 gen_mtc0(ctx, t0, rd, sel);
9067                 break;
9068             }
9069             break;
9070         case 10:
9071             switch (sel) {
9072             case 0:
9073                 gen_helper_mttc0_entryhi(cpu_env, t0);
9074                 break;
9075             default:
9076                 gen_mtc0(ctx, t0, rd, sel);
9077                 break;
9078             }
9079         case 12:
9080             switch (sel) {
9081             case 0:
9082                 gen_helper_mttc0_status(cpu_env, t0);
9083                 break;
9084             default:
9085                 gen_mtc0(ctx, t0, rd, sel);
9086                 break;
9087             }
9088         case 13:
9089             switch (sel) {
9090             case 0:
9091                 gen_helper_mttc0_cause(cpu_env, t0);
9092                 break;
9093             default:
9094                 goto die;
9095                 break;
9096             }
9097             break;
9098         case 15:
9099             switch (sel) {
9100             case 1:
9101                 gen_helper_mttc0_ebase(cpu_env, t0);
9102                 break;
9103             default:
9104                 goto die;
9105                 break;
9106             }
9107             break;
9108         case 23:
9109             switch (sel) {
9110             case 0:
9111                 gen_helper_mttc0_debug(cpu_env, t0);
9112                 break;
9113             default:
9114                 gen_mtc0(ctx, t0, rd, sel);
9115                 break;
9116             }
9117             break;
9118         default:
9119             gen_mtc0(ctx, t0, rd, sel);
9120         }
9121     } else switch (sel) {
9122     /* GPR registers. */
9123     case 0:
9124         gen_helper_0e1i(mttgpr, t0, rd);
9125         break;
9126     /* Auxiliary CPU registers */
9127     case 1:
9128         switch (rd) {
9129         case 0:
9130             gen_helper_0e1i(mttlo, t0, 0);
9131             break;
9132         case 1:
9133             gen_helper_0e1i(mtthi, t0, 0);
9134             break;
9135         case 2:
9136             gen_helper_0e1i(mttacx, t0, 0);
9137             break;
9138         case 4:
9139             gen_helper_0e1i(mttlo, t0, 1);
9140             break;
9141         case 5:
9142             gen_helper_0e1i(mtthi, t0, 1);
9143             break;
9144         case 6:
9145             gen_helper_0e1i(mttacx, t0, 1);
9146             break;
9147         case 8:
9148             gen_helper_0e1i(mttlo, t0, 2);
9149             break;
9150         case 9:
9151             gen_helper_0e1i(mtthi, t0, 2);
9152             break;
9153         case 10:
9154             gen_helper_0e1i(mttacx, t0, 2);
9155             break;
9156         case 12:
9157             gen_helper_0e1i(mttlo, t0, 3);
9158             break;
9159         case 13:
9160             gen_helper_0e1i(mtthi, t0, 3);
9161             break;
9162         case 14:
9163             gen_helper_0e1i(mttacx, t0, 3);
9164             break;
9165         case 16:
9166             gen_helper_mttdsp(cpu_env, t0);
9167             break;
9168         default:
9169             goto die;
9170         }
9171         break;
9172     /* Floating point (COP1). */
9173     case 2:
9174         /* XXX: For now we support only a single FPU context. */
9175         if (h == 0) {
9176             TCGv_i32 fp0 = tcg_temp_new_i32();
9177
9178             tcg_gen_trunc_tl_i32(fp0, t0);
9179             gen_store_fpr32(ctx, fp0, rd);
9180             tcg_temp_free_i32(fp0);
9181         } else {
9182             TCGv_i32 fp0 = tcg_temp_new_i32();
9183
9184             tcg_gen_trunc_tl_i32(fp0, t0);
9185             gen_store_fpr32h(ctx, fp0, rd);
9186             tcg_temp_free_i32(fp0);
9187         }
9188         break;
9189     case 3:
9190         /* XXX: For now we support only a single FPU context. */
9191         {
9192             TCGv_i32 fs_tmp = tcg_const_i32(rd);
9193
9194             gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9195             tcg_temp_free_i32(fs_tmp);
9196         }
9197         /* Stop translation as we may have changed hflags */
9198         ctx->base.is_jmp = DISAS_STOP;
9199         break;
9200     /* COP2: Not implemented. */
9201     case 4:
9202     case 5:
9203         /* fall through */
9204     default:
9205         goto die;
9206     }
9207     trace_mips_translate_tr("mttr", rd, u, sel, h);
9208     tcg_temp_free(t0);
9209     return;
9210
9211 die:
9212     tcg_temp_free(t0);
9213     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9214     generate_exception_end(ctx, EXCP_RI);
9215 }
9216
9217 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
9218 {
9219     const char *opn = "ldst";
9220
9221     check_cp0_enabled(ctx);
9222     switch (opc) {
9223     case OPC_MFC0:
9224         if (rt == 0) {
9225             /* Treat as NOP. */
9226             return;
9227         }
9228         gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9229         opn = "mfc0";
9230         break;
9231     case OPC_MTC0:
9232         {
9233             TCGv t0 = tcg_temp_new();
9234
9235             gen_load_gpr(t0, rt);
9236             gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
9237             tcg_temp_free(t0);
9238         }
9239         opn = "mtc0";
9240         break;
9241 #if defined(TARGET_MIPS64)
9242     case OPC_DMFC0:
9243         check_insn(ctx, ISA_MIPS3);
9244         if (rt == 0) {
9245             /* Treat as NOP. */
9246             return;
9247         }
9248         gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9249         opn = "dmfc0";
9250         break;
9251     case OPC_DMTC0:
9252         check_insn(ctx, ISA_MIPS3);
9253         {
9254             TCGv t0 = tcg_temp_new();
9255
9256             gen_load_gpr(t0, rt);
9257             gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
9258             tcg_temp_free(t0);
9259         }
9260         opn = "dmtc0";
9261         break;
9262 #endif
9263     case OPC_MFHC0:
9264         check_mvh(ctx);
9265         if (rt == 0) {
9266             /* Treat as NOP. */
9267             return;
9268         }
9269         gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9270         opn = "mfhc0";
9271         break;
9272     case OPC_MTHC0:
9273         check_mvh(ctx);
9274         {
9275             TCGv t0 = tcg_temp_new();
9276             gen_load_gpr(t0, rt);
9277             gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
9278             tcg_temp_free(t0);
9279         }
9280         opn = "mthc0";
9281         break;
9282     case OPC_MFTR:
9283         check_cp0_enabled(ctx);
9284         if (rd == 0) {
9285             /* Treat as NOP. */
9286             return;
9287         }
9288         gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
9289                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9290         opn = "mftr";
9291         break;
9292     case OPC_MTTR:
9293         check_cp0_enabled(ctx);
9294         gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
9295                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9296         opn = "mttr";
9297         break;
9298     case OPC_TLBWI:
9299         opn = "tlbwi";
9300         if (!env->tlb->helper_tlbwi)
9301             goto die;
9302         gen_helper_tlbwi(cpu_env);
9303         break;
9304     case OPC_TLBINV:
9305         opn = "tlbinv";
9306         if (ctx->ie >= 2) {
9307             if (!env->tlb->helper_tlbinv) {
9308                 goto die;
9309             }
9310             gen_helper_tlbinv(cpu_env);
9311         } /* treat as nop if TLBINV not supported */
9312         break;
9313     case OPC_TLBINVF:
9314         opn = "tlbinvf";
9315         if (ctx->ie >= 2) {
9316             if (!env->tlb->helper_tlbinvf) {
9317                 goto die;
9318             }
9319             gen_helper_tlbinvf(cpu_env);
9320         } /* treat as nop if TLBINV not supported */
9321         break;
9322     case OPC_TLBWR:
9323         opn = "tlbwr";
9324         if (!env->tlb->helper_tlbwr)
9325             goto die;
9326         gen_helper_tlbwr(cpu_env);
9327         break;
9328     case OPC_TLBP:
9329         opn = "tlbp";
9330         if (!env->tlb->helper_tlbp)
9331             goto die;
9332         gen_helper_tlbp(cpu_env);
9333         break;
9334     case OPC_TLBR:
9335         opn = "tlbr";
9336         if (!env->tlb->helper_tlbr)
9337             goto die;
9338         gen_helper_tlbr(cpu_env);
9339         break;
9340     case OPC_ERET: /* OPC_ERETNC */
9341         if ((ctx->insn_flags & ISA_MIPS32R6) &&
9342             (ctx->hflags & MIPS_HFLAG_BMASK)) {
9343             goto die;
9344         } else {
9345             int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
9346             if (ctx->opcode & (1 << bit_shift)) {
9347                 /* OPC_ERETNC */
9348                 opn = "eretnc";
9349                 check_insn(ctx, ISA_MIPS32R5);
9350                 gen_helper_eretnc(cpu_env);
9351             } else {
9352                 /* OPC_ERET */
9353                 opn = "eret";
9354                 check_insn(ctx, ISA_MIPS2);
9355                 gen_helper_eret(cpu_env);
9356             }
9357             ctx->base.is_jmp = DISAS_EXIT;
9358         }
9359         break;
9360     case OPC_DERET:
9361         opn = "deret";
9362         check_insn(ctx, ISA_MIPS32);
9363         if ((ctx->insn_flags & ISA_MIPS32R6) &&
9364             (ctx->hflags & MIPS_HFLAG_BMASK)) {
9365             goto die;
9366         }
9367         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9368             MIPS_INVAL(opn);
9369             generate_exception_end(ctx, EXCP_RI);
9370         } else {
9371             gen_helper_deret(cpu_env);
9372             ctx->base.is_jmp = DISAS_EXIT;
9373         }
9374         break;
9375     case OPC_WAIT:
9376         opn = "wait";
9377         check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
9378         if ((ctx->insn_flags & ISA_MIPS32R6) &&
9379             (ctx->hflags & MIPS_HFLAG_BMASK)) {
9380             goto die;
9381         }
9382         /* If we get an exception, we want to restart at next instruction */
9383         ctx->base.pc_next += 4;
9384         save_cpu_state(ctx, 1);
9385         ctx->base.pc_next -= 4;
9386         gen_helper_wait(cpu_env);
9387         ctx->base.is_jmp = DISAS_NORETURN;
9388         break;
9389     default:
9390  die:
9391         MIPS_INVAL(opn);
9392         generate_exception_end(ctx, EXCP_RI);
9393         return;
9394     }
9395     (void)opn; /* avoid a compiler warning */
9396 }
9397 #endif /* !CONFIG_USER_ONLY */
9398
9399 /* CP1 Branches (before delay slot) */
9400 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
9401                                 int32_t cc, int32_t offset)
9402 {
9403     target_ulong btarget;
9404     TCGv_i32 t0 = tcg_temp_new_i32();
9405
9406     if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9407         generate_exception_end(ctx, EXCP_RI);
9408         goto out;
9409     }
9410
9411     if (cc != 0)
9412         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
9413
9414     btarget = ctx->base.pc_next + 4 + offset;
9415
9416     switch (op) {
9417     case OPC_BC1F:
9418         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9419         tcg_gen_not_i32(t0, t0);
9420         tcg_gen_andi_i32(t0, t0, 1);
9421         tcg_gen_extu_i32_tl(bcond, t0);
9422         goto not_likely;
9423     case OPC_BC1FL:
9424         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9425         tcg_gen_not_i32(t0, t0);
9426         tcg_gen_andi_i32(t0, t0, 1);
9427         tcg_gen_extu_i32_tl(bcond, t0);
9428         goto likely;
9429     case OPC_BC1T:
9430         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9431         tcg_gen_andi_i32(t0, t0, 1);
9432         tcg_gen_extu_i32_tl(bcond, t0);
9433         goto not_likely;
9434     case OPC_BC1TL:
9435         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9436         tcg_gen_andi_i32(t0, t0, 1);
9437         tcg_gen_extu_i32_tl(bcond, t0);
9438     likely:
9439         ctx->hflags |= MIPS_HFLAG_BL;
9440         break;
9441     case OPC_BC1FANY2:
9442         {
9443             TCGv_i32 t1 = tcg_temp_new_i32();
9444             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9445             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9446             tcg_gen_nand_i32(t0, t0, t1);
9447             tcg_temp_free_i32(t1);
9448             tcg_gen_andi_i32(t0, t0, 1);
9449             tcg_gen_extu_i32_tl(bcond, t0);
9450         }
9451         goto not_likely;
9452     case OPC_BC1TANY2:
9453         {
9454             TCGv_i32 t1 = tcg_temp_new_i32();
9455             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9456             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9457             tcg_gen_or_i32(t0, t0, t1);
9458             tcg_temp_free_i32(t1);
9459             tcg_gen_andi_i32(t0, t0, 1);
9460             tcg_gen_extu_i32_tl(bcond, t0);
9461         }
9462         goto not_likely;
9463     case OPC_BC1FANY4:
9464         {
9465             TCGv_i32 t1 = tcg_temp_new_i32();
9466             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9467             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9468             tcg_gen_and_i32(t0, t0, t1);
9469             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
9470             tcg_gen_and_i32(t0, t0, t1);
9471             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
9472             tcg_gen_nand_i32(t0, t0, t1);
9473             tcg_temp_free_i32(t1);
9474             tcg_gen_andi_i32(t0, t0, 1);
9475             tcg_gen_extu_i32_tl(bcond, t0);
9476         }
9477         goto not_likely;
9478     case OPC_BC1TANY4:
9479         {
9480             TCGv_i32 t1 = tcg_temp_new_i32();
9481             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9482             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
9483             tcg_gen_or_i32(t0, t0, t1);
9484             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
9485             tcg_gen_or_i32(t0, t0, t1);
9486             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
9487             tcg_gen_or_i32(t0, t0, t1);
9488             tcg_temp_free_i32(t1);
9489             tcg_gen_andi_i32(t0, t0, 1);
9490             tcg_gen_extu_i32_tl(bcond, t0);
9491         }
9492     not_likely:
9493         ctx->hflags |= MIPS_HFLAG_BC;
9494         break;
9495     default:
9496         MIPS_INVAL("cp1 cond branch");
9497         generate_exception_end(ctx, EXCP_RI);
9498         goto out;
9499     }
9500     ctx->btarget = btarget;
9501     ctx->hflags |= MIPS_HFLAG_BDS32;
9502  out:
9503     tcg_temp_free_i32(t0);
9504 }
9505
9506 /* R6 CP1 Branches */
9507 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
9508                                    int32_t ft, int32_t offset,
9509                                    int delayslot_size)
9510 {
9511     target_ulong btarget;
9512     TCGv_i64 t0 = tcg_temp_new_i64();
9513
9514     if (ctx->hflags & MIPS_HFLAG_BMASK) {
9515 #ifdef MIPS_DEBUG_DISAS
9516         LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
9517                   "\n", ctx->base.pc_next);
9518 #endif
9519         generate_exception_end(ctx, EXCP_RI);
9520         goto out;
9521     }
9522
9523     gen_load_fpr64(ctx, t0, ft);
9524     tcg_gen_andi_i64(t0, t0, 1);
9525
9526     btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
9527
9528     switch (op) {
9529     case OPC_BC1EQZ:
9530         tcg_gen_xori_i64(t0, t0, 1);
9531         ctx->hflags |= MIPS_HFLAG_BC;
9532         break;
9533     case OPC_BC1NEZ:
9534         /* t0 already set */
9535         ctx->hflags |= MIPS_HFLAG_BC;
9536         break;
9537     default:
9538         MIPS_INVAL("cp1 cond branch");
9539         generate_exception_end(ctx, EXCP_RI);
9540         goto out;
9541     }
9542
9543     tcg_gen_trunc_i64_tl(bcond, t0);
9544
9545     ctx->btarget = btarget;
9546
9547     switch (delayslot_size) {
9548     case 2:
9549         ctx->hflags |= MIPS_HFLAG_BDS16;
9550         break;
9551     case 4:
9552         ctx->hflags |= MIPS_HFLAG_BDS32;
9553         break;
9554     }
9555
9556 out:
9557     tcg_temp_free_i64(t0);
9558 }
9559
9560 /* Coprocessor 1 (FPU) */
9561
9562 #define FOP(func, fmt) (((fmt) << 21) | (func))
9563
9564 enum fopcode {
9565     OPC_ADD_S = FOP(0, FMT_S),
9566     OPC_SUB_S = FOP(1, FMT_S),
9567     OPC_MUL_S = FOP(2, FMT_S),
9568     OPC_DIV_S = FOP(3, FMT_S),
9569     OPC_SQRT_S = FOP(4, FMT_S),
9570     OPC_ABS_S = FOP(5, FMT_S),
9571     OPC_MOV_S = FOP(6, FMT_S),
9572     OPC_NEG_S = FOP(7, FMT_S),
9573     OPC_ROUND_L_S = FOP(8, FMT_S),
9574     OPC_TRUNC_L_S = FOP(9, FMT_S),
9575     OPC_CEIL_L_S = FOP(10, FMT_S),
9576     OPC_FLOOR_L_S = FOP(11, FMT_S),
9577     OPC_ROUND_W_S = FOP(12, FMT_S),
9578     OPC_TRUNC_W_S = FOP(13, FMT_S),
9579     OPC_CEIL_W_S = FOP(14, FMT_S),
9580     OPC_FLOOR_W_S = FOP(15, FMT_S),
9581     OPC_SEL_S = FOP(16, FMT_S),
9582     OPC_MOVCF_S = FOP(17, FMT_S),
9583     OPC_MOVZ_S = FOP(18, FMT_S),
9584     OPC_MOVN_S = FOP(19, FMT_S),
9585     OPC_SELEQZ_S = FOP(20, FMT_S),
9586     OPC_RECIP_S = FOP(21, FMT_S),
9587     OPC_RSQRT_S = FOP(22, FMT_S),
9588     OPC_SELNEZ_S = FOP(23, FMT_S),
9589     OPC_MADDF_S = FOP(24, FMT_S),
9590     OPC_MSUBF_S = FOP(25, FMT_S),
9591     OPC_RINT_S = FOP(26, FMT_S),
9592     OPC_CLASS_S = FOP(27, FMT_S),
9593     OPC_MIN_S = FOP(28, FMT_S),
9594     OPC_RECIP2_S = FOP(28, FMT_S),
9595     OPC_MINA_S = FOP(29, FMT_S),
9596     OPC_RECIP1_S = FOP(29, FMT_S),
9597     OPC_MAX_S = FOP(30, FMT_S),
9598     OPC_RSQRT1_S = FOP(30, FMT_S),
9599     OPC_MAXA_S = FOP(31, FMT_S),
9600     OPC_RSQRT2_S = FOP(31, FMT_S),
9601     OPC_CVT_D_S = FOP(33, FMT_S),
9602     OPC_CVT_W_S = FOP(36, FMT_S),
9603     OPC_CVT_L_S = FOP(37, FMT_S),
9604     OPC_CVT_PS_S = FOP(38, FMT_S),
9605     OPC_CMP_F_S = FOP (48, FMT_S),
9606     OPC_CMP_UN_S = FOP (49, FMT_S),
9607     OPC_CMP_EQ_S = FOP (50, FMT_S),
9608     OPC_CMP_UEQ_S = FOP (51, FMT_S),
9609     OPC_CMP_OLT_S = FOP (52, FMT_S),
9610     OPC_CMP_ULT_S = FOP (53, FMT_S),
9611     OPC_CMP_OLE_S = FOP (54, FMT_S),
9612     OPC_CMP_ULE_S = FOP (55, FMT_S),
9613     OPC_CMP_SF_S = FOP (56, FMT_S),
9614     OPC_CMP_NGLE_S = FOP (57, FMT_S),
9615     OPC_CMP_SEQ_S = FOP (58, FMT_S),
9616     OPC_CMP_NGL_S = FOP (59, FMT_S),
9617     OPC_CMP_LT_S = FOP (60, FMT_S),
9618     OPC_CMP_NGE_S = FOP (61, FMT_S),
9619     OPC_CMP_LE_S = FOP (62, FMT_S),
9620     OPC_CMP_NGT_S = FOP (63, FMT_S),
9621
9622     OPC_ADD_D = FOP(0, FMT_D),
9623     OPC_SUB_D = FOP(1, FMT_D),
9624     OPC_MUL_D = FOP(2, FMT_D),
9625     OPC_DIV_D = FOP(3, FMT_D),
9626     OPC_SQRT_D = FOP(4, FMT_D),
9627     OPC_ABS_D = FOP(5, FMT_D),
9628     OPC_MOV_D = FOP(6, FMT_D),
9629     OPC_NEG_D = FOP(7, FMT_D),
9630     OPC_ROUND_L_D = FOP(8, FMT_D),
9631     OPC_TRUNC_L_D = FOP(9, FMT_D),
9632     OPC_CEIL_L_D = FOP(10, FMT_D),
9633     OPC_FLOOR_L_D = FOP(11, FMT_D),
9634     OPC_ROUND_W_D = FOP(12, FMT_D),
9635     OPC_TRUNC_W_D = FOP(13, FMT_D),
9636     OPC_CEIL_W_D = FOP(14, FMT_D),
9637     OPC_FLOOR_W_D = FOP(15, FMT_D),
9638     OPC_SEL_D = FOP(16, FMT_D),
9639     OPC_MOVCF_D = FOP(17, FMT_D),
9640     OPC_MOVZ_D = FOP(18, FMT_D),
9641     OPC_MOVN_D = FOP(19, FMT_D),
9642     OPC_SELEQZ_D = FOP(20, FMT_D),
9643     OPC_RECIP_D = FOP(21, FMT_D),
9644     OPC_RSQRT_D = FOP(22, FMT_D),
9645     OPC_SELNEZ_D = FOP(23, FMT_D),
9646     OPC_MADDF_D = FOP(24, FMT_D),
9647     OPC_MSUBF_D = FOP(25, FMT_D),
9648     OPC_RINT_D = FOP(26, FMT_D),
9649     OPC_CLASS_D = FOP(27, FMT_D),
9650     OPC_MIN_D = FOP(28, FMT_D),
9651     OPC_RECIP2_D = FOP(28, FMT_D),
9652     OPC_MINA_D = FOP(29, FMT_D),
9653     OPC_RECIP1_D = FOP(29, FMT_D),
9654     OPC_MAX_D = FOP(30, FMT_D),
9655     OPC_RSQRT1_D = FOP(30, FMT_D),
9656     OPC_MAXA_D = FOP(31, FMT_D),
9657     OPC_RSQRT2_D = FOP(31, FMT_D),
9658     OPC_CVT_S_D = FOP(32, FMT_D),
9659     OPC_CVT_W_D = FOP(36, FMT_D),
9660     OPC_CVT_L_D = FOP(37, FMT_D),
9661     OPC_CMP_F_D = FOP (48, FMT_D),
9662     OPC_CMP_UN_D = FOP (49, FMT_D),
9663     OPC_CMP_EQ_D = FOP (50, FMT_D),
9664     OPC_CMP_UEQ_D = FOP (51, FMT_D),
9665     OPC_CMP_OLT_D = FOP (52, FMT_D),
9666     OPC_CMP_ULT_D = FOP (53, FMT_D),
9667     OPC_CMP_OLE_D = FOP (54, FMT_D),
9668     OPC_CMP_ULE_D = FOP (55, FMT_D),
9669     OPC_CMP_SF_D = FOP (56, FMT_D),
9670     OPC_CMP_NGLE_D = FOP (57, FMT_D),
9671     OPC_CMP_SEQ_D = FOP (58, FMT_D),
9672     OPC_CMP_NGL_D = FOP (59, FMT_D),
9673     OPC_CMP_LT_D = FOP (60, FMT_D),
9674     OPC_CMP_NGE_D = FOP (61, FMT_D),
9675     OPC_CMP_LE_D = FOP (62, FMT_D),
9676     OPC_CMP_NGT_D = FOP (63, FMT_D),
9677
9678     OPC_CVT_S_W = FOP(32, FMT_W),
9679     OPC_CVT_D_W = FOP(33, FMT_W),
9680     OPC_CVT_S_L = FOP(32, FMT_L),
9681     OPC_CVT_D_L = FOP(33, FMT_L),
9682     OPC_CVT_PS_PW = FOP(38, FMT_W),
9683
9684     OPC_ADD_PS = FOP(0, FMT_PS),
9685     OPC_SUB_PS = FOP(1, FMT_PS),
9686     OPC_MUL_PS = FOP(2, FMT_PS),
9687     OPC_DIV_PS = FOP(3, FMT_PS),
9688     OPC_ABS_PS = FOP(5, FMT_PS),
9689     OPC_MOV_PS = FOP(6, FMT_PS),
9690     OPC_NEG_PS = FOP(7, FMT_PS),
9691     OPC_MOVCF_PS = FOP(17, FMT_PS),
9692     OPC_MOVZ_PS = FOP(18, FMT_PS),
9693     OPC_MOVN_PS = FOP(19, FMT_PS),
9694     OPC_ADDR_PS = FOP(24, FMT_PS),
9695     OPC_MULR_PS = FOP(26, FMT_PS),
9696     OPC_RECIP2_PS = FOP(28, FMT_PS),
9697     OPC_RECIP1_PS = FOP(29, FMT_PS),
9698     OPC_RSQRT1_PS = FOP(30, FMT_PS),
9699     OPC_RSQRT2_PS = FOP(31, FMT_PS),
9700
9701     OPC_CVT_S_PU = FOP(32, FMT_PS),
9702     OPC_CVT_PW_PS = FOP(36, FMT_PS),
9703     OPC_CVT_S_PL = FOP(40, FMT_PS),
9704     OPC_PLL_PS = FOP(44, FMT_PS),
9705     OPC_PLU_PS = FOP(45, FMT_PS),
9706     OPC_PUL_PS = FOP(46, FMT_PS),
9707     OPC_PUU_PS = FOP(47, FMT_PS),
9708     OPC_CMP_F_PS = FOP (48, FMT_PS),
9709     OPC_CMP_UN_PS = FOP (49, FMT_PS),
9710     OPC_CMP_EQ_PS = FOP (50, FMT_PS),
9711     OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
9712     OPC_CMP_OLT_PS = FOP (52, FMT_PS),
9713     OPC_CMP_ULT_PS = FOP (53, FMT_PS),
9714     OPC_CMP_OLE_PS = FOP (54, FMT_PS),
9715     OPC_CMP_ULE_PS = FOP (55, FMT_PS),
9716     OPC_CMP_SF_PS = FOP (56, FMT_PS),
9717     OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
9718     OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
9719     OPC_CMP_NGL_PS = FOP (59, FMT_PS),
9720     OPC_CMP_LT_PS = FOP (60, FMT_PS),
9721     OPC_CMP_NGE_PS = FOP (61, FMT_PS),
9722     OPC_CMP_LE_PS = FOP (62, FMT_PS),
9723     OPC_CMP_NGT_PS = FOP (63, FMT_PS),
9724 };
9725
9726 enum r6_f_cmp_op {
9727     R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
9728     R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
9729     R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
9730     R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
9731     R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
9732     R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
9733     R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
9734     R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
9735     R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
9736     R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
9737     R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
9738     R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
9739     R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
9740     R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
9741     R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
9742     R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
9743     R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
9744     R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
9745     R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
9746     R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
9747     R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
9748     R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
9749
9750     R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
9751     R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
9752     R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
9753     R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
9754     R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
9755     R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
9756     R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
9757     R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
9758     R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
9759     R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
9760     R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
9761     R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
9762     R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
9763     R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
9764     R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
9765     R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
9766     R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
9767     R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
9768     R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
9769     R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
9770     R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
9771     R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
9772 };
9773 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
9774 {
9775     TCGv t0 = tcg_temp_new();
9776
9777     switch (opc) {
9778     case OPC_MFC1:
9779         {
9780             TCGv_i32 fp0 = tcg_temp_new_i32();
9781
9782             gen_load_fpr32(ctx, fp0, fs);
9783             tcg_gen_ext_i32_tl(t0, fp0);
9784             tcg_temp_free_i32(fp0);
9785         }
9786         gen_store_gpr(t0, rt);
9787         break;
9788     case OPC_MTC1:
9789         gen_load_gpr(t0, rt);
9790         {
9791             TCGv_i32 fp0 = tcg_temp_new_i32();
9792
9793             tcg_gen_trunc_tl_i32(fp0, t0);
9794             gen_store_fpr32(ctx, fp0, fs);
9795             tcg_temp_free_i32(fp0);
9796         }
9797         break;
9798     case OPC_CFC1:
9799         gen_helper_1e0i(cfc1, t0, fs);
9800         gen_store_gpr(t0, rt);
9801         break;
9802     case OPC_CTC1:
9803         gen_load_gpr(t0, rt);
9804         save_cpu_state(ctx, 0);
9805         {
9806             TCGv_i32 fs_tmp = tcg_const_i32(fs);
9807
9808             gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9809             tcg_temp_free_i32(fs_tmp);
9810         }
9811         /* Stop translation as we may have changed hflags */
9812         ctx->base.is_jmp = DISAS_STOP;
9813         break;
9814 #if defined(TARGET_MIPS64)
9815     case OPC_DMFC1:
9816         gen_load_fpr64(ctx, t0, fs);
9817         gen_store_gpr(t0, rt);
9818         break;
9819     case OPC_DMTC1:
9820         gen_load_gpr(t0, rt);
9821         gen_store_fpr64(ctx, t0, fs);
9822         break;
9823 #endif
9824     case OPC_MFHC1:
9825         {
9826             TCGv_i32 fp0 = tcg_temp_new_i32();
9827
9828             gen_load_fpr32h(ctx, fp0, fs);
9829             tcg_gen_ext_i32_tl(t0, fp0);
9830             tcg_temp_free_i32(fp0);
9831         }
9832         gen_store_gpr(t0, rt);
9833         break;
9834     case OPC_MTHC1:
9835         gen_load_gpr(t0, rt);
9836         {
9837             TCGv_i32 fp0 = tcg_temp_new_i32();
9838
9839             tcg_gen_trunc_tl_i32(fp0, t0);
9840             gen_store_fpr32h(ctx, fp0, fs);
9841             tcg_temp_free_i32(fp0);
9842         }
9843         break;
9844     default:
9845         MIPS_INVAL("cp1 move");
9846         generate_exception_end(ctx, EXCP_RI);
9847         goto out;
9848     }
9849
9850  out:
9851     tcg_temp_free(t0);
9852 }
9853
9854 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
9855 {
9856     TCGLabel *l1;
9857     TCGCond cond;
9858     TCGv_i32 t0;
9859
9860     if (rd == 0) {
9861         /* Treat as NOP. */
9862         return;
9863     }
9864
9865     if (tf)
9866         cond = TCG_COND_EQ;
9867     else
9868         cond = TCG_COND_NE;
9869
9870     l1 = gen_new_label();
9871     t0 = tcg_temp_new_i32();
9872     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9873     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9874     tcg_temp_free_i32(t0);
9875     if (rs == 0) {
9876         tcg_gen_movi_tl(cpu_gpr[rd], 0);
9877     } else {
9878         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
9879     }
9880     gen_set_label(l1);
9881 }
9882
9883 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
9884                                int tf)
9885 {
9886     int cond;
9887     TCGv_i32 t0 = tcg_temp_new_i32();
9888     TCGLabel *l1 = gen_new_label();
9889
9890     if (tf)
9891         cond = TCG_COND_EQ;
9892     else
9893         cond = TCG_COND_NE;
9894
9895     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9896     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9897     gen_load_fpr32(ctx, t0, fs);
9898     gen_store_fpr32(ctx, t0, fd);
9899     gen_set_label(l1);
9900     tcg_temp_free_i32(t0);
9901 }
9902
9903 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
9904 {
9905     int cond;
9906     TCGv_i32 t0 = tcg_temp_new_i32();
9907     TCGv_i64 fp0;
9908     TCGLabel *l1 = gen_new_label();
9909
9910     if (tf)
9911         cond = TCG_COND_EQ;
9912     else
9913         cond = TCG_COND_NE;
9914
9915     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9916     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9917     tcg_temp_free_i32(t0);
9918     fp0 = tcg_temp_new_i64();
9919     gen_load_fpr64(ctx, fp0, fs);
9920     gen_store_fpr64(ctx, fp0, fd);
9921     tcg_temp_free_i64(fp0);
9922     gen_set_label(l1);
9923 }
9924
9925 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
9926                                 int cc, int tf)
9927 {
9928     int cond;
9929     TCGv_i32 t0 = tcg_temp_new_i32();
9930     TCGLabel *l1 = gen_new_label();
9931     TCGLabel *l2 = gen_new_label();
9932
9933     if (tf)
9934         cond = TCG_COND_EQ;
9935     else
9936         cond = TCG_COND_NE;
9937
9938     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9939     tcg_gen_brcondi_i32(cond, t0, 0, l1);
9940     gen_load_fpr32(ctx, t0, fs);
9941     gen_store_fpr32(ctx, t0, fd);
9942     gen_set_label(l1);
9943
9944     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
9945     tcg_gen_brcondi_i32(cond, t0, 0, l2);
9946     gen_load_fpr32h(ctx, t0, fs);
9947     gen_store_fpr32h(ctx, t0, fd);
9948     tcg_temp_free_i32(t0);
9949     gen_set_label(l2);
9950 }
9951
9952 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9953                       int fs)
9954 {
9955     TCGv_i32 t1 = tcg_const_i32(0);
9956     TCGv_i32 fp0 = tcg_temp_new_i32();
9957     TCGv_i32 fp1 = tcg_temp_new_i32();
9958     TCGv_i32 fp2 = tcg_temp_new_i32();
9959     gen_load_fpr32(ctx, fp0, fd);
9960     gen_load_fpr32(ctx, fp1, ft);
9961     gen_load_fpr32(ctx, fp2, fs);
9962
9963     switch (op1) {
9964     case OPC_SEL_S:
9965         tcg_gen_andi_i32(fp0, fp0, 1);
9966         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9967         break;
9968     case OPC_SELEQZ_S:
9969         tcg_gen_andi_i32(fp1, fp1, 1);
9970         tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9971         break;
9972     case OPC_SELNEZ_S:
9973         tcg_gen_andi_i32(fp1, fp1, 1);
9974         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9975         break;
9976     default:
9977         MIPS_INVAL("gen_sel_s");
9978         generate_exception_end(ctx, EXCP_RI);
9979         break;
9980     }
9981
9982     gen_store_fpr32(ctx, fp0, fd);
9983     tcg_temp_free_i32(fp2);
9984     tcg_temp_free_i32(fp1);
9985     tcg_temp_free_i32(fp0);
9986     tcg_temp_free_i32(t1);
9987 }
9988
9989 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9990                       int fs)
9991 {
9992     TCGv_i64 t1 = tcg_const_i64(0);
9993     TCGv_i64 fp0 = tcg_temp_new_i64();
9994     TCGv_i64 fp1 = tcg_temp_new_i64();
9995     TCGv_i64 fp2 = tcg_temp_new_i64();
9996     gen_load_fpr64(ctx, fp0, fd);
9997     gen_load_fpr64(ctx, fp1, ft);
9998     gen_load_fpr64(ctx, fp2, fs);
9999
10000     switch (op1) {
10001     case OPC_SEL_D:
10002         tcg_gen_andi_i64(fp0, fp0, 1);
10003         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10004         break;
10005     case OPC_SELEQZ_D:
10006         tcg_gen_andi_i64(fp1, fp1, 1);
10007         tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10008         break;
10009     case OPC_SELNEZ_D:
10010         tcg_gen_andi_i64(fp1, fp1, 1);
10011         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10012         break;
10013     default:
10014         MIPS_INVAL("gen_sel_d");
10015         generate_exception_end(ctx, EXCP_RI);
10016         break;
10017     }
10018
10019     gen_store_fpr64(ctx, fp0, fd);
10020     tcg_temp_free_i64(fp2);
10021     tcg_temp_free_i64(fp1);
10022     tcg_temp_free_i64(fp0);
10023     tcg_temp_free_i64(t1);
10024 }
10025
10026 static void gen_farith (DisasContext *ctx, enum fopcode op1,
10027                         int ft, int fs, int fd, int cc)
10028 {
10029     uint32_t func = ctx->opcode & 0x3f;
10030     switch (op1) {
10031     case OPC_ADD_S:
10032         {
10033             TCGv_i32 fp0 = tcg_temp_new_i32();
10034             TCGv_i32 fp1 = tcg_temp_new_i32();
10035
10036             gen_load_fpr32(ctx, fp0, fs);
10037             gen_load_fpr32(ctx, fp1, ft);
10038             gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
10039             tcg_temp_free_i32(fp1);
10040             gen_store_fpr32(ctx, fp0, fd);
10041             tcg_temp_free_i32(fp0);
10042         }
10043         break;
10044     case OPC_SUB_S:
10045         {
10046             TCGv_i32 fp0 = tcg_temp_new_i32();
10047             TCGv_i32 fp1 = tcg_temp_new_i32();
10048
10049             gen_load_fpr32(ctx, fp0, fs);
10050             gen_load_fpr32(ctx, fp1, ft);
10051             gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
10052             tcg_temp_free_i32(fp1);
10053             gen_store_fpr32(ctx, fp0, fd);
10054             tcg_temp_free_i32(fp0);
10055         }
10056         break;
10057     case OPC_MUL_S:
10058         {
10059             TCGv_i32 fp0 = tcg_temp_new_i32();
10060             TCGv_i32 fp1 = tcg_temp_new_i32();
10061
10062             gen_load_fpr32(ctx, fp0, fs);
10063             gen_load_fpr32(ctx, fp1, ft);
10064             gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
10065             tcg_temp_free_i32(fp1);
10066             gen_store_fpr32(ctx, fp0, fd);
10067             tcg_temp_free_i32(fp0);
10068         }
10069         break;
10070     case OPC_DIV_S:
10071         {
10072             TCGv_i32 fp0 = tcg_temp_new_i32();
10073             TCGv_i32 fp1 = tcg_temp_new_i32();
10074
10075             gen_load_fpr32(ctx, fp0, fs);
10076             gen_load_fpr32(ctx, fp1, ft);
10077             gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
10078             tcg_temp_free_i32(fp1);
10079             gen_store_fpr32(ctx, fp0, fd);
10080             tcg_temp_free_i32(fp0);
10081         }
10082         break;
10083     case OPC_SQRT_S:
10084         {
10085             TCGv_i32 fp0 = tcg_temp_new_i32();
10086
10087             gen_load_fpr32(ctx, fp0, fs);
10088             gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
10089             gen_store_fpr32(ctx, fp0, fd);
10090             tcg_temp_free_i32(fp0);
10091         }
10092         break;
10093     case OPC_ABS_S:
10094         {
10095             TCGv_i32 fp0 = tcg_temp_new_i32();
10096
10097             gen_load_fpr32(ctx, fp0, fs);
10098             if (ctx->abs2008) {
10099                 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10100             } else {
10101                 gen_helper_float_abs_s(fp0, fp0);
10102             }
10103             gen_store_fpr32(ctx, fp0, fd);
10104             tcg_temp_free_i32(fp0);
10105         }
10106         break;
10107     case OPC_MOV_S:
10108         {
10109             TCGv_i32 fp0 = tcg_temp_new_i32();
10110
10111             gen_load_fpr32(ctx, fp0, fs);
10112             gen_store_fpr32(ctx, fp0, fd);
10113             tcg_temp_free_i32(fp0);
10114         }
10115         break;
10116     case OPC_NEG_S:
10117         {
10118             TCGv_i32 fp0 = tcg_temp_new_i32();
10119
10120             gen_load_fpr32(ctx, fp0, fs);
10121             if (ctx->abs2008) {
10122                 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10123             } else {
10124                 gen_helper_float_chs_s(fp0, fp0);
10125             }
10126             gen_store_fpr32(ctx, fp0, fd);
10127             tcg_temp_free_i32(fp0);
10128         }
10129         break;
10130     case OPC_ROUND_L_S:
10131         check_cp1_64bitmode(ctx);
10132         {
10133             TCGv_i32 fp32 = tcg_temp_new_i32();
10134             TCGv_i64 fp64 = tcg_temp_new_i64();
10135
10136             gen_load_fpr32(ctx, fp32, fs);
10137             if (ctx->nan2008) {
10138                 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10139             } else {
10140                 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10141             }
10142             tcg_temp_free_i32(fp32);
10143             gen_store_fpr64(ctx, fp64, fd);
10144             tcg_temp_free_i64(fp64);
10145         }
10146         break;
10147     case OPC_TRUNC_L_S:
10148         check_cp1_64bitmode(ctx);
10149         {
10150             TCGv_i32 fp32 = tcg_temp_new_i32();
10151             TCGv_i64 fp64 = tcg_temp_new_i64();
10152
10153             gen_load_fpr32(ctx, fp32, fs);
10154             if (ctx->nan2008) {
10155                 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10156             } else {
10157                 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10158             }
10159             tcg_temp_free_i32(fp32);
10160             gen_store_fpr64(ctx, fp64, fd);
10161             tcg_temp_free_i64(fp64);
10162         }
10163         break;
10164     case OPC_CEIL_L_S:
10165         check_cp1_64bitmode(ctx);
10166         {
10167             TCGv_i32 fp32 = tcg_temp_new_i32();
10168             TCGv_i64 fp64 = tcg_temp_new_i64();
10169
10170             gen_load_fpr32(ctx, fp32, fs);
10171             if (ctx->nan2008) {
10172                 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10173             } else {
10174                 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10175             }
10176             tcg_temp_free_i32(fp32);
10177             gen_store_fpr64(ctx, fp64, fd);
10178             tcg_temp_free_i64(fp64);
10179         }
10180         break;
10181     case OPC_FLOOR_L_S:
10182         check_cp1_64bitmode(ctx);
10183         {
10184             TCGv_i32 fp32 = tcg_temp_new_i32();
10185             TCGv_i64 fp64 = tcg_temp_new_i64();
10186
10187             gen_load_fpr32(ctx, fp32, fs);
10188             if (ctx->nan2008) {
10189                 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10190             } else {
10191                 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10192             }
10193             tcg_temp_free_i32(fp32);
10194             gen_store_fpr64(ctx, fp64, fd);
10195             tcg_temp_free_i64(fp64);
10196         }
10197         break;
10198     case OPC_ROUND_W_S:
10199         {
10200             TCGv_i32 fp0 = tcg_temp_new_i32();
10201
10202             gen_load_fpr32(ctx, fp0, fs);
10203             if (ctx->nan2008) {
10204                 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10205             } else {
10206                 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10207             }
10208             gen_store_fpr32(ctx, fp0, fd);
10209             tcg_temp_free_i32(fp0);
10210         }
10211         break;
10212     case OPC_TRUNC_W_S:
10213         {
10214             TCGv_i32 fp0 = tcg_temp_new_i32();
10215
10216             gen_load_fpr32(ctx, fp0, fs);
10217             if (ctx->nan2008) {
10218                 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10219             } else {
10220                 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10221             }
10222             gen_store_fpr32(ctx, fp0, fd);
10223             tcg_temp_free_i32(fp0);
10224         }
10225         break;
10226     case OPC_CEIL_W_S:
10227         {
10228             TCGv_i32 fp0 = tcg_temp_new_i32();
10229
10230             gen_load_fpr32(ctx, fp0, fs);
10231             if (ctx->nan2008) {
10232                 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10233             } else {
10234                 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10235             }
10236             gen_store_fpr32(ctx, fp0, fd);
10237             tcg_temp_free_i32(fp0);
10238         }
10239         break;
10240     case OPC_FLOOR_W_S:
10241         {
10242             TCGv_i32 fp0 = tcg_temp_new_i32();
10243
10244             gen_load_fpr32(ctx, fp0, fs);
10245             if (ctx->nan2008) {
10246                 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10247             } else {
10248                 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10249             }
10250             gen_store_fpr32(ctx, fp0, fd);
10251             tcg_temp_free_i32(fp0);
10252         }
10253         break;
10254     case OPC_SEL_S:
10255         check_insn(ctx, ISA_MIPS32R6);
10256         gen_sel_s(ctx, op1, fd, ft, fs);
10257         break;
10258     case OPC_SELEQZ_S:
10259         check_insn(ctx, ISA_MIPS32R6);
10260         gen_sel_s(ctx, op1, fd, ft, fs);
10261         break;
10262     case OPC_SELNEZ_S:
10263         check_insn(ctx, ISA_MIPS32R6);
10264         gen_sel_s(ctx, op1, fd, ft, fs);
10265         break;
10266     case OPC_MOVCF_S:
10267         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10268         gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10269         break;
10270     case OPC_MOVZ_S:
10271         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10272         {
10273             TCGLabel *l1 = gen_new_label();
10274             TCGv_i32 fp0;
10275
10276             if (ft != 0) {
10277                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10278             }
10279             fp0 = tcg_temp_new_i32();
10280             gen_load_fpr32(ctx, fp0, fs);
10281             gen_store_fpr32(ctx, fp0, fd);
10282             tcg_temp_free_i32(fp0);
10283             gen_set_label(l1);
10284         }
10285         break;
10286     case OPC_MOVN_S:
10287         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10288         {
10289             TCGLabel *l1 = gen_new_label();
10290             TCGv_i32 fp0;
10291
10292             if (ft != 0) {
10293                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10294                 fp0 = tcg_temp_new_i32();
10295                 gen_load_fpr32(ctx, fp0, fs);
10296                 gen_store_fpr32(ctx, fp0, fd);
10297                 tcg_temp_free_i32(fp0);
10298                 gen_set_label(l1);
10299             }
10300         }
10301         break;
10302     case OPC_RECIP_S:
10303         {
10304             TCGv_i32 fp0 = tcg_temp_new_i32();
10305
10306             gen_load_fpr32(ctx, fp0, fs);
10307             gen_helper_float_recip_s(fp0, cpu_env, fp0);
10308             gen_store_fpr32(ctx, fp0, fd);
10309             tcg_temp_free_i32(fp0);
10310         }
10311         break;
10312     case OPC_RSQRT_S:
10313         {
10314             TCGv_i32 fp0 = tcg_temp_new_i32();
10315
10316             gen_load_fpr32(ctx, fp0, fs);
10317             gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
10318             gen_store_fpr32(ctx, fp0, fd);
10319             tcg_temp_free_i32(fp0);
10320         }
10321         break;
10322     case OPC_MADDF_S:
10323         check_insn(ctx, ISA_MIPS32R6);
10324         {
10325             TCGv_i32 fp0 = tcg_temp_new_i32();
10326             TCGv_i32 fp1 = tcg_temp_new_i32();
10327             TCGv_i32 fp2 = tcg_temp_new_i32();
10328             gen_load_fpr32(ctx, fp0, fs);
10329             gen_load_fpr32(ctx, fp1, ft);
10330             gen_load_fpr32(ctx, fp2, fd);
10331             gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
10332             gen_store_fpr32(ctx, fp2, fd);
10333             tcg_temp_free_i32(fp2);
10334             tcg_temp_free_i32(fp1);
10335             tcg_temp_free_i32(fp0);
10336         }
10337         break;
10338     case OPC_MSUBF_S:
10339         check_insn(ctx, ISA_MIPS32R6);
10340         {
10341             TCGv_i32 fp0 = tcg_temp_new_i32();
10342             TCGv_i32 fp1 = tcg_temp_new_i32();
10343             TCGv_i32 fp2 = tcg_temp_new_i32();
10344             gen_load_fpr32(ctx, fp0, fs);
10345             gen_load_fpr32(ctx, fp1, ft);
10346             gen_load_fpr32(ctx, fp2, fd);
10347             gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
10348             gen_store_fpr32(ctx, fp2, fd);
10349             tcg_temp_free_i32(fp2);
10350             tcg_temp_free_i32(fp1);
10351             tcg_temp_free_i32(fp0);
10352         }
10353         break;
10354     case OPC_RINT_S:
10355         check_insn(ctx, ISA_MIPS32R6);
10356         {
10357             TCGv_i32 fp0 = tcg_temp_new_i32();
10358             gen_load_fpr32(ctx, fp0, fs);
10359             gen_helper_float_rint_s(fp0, cpu_env, fp0);
10360             gen_store_fpr32(ctx, fp0, fd);
10361             tcg_temp_free_i32(fp0);
10362         }
10363         break;
10364     case OPC_CLASS_S:
10365         check_insn(ctx, ISA_MIPS32R6);
10366         {
10367             TCGv_i32 fp0 = tcg_temp_new_i32();
10368             gen_load_fpr32(ctx, fp0, fs);
10369             gen_helper_float_class_s(fp0, cpu_env, fp0);
10370             gen_store_fpr32(ctx, fp0, fd);
10371             tcg_temp_free_i32(fp0);
10372         }
10373         break;
10374     case OPC_MIN_S: /* OPC_RECIP2_S */
10375         if (ctx->insn_flags & ISA_MIPS32R6) {
10376             /* OPC_MIN_S */
10377             TCGv_i32 fp0 = tcg_temp_new_i32();
10378             TCGv_i32 fp1 = tcg_temp_new_i32();
10379             TCGv_i32 fp2 = tcg_temp_new_i32();
10380             gen_load_fpr32(ctx, fp0, fs);
10381             gen_load_fpr32(ctx, fp1, ft);
10382             gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
10383             gen_store_fpr32(ctx, fp2, fd);
10384             tcg_temp_free_i32(fp2);
10385             tcg_temp_free_i32(fp1);
10386             tcg_temp_free_i32(fp0);
10387         } else {
10388             /* OPC_RECIP2_S */
10389             check_cp1_64bitmode(ctx);
10390             {
10391                 TCGv_i32 fp0 = tcg_temp_new_i32();
10392                 TCGv_i32 fp1 = tcg_temp_new_i32();
10393
10394                 gen_load_fpr32(ctx, fp0, fs);
10395                 gen_load_fpr32(ctx, fp1, ft);
10396                 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
10397                 tcg_temp_free_i32(fp1);
10398                 gen_store_fpr32(ctx, fp0, fd);
10399                 tcg_temp_free_i32(fp0);
10400             }
10401         }
10402         break;
10403     case OPC_MINA_S: /* OPC_RECIP1_S */
10404         if (ctx->insn_flags & ISA_MIPS32R6) {
10405             /* OPC_MINA_S */
10406             TCGv_i32 fp0 = tcg_temp_new_i32();
10407             TCGv_i32 fp1 = tcg_temp_new_i32();
10408             TCGv_i32 fp2 = tcg_temp_new_i32();
10409             gen_load_fpr32(ctx, fp0, fs);
10410             gen_load_fpr32(ctx, fp1, ft);
10411             gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
10412             gen_store_fpr32(ctx, fp2, fd);
10413             tcg_temp_free_i32(fp2);
10414             tcg_temp_free_i32(fp1);
10415             tcg_temp_free_i32(fp0);
10416         } else {
10417             /* OPC_RECIP1_S */
10418             check_cp1_64bitmode(ctx);
10419             {
10420                 TCGv_i32 fp0 = tcg_temp_new_i32();
10421
10422                 gen_load_fpr32(ctx, fp0, fs);
10423                 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
10424                 gen_store_fpr32(ctx, fp0, fd);
10425                 tcg_temp_free_i32(fp0);
10426             }
10427         }
10428         break;
10429     case OPC_MAX_S: /* OPC_RSQRT1_S */
10430         if (ctx->insn_flags & ISA_MIPS32R6) {
10431             /* OPC_MAX_S */
10432             TCGv_i32 fp0 = tcg_temp_new_i32();
10433             TCGv_i32 fp1 = tcg_temp_new_i32();
10434             gen_load_fpr32(ctx, fp0, fs);
10435             gen_load_fpr32(ctx, fp1, ft);
10436             gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
10437             gen_store_fpr32(ctx, fp1, fd);
10438             tcg_temp_free_i32(fp1);
10439             tcg_temp_free_i32(fp0);
10440         } else {
10441             /* OPC_RSQRT1_S */
10442             check_cp1_64bitmode(ctx);
10443             {
10444                 TCGv_i32 fp0 = tcg_temp_new_i32();
10445
10446                 gen_load_fpr32(ctx, fp0, fs);
10447                 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
10448                 gen_store_fpr32(ctx, fp0, fd);
10449                 tcg_temp_free_i32(fp0);
10450             }
10451         }
10452         break;
10453     case OPC_MAXA_S: /* OPC_RSQRT2_S */
10454         if (ctx->insn_flags & ISA_MIPS32R6) {
10455             /* OPC_MAXA_S */
10456             TCGv_i32 fp0 = tcg_temp_new_i32();
10457             TCGv_i32 fp1 = tcg_temp_new_i32();
10458             gen_load_fpr32(ctx, fp0, fs);
10459             gen_load_fpr32(ctx, fp1, ft);
10460             gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
10461             gen_store_fpr32(ctx, fp1, fd);
10462             tcg_temp_free_i32(fp1);
10463             tcg_temp_free_i32(fp0);
10464         } else {
10465             /* OPC_RSQRT2_S */
10466             check_cp1_64bitmode(ctx);
10467             {
10468                 TCGv_i32 fp0 = tcg_temp_new_i32();
10469                 TCGv_i32 fp1 = tcg_temp_new_i32();
10470
10471                 gen_load_fpr32(ctx, fp0, fs);
10472                 gen_load_fpr32(ctx, fp1, ft);
10473                 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
10474                 tcg_temp_free_i32(fp1);
10475                 gen_store_fpr32(ctx, fp0, fd);
10476                 tcg_temp_free_i32(fp0);
10477             }
10478         }
10479         break;
10480     case OPC_CVT_D_S:
10481         check_cp1_registers(ctx, fd);
10482         {
10483             TCGv_i32 fp32 = tcg_temp_new_i32();
10484             TCGv_i64 fp64 = tcg_temp_new_i64();
10485
10486             gen_load_fpr32(ctx, fp32, fs);
10487             gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
10488             tcg_temp_free_i32(fp32);
10489             gen_store_fpr64(ctx, fp64, fd);
10490             tcg_temp_free_i64(fp64);
10491         }
10492         break;
10493     case OPC_CVT_W_S:
10494         {
10495             TCGv_i32 fp0 = tcg_temp_new_i32();
10496
10497             gen_load_fpr32(ctx, fp0, fs);
10498             if (ctx->nan2008) {
10499                 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
10500             } else {
10501                 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
10502             }
10503             gen_store_fpr32(ctx, fp0, fd);
10504             tcg_temp_free_i32(fp0);
10505         }
10506         break;
10507     case OPC_CVT_L_S:
10508         check_cp1_64bitmode(ctx);
10509         {
10510             TCGv_i32 fp32 = tcg_temp_new_i32();
10511             TCGv_i64 fp64 = tcg_temp_new_i64();
10512
10513             gen_load_fpr32(ctx, fp32, fs);
10514             if (ctx->nan2008) {
10515                 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
10516             } else {
10517                 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
10518             }
10519             tcg_temp_free_i32(fp32);
10520             gen_store_fpr64(ctx, fp64, fd);
10521             tcg_temp_free_i64(fp64);
10522         }
10523         break;
10524     case OPC_CVT_PS_S:
10525         check_ps(ctx);
10526         {
10527             TCGv_i64 fp64 = tcg_temp_new_i64();
10528             TCGv_i32 fp32_0 = tcg_temp_new_i32();
10529             TCGv_i32 fp32_1 = tcg_temp_new_i32();
10530
10531             gen_load_fpr32(ctx, fp32_0, fs);
10532             gen_load_fpr32(ctx, fp32_1, ft);
10533             tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
10534             tcg_temp_free_i32(fp32_1);
10535             tcg_temp_free_i32(fp32_0);
10536             gen_store_fpr64(ctx, fp64, fd);
10537             tcg_temp_free_i64(fp64);
10538         }
10539         break;
10540     case OPC_CMP_F_S:
10541     case OPC_CMP_UN_S:
10542     case OPC_CMP_EQ_S:
10543     case OPC_CMP_UEQ_S:
10544     case OPC_CMP_OLT_S:
10545     case OPC_CMP_ULT_S:
10546     case OPC_CMP_OLE_S:
10547     case OPC_CMP_ULE_S:
10548     case OPC_CMP_SF_S:
10549     case OPC_CMP_NGLE_S:
10550     case OPC_CMP_SEQ_S:
10551     case OPC_CMP_NGL_S:
10552     case OPC_CMP_LT_S:
10553     case OPC_CMP_NGE_S:
10554     case OPC_CMP_LE_S:
10555     case OPC_CMP_NGT_S:
10556         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10557         if (ctx->opcode & (1 << 6)) {
10558             gen_cmpabs_s(ctx, func-48, ft, fs, cc);
10559         } else {
10560             gen_cmp_s(ctx, func-48, ft, fs, cc);
10561         }
10562         break;
10563     case OPC_ADD_D:
10564         check_cp1_registers(ctx, fs | ft | fd);
10565         {
10566             TCGv_i64 fp0 = tcg_temp_new_i64();
10567             TCGv_i64 fp1 = tcg_temp_new_i64();
10568
10569             gen_load_fpr64(ctx, fp0, fs);
10570             gen_load_fpr64(ctx, fp1, ft);
10571             gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
10572             tcg_temp_free_i64(fp1);
10573             gen_store_fpr64(ctx, fp0, fd);
10574             tcg_temp_free_i64(fp0);
10575         }
10576         break;
10577     case OPC_SUB_D:
10578         check_cp1_registers(ctx, fs | ft | fd);
10579         {
10580             TCGv_i64 fp0 = tcg_temp_new_i64();
10581             TCGv_i64 fp1 = tcg_temp_new_i64();
10582
10583             gen_load_fpr64(ctx, fp0, fs);
10584             gen_load_fpr64(ctx, fp1, ft);
10585             gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
10586             tcg_temp_free_i64(fp1);
10587             gen_store_fpr64(ctx, fp0, fd);
10588             tcg_temp_free_i64(fp0);
10589         }
10590         break;
10591     case OPC_MUL_D:
10592         check_cp1_registers(ctx, fs | ft | fd);
10593         {
10594             TCGv_i64 fp0 = tcg_temp_new_i64();
10595             TCGv_i64 fp1 = tcg_temp_new_i64();
10596
10597             gen_load_fpr64(ctx, fp0, fs);
10598             gen_load_fpr64(ctx, fp1, ft);
10599             gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
10600             tcg_temp_free_i64(fp1);
10601             gen_store_fpr64(ctx, fp0, fd);
10602             tcg_temp_free_i64(fp0);
10603         }
10604         break;
10605     case OPC_DIV_D:
10606         check_cp1_registers(ctx, fs | ft | fd);
10607         {
10608             TCGv_i64 fp0 = tcg_temp_new_i64();
10609             TCGv_i64 fp1 = tcg_temp_new_i64();
10610
10611             gen_load_fpr64(ctx, fp0, fs);
10612             gen_load_fpr64(ctx, fp1, ft);
10613             gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
10614             tcg_temp_free_i64(fp1);
10615             gen_store_fpr64(ctx, fp0, fd);
10616             tcg_temp_free_i64(fp0);
10617         }
10618         break;
10619     case OPC_SQRT_D:
10620         check_cp1_registers(ctx, fs | fd);
10621         {
10622             TCGv_i64 fp0 = tcg_temp_new_i64();
10623
10624             gen_load_fpr64(ctx, fp0, fs);
10625             gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
10626             gen_store_fpr64(ctx, fp0, fd);
10627             tcg_temp_free_i64(fp0);
10628         }
10629         break;
10630     case OPC_ABS_D:
10631         check_cp1_registers(ctx, fs | fd);
10632         {
10633             TCGv_i64 fp0 = tcg_temp_new_i64();
10634
10635             gen_load_fpr64(ctx, fp0, fs);
10636             if (ctx->abs2008) {
10637                 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
10638             } else {
10639                 gen_helper_float_abs_d(fp0, fp0);
10640             }
10641             gen_store_fpr64(ctx, fp0, fd);
10642             tcg_temp_free_i64(fp0);
10643         }
10644         break;
10645     case OPC_MOV_D:
10646         check_cp1_registers(ctx, fs | fd);
10647         {
10648             TCGv_i64 fp0 = tcg_temp_new_i64();
10649
10650             gen_load_fpr64(ctx, fp0, fs);
10651             gen_store_fpr64(ctx, fp0, fd);
10652             tcg_temp_free_i64(fp0);
10653         }
10654         break;
10655     case OPC_NEG_D:
10656         check_cp1_registers(ctx, fs | fd);
10657         {
10658             TCGv_i64 fp0 = tcg_temp_new_i64();
10659
10660             gen_load_fpr64(ctx, fp0, fs);
10661             if (ctx->abs2008) {
10662                 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
10663             } else {
10664                 gen_helper_float_chs_d(fp0, fp0);
10665             }
10666             gen_store_fpr64(ctx, fp0, fd);
10667             tcg_temp_free_i64(fp0);
10668         }
10669         break;
10670     case OPC_ROUND_L_D:
10671         check_cp1_64bitmode(ctx);
10672         {
10673             TCGv_i64 fp0 = tcg_temp_new_i64();
10674
10675             gen_load_fpr64(ctx, fp0, fs);
10676             if (ctx->nan2008) {
10677                 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
10678             } else {
10679                 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
10680             }
10681             gen_store_fpr64(ctx, fp0, fd);
10682             tcg_temp_free_i64(fp0);
10683         }
10684         break;
10685     case OPC_TRUNC_L_D:
10686         check_cp1_64bitmode(ctx);
10687         {
10688             TCGv_i64 fp0 = tcg_temp_new_i64();
10689
10690             gen_load_fpr64(ctx, fp0, fs);
10691             if (ctx->nan2008) {
10692                 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
10693             } else {
10694                 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
10695             }
10696             gen_store_fpr64(ctx, fp0, fd);
10697             tcg_temp_free_i64(fp0);
10698         }
10699         break;
10700     case OPC_CEIL_L_D:
10701         check_cp1_64bitmode(ctx);
10702         {
10703             TCGv_i64 fp0 = tcg_temp_new_i64();
10704
10705             gen_load_fpr64(ctx, fp0, fs);
10706             if (ctx->nan2008) {
10707                 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
10708             } else {
10709                 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
10710             }
10711             gen_store_fpr64(ctx, fp0, fd);
10712             tcg_temp_free_i64(fp0);
10713         }
10714         break;
10715     case OPC_FLOOR_L_D:
10716         check_cp1_64bitmode(ctx);
10717         {
10718             TCGv_i64 fp0 = tcg_temp_new_i64();
10719
10720             gen_load_fpr64(ctx, fp0, fs);
10721             if (ctx->nan2008) {
10722                 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
10723             } else {
10724                 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
10725             }
10726             gen_store_fpr64(ctx, fp0, fd);
10727             tcg_temp_free_i64(fp0);
10728         }
10729         break;
10730     case OPC_ROUND_W_D:
10731         check_cp1_registers(ctx, fs);
10732         {
10733             TCGv_i32 fp32 = tcg_temp_new_i32();
10734             TCGv_i64 fp64 = tcg_temp_new_i64();
10735
10736             gen_load_fpr64(ctx, fp64, fs);
10737             if (ctx->nan2008) {
10738                 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
10739             } else {
10740                 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
10741             }
10742             tcg_temp_free_i64(fp64);
10743             gen_store_fpr32(ctx, fp32, fd);
10744             tcg_temp_free_i32(fp32);
10745         }
10746         break;
10747     case OPC_TRUNC_W_D:
10748         check_cp1_registers(ctx, fs);
10749         {
10750             TCGv_i32 fp32 = tcg_temp_new_i32();
10751             TCGv_i64 fp64 = tcg_temp_new_i64();
10752
10753             gen_load_fpr64(ctx, fp64, fs);
10754             if (ctx->nan2008) {
10755                 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
10756             } else {
10757                 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
10758             }
10759             tcg_temp_free_i64(fp64);
10760             gen_store_fpr32(ctx, fp32, fd);
10761             tcg_temp_free_i32(fp32);
10762         }
10763         break;
10764     case OPC_CEIL_W_D:
10765         check_cp1_registers(ctx, fs);
10766         {
10767             TCGv_i32 fp32 = tcg_temp_new_i32();
10768             TCGv_i64 fp64 = tcg_temp_new_i64();
10769
10770             gen_load_fpr64(ctx, fp64, fs);
10771             if (ctx->nan2008) {
10772                 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
10773             } else {
10774                 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
10775             }
10776             tcg_temp_free_i64(fp64);
10777             gen_store_fpr32(ctx, fp32, fd);
10778             tcg_temp_free_i32(fp32);
10779         }
10780         break;
10781     case OPC_FLOOR_W_D:
10782         check_cp1_registers(ctx, fs);
10783         {
10784             TCGv_i32 fp32 = tcg_temp_new_i32();
10785             TCGv_i64 fp64 = tcg_temp_new_i64();
10786
10787             gen_load_fpr64(ctx, fp64, fs);
10788             if (ctx->nan2008) {
10789                 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
10790             } else {
10791                 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
10792             }
10793             tcg_temp_free_i64(fp64);
10794             gen_store_fpr32(ctx, fp32, fd);
10795             tcg_temp_free_i32(fp32);
10796         }
10797         break;
10798     case OPC_SEL_D:
10799         check_insn(ctx, ISA_MIPS32R6);
10800         gen_sel_d(ctx, op1, fd, ft, fs);
10801         break;
10802     case OPC_SELEQZ_D:
10803         check_insn(ctx, ISA_MIPS32R6);
10804         gen_sel_d(ctx, op1, fd, ft, fs);
10805         break;
10806     case OPC_SELNEZ_D:
10807         check_insn(ctx, ISA_MIPS32R6);
10808         gen_sel_d(ctx, op1, fd, ft, fs);
10809         break;
10810     case OPC_MOVCF_D:
10811         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10812         gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10813         break;
10814     case OPC_MOVZ_D:
10815         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10816         {
10817             TCGLabel *l1 = gen_new_label();
10818             TCGv_i64 fp0;
10819
10820             if (ft != 0) {
10821                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10822             }
10823             fp0 = tcg_temp_new_i64();
10824             gen_load_fpr64(ctx, fp0, fs);
10825             gen_store_fpr64(ctx, fp0, fd);
10826             tcg_temp_free_i64(fp0);
10827             gen_set_label(l1);
10828         }
10829         break;
10830     case OPC_MOVN_D:
10831         check_insn_opc_removed(ctx, ISA_MIPS32R6);
10832         {
10833             TCGLabel *l1 = gen_new_label();
10834             TCGv_i64 fp0;
10835
10836             if (ft != 0) {
10837                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10838                 fp0 = tcg_temp_new_i64();
10839                 gen_load_fpr64(ctx, fp0, fs);
10840                 gen_store_fpr64(ctx, fp0, fd);
10841                 tcg_temp_free_i64(fp0);
10842                 gen_set_label(l1);
10843             }
10844         }
10845         break;
10846     case OPC_RECIP_D:
10847         check_cp1_registers(ctx, fs | fd);
10848         {
10849             TCGv_i64 fp0 = tcg_temp_new_i64();
10850
10851             gen_load_fpr64(ctx, fp0, fs);
10852             gen_helper_float_recip_d(fp0, cpu_env, fp0);
10853             gen_store_fpr64(ctx, fp0, fd);
10854             tcg_temp_free_i64(fp0);
10855         }
10856         break;
10857     case OPC_RSQRT_D:
10858         check_cp1_registers(ctx, fs | fd);
10859         {
10860             TCGv_i64 fp0 = tcg_temp_new_i64();
10861
10862             gen_load_fpr64(ctx, fp0, fs);
10863             gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
10864             gen_store_fpr64(ctx, fp0, fd);
10865             tcg_temp_free_i64(fp0);
10866         }
10867         break;
10868     case OPC_MADDF_D:
10869         check_insn(ctx, ISA_MIPS32R6);
10870         {
10871             TCGv_i64 fp0 = tcg_temp_new_i64();
10872             TCGv_i64 fp1 = tcg_temp_new_i64();
10873             TCGv_i64 fp2 = tcg_temp_new_i64();
10874             gen_load_fpr64(ctx, fp0, fs);
10875             gen_load_fpr64(ctx, fp1, ft);
10876             gen_load_fpr64(ctx, fp2, fd);
10877             gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
10878             gen_store_fpr64(ctx, fp2, fd);
10879             tcg_temp_free_i64(fp2);
10880             tcg_temp_free_i64(fp1);
10881             tcg_temp_free_i64(fp0);
10882         }
10883         break;
10884     case OPC_MSUBF_D:
10885         check_insn(ctx, ISA_MIPS32R6);
10886         {
10887             TCGv_i64 fp0 = tcg_temp_new_i64();
10888             TCGv_i64 fp1 = tcg_temp_new_i64();
10889             TCGv_i64 fp2 = tcg_temp_new_i64();
10890             gen_load_fpr64(ctx, fp0, fs);
10891             gen_load_fpr64(ctx, fp1, ft);
10892             gen_load_fpr64(ctx, fp2, fd);
10893             gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
10894             gen_store_fpr64(ctx, fp2, fd);
10895             tcg_temp_free_i64(fp2);
10896             tcg_temp_free_i64(fp1);
10897             tcg_temp_free_i64(fp0);
10898         }
10899         break;
10900     case OPC_RINT_D:
10901         check_insn(ctx, ISA_MIPS32R6);
10902         {
10903             TCGv_i64 fp0 = tcg_temp_new_i64();
10904             gen_load_fpr64(ctx, fp0, fs);
10905             gen_helper_float_rint_d(fp0, cpu_env, fp0);
10906             gen_store_fpr64(ctx, fp0, fd);
10907             tcg_temp_free_i64(fp0);
10908         }
10909         break;
10910     case OPC_CLASS_D:
10911         check_insn(ctx, ISA_MIPS32R6);
10912         {
10913             TCGv_i64 fp0 = tcg_temp_new_i64();
10914             gen_load_fpr64(ctx, fp0, fs);
10915             gen_helper_float_class_d(fp0, cpu_env, fp0);
10916             gen_store_fpr64(ctx, fp0, fd);
10917             tcg_temp_free_i64(fp0);
10918         }
10919         break;
10920     case OPC_MIN_D: /* OPC_RECIP2_D */
10921         if (ctx->insn_flags & ISA_MIPS32R6) {
10922             /* OPC_MIN_D */
10923             TCGv_i64 fp0 = tcg_temp_new_i64();
10924             TCGv_i64 fp1 = tcg_temp_new_i64();
10925             gen_load_fpr64(ctx, fp0, fs);
10926             gen_load_fpr64(ctx, fp1, ft);
10927             gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
10928             gen_store_fpr64(ctx, fp1, fd);
10929             tcg_temp_free_i64(fp1);
10930             tcg_temp_free_i64(fp0);
10931         } else {
10932             /* OPC_RECIP2_D */
10933             check_cp1_64bitmode(ctx);
10934             {
10935                 TCGv_i64 fp0 = tcg_temp_new_i64();
10936                 TCGv_i64 fp1 = tcg_temp_new_i64();
10937
10938                 gen_load_fpr64(ctx, fp0, fs);
10939                 gen_load_fpr64(ctx, fp1, ft);
10940                 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
10941                 tcg_temp_free_i64(fp1);
10942                 gen_store_fpr64(ctx, fp0, fd);
10943                 tcg_temp_free_i64(fp0);
10944             }
10945         }
10946         break;
10947     case OPC_MINA_D: /* OPC_RECIP1_D */
10948         if (ctx->insn_flags & ISA_MIPS32R6) {
10949             /* OPC_MINA_D */
10950             TCGv_i64 fp0 = tcg_temp_new_i64();
10951             TCGv_i64 fp1 = tcg_temp_new_i64();
10952             gen_load_fpr64(ctx, fp0, fs);
10953             gen_load_fpr64(ctx, fp1, ft);
10954             gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
10955             gen_store_fpr64(ctx, fp1, fd);
10956             tcg_temp_free_i64(fp1);
10957             tcg_temp_free_i64(fp0);
10958         } else {
10959             /* OPC_RECIP1_D */
10960             check_cp1_64bitmode(ctx);
10961             {
10962                 TCGv_i64 fp0 = tcg_temp_new_i64();
10963
10964                 gen_load_fpr64(ctx, fp0, fs);
10965                 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
10966                 gen_store_fpr64(ctx, fp0, fd);
10967                 tcg_temp_free_i64(fp0);
10968             }
10969         }
10970         break;
10971     case OPC_MAX_D: /*  OPC_RSQRT1_D */
10972         if (ctx->insn_flags & ISA_MIPS32R6) {
10973             /* OPC_MAX_D */
10974             TCGv_i64 fp0 = tcg_temp_new_i64();
10975             TCGv_i64 fp1 = tcg_temp_new_i64();
10976             gen_load_fpr64(ctx, fp0, fs);
10977             gen_load_fpr64(ctx, fp1, ft);
10978             gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
10979             gen_store_fpr64(ctx, fp1, fd);
10980             tcg_temp_free_i64(fp1);
10981             tcg_temp_free_i64(fp0);
10982         } else {
10983             /* OPC_RSQRT1_D */
10984             check_cp1_64bitmode(ctx);
10985             {
10986                 TCGv_i64 fp0 = tcg_temp_new_i64();
10987
10988                 gen_load_fpr64(ctx, fp0, fs);
10989                 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
10990                 gen_store_fpr64(ctx, fp0, fd);
10991                 tcg_temp_free_i64(fp0);
10992             }
10993         }
10994         break;
10995     case OPC_MAXA_D: /* OPC_RSQRT2_D */
10996         if (ctx->insn_flags & ISA_MIPS32R6) {
10997             /* OPC_MAXA_D */
10998             TCGv_i64 fp0 = tcg_temp_new_i64();
10999             TCGv_i64 fp1 = tcg_temp_new_i64();
11000             gen_load_fpr64(ctx, fp0, fs);
11001             gen_load_fpr64(ctx, fp1, ft);
11002             gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11003             gen_store_fpr64(ctx, fp1, fd);
11004             tcg_temp_free_i64(fp1);
11005             tcg_temp_free_i64(fp0);
11006         } else {
11007             /* OPC_RSQRT2_D */
11008             check_cp1_64bitmode(ctx);
11009             {
11010                 TCGv_i64 fp0 = tcg_temp_new_i64();
11011                 TCGv_i64 fp1 = tcg_temp_new_i64();
11012
11013                 gen_load_fpr64(ctx, fp0, fs);
11014                 gen_load_fpr64(ctx, fp1, ft);
11015                 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11016                 tcg_temp_free_i64(fp1);
11017                 gen_store_fpr64(ctx, fp0, fd);
11018                 tcg_temp_free_i64(fp0);
11019             }
11020         }
11021         break;
11022     case OPC_CMP_F_D:
11023     case OPC_CMP_UN_D:
11024     case OPC_CMP_EQ_D:
11025     case OPC_CMP_UEQ_D:
11026     case OPC_CMP_OLT_D:
11027     case OPC_CMP_ULT_D:
11028     case OPC_CMP_OLE_D:
11029     case OPC_CMP_ULE_D:
11030     case OPC_CMP_SF_D:
11031     case OPC_CMP_NGLE_D:
11032     case OPC_CMP_SEQ_D:
11033     case OPC_CMP_NGL_D:
11034     case OPC_CMP_LT_D:
11035     case OPC_CMP_NGE_D:
11036     case OPC_CMP_LE_D:
11037     case OPC_CMP_NGT_D:
11038         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11039         if (ctx->opcode & (1 << 6)) {
11040             gen_cmpabs_d(ctx, func-48, ft, fs, cc);
11041         } else {
11042             gen_cmp_d(ctx, func-48, ft, fs, cc);
11043         }
11044         break;
11045     case OPC_CVT_S_D:
11046         check_cp1_registers(ctx, fs);
11047         {
11048             TCGv_i32 fp32 = tcg_temp_new_i32();
11049             TCGv_i64 fp64 = tcg_temp_new_i64();
11050
11051             gen_load_fpr64(ctx, fp64, fs);
11052             gen_helper_float_cvts_d(fp32, cpu_env, fp64);
11053             tcg_temp_free_i64(fp64);
11054             gen_store_fpr32(ctx, fp32, fd);
11055             tcg_temp_free_i32(fp32);
11056         }
11057         break;
11058     case OPC_CVT_W_D:
11059         check_cp1_registers(ctx, fs);
11060         {
11061             TCGv_i32 fp32 = tcg_temp_new_i32();
11062             TCGv_i64 fp64 = tcg_temp_new_i64();
11063
11064             gen_load_fpr64(ctx, fp64, fs);
11065             if (ctx->nan2008) {
11066                 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11067             } else {
11068                 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11069             }
11070             tcg_temp_free_i64(fp64);
11071             gen_store_fpr32(ctx, fp32, fd);
11072             tcg_temp_free_i32(fp32);
11073         }
11074         break;
11075     case OPC_CVT_L_D:
11076         check_cp1_64bitmode(ctx);
11077         {
11078             TCGv_i64 fp0 = tcg_temp_new_i64();
11079
11080             gen_load_fpr64(ctx, fp0, fs);
11081             if (ctx->nan2008) {
11082                 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11083             } else {
11084                 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11085             }
11086             gen_store_fpr64(ctx, fp0, fd);
11087             tcg_temp_free_i64(fp0);
11088         }
11089         break;
11090     case OPC_CVT_S_W:
11091         {
11092             TCGv_i32 fp0 = tcg_temp_new_i32();
11093
11094             gen_load_fpr32(ctx, fp0, fs);
11095             gen_helper_float_cvts_w(fp0, cpu_env, fp0);
11096             gen_store_fpr32(ctx, fp0, fd);
11097             tcg_temp_free_i32(fp0);
11098         }
11099         break;
11100     case OPC_CVT_D_W:
11101         check_cp1_registers(ctx, fd);
11102         {
11103             TCGv_i32 fp32 = tcg_temp_new_i32();
11104             TCGv_i64 fp64 = tcg_temp_new_i64();
11105
11106             gen_load_fpr32(ctx, fp32, fs);
11107             gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
11108             tcg_temp_free_i32(fp32);
11109             gen_store_fpr64(ctx, fp64, fd);
11110             tcg_temp_free_i64(fp64);
11111         }
11112         break;
11113     case OPC_CVT_S_L:
11114         check_cp1_64bitmode(ctx);
11115         {
11116             TCGv_i32 fp32 = tcg_temp_new_i32();
11117             TCGv_i64 fp64 = tcg_temp_new_i64();
11118
11119             gen_load_fpr64(ctx, fp64, fs);
11120             gen_helper_float_cvts_l(fp32, cpu_env, fp64);
11121             tcg_temp_free_i64(fp64);
11122             gen_store_fpr32(ctx, fp32, fd);
11123             tcg_temp_free_i32(fp32);
11124         }
11125         break;
11126     case OPC_CVT_D_L:
11127         check_cp1_64bitmode(ctx);
11128         {
11129             TCGv_i64 fp0 = tcg_temp_new_i64();
11130
11131             gen_load_fpr64(ctx, fp0, fs);
11132             gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
11133             gen_store_fpr64(ctx, fp0, fd);
11134             tcg_temp_free_i64(fp0);
11135         }
11136         break;
11137     case OPC_CVT_PS_PW:
11138         check_ps(ctx);
11139         {
11140             TCGv_i64 fp0 = tcg_temp_new_i64();
11141
11142             gen_load_fpr64(ctx, fp0, fs);
11143             gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
11144             gen_store_fpr64(ctx, fp0, fd);
11145             tcg_temp_free_i64(fp0);
11146         }
11147         break;
11148     case OPC_ADD_PS:
11149         check_ps(ctx);
11150         {
11151             TCGv_i64 fp0 = tcg_temp_new_i64();
11152             TCGv_i64 fp1 = tcg_temp_new_i64();
11153
11154             gen_load_fpr64(ctx, fp0, fs);
11155             gen_load_fpr64(ctx, fp1, ft);
11156             gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
11157             tcg_temp_free_i64(fp1);
11158             gen_store_fpr64(ctx, fp0, fd);
11159             tcg_temp_free_i64(fp0);
11160         }
11161         break;
11162     case OPC_SUB_PS:
11163         check_ps(ctx);
11164         {
11165             TCGv_i64 fp0 = tcg_temp_new_i64();
11166             TCGv_i64 fp1 = tcg_temp_new_i64();
11167
11168             gen_load_fpr64(ctx, fp0, fs);
11169             gen_load_fpr64(ctx, fp1, ft);
11170             gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
11171             tcg_temp_free_i64(fp1);
11172             gen_store_fpr64(ctx, fp0, fd);
11173             tcg_temp_free_i64(fp0);
11174         }
11175         break;
11176     case OPC_MUL_PS:
11177         check_ps(ctx);
11178         {
11179             TCGv_i64 fp0 = tcg_temp_new_i64();
11180             TCGv_i64 fp1 = tcg_temp_new_i64();
11181
11182             gen_load_fpr64(ctx, fp0, fs);
11183             gen_load_fpr64(ctx, fp1, ft);
11184             gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
11185             tcg_temp_free_i64(fp1);
11186             gen_store_fpr64(ctx, fp0, fd);
11187             tcg_temp_free_i64(fp0);
11188         }
11189         break;
11190     case OPC_ABS_PS:
11191         check_ps(ctx);
11192         {
11193             TCGv_i64 fp0 = tcg_temp_new_i64();
11194
11195             gen_load_fpr64(ctx, fp0, fs);
11196             gen_helper_float_abs_ps(fp0, fp0);
11197             gen_store_fpr64(ctx, fp0, fd);
11198             tcg_temp_free_i64(fp0);
11199         }
11200         break;
11201     case OPC_MOV_PS:
11202         check_ps(ctx);
11203         {
11204             TCGv_i64 fp0 = tcg_temp_new_i64();
11205
11206             gen_load_fpr64(ctx, fp0, fs);
11207             gen_store_fpr64(ctx, fp0, fd);
11208             tcg_temp_free_i64(fp0);
11209         }
11210         break;
11211     case OPC_NEG_PS:
11212         check_ps(ctx);
11213         {
11214             TCGv_i64 fp0 = tcg_temp_new_i64();
11215
11216             gen_load_fpr64(ctx, fp0, fs);
11217             gen_helper_float_chs_ps(fp0, fp0);
11218             gen_store_fpr64(ctx, fp0, fd);
11219             tcg_temp_free_i64(fp0);
11220         }
11221         break;
11222     case OPC_MOVCF_PS:
11223         check_ps(ctx);
11224         gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11225         break;
11226     case OPC_MOVZ_PS:
11227         check_ps(ctx);
11228         {
11229             TCGLabel *l1 = gen_new_label();
11230             TCGv_i64 fp0;
11231
11232             if (ft != 0)
11233                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11234             fp0 = tcg_temp_new_i64();
11235             gen_load_fpr64(ctx, fp0, fs);
11236             gen_store_fpr64(ctx, fp0, fd);
11237             tcg_temp_free_i64(fp0);
11238             gen_set_label(l1);
11239         }
11240         break;
11241     case OPC_MOVN_PS:
11242         check_ps(ctx);
11243         {
11244             TCGLabel *l1 = gen_new_label();
11245             TCGv_i64 fp0;
11246
11247             if (ft != 0) {
11248                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11249                 fp0 = tcg_temp_new_i64();
11250                 gen_load_fpr64(ctx, fp0, fs);
11251                 gen_store_fpr64(ctx, fp0, fd);
11252                 tcg_temp_free_i64(fp0);
11253                 gen_set_label(l1);
11254             }
11255         }
11256         break;
11257     case OPC_ADDR_PS:
11258         check_ps(ctx);
11259         {
11260             TCGv_i64 fp0 = tcg_temp_new_i64();
11261             TCGv_i64 fp1 = tcg_temp_new_i64();
11262
11263             gen_load_fpr64(ctx, fp0, ft);
11264             gen_load_fpr64(ctx, fp1, fs);
11265             gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
11266             tcg_temp_free_i64(fp1);
11267             gen_store_fpr64(ctx, fp0, fd);
11268             tcg_temp_free_i64(fp0);
11269         }
11270         break;
11271     case OPC_MULR_PS:
11272         check_ps(ctx);
11273         {
11274             TCGv_i64 fp0 = tcg_temp_new_i64();
11275             TCGv_i64 fp1 = tcg_temp_new_i64();
11276
11277             gen_load_fpr64(ctx, fp0, ft);
11278             gen_load_fpr64(ctx, fp1, fs);
11279             gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
11280             tcg_temp_free_i64(fp1);
11281             gen_store_fpr64(ctx, fp0, fd);
11282             tcg_temp_free_i64(fp0);
11283         }
11284         break;
11285     case OPC_RECIP2_PS:
11286         check_ps(ctx);
11287         {
11288             TCGv_i64 fp0 = tcg_temp_new_i64();
11289             TCGv_i64 fp1 = tcg_temp_new_i64();
11290
11291             gen_load_fpr64(ctx, fp0, fs);
11292             gen_load_fpr64(ctx, fp1, ft);
11293             gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
11294             tcg_temp_free_i64(fp1);
11295             gen_store_fpr64(ctx, fp0, fd);
11296             tcg_temp_free_i64(fp0);
11297         }
11298         break;
11299     case OPC_RECIP1_PS:
11300         check_ps(ctx);
11301         {
11302             TCGv_i64 fp0 = tcg_temp_new_i64();
11303
11304             gen_load_fpr64(ctx, fp0, fs);
11305             gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
11306             gen_store_fpr64(ctx, fp0, fd);
11307             tcg_temp_free_i64(fp0);
11308         }
11309         break;
11310     case OPC_RSQRT1_PS:
11311         check_ps(ctx);
11312         {
11313             TCGv_i64 fp0 = tcg_temp_new_i64();
11314
11315             gen_load_fpr64(ctx, fp0, fs);
11316             gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
11317             gen_store_fpr64(ctx, fp0, fd);
11318             tcg_temp_free_i64(fp0);
11319         }
11320         break;
11321     case OPC_RSQRT2_PS:
11322         check_ps(ctx);
11323         {
11324             TCGv_i64 fp0 = tcg_temp_new_i64();
11325             TCGv_i64 fp1 = tcg_temp_new_i64();
11326
11327             gen_load_fpr64(ctx, fp0, fs);
11328             gen_load_fpr64(ctx, fp1, ft);
11329             gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
11330             tcg_temp_free_i64(fp1);
11331             gen_store_fpr64(ctx, fp0, fd);
11332             tcg_temp_free_i64(fp0);
11333         }
11334         break;
11335     case OPC_CVT_S_PU:
11336         check_cp1_64bitmode(ctx);
11337         {
11338             TCGv_i32 fp0 = tcg_temp_new_i32();
11339
11340             gen_load_fpr32h(ctx, fp0, fs);
11341             gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
11342             gen_store_fpr32(ctx, fp0, fd);
11343             tcg_temp_free_i32(fp0);
11344         }
11345         break;
11346     case OPC_CVT_PW_PS:
11347         check_ps(ctx);
11348         {
11349             TCGv_i64 fp0 = tcg_temp_new_i64();
11350
11351             gen_load_fpr64(ctx, fp0, fs);
11352             gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
11353             gen_store_fpr64(ctx, fp0, fd);
11354             tcg_temp_free_i64(fp0);
11355         }
11356         break;
11357     case OPC_CVT_S_PL:
11358         check_cp1_64bitmode(ctx);
11359         {
11360             TCGv_i32 fp0 = tcg_temp_new_i32();
11361
11362             gen_load_fpr32(ctx, fp0, fs);
11363             gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
11364             gen_store_fpr32(ctx, fp0, fd);
11365             tcg_temp_free_i32(fp0);
11366         }
11367         break;
11368     case OPC_PLL_PS:
11369         check_ps(ctx);
11370         {
11371             TCGv_i32 fp0 = tcg_temp_new_i32();
11372             TCGv_i32 fp1 = tcg_temp_new_i32();
11373
11374             gen_load_fpr32(ctx, fp0, fs);
11375             gen_load_fpr32(ctx, fp1, ft);
11376             gen_store_fpr32h(ctx, fp0, fd);
11377             gen_store_fpr32(ctx, fp1, fd);
11378             tcg_temp_free_i32(fp0);
11379             tcg_temp_free_i32(fp1);
11380         }
11381         break;
11382     case OPC_PLU_PS:
11383         check_ps(ctx);
11384         {
11385             TCGv_i32 fp0 = tcg_temp_new_i32();
11386             TCGv_i32 fp1 = tcg_temp_new_i32();
11387
11388             gen_load_fpr32(ctx, fp0, fs);
11389             gen_load_fpr32h(ctx, fp1, ft);
11390             gen_store_fpr32(ctx, fp1, fd);
11391             gen_store_fpr32h(ctx, fp0, fd);
11392             tcg_temp_free_i32(fp0);
11393             tcg_temp_free_i32(fp1);
11394         }
11395         break;
11396     case OPC_PUL_PS:
11397         check_ps(ctx);
11398         {
11399             TCGv_i32 fp0 = tcg_temp_new_i32();
11400             TCGv_i32 fp1 = tcg_temp_new_i32();
11401
11402             gen_load_fpr32h(ctx, fp0, fs);
11403             gen_load_fpr32(ctx, fp1, ft);
11404             gen_store_fpr32(ctx, fp1, fd);
11405             gen_store_fpr32h(ctx, fp0, fd);
11406             tcg_temp_free_i32(fp0);
11407             tcg_temp_free_i32(fp1);
11408         }
11409         break;
11410     case OPC_PUU_PS:
11411         check_ps(ctx);
11412         {
11413             TCGv_i32 fp0 = tcg_temp_new_i32();
11414             TCGv_i32 fp1 = tcg_temp_new_i32();
11415
11416             gen_load_fpr32h(ctx, fp0, fs);
11417             gen_load_fpr32h(ctx, fp1, ft);
11418             gen_store_fpr32(ctx, fp1, fd);
11419             gen_store_fpr32h(ctx, fp0, fd);
11420             tcg_temp_free_i32(fp0);
11421             tcg_temp_free_i32(fp1);
11422         }
11423         break;
11424     case OPC_CMP_F_PS:
11425     case OPC_CMP_UN_PS:
11426     case OPC_CMP_EQ_PS:
11427     case OPC_CMP_UEQ_PS:
11428     case OPC_CMP_OLT_PS:
11429     case OPC_CMP_ULT_PS:
11430     case OPC_CMP_OLE_PS:
11431     case OPC_CMP_ULE_PS:
11432     case OPC_CMP_SF_PS:
11433     case OPC_CMP_NGLE_PS:
11434     case OPC_CMP_SEQ_PS:
11435     case OPC_CMP_NGL_PS:
11436     case OPC_CMP_LT_PS:
11437     case OPC_CMP_NGE_PS:
11438     case OPC_CMP_LE_PS:
11439     case OPC_CMP_NGT_PS:
11440         if (ctx->opcode & (1 << 6)) {
11441             gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
11442         } else {
11443             gen_cmp_ps(ctx, func-48, ft, fs, cc);
11444         }
11445         break;
11446     default:
11447         MIPS_INVAL("farith");
11448         generate_exception_end(ctx, EXCP_RI);
11449         return;
11450     }
11451 }
11452
11453 /* Coprocessor 3 (FPU) */
11454 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
11455                            int fd, int fs, int base, int index)
11456 {
11457     TCGv t0 = tcg_temp_new();
11458
11459     if (base == 0) {
11460         gen_load_gpr(t0, index);
11461     } else if (index == 0) {
11462         gen_load_gpr(t0, base);
11463     } else {
11464         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
11465     }
11466     /* Don't do NOP if destination is zero: we must perform the actual
11467        memory access. */
11468     switch (opc) {
11469     case OPC_LWXC1:
11470         check_cop1x(ctx);
11471         {
11472             TCGv_i32 fp0 = tcg_temp_new_i32();
11473
11474             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
11475             tcg_gen_trunc_tl_i32(fp0, t0);
11476             gen_store_fpr32(ctx, fp0, fd);
11477             tcg_temp_free_i32(fp0);
11478         }
11479         break;
11480     case OPC_LDXC1:
11481         check_cop1x(ctx);
11482         check_cp1_registers(ctx, fd);
11483         {
11484             TCGv_i64 fp0 = tcg_temp_new_i64();
11485             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11486             gen_store_fpr64(ctx, fp0, fd);
11487             tcg_temp_free_i64(fp0);
11488         }
11489         break;
11490     case OPC_LUXC1:
11491         check_cp1_64bitmode(ctx);
11492         tcg_gen_andi_tl(t0, t0, ~0x7);
11493         {
11494             TCGv_i64 fp0 = tcg_temp_new_i64();
11495
11496             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11497             gen_store_fpr64(ctx, fp0, fd);
11498             tcg_temp_free_i64(fp0);
11499         }
11500         break;
11501     case OPC_SWXC1:
11502         check_cop1x(ctx);
11503         {
11504             TCGv_i32 fp0 = tcg_temp_new_i32();
11505             gen_load_fpr32(ctx, fp0, fs);
11506             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
11507             tcg_temp_free_i32(fp0);
11508         }
11509         break;
11510     case OPC_SDXC1:
11511         check_cop1x(ctx);
11512         check_cp1_registers(ctx, fs);
11513         {
11514             TCGv_i64 fp0 = tcg_temp_new_i64();
11515             gen_load_fpr64(ctx, fp0, fs);
11516             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11517             tcg_temp_free_i64(fp0);
11518         }
11519         break;
11520     case OPC_SUXC1:
11521         check_cp1_64bitmode(ctx);
11522         tcg_gen_andi_tl(t0, t0, ~0x7);
11523         {
11524             TCGv_i64 fp0 = tcg_temp_new_i64();
11525             gen_load_fpr64(ctx, fp0, fs);
11526             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11527             tcg_temp_free_i64(fp0);
11528         }
11529         break;
11530     }
11531     tcg_temp_free(t0);
11532 }
11533
11534 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
11535                             int fd, int fr, int fs, int ft)
11536 {
11537     switch (opc) {
11538     case OPC_ALNV_PS:
11539         check_ps(ctx);
11540         {
11541             TCGv t0 = tcg_temp_local_new();
11542             TCGv_i32 fp = tcg_temp_new_i32();
11543             TCGv_i32 fph = tcg_temp_new_i32();
11544             TCGLabel *l1 = gen_new_label();
11545             TCGLabel *l2 = gen_new_label();
11546
11547             gen_load_gpr(t0, fr);
11548             tcg_gen_andi_tl(t0, t0, 0x7);
11549
11550             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
11551             gen_load_fpr32(ctx, fp, fs);
11552             gen_load_fpr32h(ctx, fph, fs);
11553             gen_store_fpr32(ctx, fp, fd);
11554             gen_store_fpr32h(ctx, fph, fd);
11555             tcg_gen_br(l2);
11556             gen_set_label(l1);
11557             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
11558             tcg_temp_free(t0);
11559 #ifdef TARGET_WORDS_BIGENDIAN
11560             gen_load_fpr32(ctx, fp, fs);
11561             gen_load_fpr32h(ctx, fph, ft);
11562             gen_store_fpr32h(ctx, fp, fd);
11563             gen_store_fpr32(ctx, fph, fd);
11564 #else
11565             gen_load_fpr32h(ctx, fph, fs);
11566             gen_load_fpr32(ctx, fp, ft);
11567             gen_store_fpr32(ctx, fph, fd);
11568             gen_store_fpr32h(ctx, fp, fd);
11569 #endif
11570             gen_set_label(l2);
11571             tcg_temp_free_i32(fp);
11572             tcg_temp_free_i32(fph);
11573         }
11574         break;
11575     case OPC_MADD_S:
11576         check_cop1x(ctx);
11577         {
11578             TCGv_i32 fp0 = tcg_temp_new_i32();
11579             TCGv_i32 fp1 = tcg_temp_new_i32();
11580             TCGv_i32 fp2 = tcg_temp_new_i32();
11581
11582             gen_load_fpr32(ctx, fp0, fs);
11583             gen_load_fpr32(ctx, fp1, ft);
11584             gen_load_fpr32(ctx, fp2, fr);
11585             gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
11586             tcg_temp_free_i32(fp0);
11587             tcg_temp_free_i32(fp1);
11588             gen_store_fpr32(ctx, fp2, fd);
11589             tcg_temp_free_i32(fp2);
11590         }
11591         break;
11592     case OPC_MADD_D:
11593         check_cop1x(ctx);
11594         check_cp1_registers(ctx, fd | fs | ft | fr);
11595         {
11596             TCGv_i64 fp0 = tcg_temp_new_i64();
11597             TCGv_i64 fp1 = tcg_temp_new_i64();
11598             TCGv_i64 fp2 = tcg_temp_new_i64();
11599
11600             gen_load_fpr64(ctx, fp0, fs);
11601             gen_load_fpr64(ctx, fp1, ft);
11602             gen_load_fpr64(ctx, fp2, fr);
11603             gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
11604             tcg_temp_free_i64(fp0);
11605             tcg_temp_free_i64(fp1);
11606             gen_store_fpr64(ctx, fp2, fd);
11607             tcg_temp_free_i64(fp2);
11608         }
11609         break;
11610     case OPC_MADD_PS:
11611         check_ps(ctx);
11612         {
11613             TCGv_i64 fp0 = tcg_temp_new_i64();
11614             TCGv_i64 fp1 = tcg_temp_new_i64();
11615             TCGv_i64 fp2 = tcg_temp_new_i64();
11616
11617             gen_load_fpr64(ctx, fp0, fs);
11618             gen_load_fpr64(ctx, fp1, ft);
11619             gen_load_fpr64(ctx, fp2, fr);
11620             gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
11621             tcg_temp_free_i64(fp0);
11622             tcg_temp_free_i64(fp1);
11623             gen_store_fpr64(ctx, fp2, fd);
11624             tcg_temp_free_i64(fp2);
11625         }
11626         break;
11627     case OPC_MSUB_S:
11628         check_cop1x(ctx);
11629         {
11630             TCGv_i32 fp0 = tcg_temp_new_i32();
11631             TCGv_i32 fp1 = tcg_temp_new_i32();
11632             TCGv_i32 fp2 = tcg_temp_new_i32();
11633
11634             gen_load_fpr32(ctx, fp0, fs);
11635             gen_load_fpr32(ctx, fp1, ft);
11636             gen_load_fpr32(ctx, fp2, fr);
11637             gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
11638             tcg_temp_free_i32(fp0);
11639             tcg_temp_free_i32(fp1);
11640             gen_store_fpr32(ctx, fp2, fd);
11641             tcg_temp_free_i32(fp2);
11642         }
11643         break;
11644     case OPC_MSUB_D:
11645         check_cop1x(ctx);
11646         check_cp1_registers(ctx, fd | fs | ft | fr);
11647         {
11648             TCGv_i64 fp0 = tcg_temp_new_i64();
11649             TCGv_i64 fp1 = tcg_temp_new_i64();
11650             TCGv_i64 fp2 = tcg_temp_new_i64();
11651
11652             gen_load_fpr64(ctx, fp0, fs);
11653             gen_load_fpr64(ctx, fp1, ft);
11654             gen_load_fpr64(ctx, fp2, fr);
11655             gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
11656             tcg_temp_free_i64(fp0);
11657             tcg_temp_free_i64(fp1);
11658             gen_store_fpr64(ctx, fp2, fd);
11659             tcg_temp_free_i64(fp2);
11660         }
11661         break;
11662     case OPC_MSUB_PS:
11663         check_ps(ctx);
11664         {
11665             TCGv_i64 fp0 = tcg_temp_new_i64();
11666             TCGv_i64 fp1 = tcg_temp_new_i64();
11667             TCGv_i64 fp2 = tcg_temp_new_i64();
11668
11669             gen_load_fpr64(ctx, fp0, fs);
11670             gen_load_fpr64(ctx, fp1, ft);
11671             gen_load_fpr64(ctx, fp2, fr);
11672             gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
11673             tcg_temp_free_i64(fp0);
11674             tcg_temp_free_i64(fp1);
11675             gen_store_fpr64(ctx, fp2, fd);
11676             tcg_temp_free_i64(fp2);
11677         }
11678         break;
11679     case OPC_NMADD_S:
11680         check_cop1x(ctx);
11681         {
11682             TCGv_i32 fp0 = tcg_temp_new_i32();
11683             TCGv_i32 fp1 = tcg_temp_new_i32();
11684             TCGv_i32 fp2 = tcg_temp_new_i32();
11685
11686             gen_load_fpr32(ctx, fp0, fs);
11687             gen_load_fpr32(ctx, fp1, ft);
11688             gen_load_fpr32(ctx, fp2, fr);
11689             gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
11690             tcg_temp_free_i32(fp0);
11691             tcg_temp_free_i32(fp1);
11692             gen_store_fpr32(ctx, fp2, fd);
11693             tcg_temp_free_i32(fp2);
11694         }
11695         break;
11696     case OPC_NMADD_D:
11697         check_cop1x(ctx);
11698         check_cp1_registers(ctx, fd | fs | ft | fr);
11699         {
11700             TCGv_i64 fp0 = tcg_temp_new_i64();
11701             TCGv_i64 fp1 = tcg_temp_new_i64();
11702             TCGv_i64 fp2 = tcg_temp_new_i64();
11703
11704             gen_load_fpr64(ctx, fp0, fs);
11705             gen_load_fpr64(ctx, fp1, ft);
11706             gen_load_fpr64(ctx, fp2, fr);
11707             gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
11708             tcg_temp_free_i64(fp0);
11709             tcg_temp_free_i64(fp1);
11710             gen_store_fpr64(ctx, fp2, fd);
11711             tcg_temp_free_i64(fp2);
11712         }
11713         break;
11714     case OPC_NMADD_PS:
11715         check_ps(ctx);
11716         {
11717             TCGv_i64 fp0 = tcg_temp_new_i64();
11718             TCGv_i64 fp1 = tcg_temp_new_i64();
11719             TCGv_i64 fp2 = tcg_temp_new_i64();
11720
11721             gen_load_fpr64(ctx, fp0, fs);
11722             gen_load_fpr64(ctx, fp1, ft);
11723             gen_load_fpr64(ctx, fp2, fr);
11724             gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
11725             tcg_temp_free_i64(fp0);
11726             tcg_temp_free_i64(fp1);
11727             gen_store_fpr64(ctx, fp2, fd);
11728             tcg_temp_free_i64(fp2);
11729         }
11730         break;
11731     case OPC_NMSUB_S:
11732         check_cop1x(ctx);
11733         {
11734             TCGv_i32 fp0 = tcg_temp_new_i32();
11735             TCGv_i32 fp1 = tcg_temp_new_i32();
11736             TCGv_i32 fp2 = tcg_temp_new_i32();
11737
11738             gen_load_fpr32(ctx, fp0, fs);
11739             gen_load_fpr32(ctx, fp1, ft);
11740             gen_load_fpr32(ctx, fp2, fr);
11741             gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
11742             tcg_temp_free_i32(fp0);
11743             tcg_temp_free_i32(fp1);
11744             gen_store_fpr32(ctx, fp2, fd);
11745             tcg_temp_free_i32(fp2);
11746         }
11747         break;
11748     case OPC_NMSUB_D:
11749         check_cop1x(ctx);
11750         check_cp1_registers(ctx, fd | fs | ft | fr);
11751         {
11752             TCGv_i64 fp0 = tcg_temp_new_i64();
11753             TCGv_i64 fp1 = tcg_temp_new_i64();
11754             TCGv_i64 fp2 = tcg_temp_new_i64();
11755
11756             gen_load_fpr64(ctx, fp0, fs);
11757             gen_load_fpr64(ctx, fp1, ft);
11758             gen_load_fpr64(ctx, fp2, fr);
11759             gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
11760             tcg_temp_free_i64(fp0);
11761             tcg_temp_free_i64(fp1);
11762             gen_store_fpr64(ctx, fp2, fd);
11763             tcg_temp_free_i64(fp2);
11764         }
11765         break;
11766     case OPC_NMSUB_PS:
11767         check_ps(ctx);
11768         {
11769             TCGv_i64 fp0 = tcg_temp_new_i64();
11770             TCGv_i64 fp1 = tcg_temp_new_i64();
11771             TCGv_i64 fp2 = tcg_temp_new_i64();
11772
11773             gen_load_fpr64(ctx, fp0, fs);
11774             gen_load_fpr64(ctx, fp1, ft);
11775             gen_load_fpr64(ctx, fp2, fr);
11776             gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
11777             tcg_temp_free_i64(fp0);
11778             tcg_temp_free_i64(fp1);
11779             gen_store_fpr64(ctx, fp2, fd);
11780             tcg_temp_free_i64(fp2);
11781         }
11782         break;
11783     default:
11784         MIPS_INVAL("flt3_arith");
11785         generate_exception_end(ctx, EXCP_RI);
11786         return;
11787     }
11788 }
11789
11790 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
11791 {
11792     TCGv t0;
11793
11794 #if !defined(CONFIG_USER_ONLY)
11795     /* The Linux kernel will emulate rdhwr if it's not supported natively.
11796        Therefore only check the ISA in system mode.  */
11797     check_insn(ctx, ISA_MIPS32R2);
11798 #endif
11799     t0 = tcg_temp_new();
11800
11801     switch (rd) {
11802     case 0:
11803         gen_helper_rdhwr_cpunum(t0, cpu_env);
11804         gen_store_gpr(t0, rt);
11805         break;
11806     case 1:
11807         gen_helper_rdhwr_synci_step(t0, cpu_env);
11808         gen_store_gpr(t0, rt);
11809         break;
11810     case 2:
11811         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
11812             gen_io_start();
11813         }
11814         gen_helper_rdhwr_cc(t0, cpu_env);
11815         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
11816             gen_io_end();
11817         }
11818         gen_store_gpr(t0, rt);
11819         /* Break the TB to be able to take timer interrupts immediately
11820            after reading count. DISAS_STOP isn't sufficient, we need to ensure
11821            we break completely out of translated code.  */
11822         gen_save_pc(ctx->base.pc_next + 4);
11823         ctx->base.is_jmp = DISAS_EXIT;
11824         break;
11825     case 3:
11826         gen_helper_rdhwr_ccres(t0, cpu_env);
11827         gen_store_gpr(t0, rt);
11828         break;
11829     case 4:
11830         check_insn(ctx, ISA_MIPS32R6);
11831         if (sel != 0) {
11832             /* Performance counter registers are not implemented other than
11833              * control register 0.
11834              */
11835             generate_exception(ctx, EXCP_RI);
11836         }
11837         gen_helper_rdhwr_performance(t0, cpu_env);
11838         gen_store_gpr(t0, rt);
11839         break;
11840     case 5:
11841         check_insn(ctx, ISA_MIPS32R6);
11842         gen_helper_rdhwr_xnp(t0, cpu_env);
11843         gen_store_gpr(t0, rt);
11844         break;
11845     case 29:
11846 #if defined(CONFIG_USER_ONLY)
11847         tcg_gen_ld_tl(t0, cpu_env,
11848                       offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11849         gen_store_gpr(t0, rt);
11850         break;
11851 #else
11852         if ((ctx->hflags & MIPS_HFLAG_CP0) ||
11853             (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
11854             tcg_gen_ld_tl(t0, cpu_env,
11855                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11856             gen_store_gpr(t0, rt);
11857         } else {
11858             generate_exception_end(ctx, EXCP_RI);
11859         }
11860         break;
11861 #endif
11862     default:            /* Invalid */
11863         MIPS_INVAL("rdhwr");
11864         generate_exception_end(ctx, EXCP_RI);
11865         break;
11866     }
11867     tcg_temp_free(t0);
11868 }
11869
11870 static inline void clear_branch_hflags(DisasContext *ctx)
11871 {
11872     ctx->hflags &= ~MIPS_HFLAG_BMASK;
11873     if (ctx->base.is_jmp == DISAS_NEXT) {
11874         save_cpu_state(ctx, 0);
11875     } else {
11876         /* it is not safe to save ctx->hflags as hflags may be changed
11877            in execution time by the instruction in delay / forbidden slot. */
11878         tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
11879     }
11880 }
11881
11882 static void gen_branch(DisasContext *ctx, int insn_bytes)
11883 {
11884     if (ctx->hflags & MIPS_HFLAG_BMASK) {
11885         int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
11886         /* Branches completion */
11887         clear_branch_hflags(ctx);
11888         ctx->base.is_jmp = DISAS_NORETURN;
11889         /* FIXME: Need to clear can_do_io.  */
11890         switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
11891         case MIPS_HFLAG_FBNSLOT:
11892             gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
11893             break;
11894         case MIPS_HFLAG_B:
11895             /* unconditional branch */
11896             if (proc_hflags & MIPS_HFLAG_BX) {
11897                 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
11898             }
11899             gen_goto_tb(ctx, 0, ctx->btarget);
11900             break;
11901         case MIPS_HFLAG_BL:
11902             /* blikely taken case */
11903             gen_goto_tb(ctx, 0, ctx->btarget);
11904             break;
11905         case MIPS_HFLAG_BC:
11906             /* Conditional branch */
11907             {
11908                 TCGLabel *l1 = gen_new_label();
11909
11910                 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11911                 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
11912                 gen_set_label(l1);
11913                 gen_goto_tb(ctx, 0, ctx->btarget);
11914             }
11915             break;
11916         case MIPS_HFLAG_BR:
11917             /* unconditional branch to register */
11918             if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
11919                 TCGv t0 = tcg_temp_new();
11920                 TCGv_i32 t1 = tcg_temp_new_i32();
11921
11922                 tcg_gen_andi_tl(t0, btarget, 0x1);
11923                 tcg_gen_trunc_tl_i32(t1, t0);
11924                 tcg_temp_free(t0);
11925                 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
11926                 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
11927                 tcg_gen_or_i32(hflags, hflags, t1);
11928                 tcg_temp_free_i32(t1);
11929
11930                 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
11931             } else {
11932                 tcg_gen_mov_tl(cpu_PC, btarget);
11933             }
11934             if (ctx->base.singlestep_enabled) {
11935                 save_cpu_state(ctx, 0);
11936                 gen_helper_raise_exception_debug(cpu_env);
11937             }
11938             tcg_gen_lookup_and_goto_ptr();
11939             break;
11940         default:
11941             fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
11942             abort();
11943         }
11944     }
11945 }
11946
11947 /* Compact Branches */
11948 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
11949                                        int rs, int rt, int32_t offset)
11950 {
11951     int bcond_compute = 0;
11952     TCGv t0 = tcg_temp_new();
11953     TCGv t1 = tcg_temp_new();
11954     int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
11955
11956     if (ctx->hflags & MIPS_HFLAG_BMASK) {
11957 #ifdef MIPS_DEBUG_DISAS
11958         LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11959                   "\n", ctx->base.pc_next);
11960 #endif
11961         generate_exception_end(ctx, EXCP_RI);
11962         goto out;
11963     }
11964
11965     /* Load needed operands and calculate btarget */
11966     switch (opc) {
11967     /* compact branch */
11968     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11969     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11970         gen_load_gpr(t0, rs);
11971         gen_load_gpr(t1, rt);
11972         bcond_compute = 1;
11973         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11974         if (rs <= rt && rs == 0) {
11975             /* OPC_BEQZALC, OPC_BNEZALC */
11976             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11977         }
11978         break;
11979     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11980     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11981         gen_load_gpr(t0, rs);
11982         gen_load_gpr(t1, rt);
11983         bcond_compute = 1;
11984         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11985         break;
11986     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11987     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11988         if (rs == 0 || rs == rt) {
11989             /* OPC_BLEZALC, OPC_BGEZALC */
11990             /* OPC_BGTZALC, OPC_BLTZALC */
11991             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11992         }
11993         gen_load_gpr(t0, rs);
11994         gen_load_gpr(t1, rt);
11995         bcond_compute = 1;
11996         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11997         break;
11998     case OPC_BC:
11999     case OPC_BALC:
12000         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12001         break;
12002     case OPC_BEQZC:
12003     case OPC_BNEZC:
12004         if (rs != 0) {
12005             /* OPC_BEQZC, OPC_BNEZC */
12006             gen_load_gpr(t0, rs);
12007             bcond_compute = 1;
12008             ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12009         } else {
12010             /* OPC_JIC, OPC_JIALC */
12011             TCGv tbase = tcg_temp_new();
12012             TCGv toffset = tcg_temp_new();
12013
12014             gen_load_gpr(tbase, rt);
12015             tcg_gen_movi_tl(toffset, offset);
12016             gen_op_addr_add(ctx, btarget, tbase, toffset);
12017             tcg_temp_free(tbase);
12018             tcg_temp_free(toffset);
12019         }
12020         break;
12021     default:
12022         MIPS_INVAL("Compact branch/jump");
12023         generate_exception_end(ctx, EXCP_RI);
12024         goto out;
12025     }
12026
12027     if (bcond_compute == 0) {
12028         /* Uncoditional compact branch */
12029         switch (opc) {
12030         case OPC_JIALC:
12031             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12032             /* Fallthrough */
12033         case OPC_JIC:
12034             ctx->hflags |= MIPS_HFLAG_BR;
12035             break;
12036         case OPC_BALC:
12037             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12038             /* Fallthrough */
12039         case OPC_BC:
12040             ctx->hflags |= MIPS_HFLAG_B;
12041             break;
12042         default:
12043             MIPS_INVAL("Compact branch/jump");
12044             generate_exception_end(ctx, EXCP_RI);
12045             goto out;
12046         }
12047
12048         /* Generating branch here as compact branches don't have delay slot */
12049         gen_branch(ctx, 4);
12050     } else {
12051         /* Conditional compact branch */
12052         TCGLabel *fs = gen_new_label();
12053         save_cpu_state(ctx, 0);
12054
12055         switch (opc) {
12056         case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12057             if (rs == 0 && rt != 0) {
12058                 /* OPC_BLEZALC */
12059                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12060             } else if (rs != 0 && rt != 0 && rs == rt) {
12061                 /* OPC_BGEZALC */
12062                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12063             } else {
12064                 /* OPC_BGEUC */
12065                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12066             }
12067             break;
12068         case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12069             if (rs == 0 && rt != 0) {
12070                 /* OPC_BGTZALC */
12071                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12072             } else if (rs != 0 && rt != 0 && rs == rt) {
12073                 /* OPC_BLTZALC */
12074                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12075             } else {
12076                 /* OPC_BLTUC */
12077                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12078             }
12079             break;
12080         case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12081             if (rs == 0 && rt != 0) {
12082                 /* OPC_BLEZC */
12083                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12084             } else if (rs != 0 && rt != 0 && rs == rt) {
12085                 /* OPC_BGEZC */
12086                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12087             } else {
12088                 /* OPC_BGEC */
12089                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12090             }
12091             break;
12092         case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12093             if (rs == 0 && rt != 0) {
12094                 /* OPC_BGTZC */
12095                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12096             } else if (rs != 0 && rt != 0 && rs == rt) {
12097                 /* OPC_BLTZC */
12098                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12099             } else {
12100                 /* OPC_BLTC */
12101                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12102             }
12103             break;
12104         case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12105         case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12106             if (rs >= rt) {
12107                 /* OPC_BOVC, OPC_BNVC */
12108                 TCGv t2 = tcg_temp_new();
12109                 TCGv t3 = tcg_temp_new();
12110                 TCGv t4 = tcg_temp_new();
12111                 TCGv input_overflow = tcg_temp_new();
12112
12113                 gen_load_gpr(t0, rs);
12114                 gen_load_gpr(t1, rt);
12115                 tcg_gen_ext32s_tl(t2, t0);
12116                 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12117                 tcg_gen_ext32s_tl(t3, t1);
12118                 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12119                 tcg_gen_or_tl(input_overflow, input_overflow, t4);
12120
12121                 tcg_gen_add_tl(t4, t2, t3);
12122                 tcg_gen_ext32s_tl(t4, t4);
12123                 tcg_gen_xor_tl(t2, t2, t3);
12124                 tcg_gen_xor_tl(t3, t4, t3);
12125                 tcg_gen_andc_tl(t2, t3, t2);
12126                 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12127                 tcg_gen_or_tl(t4, t4, input_overflow);
12128                 if (opc == OPC_BOVC) {
12129                     /* OPC_BOVC */
12130                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12131                 } else {
12132                     /* OPC_BNVC */
12133                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12134                 }
12135                 tcg_temp_free(input_overflow);
12136                 tcg_temp_free(t4);
12137                 tcg_temp_free(t3);
12138                 tcg_temp_free(t2);
12139             } else if (rs < rt && rs == 0) {
12140                 /* OPC_BEQZALC, OPC_BNEZALC */
12141                 if (opc == OPC_BEQZALC) {
12142                     /* OPC_BEQZALC */
12143                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12144                 } else {
12145                     /* OPC_BNEZALC */
12146                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12147                 }
12148             } else {
12149                 /* OPC_BEQC, OPC_BNEC */
12150                 if (opc == OPC_BEQC) {
12151                     /* OPC_BEQC */
12152                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12153                 } else {
12154                     /* OPC_BNEC */
12155                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12156                 }
12157             }
12158             break;
12159         case OPC_BEQZC:
12160             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12161             break;
12162         case OPC_BNEZC:
12163             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12164             break;
12165         default:
12166             MIPS_INVAL("Compact conditional branch/jump");
12167             generate_exception_end(ctx, EXCP_RI);
12168             goto out;
12169         }
12170
12171         /* Generating branch here as compact branches don't have delay slot */
12172         gen_goto_tb(ctx, 1, ctx->btarget);
12173         gen_set_label(fs);
12174
12175         ctx->hflags |= MIPS_HFLAG_FBNSLOT;
12176     }
12177
12178 out:
12179     tcg_temp_free(t0);
12180     tcg_temp_free(t1);
12181 }
12182
12183 /* ISA extensions (ASEs) */
12184 /* MIPS16 extension to MIPS32 */
12185
12186 /* MIPS16 major opcodes */
12187 enum {
12188   M16_OPC_ADDIUSP = 0x00,
12189   M16_OPC_ADDIUPC = 0x01,
12190   M16_OPC_B = 0x02,
12191   M16_OPC_JAL = 0x03,
12192   M16_OPC_BEQZ = 0x04,
12193   M16_OPC_BNEQZ = 0x05,
12194   M16_OPC_SHIFT = 0x06,
12195   M16_OPC_LD = 0x07,
12196   M16_OPC_RRIA = 0x08,
12197   M16_OPC_ADDIU8 = 0x09,
12198   M16_OPC_SLTI = 0x0a,
12199   M16_OPC_SLTIU = 0x0b,
12200   M16_OPC_I8 = 0x0c,
12201   M16_OPC_LI = 0x0d,
12202   M16_OPC_CMPI = 0x0e,
12203   M16_OPC_SD = 0x0f,
12204   M16_OPC_LB = 0x10,
12205   M16_OPC_LH = 0x11,
12206   M16_OPC_LWSP = 0x12,
12207   M16_OPC_LW = 0x13,
12208   M16_OPC_LBU = 0x14,
12209   M16_OPC_LHU = 0x15,
12210   M16_OPC_LWPC = 0x16,
12211   M16_OPC_LWU = 0x17,
12212   M16_OPC_SB = 0x18,
12213   M16_OPC_SH = 0x19,
12214   M16_OPC_SWSP = 0x1a,
12215   M16_OPC_SW = 0x1b,
12216   M16_OPC_RRR = 0x1c,
12217   M16_OPC_RR = 0x1d,
12218   M16_OPC_EXTEND = 0x1e,
12219   M16_OPC_I64 = 0x1f
12220 };
12221
12222 /* I8 funct field */
12223 enum {
12224   I8_BTEQZ = 0x0,
12225   I8_BTNEZ = 0x1,
12226   I8_SWRASP = 0x2,
12227   I8_ADJSP = 0x3,
12228   I8_SVRS = 0x4,
12229   I8_MOV32R = 0x5,
12230   I8_MOVR32 = 0x7
12231 };
12232
12233 /* RRR f field */
12234 enum {
12235   RRR_DADDU = 0x0,
12236   RRR_ADDU = 0x1,
12237   RRR_DSUBU = 0x2,
12238   RRR_SUBU = 0x3
12239 };
12240
12241 /* RR funct field */
12242 enum {
12243   RR_JR = 0x00,
12244   RR_SDBBP = 0x01,
12245   RR_SLT = 0x02,
12246   RR_SLTU = 0x03,
12247   RR_SLLV = 0x04,
12248   RR_BREAK = 0x05,
12249   RR_SRLV = 0x06,
12250   RR_SRAV = 0x07,
12251   RR_DSRL = 0x08,
12252   RR_CMP = 0x0a,
12253   RR_NEG = 0x0b,
12254   RR_AND = 0x0c,
12255   RR_OR = 0x0d,
12256   RR_XOR = 0x0e,
12257   RR_NOT = 0x0f,
12258   RR_MFHI = 0x10,
12259   RR_CNVT = 0x11,
12260   RR_MFLO = 0x12,
12261   RR_DSRA = 0x13,
12262   RR_DSLLV = 0x14,
12263   RR_DSRLV = 0x16,
12264   RR_DSRAV = 0x17,
12265   RR_MULT = 0x18,
12266   RR_MULTU = 0x19,
12267   RR_DIV = 0x1a,
12268   RR_DIVU = 0x1b,
12269   RR_DMULT = 0x1c,
12270   RR_DMULTU = 0x1d,
12271   RR_DDIV = 0x1e,
12272   RR_DDIVU = 0x1f
12273 };
12274
12275 /* I64 funct field */
12276 enum {
12277   I64_LDSP = 0x0,
12278   I64_SDSP = 0x1,
12279   I64_SDRASP = 0x2,
12280   I64_DADJSP = 0x3,
12281   I64_LDPC = 0x4,
12282   I64_DADDIU5 = 0x5,
12283   I64_DADDIUPC = 0x6,
12284   I64_DADDIUSP = 0x7
12285 };
12286
12287 /* RR ry field for CNVT */
12288 enum {
12289   RR_RY_CNVT_ZEB = 0x0,
12290   RR_RY_CNVT_ZEH = 0x1,
12291   RR_RY_CNVT_ZEW = 0x2,
12292   RR_RY_CNVT_SEB = 0x4,
12293   RR_RY_CNVT_SEH = 0x5,
12294   RR_RY_CNVT_SEW = 0x6,
12295 };
12296
12297 static int xlat (int r)
12298 {
12299   static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12300
12301   return map[r];
12302 }
12303
12304 static void gen_mips16_save (DisasContext *ctx,
12305                              int xsregs, int aregs,
12306                              int do_ra, int do_s0, int do_s1,
12307                              int framesize)
12308 {
12309     TCGv t0 = tcg_temp_new();
12310     TCGv t1 = tcg_temp_new();
12311     TCGv t2 = tcg_temp_new();
12312     int args, astatic;
12313
12314     switch (aregs) {
12315     case 0:
12316     case 1:
12317     case 2:
12318     case 3:
12319     case 11:
12320         args = 0;
12321         break;
12322     case 4:
12323     case 5:
12324     case 6:
12325     case 7:
12326         args = 1;
12327         break;
12328     case 8:
12329     case 9:
12330     case 10:
12331         args = 2;
12332         break;
12333     case 12:
12334     case 13:
12335         args = 3;
12336         break;
12337     case 14:
12338         args = 4;
12339         break;
12340     default:
12341         generate_exception_end(ctx, EXCP_RI);
12342         return;
12343     }
12344
12345     switch (args) {
12346     case 4:
12347         gen_base_offset_addr(ctx, t0, 29, 12);
12348         gen_load_gpr(t1, 7);
12349         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12350         /* Fall through */
12351     case 3:
12352         gen_base_offset_addr(ctx, t0, 29, 8);
12353         gen_load_gpr(t1, 6);
12354         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12355         /* Fall through */
12356     case 2:
12357         gen_base_offset_addr(ctx, t0, 29, 4);
12358         gen_load_gpr(t1, 5);
12359         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12360         /* Fall through */
12361     case 1:
12362         gen_base_offset_addr(ctx, t0, 29, 0);
12363         gen_load_gpr(t1, 4);
12364         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12365     }
12366
12367     gen_load_gpr(t0, 29);
12368
12369 #define DECR_AND_STORE(reg) do {                                 \
12370         tcg_gen_movi_tl(t2, -4);                                 \
12371         gen_op_addr_add(ctx, t0, t0, t2);                        \
12372         gen_load_gpr(t1, reg);                                   \
12373         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
12374     } while (0)
12375
12376     if (do_ra) {
12377         DECR_AND_STORE(31);
12378     }
12379
12380     switch (xsregs) {
12381     case 7:
12382         DECR_AND_STORE(30);
12383         /* Fall through */
12384     case 6:
12385         DECR_AND_STORE(23);
12386         /* Fall through */
12387     case 5:
12388         DECR_AND_STORE(22);
12389         /* Fall through */
12390     case 4:
12391         DECR_AND_STORE(21);
12392         /* Fall through */
12393     case 3:
12394         DECR_AND_STORE(20);
12395         /* Fall through */
12396     case 2:
12397         DECR_AND_STORE(19);
12398         /* Fall through */
12399     case 1:
12400         DECR_AND_STORE(18);
12401     }
12402
12403     if (do_s1) {
12404         DECR_AND_STORE(17);
12405     }
12406     if (do_s0) {
12407         DECR_AND_STORE(16);
12408     }
12409
12410     switch (aregs) {
12411     case 0:
12412     case 4:
12413     case 8:
12414     case 12:
12415     case 14:
12416         astatic = 0;
12417         break;
12418     case 1:
12419     case 5:
12420     case 9:
12421     case 13:
12422         astatic = 1;
12423         break;
12424     case 2:
12425     case 6:
12426     case 10:
12427         astatic = 2;
12428         break;
12429     case 3:
12430     case 7:
12431         astatic = 3;
12432         break;
12433     case 11:
12434         astatic = 4;
12435         break;
12436     default:
12437         generate_exception_end(ctx, EXCP_RI);
12438         return;
12439     }
12440
12441     if (astatic > 0) {
12442         DECR_AND_STORE(7);
12443         if (astatic > 1) {
12444             DECR_AND_STORE(6);
12445             if (astatic > 2) {
12446                 DECR_AND_STORE(5);
12447                 if (astatic > 3) {
12448                     DECR_AND_STORE(4);
12449                 }
12450             }
12451         }
12452     }
12453 #undef DECR_AND_STORE
12454
12455     tcg_gen_movi_tl(t2, -framesize);
12456     gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
12457     tcg_temp_free(t0);
12458     tcg_temp_free(t1);
12459     tcg_temp_free(t2);
12460 }
12461
12462 static void gen_mips16_restore (DisasContext *ctx,
12463                                 int xsregs, int aregs,
12464                                 int do_ra, int do_s0, int do_s1,
12465                                 int framesize)
12466 {
12467     int astatic;
12468     TCGv t0 = tcg_temp_new();
12469     TCGv t1 = tcg_temp_new();
12470     TCGv t2 = tcg_temp_new();
12471
12472     tcg_gen_movi_tl(t2, framesize);
12473     gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
12474
12475 #define DECR_AND_LOAD(reg) do {                            \
12476         tcg_gen_movi_tl(t2, -4);                           \
12477         gen_op_addr_add(ctx, t0, t0, t2);                  \
12478         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
12479         gen_store_gpr(t1, reg);                            \
12480     } while (0)
12481
12482     if (do_ra) {
12483         DECR_AND_LOAD(31);
12484     }
12485
12486     switch (xsregs) {
12487     case 7:
12488         DECR_AND_LOAD(30);
12489         /* Fall through */
12490     case 6:
12491         DECR_AND_LOAD(23);
12492         /* Fall through */
12493     case 5:
12494         DECR_AND_LOAD(22);
12495         /* Fall through */
12496     case 4:
12497         DECR_AND_LOAD(21);
12498         /* Fall through */
12499     case 3:
12500         DECR_AND_LOAD(20);
12501         /* Fall through */
12502     case 2:
12503         DECR_AND_LOAD(19);
12504         /* Fall through */
12505     case 1:
12506         DECR_AND_LOAD(18);
12507     }
12508
12509     if (do_s1) {
12510         DECR_AND_LOAD(17);
12511     }
12512     if (do_s0) {
12513         DECR_AND_LOAD(16);
12514     }
12515
12516     switch (aregs) {
12517     case 0:
12518     case 4:
12519     case 8:
12520     case 12:
12521     case 14:
12522         astatic = 0;
12523         break;
12524     case 1:
12525     case 5:
12526     case 9:
12527     case 13:
12528         astatic = 1;
12529         break;
12530     case 2:
12531     case 6:
12532     case 10:
12533         astatic = 2;
12534         break;
12535     case 3:
12536     case 7:
12537         astatic = 3;
12538         break;
12539     case 11:
12540         astatic = 4;
12541         break;
12542     default:
12543         generate_exception_end(ctx, EXCP_RI);
12544         return;
12545     }
12546
12547     if (astatic > 0) {
12548         DECR_AND_LOAD(7);
12549         if (astatic > 1) {
12550             DECR_AND_LOAD(6);
12551             if (astatic > 2) {
12552                 DECR_AND_LOAD(5);
12553                 if (astatic > 3) {
12554                     DECR_AND_LOAD(4);
12555                 }
12556             }
12557         }
12558     }
12559 #undef DECR_AND_LOAD
12560
12561     tcg_gen_movi_tl(t2, framesize);
12562     gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
12563     tcg_temp_free(t0);
12564     tcg_temp_free(t1);
12565     tcg_temp_free(t2);
12566 }
12567
12568 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
12569                          int is_64_bit, int extended)
12570 {
12571     TCGv t0;
12572
12573     if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
12574         generate_exception_end(ctx, EXCP_RI);
12575         return;
12576     }
12577
12578     t0 = tcg_temp_new();
12579
12580     tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
12581     tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
12582     if (!is_64_bit) {
12583         tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12584     }
12585
12586     tcg_temp_free(t0);
12587 }
12588
12589 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
12590                                 int16_t offset)
12591 {
12592     TCGv_i32 t0 = tcg_const_i32(op);
12593     TCGv t1 = tcg_temp_new();
12594     gen_base_offset_addr(ctx, t1, base, offset);
12595     gen_helper_cache(cpu_env, t1, t0);
12596 }
12597
12598 #if defined(TARGET_MIPS64)
12599 static void decode_i64_mips16 (DisasContext *ctx,
12600                                int ry, int funct, int16_t offset,
12601                                int extended)
12602 {
12603     switch (funct) {
12604     case I64_LDSP:
12605         check_insn(ctx, ISA_MIPS3);
12606         check_mips_64(ctx);
12607         offset = extended ? offset : offset << 3;
12608         gen_ld(ctx, OPC_LD, ry, 29, offset);
12609         break;
12610     case I64_SDSP:
12611         check_insn(ctx, ISA_MIPS3);
12612         check_mips_64(ctx);
12613         offset = extended ? offset : offset << 3;
12614         gen_st(ctx, OPC_SD, ry, 29, offset);
12615         break;
12616     case I64_SDRASP:
12617         check_insn(ctx, ISA_MIPS3);
12618         check_mips_64(ctx);
12619         offset = extended ? offset : (ctx->opcode & 0xff) << 3;
12620         gen_st(ctx, OPC_SD, 31, 29, offset);
12621         break;
12622     case I64_DADJSP:
12623         check_insn(ctx, ISA_MIPS3);
12624         check_mips_64(ctx);
12625         offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
12626         gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
12627         break;
12628     case I64_LDPC:
12629         check_insn(ctx, ISA_MIPS3);
12630         check_mips_64(ctx);
12631         if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
12632             generate_exception_end(ctx, EXCP_RI);
12633         } else {
12634             offset = extended ? offset : offset << 3;
12635             gen_ld(ctx, OPC_LDPC, ry, 0, offset);
12636         }
12637         break;
12638     case I64_DADDIU5:
12639         check_insn(ctx, ISA_MIPS3);
12640         check_mips_64(ctx);
12641         offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
12642         gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
12643         break;
12644     case I64_DADDIUPC:
12645         check_insn(ctx, ISA_MIPS3);
12646         check_mips_64(ctx);
12647         offset = extended ? offset : offset << 2;
12648         gen_addiupc(ctx, ry, offset, 1, extended);
12649         break;
12650     case I64_DADDIUSP:
12651         check_insn(ctx, ISA_MIPS3);
12652         check_mips_64(ctx);
12653         offset = extended ? offset : offset << 2;
12654         gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
12655         break;
12656     }
12657 }
12658 #endif
12659
12660 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
12661 {
12662     int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
12663     int op, rx, ry, funct, sa;
12664     int16_t imm, offset;
12665
12666     ctx->opcode = (ctx->opcode << 16) | extend;
12667     op = (ctx->opcode >> 11) & 0x1f;
12668     sa = (ctx->opcode >> 22) & 0x1f;
12669     funct = (ctx->opcode >> 8) & 0x7;
12670     rx = xlat((ctx->opcode >> 8) & 0x7);
12671     ry = xlat((ctx->opcode >> 5) & 0x7);
12672     offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
12673                               | ((ctx->opcode >> 21) & 0x3f) << 5
12674                               | (ctx->opcode & 0x1f));
12675
12676     /* The extended opcodes cleverly reuse the opcodes from their 16-bit
12677        counterparts.  */
12678     switch (op) {
12679     case M16_OPC_ADDIUSP:
12680         gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
12681         break;
12682     case M16_OPC_ADDIUPC:
12683         gen_addiupc(ctx, rx, imm, 0, 1);
12684         break;
12685     case M16_OPC_B:
12686         gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
12687         /* No delay slot, so just process as a normal instruction */
12688         break;
12689     case M16_OPC_BEQZ:
12690         gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
12691         /* No delay slot, so just process as a normal instruction */
12692         break;
12693     case M16_OPC_BNEQZ:
12694         gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
12695         /* No delay slot, so just process as a normal instruction */
12696         break;
12697     case M16_OPC_SHIFT:
12698         switch (ctx->opcode & 0x3) {
12699         case 0x0:
12700             gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
12701             break;
12702         case 0x1:
12703 #if defined(TARGET_MIPS64)
12704             check_mips_64(ctx);
12705             gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
12706 #else
12707             generate_exception_end(ctx, EXCP_RI);
12708 #endif
12709             break;
12710         case 0x2:
12711             gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
12712             break;
12713         case 0x3:
12714             gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
12715             break;
12716         }
12717         break;
12718 #if defined(TARGET_MIPS64)
12719     case M16_OPC_LD:
12720         check_insn(ctx, ISA_MIPS3);
12721         check_mips_64(ctx);
12722         gen_ld(ctx, OPC_LD, ry, rx, offset);
12723         break;
12724 #endif
12725     case M16_OPC_RRIA:
12726         imm = ctx->opcode & 0xf;
12727         imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
12728         imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
12729         imm = (int16_t) (imm << 1) >> 1;
12730         if ((ctx->opcode >> 4) & 0x1) {
12731 #if defined(TARGET_MIPS64)
12732             check_mips_64(ctx);
12733             gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
12734 #else
12735             generate_exception_end(ctx, EXCP_RI);
12736 #endif
12737         } else {
12738             gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
12739         }
12740         break;
12741     case M16_OPC_ADDIU8:
12742         gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
12743         break;
12744     case M16_OPC_SLTI:
12745         gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
12746         break;
12747     case M16_OPC_SLTIU:
12748         gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
12749         break;
12750     case M16_OPC_I8:
12751         switch (funct) {
12752         case I8_BTEQZ:
12753             gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
12754             break;
12755         case I8_BTNEZ:
12756             gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
12757             break;
12758         case I8_SWRASP:
12759             gen_st(ctx, OPC_SW, 31, 29, imm);
12760             break;
12761         case I8_ADJSP:
12762             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
12763             break;
12764         case I8_SVRS:
12765             check_insn(ctx, ISA_MIPS32);
12766             {
12767                 int xsregs = (ctx->opcode >> 24) & 0x7;
12768                 int aregs = (ctx->opcode >> 16) & 0xf;
12769                 int do_ra = (ctx->opcode >> 6) & 0x1;
12770                 int do_s0 = (ctx->opcode >> 5) & 0x1;
12771                 int do_s1 = (ctx->opcode >> 4) & 0x1;
12772                 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
12773                                  | (ctx->opcode & 0xf)) << 3;
12774
12775                 if (ctx->opcode & (1 << 7)) {
12776                     gen_mips16_save(ctx, xsregs, aregs,
12777                                     do_ra, do_s0, do_s1,
12778                                     framesize);
12779                 } else {
12780                     gen_mips16_restore(ctx, xsregs, aregs,
12781                                        do_ra, do_s0, do_s1,
12782                                        framesize);
12783                 }
12784             }
12785             break;
12786         default:
12787             generate_exception_end(ctx, EXCP_RI);
12788             break;
12789         }
12790         break;
12791     case M16_OPC_LI:
12792         tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
12793         break;
12794     case M16_OPC_CMPI:
12795         tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
12796         break;
12797 #if defined(TARGET_MIPS64)
12798     case M16_OPC_SD:
12799         check_insn(ctx, ISA_MIPS3);
12800         check_mips_64(ctx);
12801         gen_st(ctx, OPC_SD, ry, rx, offset);
12802         break;
12803 #endif
12804     case M16_OPC_LB:
12805         gen_ld(ctx, OPC_LB, ry, rx, offset);
12806         break;
12807     case M16_OPC_LH:
12808         gen_ld(ctx, OPC_LH, ry, rx, offset);
12809         break;
12810     case M16_OPC_LWSP:
12811         gen_ld(ctx, OPC_LW, rx, 29, offset);
12812         break;
12813     case M16_OPC_LW:
12814         gen_ld(ctx, OPC_LW, ry, rx, offset);
12815         break;
12816     case M16_OPC_LBU:
12817         gen_ld(ctx, OPC_LBU, ry, rx, offset);
12818         break;
12819     case M16_OPC_LHU:
12820         gen_ld(ctx, OPC_LHU, ry, rx, offset);
12821         break;
12822     case M16_OPC_LWPC:
12823         gen_ld(ctx, OPC_LWPC, rx, 0, offset);
12824         break;
12825 #if defined(TARGET_MIPS64)
12826     case M16_OPC_LWU:
12827         check_insn(ctx, ISA_MIPS3);
12828         check_mips_64(ctx);
12829         gen_ld(ctx, OPC_LWU, ry, rx, offset);
12830         break;
12831 #endif
12832     case M16_OPC_SB:
12833         gen_st(ctx, OPC_SB, ry, rx, offset);
12834         break;
12835     case M16_OPC_SH:
12836         gen_st(ctx, OPC_SH, ry, rx, offset);
12837         break;
12838     case M16_OPC_SWSP:
12839         gen_st(ctx, OPC_SW, rx, 29, offset);
12840         break;
12841     case M16_OPC_SW:
12842         gen_st(ctx, OPC_SW, ry, rx, offset);
12843         break;
12844 #if defined(TARGET_MIPS64)
12845     case M16_OPC_I64:
12846         decode_i64_mips16(ctx, ry, funct, offset, 1);
12847         break;
12848 #endif
12849     default:
12850         generate_exception_end(ctx, EXCP_RI);
12851         break;
12852     }
12853
12854     return 4;
12855 }
12856
12857 static inline bool is_uhi(int sdbbp_code)
12858 {
12859 #ifdef CONFIG_USER_ONLY
12860     return false;
12861 #else
12862     return semihosting_enabled() && sdbbp_code == 1;
12863 #endif
12864 }
12865
12866 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
12867 {
12868     int rx, ry;
12869     int sa;
12870     int op, cnvt_op, op1, offset;
12871     int funct;
12872     int n_bytes;
12873
12874     op = (ctx->opcode >> 11) & 0x1f;
12875     sa = (ctx->opcode >> 2) & 0x7;
12876     sa = sa == 0 ? 8 : sa;
12877     rx = xlat((ctx->opcode >> 8) & 0x7);
12878     cnvt_op = (ctx->opcode >> 5) & 0x7;
12879     ry = xlat((ctx->opcode >> 5) & 0x7);
12880     op1 = offset = ctx->opcode & 0x1f;
12881
12882     n_bytes = 2;
12883
12884     switch (op) {
12885     case M16_OPC_ADDIUSP:
12886         {
12887             int16_t imm = ((uint8_t) ctx->opcode) << 2;
12888
12889             gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
12890         }
12891         break;
12892     case M16_OPC_ADDIUPC:
12893         gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
12894         break;
12895     case M16_OPC_B:
12896         offset = (ctx->opcode & 0x7ff) << 1;
12897         offset = (int16_t)(offset << 4) >> 4;
12898         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
12899         /* No delay slot, so just process as a normal instruction */
12900         break;
12901     case M16_OPC_JAL:
12902         offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
12903         offset = (((ctx->opcode & 0x1f) << 21)
12904                   | ((ctx->opcode >> 5) & 0x1f) << 16
12905                   | offset) << 2;
12906         op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
12907         gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
12908         n_bytes = 4;
12909         break;
12910     case M16_OPC_BEQZ:
12911         gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
12912                            ((int8_t)ctx->opcode) << 1, 0);
12913         /* No delay slot, so just process as a normal instruction */
12914         break;
12915     case M16_OPC_BNEQZ:
12916         gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
12917                            ((int8_t)ctx->opcode) << 1, 0);
12918         /* No delay slot, so just process as a normal instruction */
12919         break;
12920     case M16_OPC_SHIFT:
12921         switch (ctx->opcode & 0x3) {
12922         case 0x0:
12923             gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
12924             break;
12925         case 0x1:
12926 #if defined(TARGET_MIPS64)
12927             check_insn(ctx, ISA_MIPS3);
12928             check_mips_64(ctx);
12929             gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
12930 #else
12931             generate_exception_end(ctx, EXCP_RI);
12932 #endif
12933             break;
12934         case 0x2:
12935             gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
12936             break;
12937         case 0x3:
12938             gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
12939             break;
12940         }
12941         break;
12942 #if defined(TARGET_MIPS64)
12943     case M16_OPC_LD:
12944         check_insn(ctx, ISA_MIPS3);
12945         check_mips_64(ctx);
12946         gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
12947         break;
12948 #endif
12949     case M16_OPC_RRIA:
12950         {
12951             int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
12952
12953             if ((ctx->opcode >> 4) & 1) {
12954 #if defined(TARGET_MIPS64)
12955                 check_insn(ctx, ISA_MIPS3);
12956                 check_mips_64(ctx);
12957                 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
12958 #else
12959                 generate_exception_end(ctx, EXCP_RI);
12960 #endif
12961             } else {
12962                 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
12963             }
12964         }
12965         break;
12966     case M16_OPC_ADDIU8:
12967         {
12968             int16_t imm = (int8_t) ctx->opcode;
12969
12970             gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
12971         }
12972         break;
12973     case M16_OPC_SLTI:
12974         {
12975             int16_t imm = (uint8_t) ctx->opcode;
12976             gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
12977         }
12978         break;
12979     case M16_OPC_SLTIU:
12980         {
12981             int16_t imm = (uint8_t) ctx->opcode;
12982             gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
12983         }
12984         break;
12985     case M16_OPC_I8:
12986         {
12987             int reg32;
12988
12989             funct = (ctx->opcode >> 8) & 0x7;
12990             switch (funct) {
12991             case I8_BTEQZ:
12992                 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
12993                                    ((int8_t)ctx->opcode) << 1, 0);
12994                 break;
12995             case I8_BTNEZ:
12996                 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
12997                                    ((int8_t)ctx->opcode) << 1, 0);
12998                 break;
12999             case I8_SWRASP:
13000                 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
13001                 break;
13002             case I8_ADJSP:
13003                 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
13004                               ((int8_t)ctx->opcode) << 3);
13005                 break;
13006             case I8_SVRS:
13007                 check_insn(ctx, ISA_MIPS32);
13008                 {
13009                     int do_ra = ctx->opcode & (1 << 6);
13010                     int do_s0 = ctx->opcode & (1 << 5);
13011                     int do_s1 = ctx->opcode & (1 << 4);
13012                     int framesize = ctx->opcode & 0xf;
13013
13014                     if (framesize == 0) {
13015                         framesize = 128;
13016                     } else {
13017                         framesize = framesize << 3;
13018                     }
13019
13020                     if (ctx->opcode & (1 << 7)) {
13021                         gen_mips16_save(ctx, 0, 0,
13022                                         do_ra, do_s0, do_s1, framesize);
13023                     } else {
13024                         gen_mips16_restore(ctx, 0, 0,
13025                                            do_ra, do_s0, do_s1, framesize);
13026                     }
13027                 }
13028                 break;
13029             case I8_MOV32R:
13030                 {
13031                     int rz = xlat(ctx->opcode & 0x7);
13032
13033                     reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
13034                         ((ctx->opcode >> 5) & 0x7);
13035                     gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
13036                 }
13037                 break;
13038             case I8_MOVR32:
13039                 reg32 = ctx->opcode & 0x1f;
13040                 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
13041                 break;
13042             default:
13043                 generate_exception_end(ctx, EXCP_RI);
13044                 break;
13045             }
13046         }
13047         break;
13048     case M16_OPC_LI:
13049         {
13050             int16_t imm = (uint8_t) ctx->opcode;
13051
13052             gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
13053         }
13054         break;
13055     case M16_OPC_CMPI:
13056         {
13057             int16_t imm = (uint8_t) ctx->opcode;
13058             gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
13059         }
13060         break;
13061 #if defined(TARGET_MIPS64)
13062     case M16_OPC_SD:
13063         check_insn(ctx, ISA_MIPS3);
13064         check_mips_64(ctx);
13065         gen_st(ctx, OPC_SD, ry, rx, offset << 3);
13066         break;
13067 #endif
13068     case M16_OPC_LB:
13069         gen_ld(ctx, OPC_LB, ry, rx, offset);
13070         break;
13071     case M16_OPC_LH:
13072         gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
13073         break;
13074     case M16_OPC_LWSP:
13075         gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13076         break;
13077     case M16_OPC_LW:
13078         gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
13079         break;
13080     case M16_OPC_LBU:
13081         gen_ld(ctx, OPC_LBU, ry, rx, offset);
13082         break;
13083     case M16_OPC_LHU:
13084         gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
13085         break;
13086     case M16_OPC_LWPC:
13087         gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
13088         break;
13089 #if defined (TARGET_MIPS64)
13090     case M16_OPC_LWU:
13091         check_insn(ctx, ISA_MIPS3);
13092         check_mips_64(ctx);
13093         gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
13094         break;
13095 #endif
13096     case M16_OPC_SB:
13097         gen_st(ctx, OPC_SB, ry, rx, offset);
13098         break;
13099     case M16_OPC_SH:
13100         gen_st(ctx, OPC_SH, ry, rx, offset << 1);
13101         break;
13102     case M16_OPC_SWSP:
13103         gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13104         break;
13105     case M16_OPC_SW:
13106         gen_st(ctx, OPC_SW, ry, rx, offset << 2);
13107         break;
13108     case M16_OPC_RRR:
13109         {
13110             int rz = xlat((ctx->opcode >> 2) & 0x7);
13111             int mips32_op;
13112
13113             switch (ctx->opcode & 0x3) {
13114             case RRR_ADDU:
13115                 mips32_op = OPC_ADDU;
13116                 break;
13117             case RRR_SUBU:
13118                 mips32_op = OPC_SUBU;
13119                 break;
13120 #if defined(TARGET_MIPS64)
13121             case RRR_DADDU:
13122                 mips32_op = OPC_DADDU;
13123                 check_insn(ctx, ISA_MIPS3);
13124                 check_mips_64(ctx);
13125                 break;
13126             case RRR_DSUBU:
13127                 mips32_op = OPC_DSUBU;
13128                 check_insn(ctx, ISA_MIPS3);
13129                 check_mips_64(ctx);
13130                 break;
13131 #endif
13132             default:
13133                 generate_exception_end(ctx, EXCP_RI);
13134                 goto done;
13135             }
13136
13137             gen_arith(ctx, mips32_op, rz, rx, ry);
13138         done:
13139             ;
13140         }
13141         break;
13142     case M16_OPC_RR:
13143         switch (op1) {
13144         case RR_JR:
13145             {
13146                 int nd = (ctx->opcode >> 7) & 0x1;
13147                 int link = (ctx->opcode >> 6) & 0x1;
13148                 int ra = (ctx->opcode >> 5) & 0x1;
13149
13150                 if (nd) {
13151                     check_insn(ctx, ISA_MIPS32);
13152                 }
13153
13154                 if (link) {
13155                     op = OPC_JALR;
13156                 } else {
13157                     op = OPC_JR;
13158                 }
13159
13160                 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
13161                                    (nd ? 0 : 2));
13162             }
13163             break;
13164         case RR_SDBBP:
13165             if (is_uhi(extract32(ctx->opcode, 5, 6))) {
13166                 gen_helper_do_semihosting(cpu_env);
13167             } else {
13168                 /* XXX: not clear which exception should be raised
13169                  *      when in debug mode...
13170                  */
13171                 check_insn(ctx, ISA_MIPS32);
13172                 generate_exception_end(ctx, EXCP_DBp);
13173             }
13174             break;
13175         case RR_SLT:
13176             gen_slt(ctx, OPC_SLT, 24, rx, ry);
13177             break;
13178         case RR_SLTU:
13179             gen_slt(ctx, OPC_SLTU, 24, rx, ry);
13180             break;
13181         case RR_BREAK:
13182             generate_exception_end(ctx, EXCP_BREAK);
13183             break;
13184         case RR_SLLV:
13185             gen_shift(ctx, OPC_SLLV, ry, rx, ry);
13186             break;
13187         case RR_SRLV:
13188             gen_shift(ctx, OPC_SRLV, ry, rx, ry);
13189             break;
13190         case RR_SRAV:
13191             gen_shift(ctx, OPC_SRAV, ry, rx, ry);
13192             break;
13193 #if defined (TARGET_MIPS64)
13194         case RR_DSRL:
13195             check_insn(ctx, ISA_MIPS3);
13196             check_mips_64(ctx);
13197             gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
13198             break;
13199 #endif
13200         case RR_CMP:
13201             gen_logic(ctx, OPC_XOR, 24, rx, ry);
13202             break;
13203         case RR_NEG:
13204             gen_arith(ctx, OPC_SUBU, rx, 0, ry);
13205             break;
13206         case RR_AND:
13207             gen_logic(ctx, OPC_AND, rx, rx, ry);
13208             break;
13209         case RR_OR:
13210             gen_logic(ctx, OPC_OR, rx, rx, ry);
13211             break;
13212         case RR_XOR:
13213             gen_logic(ctx, OPC_XOR, rx, rx, ry);
13214             break;
13215         case RR_NOT:
13216             gen_logic(ctx, OPC_NOR, rx, ry, 0);
13217             break;
13218         case RR_MFHI:
13219             gen_HILO(ctx, OPC_MFHI, 0, rx);
13220             break;
13221         case RR_CNVT:
13222             check_insn(ctx, ISA_MIPS32);
13223             switch (cnvt_op) {
13224             case RR_RY_CNVT_ZEB:
13225                 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13226                 break;
13227             case RR_RY_CNVT_ZEH:
13228                 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13229                 break;
13230             case RR_RY_CNVT_SEB:
13231                 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13232                 break;
13233             case RR_RY_CNVT_SEH:
13234                 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13235                 break;
13236 #if defined (TARGET_MIPS64)
13237             case RR_RY_CNVT_ZEW:
13238                 check_insn(ctx, ISA_MIPS64);
13239                 check_mips_64(ctx);
13240                 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13241                 break;
13242             case RR_RY_CNVT_SEW:
13243                 check_insn(ctx, ISA_MIPS64);
13244                 check_mips_64(ctx);
13245                 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13246                 break;
13247 #endif
13248             default:
13249                 generate_exception_end(ctx, EXCP_RI);
13250                 break;
13251             }
13252             break;
13253         case RR_MFLO:
13254             gen_HILO(ctx, OPC_MFLO, 0, rx);
13255             break;
13256 #if defined (TARGET_MIPS64)
13257         case RR_DSRA:
13258             check_insn(ctx, ISA_MIPS3);
13259             check_mips_64(ctx);
13260             gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
13261             break;
13262         case RR_DSLLV:
13263             check_insn(ctx, ISA_MIPS3);
13264             check_mips_64(ctx);
13265             gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
13266             break;
13267         case RR_DSRLV:
13268             check_insn(ctx, ISA_MIPS3);
13269             check_mips_64(ctx);
13270             gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
13271             break;
13272         case RR_DSRAV:
13273             check_insn(ctx, ISA_MIPS3);
13274             check_mips_64(ctx);
13275             gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
13276             break;
13277 #endif
13278         case RR_MULT:
13279             gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
13280             break;
13281         case RR_MULTU:
13282             gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
13283             break;
13284         case RR_DIV:
13285             gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
13286             break;
13287         case RR_DIVU:
13288             gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
13289             break;
13290 #if defined (TARGET_MIPS64)
13291         case RR_DMULT:
13292             check_insn(ctx, ISA_MIPS3);
13293             check_mips_64(ctx);
13294             gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
13295             break;
13296         case RR_DMULTU:
13297             check_insn(ctx, ISA_MIPS3);
13298             check_mips_64(ctx);
13299             gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
13300             break;
13301         case RR_DDIV:
13302             check_insn(ctx, ISA_MIPS3);
13303             check_mips_64(ctx);
13304             gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
13305             break;
13306         case RR_DDIVU:
13307             check_insn(ctx, ISA_MIPS3);
13308             check_mips_64(ctx);
13309             gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
13310             break;
13311 #endif
13312         default:
13313             generate_exception_end(ctx, EXCP_RI);
13314             break;
13315         }
13316         break;
13317     case M16_OPC_EXTEND:
13318         decode_extended_mips16_opc(env, ctx);
13319         n_bytes = 4;
13320         break;
13321 #if defined(TARGET_MIPS64)
13322     case M16_OPC_I64:
13323         funct = (ctx->opcode >> 8) & 0x7;
13324         decode_i64_mips16(ctx, ry, funct, offset, 0);
13325         break;
13326 #endif
13327     default:
13328         generate_exception_end(ctx, EXCP_RI);
13329         break;
13330     }
13331
13332     return n_bytes;
13333 }
13334
13335 /* microMIPS extension to MIPS32/MIPS64 */
13336
13337 /*
13338  * microMIPS32/microMIPS64 major opcodes
13339  *
13340  * 1. MIPS Architecture for Programmers Volume II-B:
13341  *      The microMIPS32 Instruction Set (Revision 3.05)
13342  *
13343  *    Table 6.2 microMIPS32 Encoding of Major Opcode Field
13344  *
13345  * 2. MIPS Architecture For Programmers Volume II-A:
13346  *      The MIPS64 Instruction Set (Revision 3.51)
13347  */
13348
13349 enum {
13350     POOL32A = 0x00,
13351     POOL16A = 0x01,
13352     LBU16 = 0x02,
13353     MOVE16 = 0x03,
13354     ADDI32 = 0x04,
13355     R6_LUI = 0x04,
13356     AUI = 0x04,
13357     LBU32 = 0x05,
13358     SB32 = 0x06,
13359     LB32 = 0x07,
13360
13361     POOL32B = 0x08,
13362     POOL16B = 0x09,
13363     LHU16 = 0x0a,
13364     ANDI16 = 0x0b,
13365     ADDIU32 = 0x0c,
13366     LHU32 = 0x0d,
13367     SH32 = 0x0e,
13368     LH32 = 0x0f,
13369
13370     POOL32I = 0x10,
13371     POOL16C = 0x11,
13372     LWSP16 = 0x12,
13373     POOL16D = 0x13,
13374     ORI32 = 0x14,
13375     POOL32F = 0x15,
13376     POOL32S = 0x16,  /* MIPS64 */
13377     DADDIU32 = 0x17, /* MIPS64 */
13378
13379     POOL32C = 0x18,
13380     LWGP16 = 0x19,
13381     LW16 = 0x1a,
13382     POOL16E = 0x1b,
13383     XORI32 = 0x1c,
13384     JALS32 = 0x1d,
13385     BOVC = 0x1d,
13386     BEQC = 0x1d,
13387     BEQZALC = 0x1d,
13388     ADDIUPC = 0x1e,
13389     PCREL = 0x1e,
13390     BNVC = 0x1f,
13391     BNEC = 0x1f,
13392     BNEZALC = 0x1f,
13393
13394     R6_BEQZC = 0x20,
13395     JIC = 0x20,
13396     POOL16F = 0x21,
13397     SB16 = 0x22,
13398     BEQZ16 = 0x23,
13399     BEQZC16 = 0x23,
13400     SLTI32 = 0x24,
13401     BEQ32 = 0x25,
13402     BC = 0x25,
13403     SWC132 = 0x26,
13404     LWC132 = 0x27,
13405
13406     /* 0x29 is reserved */
13407     RES_29 = 0x29,
13408     R6_BNEZC = 0x28,
13409     JIALC = 0x28,
13410     SH16 = 0x2a,
13411     BNEZ16 = 0x2b,
13412     BNEZC16 = 0x2b,
13413     SLTIU32 = 0x2c,
13414     BNE32 = 0x2d,
13415     BALC = 0x2d,
13416     SDC132 = 0x2e,
13417     LDC132 = 0x2f,
13418
13419     /* 0x31 is reserved */
13420     RES_31 = 0x31,
13421     BLEZALC = 0x30,
13422     BGEZALC = 0x30,
13423     BGEUC = 0x30,
13424     SWSP16 = 0x32,
13425     B16 = 0x33,
13426     BC16 = 0x33,
13427     ANDI32 = 0x34,
13428     J32 = 0x35,
13429     BGTZC = 0x35,
13430     BLTZC = 0x35,
13431     BLTC = 0x35,
13432     SD32 = 0x36, /* MIPS64 */
13433     LD32 = 0x37, /* MIPS64 */
13434
13435     /* 0x39 is reserved */
13436     RES_39 = 0x39,
13437     BGTZALC = 0x38,
13438     BLTZALC = 0x38,
13439     BLTUC = 0x38,
13440     SW16 = 0x3a,
13441     LI16 = 0x3b,
13442     JALX32 = 0x3c,
13443     JAL32 = 0x3d,
13444     BLEZC = 0x3d,
13445     BGEZC = 0x3d,
13446     BGEC = 0x3d,
13447     SW32 = 0x3e,
13448     LW32 = 0x3f
13449 };
13450
13451 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
13452 enum {
13453     ADDIUPC_00 = 0x00,
13454     ADDIUPC_01 = 0x01,
13455     ADDIUPC_02 = 0x02,
13456     ADDIUPC_03 = 0x03,
13457     ADDIUPC_04 = 0x04,
13458     ADDIUPC_05 = 0x05,
13459     ADDIUPC_06 = 0x06,
13460     ADDIUPC_07 = 0x07,
13461     AUIPC = 0x1e,
13462     ALUIPC = 0x1f,
13463     LWPC_08 = 0x08,
13464     LWPC_09 = 0x09,
13465     LWPC_0A = 0x0A,
13466     LWPC_0B = 0x0B,
13467     LWPC_0C = 0x0C,
13468     LWPC_0D = 0x0D,
13469     LWPC_0E = 0x0E,
13470     LWPC_0F = 0x0F,
13471 };
13472
13473 /* POOL32A encoding of minor opcode field */
13474
13475 enum {
13476     /* These opcodes are distinguished only by bits 9..6; those bits are
13477      * what are recorded below. */
13478     SLL32 = 0x0,
13479     SRL32 = 0x1,
13480     SRA = 0x2,
13481     ROTR = 0x3,
13482     SELEQZ = 0x5,
13483     SELNEZ = 0x6,
13484     R6_RDHWR = 0x7,
13485
13486     SLLV = 0x0,
13487     SRLV = 0x1,
13488     SRAV = 0x2,
13489     ROTRV = 0x3,
13490     ADD = 0x4,
13491     ADDU32 = 0x5,
13492     SUB = 0x6,
13493     SUBU32 = 0x7,
13494     MUL = 0x8,
13495     AND = 0x9,
13496     OR32 = 0xa,
13497     NOR = 0xb,
13498     XOR32 = 0xc,
13499     SLT = 0xd,
13500     SLTU = 0xe,
13501
13502     MOVN = 0x0,
13503     R6_MUL  = 0x0,
13504     MOVZ = 0x1,
13505     MUH  = 0x1,
13506     MULU = 0x2,
13507     MUHU = 0x3,
13508     LWXS = 0x4,
13509     R6_DIV  = 0x4,
13510     MOD  = 0x5,
13511     R6_DIVU = 0x6,
13512     MODU = 0x7,
13513
13514     /* The following can be distinguished by their lower 6 bits. */
13515     BREAK32 = 0x07,
13516     INS = 0x0c,
13517     LSA = 0x0f,
13518     ALIGN = 0x1f,
13519     EXT = 0x2c,
13520     POOL32AXF = 0x3c,
13521     SIGRIE = 0x3f
13522 };
13523
13524 /* POOL32AXF encoding of minor opcode field extension */
13525
13526 /*
13527  * 1. MIPS Architecture for Programmers Volume II-B:
13528  *      The microMIPS32 Instruction Set (Revision 3.05)
13529  *
13530  *    Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
13531  *
13532  * 2. MIPS Architecture for Programmers VolumeIV-e:
13533  *      The MIPS DSP Application-Specific Extension
13534  *        to the microMIPS32 Architecture (Revision 2.34)
13535  *
13536  *    Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
13537  */
13538
13539 enum {
13540     /* bits 11..6 */
13541     TEQ = 0x00,
13542     TGE = 0x08,
13543     TGEU = 0x10,
13544     TLT = 0x20,
13545     TLTU = 0x28,
13546     TNE = 0x30,
13547
13548     MFC0 = 0x03,
13549     MTC0 = 0x0b,
13550
13551     /* begin of microMIPS32 DSP */
13552
13553     /* bits 13..12 for 0x01 */
13554     MFHI_ACC = 0x0,
13555     MFLO_ACC = 0x1,
13556     MTHI_ACC = 0x2,
13557     MTLO_ACC = 0x3,
13558
13559     /* bits 13..12 for 0x2a */
13560     MADD_ACC = 0x0,
13561     MADDU_ACC = 0x1,
13562     MSUB_ACC = 0x2,
13563     MSUBU_ACC = 0x3,
13564
13565     /* bits 13..12 for 0x32 */
13566     MULT_ACC = 0x0,
13567     MULTU_ACC = 0x1,
13568
13569     /* end of microMIPS32 DSP */
13570
13571     /* bits 15..12 for 0x2c */
13572     BITSWAP = 0x0,
13573     SEB = 0x2,
13574     SEH = 0x3,
13575     CLO = 0x4,
13576     CLZ = 0x5,
13577     RDHWR = 0x6,
13578     WSBH = 0x7,
13579     MULT = 0x8,
13580     MULTU = 0x9,
13581     DIV = 0xa,
13582     DIVU = 0xb,
13583     MADD = 0xc,
13584     MADDU = 0xd,
13585     MSUB = 0xe,
13586     MSUBU = 0xf,
13587
13588     /* bits 15..12 for 0x34 */
13589     MFC2 = 0x4,
13590     MTC2 = 0x5,
13591     MFHC2 = 0x8,
13592     MTHC2 = 0x9,
13593     CFC2 = 0xc,
13594     CTC2 = 0xd,
13595
13596     /* bits 15..12 for 0x3c */
13597     JALR = 0x0,
13598     JR = 0x0,                   /* alias */
13599     JALRC = 0x0,
13600     JRC = 0x0,
13601     JALR_HB = 0x1,
13602     JALRC_HB = 0x1,
13603     JALRS = 0x4,
13604     JALRS_HB = 0x5,
13605
13606     /* bits 15..12 for 0x05 */
13607     RDPGPR = 0xe,
13608     WRPGPR = 0xf,
13609
13610     /* bits 15..12 for 0x0d */
13611     TLBP = 0x0,
13612     TLBR = 0x1,
13613     TLBWI = 0x2,
13614     TLBWR = 0x3,
13615     TLBINV = 0x4,
13616     TLBINVF = 0x5,
13617     WAIT = 0x9,
13618     IRET = 0xd,
13619     DERET = 0xe,
13620     ERET = 0xf,
13621
13622     /* bits 15..12 for 0x15 */
13623     DMT = 0x0,
13624     DVPE = 0x1,
13625     EMT = 0x2,
13626     EVPE = 0x3,
13627
13628     /* bits 15..12 for 0x1d */
13629     DI = 0x4,
13630     EI = 0x5,
13631
13632     /* bits 15..12 for 0x2d */
13633     SYNC = 0x6,
13634     SYSCALL = 0x8,
13635     SDBBP = 0xd,
13636
13637     /* bits 15..12 for 0x35 */
13638     MFHI32 = 0x0,
13639     MFLO32 = 0x1,
13640     MTHI32 = 0x2,
13641     MTLO32 = 0x3,
13642 };
13643
13644 /* POOL32B encoding of minor opcode field (bits 15..12) */
13645
13646 enum {
13647     LWC2 = 0x0,
13648     LWP = 0x1,
13649     LDP = 0x4,
13650     LWM32 = 0x5,
13651     CACHE = 0x6,
13652     LDM = 0x7,
13653     SWC2 = 0x8,
13654     SWP = 0x9,
13655     SDP = 0xc,
13656     SWM32 = 0xd,
13657     SDM = 0xf
13658 };
13659
13660 /* POOL32C encoding of minor opcode field (bits 15..12) */
13661
13662 enum {
13663     LWL = 0x0,
13664     SWL = 0x8,
13665     LWR = 0x1,
13666     SWR = 0x9,
13667     PREF = 0x2,
13668     ST_EVA = 0xa,
13669     LL = 0x3,
13670     SC = 0xb,
13671     LDL = 0x4,
13672     SDL = 0xc,
13673     LDR = 0x5,
13674     SDR = 0xd,
13675     LD_EVA = 0x6,
13676     LWU = 0xe,
13677     LLD = 0x7,
13678     SCD = 0xf
13679 };
13680
13681 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
13682
13683 enum {
13684     LBUE = 0x0,
13685     LHUE = 0x1,
13686     LWLE = 0x2,
13687     LWRE = 0x3,
13688     LBE = 0x4,
13689     LHE = 0x5,
13690     LLE = 0x6,
13691     LWE = 0x7,
13692 };
13693
13694 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
13695
13696 enum {
13697     SWLE = 0x0,
13698     SWRE = 0x1,
13699     PREFE = 0x2,
13700     CACHEE = 0x3,
13701     SBE = 0x4,
13702     SHE = 0x5,
13703     SCE = 0x6,
13704     SWE = 0x7,
13705 };
13706
13707 /* POOL32F encoding of minor opcode field (bits 5..0) */
13708
13709 enum {
13710     /* These are the bit 7..6 values */
13711     ADD_FMT = 0x0,
13712
13713     SUB_FMT = 0x1,
13714
13715     MUL_FMT = 0x2,
13716
13717     DIV_FMT = 0x3,
13718
13719     /* These are the bit 8..6 values */
13720     MOVN_FMT = 0x0,
13721     RSQRT2_FMT = 0x0,
13722     MOVF_FMT = 0x0,
13723     RINT_FMT = 0x0,
13724     SELNEZ_FMT = 0x0,
13725
13726     MOVZ_FMT = 0x1,
13727     LWXC1 = 0x1,
13728     MOVT_FMT = 0x1,
13729     CLASS_FMT = 0x1,
13730     SELEQZ_FMT = 0x1,
13731
13732     PLL_PS = 0x2,
13733     SWXC1 = 0x2,
13734     SEL_FMT = 0x2,
13735
13736     PLU_PS = 0x3,
13737     LDXC1 = 0x3,
13738
13739     MOVN_FMT_04 = 0x4,
13740     PUL_PS = 0x4,
13741     SDXC1 = 0x4,
13742     RECIP2_FMT = 0x4,
13743
13744     MOVZ_FMT_05 = 0x05,
13745     PUU_PS = 0x5,
13746     LUXC1 = 0x5,
13747
13748     CVT_PS_S = 0x6,
13749     SUXC1 = 0x6,
13750     ADDR_PS = 0x6,
13751     PREFX = 0x6,
13752     MADDF_FMT = 0x6,
13753
13754     MULR_PS = 0x7,
13755     MSUBF_FMT = 0x7,
13756
13757     MADD_S = 0x01,
13758     MADD_D = 0x09,
13759     MADD_PS = 0x11,
13760     ALNV_PS = 0x19,
13761     MSUB_S = 0x21,
13762     MSUB_D = 0x29,
13763     MSUB_PS = 0x31,
13764
13765     NMADD_S = 0x02,
13766     NMADD_D = 0x0a,
13767     NMADD_PS = 0x12,
13768     NMSUB_S = 0x22,
13769     NMSUB_D = 0x2a,
13770     NMSUB_PS = 0x32,
13771
13772     MIN_FMT = 0x3,
13773     MAX_FMT = 0xb,
13774     MINA_FMT = 0x23,
13775     MAXA_FMT = 0x2b,
13776     POOL32FXF = 0x3b,
13777
13778     CABS_COND_FMT = 0x1c,              /* MIPS3D */
13779     C_COND_FMT = 0x3c,
13780
13781     CMP_CONDN_S = 0x5,
13782     CMP_CONDN_D = 0x15
13783 };
13784
13785 /* POOL32Fxf encoding of minor opcode extension field */
13786
13787 enum {
13788     CVT_L = 0x04,
13789     RSQRT_FMT = 0x08,
13790     FLOOR_L = 0x0c,
13791     CVT_PW_PS = 0x1c,
13792     CVT_W = 0x24,
13793     SQRT_FMT = 0x28,
13794     FLOOR_W = 0x2c,
13795     CVT_PS_PW = 0x3c,
13796     CFC1 = 0x40,
13797     RECIP_FMT = 0x48,
13798     CEIL_L = 0x4c,
13799     CTC1 = 0x60,
13800     CEIL_W = 0x6c,
13801     MFC1 = 0x80,
13802     CVT_S_PL = 0x84,
13803     TRUNC_L = 0x8c,
13804     MTC1 = 0xa0,
13805     CVT_S_PU = 0xa4,
13806     TRUNC_W = 0xac,
13807     MFHC1 = 0xc0,
13808     ROUND_L = 0xcc,
13809     MTHC1 = 0xe0,
13810     ROUND_W = 0xec,
13811
13812     MOV_FMT = 0x01,
13813     MOVF = 0x05,
13814     ABS_FMT = 0x0d,
13815     RSQRT1_FMT = 0x1d,
13816     MOVT = 0x25,
13817     NEG_FMT = 0x2d,
13818     CVT_D = 0x4d,
13819     RECIP1_FMT = 0x5d,
13820     CVT_S = 0x6d
13821 };
13822
13823 /* POOL32I encoding of minor opcode field (bits 25..21) */
13824
13825 enum {
13826     BLTZ = 0x00,
13827     BLTZAL = 0x01,
13828     BGEZ = 0x02,
13829     BGEZAL = 0x03,
13830     BLEZ = 0x04,
13831     BNEZC = 0x05,
13832     BGTZ = 0x06,
13833     BEQZC = 0x07,
13834     TLTI = 0x08,
13835     BC1EQZC = 0x08,
13836     TGEI = 0x09,
13837     BC1NEZC = 0x09,
13838     TLTIU = 0x0a,
13839     BC2EQZC = 0x0a,
13840     TGEIU = 0x0b,
13841     BC2NEZC = 0x0a,
13842     TNEI = 0x0c,
13843     R6_SYNCI = 0x0c,
13844     LUI = 0x0d,
13845     TEQI = 0x0e,
13846     SYNCI = 0x10,
13847     BLTZALS = 0x11,
13848     BGEZALS = 0x13,
13849     BC2F = 0x14,
13850     BC2T = 0x15,
13851     BPOSGE64 = 0x1a,
13852     BPOSGE32 = 0x1b,
13853     /* These overlap and are distinguished by bit16 of the instruction */
13854     BC1F = 0x1c,
13855     BC1T = 0x1d,
13856     BC1ANY2F = 0x1c,
13857     BC1ANY2T = 0x1d,
13858     BC1ANY4F = 0x1e,
13859     BC1ANY4T = 0x1f
13860 };
13861
13862 /* POOL16A encoding of minor opcode field */
13863
13864 enum {
13865     ADDU16 = 0x0,
13866     SUBU16 = 0x1
13867 };
13868
13869 /* POOL16B encoding of minor opcode field */
13870
13871 enum {
13872     SLL16 = 0x0,
13873     SRL16 = 0x1
13874 };
13875
13876 /* POOL16C encoding of minor opcode field */
13877
13878 enum {
13879     NOT16 = 0x00,
13880     XOR16 = 0x04,
13881     AND16 = 0x08,
13882     OR16 = 0x0c,
13883     LWM16 = 0x10,
13884     SWM16 = 0x14,
13885     JR16 = 0x18,
13886     JRC16 = 0x1a,
13887     JALR16 = 0x1c,
13888     JALR16S = 0x1e,
13889     MFHI16 = 0x20,
13890     MFLO16 = 0x24,
13891     BREAK16 = 0x28,
13892     SDBBP16 = 0x2c,
13893     JRADDIUSP = 0x30
13894 };
13895
13896 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
13897
13898 enum {
13899     R6_NOT16    = 0x00,
13900     R6_AND16    = 0x01,
13901     R6_LWM16    = 0x02,
13902     R6_JRC16    = 0x03,
13903     MOVEP       = 0x04,
13904     MOVEP_05    = 0x05,
13905     MOVEP_06    = 0x06,
13906     MOVEP_07    = 0x07,
13907     R6_XOR16    = 0x08,
13908     R6_OR16     = 0x09,
13909     R6_SWM16    = 0x0a,
13910     JALRC16     = 0x0b,
13911     MOVEP_0C    = 0x0c,
13912     MOVEP_0D    = 0x0d,
13913     MOVEP_0E    = 0x0e,
13914     MOVEP_0F    = 0x0f,
13915     JRCADDIUSP  = 0x13,
13916     R6_BREAK16  = 0x1b,
13917     R6_SDBBP16  = 0x3b
13918 };
13919
13920 /* POOL16D encoding of minor opcode field */
13921
13922 enum {
13923     ADDIUS5 = 0x0,
13924     ADDIUSP = 0x1
13925 };
13926
13927 /* POOL16E encoding of minor opcode field */
13928
13929 enum {
13930     ADDIUR2 = 0x0,
13931     ADDIUR1SP = 0x1
13932 };
13933
13934 static int mmreg (int r)
13935 {
13936     static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13937
13938     return map[r];
13939 }
13940
13941 /* Used for 16-bit store instructions.  */
13942 static int mmreg2 (int r)
13943 {
13944     static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
13945
13946     return map[r];
13947 }
13948
13949 #define uMIPS_RD(op) ((op >> 7) & 0x7)
13950 #define uMIPS_RS(op) ((op >> 4) & 0x7)
13951 #define uMIPS_RS2(op) uMIPS_RS(op)
13952 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
13953 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
13954 #define uMIPS_RS5(op) (op & 0x1f)
13955
13956 /* Signed immediate */
13957 #define SIMM(op, start, width)                                          \
13958     ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
13959                << (32-width))                                           \
13960      >> (32-width))
13961 /* Zero-extended immediate */
13962 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
13963
13964 static void gen_addiur1sp(DisasContext *ctx)
13965 {
13966     int rd = mmreg(uMIPS_RD(ctx->opcode));
13967
13968     gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
13969 }
13970
13971 static void gen_addiur2(DisasContext *ctx)
13972 {
13973     static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
13974     int rd = mmreg(uMIPS_RD(ctx->opcode));
13975     int rs = mmreg(uMIPS_RS(ctx->opcode));
13976
13977     gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
13978 }
13979
13980 static void gen_addiusp(DisasContext *ctx)
13981 {
13982     int encoded = ZIMM(ctx->opcode, 1, 9);
13983     int decoded;
13984
13985     if (encoded <= 1) {
13986         decoded = 256 + encoded;
13987     } else if (encoded <= 255) {
13988         decoded = encoded;
13989     } else if (encoded <= 509) {
13990         decoded = encoded - 512;
13991     } else {
13992         decoded = encoded - 768;
13993     }
13994
13995     gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
13996 }
13997
13998 static void gen_addius5(DisasContext *ctx)
13999 {
14000     int imm = SIMM(ctx->opcode, 1, 4);
14001     int rd = (ctx->opcode >> 5) & 0x1f;
14002
14003     gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
14004 }
14005
14006 static void gen_andi16(DisasContext *ctx)
14007 {
14008     static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14009                                  31, 32, 63, 64, 255, 32768, 65535 };
14010     int rd = mmreg(uMIPS_RD(ctx->opcode));
14011     int rs = mmreg(uMIPS_RS(ctx->opcode));
14012     int encoded = ZIMM(ctx->opcode, 0, 4);
14013
14014     gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
14015 }
14016
14017 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
14018                                int base, int16_t offset)
14019 {
14020     TCGv t0, t1;
14021     TCGv_i32 t2;
14022
14023     if (ctx->hflags & MIPS_HFLAG_BMASK) {
14024         generate_exception_end(ctx, EXCP_RI);
14025         return;
14026     }
14027
14028     t0 = tcg_temp_new();
14029
14030     gen_base_offset_addr(ctx, t0, base, offset);
14031
14032     t1 = tcg_const_tl(reglist);
14033     t2 = tcg_const_i32(ctx->mem_idx);
14034
14035     save_cpu_state(ctx, 1);
14036     switch (opc) {
14037     case LWM32:
14038         gen_helper_lwm(cpu_env, t0, t1, t2);
14039         break;
14040     case SWM32:
14041         gen_helper_swm(cpu_env, t0, t1, t2);
14042         break;
14043 #ifdef TARGET_MIPS64
14044     case LDM:
14045         gen_helper_ldm(cpu_env, t0, t1, t2);
14046         break;
14047     case SDM:
14048         gen_helper_sdm(cpu_env, t0, t1, t2);
14049         break;
14050 #endif
14051     }
14052     tcg_temp_free(t0);
14053     tcg_temp_free(t1);
14054     tcg_temp_free_i32(t2);
14055 }
14056
14057
14058 static void gen_pool16c_insn(DisasContext *ctx)
14059 {
14060     int rd = mmreg((ctx->opcode >> 3) & 0x7);
14061     int rs = mmreg(ctx->opcode & 0x7);
14062
14063     switch (((ctx->opcode) >> 4) & 0x3f) {
14064     case NOT16 + 0:
14065     case NOT16 + 1:
14066     case NOT16 + 2:
14067     case NOT16 + 3:
14068         gen_logic(ctx, OPC_NOR, rd, rs, 0);
14069         break;
14070     case XOR16 + 0:
14071     case XOR16 + 1:
14072     case XOR16 + 2:
14073     case XOR16 + 3:
14074         gen_logic(ctx, OPC_XOR, rd, rd, rs);
14075         break;
14076     case AND16 + 0:
14077     case AND16 + 1:
14078     case AND16 + 2:
14079     case AND16 + 3:
14080         gen_logic(ctx, OPC_AND, rd, rd, rs);
14081         break;
14082     case OR16 + 0:
14083     case OR16 + 1:
14084     case OR16 + 2:
14085     case OR16 + 3:
14086         gen_logic(ctx, OPC_OR, rd, rd, rs);
14087         break;
14088     case LWM16 + 0:
14089     case LWM16 + 1:
14090     case LWM16 + 2:
14091     case LWM16 + 3:
14092         {
14093             static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14094             int offset = ZIMM(ctx->opcode, 0, 4);
14095
14096             gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14097                               29, offset << 2);
14098         }
14099         break;
14100     case SWM16 + 0:
14101     case SWM16 + 1:
14102     case SWM16 + 2:
14103     case SWM16 + 3:
14104         {
14105             static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14106             int offset = ZIMM(ctx->opcode, 0, 4);
14107
14108             gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
14109                               29, offset << 2);
14110         }
14111         break;
14112     case JR16 + 0:
14113     case JR16 + 1:
14114         {
14115             int reg = ctx->opcode & 0x1f;
14116
14117             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
14118         }
14119         break;
14120     case JRC16 + 0:
14121     case JRC16 + 1:
14122         {
14123             int reg = ctx->opcode & 0x1f;
14124             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
14125             /* Let normal delay slot handling in our caller take us
14126                to the branch target.  */
14127         }
14128         break;
14129     case JALR16 + 0:
14130     case JALR16 + 1:
14131         gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
14132         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14133         break;
14134     case JALR16S + 0:
14135     case JALR16S + 1:
14136         gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
14137         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14138         break;
14139     case MFHI16 + 0:
14140     case MFHI16 + 1:
14141         gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
14142         break;
14143     case MFLO16 + 0:
14144     case MFLO16 + 1:
14145         gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
14146         break;
14147     case BREAK16:
14148         generate_exception_end(ctx, EXCP_BREAK);
14149         break;
14150     case SDBBP16:
14151         if (is_uhi(extract32(ctx->opcode, 0, 4))) {
14152             gen_helper_do_semihosting(cpu_env);
14153         } else {
14154             /* XXX: not clear which exception should be raised
14155              *      when in debug mode...
14156              */
14157             check_insn(ctx, ISA_MIPS32);
14158             generate_exception_end(ctx, EXCP_DBp);
14159         }
14160         break;
14161     case JRADDIUSP + 0:
14162     case JRADDIUSP + 1:
14163         {
14164             int imm = ZIMM(ctx->opcode, 0, 5);
14165             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14166             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14167             /* Let normal delay slot handling in our caller take us
14168                to the branch target.  */
14169         }
14170         break;
14171     default:
14172         generate_exception_end(ctx, EXCP_RI);
14173         break;
14174     }
14175 }
14176
14177 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
14178                              int enc_rs)
14179 {
14180     int rd, rs, re, rt;
14181     static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14182     static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14183     static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14184     rd = rd_enc[enc_dest];
14185     re = re_enc[enc_dest];
14186     rs = rs_rt_enc[enc_rs];
14187     rt = rs_rt_enc[enc_rt];
14188     if (rs) {
14189         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
14190     } else {
14191         tcg_gen_movi_tl(cpu_gpr[rd], 0);
14192     }
14193     if (rt) {
14194         tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
14195     } else {
14196         tcg_gen_movi_tl(cpu_gpr[re], 0);
14197     }
14198 }
14199
14200 static void gen_pool16c_r6_insn(DisasContext *ctx)
14201 {
14202     int rt = mmreg((ctx->opcode >> 7) & 0x7);
14203     int rs = mmreg((ctx->opcode >> 4) & 0x7);
14204
14205     switch (ctx->opcode & 0xf) {
14206     case R6_NOT16:
14207         gen_logic(ctx, OPC_NOR, rt, rs, 0);
14208         break;
14209     case R6_AND16:
14210         gen_logic(ctx, OPC_AND, rt, rt, rs);
14211         break;
14212     case R6_LWM16:
14213         {
14214             int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14215             int offset = extract32(ctx->opcode, 4, 4);
14216             gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
14217         }
14218         break;
14219     case R6_JRC16: /* JRCADDIUSP */
14220         if ((ctx->opcode >> 4) & 1) {
14221             /* JRCADDIUSP */
14222             int imm = extract32(ctx->opcode, 5, 5);
14223             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14224             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14225         } else {
14226             /* JRC16 */
14227             rs = extract32(ctx->opcode, 5, 5);
14228             gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
14229         }
14230         break;
14231     case MOVEP:
14232     case MOVEP_05:
14233     case MOVEP_06:
14234     case MOVEP_07:
14235     case MOVEP_0C:
14236     case MOVEP_0D:
14237     case MOVEP_0E:
14238     case MOVEP_0F:
14239         {
14240             int enc_dest = uMIPS_RD(ctx->opcode);
14241             int enc_rt = uMIPS_RS2(ctx->opcode);
14242             int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
14243             gen_movep(ctx, enc_dest, enc_rt, enc_rs);
14244         }
14245         break;
14246     case R6_XOR16:
14247         gen_logic(ctx, OPC_XOR, rt, rt, rs);
14248         break;
14249     case R6_OR16:
14250         gen_logic(ctx, OPC_OR, rt, rt, rs);
14251         break;
14252     case R6_SWM16:
14253         {
14254             int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14255             int offset = extract32(ctx->opcode, 4, 4);
14256             gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
14257         }
14258         break;
14259     case JALRC16: /* BREAK16, SDBBP16 */
14260         switch (ctx->opcode & 0x3f) {
14261         case JALRC16:
14262         case JALRC16 + 0x20:
14263             /* JALRC16 */
14264             gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
14265                                31, 0, 0);
14266             break;
14267         case R6_BREAK16:
14268             /* BREAK16 */
14269             generate_exception(ctx, EXCP_BREAK);
14270             break;
14271         case R6_SDBBP16:
14272             /* SDBBP16 */
14273             if (is_uhi(extract32(ctx->opcode, 6, 4))) {
14274                 gen_helper_do_semihosting(cpu_env);
14275             } else {
14276                 if (ctx->hflags & MIPS_HFLAG_SBRI) {
14277                     generate_exception(ctx, EXCP_RI);
14278                 } else {
14279                     generate_exception(ctx, EXCP_DBp);
14280                 }
14281             }
14282             break;
14283         }
14284         break;
14285     default:
14286         generate_exception(ctx, EXCP_RI);
14287         break;
14288     }
14289 }
14290
14291 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
14292 {
14293     TCGv t0 = tcg_temp_new();
14294     TCGv t1 = tcg_temp_new();
14295
14296     gen_load_gpr(t0, base);
14297
14298     if (index != 0) {
14299         gen_load_gpr(t1, index);
14300         tcg_gen_shli_tl(t1, t1, 2);
14301         gen_op_addr_add(ctx, t0, t1, t0);
14302     }
14303
14304     tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14305     gen_store_gpr(t1, rd);
14306
14307     tcg_temp_free(t0);
14308     tcg_temp_free(t1);
14309 }
14310
14311 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
14312                            int base, int16_t offset)
14313 {
14314     TCGv t0, t1;
14315
14316     if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
14317         generate_exception_end(ctx, EXCP_RI);
14318         return;
14319     }
14320
14321     t0 = tcg_temp_new();
14322     t1 = tcg_temp_new();
14323
14324     gen_base_offset_addr(ctx, t0, base, offset);
14325
14326     switch (opc) {
14327     case LWP:
14328         if (rd == base) {
14329             generate_exception_end(ctx, EXCP_RI);
14330             return;
14331         }
14332         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14333         gen_store_gpr(t1, rd);
14334         tcg_gen_movi_tl(t1, 4);
14335         gen_op_addr_add(ctx, t0, t0, t1);
14336         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14337         gen_store_gpr(t1, rd+1);
14338         break;
14339     case SWP:
14340         gen_load_gpr(t1, rd);
14341         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14342         tcg_gen_movi_tl(t1, 4);
14343         gen_op_addr_add(ctx, t0, t0, t1);
14344         gen_load_gpr(t1, rd+1);
14345         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14346         break;
14347 #ifdef TARGET_MIPS64
14348     case LDP:
14349         if (rd == base) {
14350             generate_exception_end(ctx, EXCP_RI);
14351             return;
14352         }
14353         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14354         gen_store_gpr(t1, rd);
14355         tcg_gen_movi_tl(t1, 8);
14356         gen_op_addr_add(ctx, t0, t0, t1);
14357         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14358         gen_store_gpr(t1, rd+1);
14359         break;
14360     case SDP:
14361         gen_load_gpr(t1, rd);
14362         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14363         tcg_gen_movi_tl(t1, 8);
14364         gen_op_addr_add(ctx, t0, t0, t1);
14365         gen_load_gpr(t1, rd+1);
14366         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14367         break;
14368 #endif
14369     }
14370     tcg_temp_free(t0);
14371     tcg_temp_free(t1);
14372 }
14373
14374 static void gen_sync(int stype)
14375 {
14376     TCGBar tcg_mo = TCG_BAR_SC;
14377
14378     switch (stype) {
14379     case 0x4: /* SYNC_WMB */
14380         tcg_mo |= TCG_MO_ST_ST;
14381         break;
14382     case 0x10: /* SYNC_MB */
14383         tcg_mo |= TCG_MO_ALL;
14384         break;
14385     case 0x11: /* SYNC_ACQUIRE */
14386         tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
14387         break;
14388     case 0x12: /* SYNC_RELEASE */
14389         tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
14390         break;
14391     case 0x13: /* SYNC_RMB */
14392         tcg_mo |= TCG_MO_LD_LD;
14393         break;
14394     default:
14395         tcg_mo |= TCG_MO_ALL;
14396         break;
14397     }
14398
14399     tcg_gen_mb(tcg_mo);
14400 }
14401
14402 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
14403 {
14404     int extension = (ctx->opcode >> 6) & 0x3f;
14405     int minor = (ctx->opcode >> 12) & 0xf;
14406     uint32_t mips32_op;
14407
14408     switch (extension) {
14409     case TEQ:
14410         mips32_op = OPC_TEQ;
14411         goto do_trap;
14412     case TGE:
14413         mips32_op = OPC_TGE;
14414         goto do_trap;
14415     case TGEU:
14416         mips32_op = OPC_TGEU;
14417         goto do_trap;
14418     case TLT:
14419         mips32_op = OPC_TLT;
14420         goto do_trap;
14421     case TLTU:
14422         mips32_op = OPC_TLTU;
14423         goto do_trap;
14424     case TNE:
14425         mips32_op = OPC_TNE;
14426     do_trap:
14427         gen_trap(ctx, mips32_op, rs, rt, -1);
14428         break;
14429 #ifndef CONFIG_USER_ONLY
14430     case MFC0:
14431     case MFC0 + 32:
14432         check_cp0_enabled(ctx);
14433         if (rt == 0) {
14434             /* Treat as NOP. */
14435             break;
14436         }
14437         gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
14438         break;
14439     case MTC0:
14440     case MTC0 + 32:
14441         check_cp0_enabled(ctx);
14442         {
14443             TCGv t0 = tcg_temp_new();
14444
14445             gen_load_gpr(t0, rt);
14446             gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
14447             tcg_temp_free(t0);
14448         }
14449         break;
14450 #endif
14451     case 0x2a:
14452         switch (minor & 3) {
14453         case MADD_ACC:
14454             gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
14455             break;
14456         case MADDU_ACC:
14457             gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
14458             break;
14459         case MSUB_ACC:
14460             gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
14461             break;
14462         case MSUBU_ACC:
14463             gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
14464             break;
14465         default:
14466             goto pool32axf_invalid;
14467         }
14468         break;
14469     case 0x32:
14470         switch (minor & 3) {
14471         case MULT_ACC:
14472             gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
14473             break;
14474         case MULTU_ACC:
14475             gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
14476             break;
14477         default:
14478             goto pool32axf_invalid;
14479         }
14480         break;
14481     case 0x2c:
14482         switch (minor) {
14483         case BITSWAP:
14484             check_insn(ctx, ISA_MIPS32R6);
14485             gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
14486             break;
14487         case SEB:
14488             gen_bshfl(ctx, OPC_SEB, rs, rt);
14489             break;
14490         case SEH:
14491             gen_bshfl(ctx, OPC_SEH, rs, rt);
14492             break;
14493         case CLO:
14494             mips32_op = OPC_CLO;
14495             goto do_cl;
14496         case CLZ:
14497             mips32_op = OPC_CLZ;
14498         do_cl:
14499             check_insn(ctx, ISA_MIPS32);
14500             gen_cl(ctx, mips32_op, rt, rs);
14501             break;
14502         case RDHWR:
14503             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14504             gen_rdhwr(ctx, rt, rs, 0);
14505             break;
14506         case WSBH:
14507             gen_bshfl(ctx, OPC_WSBH, rs, rt);
14508             break;
14509         case MULT:
14510             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14511             mips32_op = OPC_MULT;
14512             goto do_mul;
14513         case MULTU:
14514             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14515             mips32_op = OPC_MULTU;
14516             goto do_mul;
14517         case DIV:
14518             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14519             mips32_op = OPC_DIV;
14520             goto do_div;
14521         case DIVU:
14522             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14523             mips32_op = OPC_DIVU;
14524             goto do_div;
14525         do_div:
14526             check_insn(ctx, ISA_MIPS32);
14527             gen_muldiv(ctx, mips32_op, 0, rs, rt);
14528             break;
14529         case MADD:
14530             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14531             mips32_op = OPC_MADD;
14532             goto do_mul;
14533         case MADDU:
14534             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14535             mips32_op = OPC_MADDU;
14536             goto do_mul;
14537         case MSUB:
14538             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14539             mips32_op = OPC_MSUB;
14540             goto do_mul;
14541         case MSUBU:
14542             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14543             mips32_op = OPC_MSUBU;
14544         do_mul:
14545             check_insn(ctx, ISA_MIPS32);
14546             gen_muldiv(ctx, mips32_op, 0, rs, rt);
14547             break;
14548         default:
14549             goto pool32axf_invalid;
14550         }
14551         break;
14552     case 0x34:
14553         switch (minor) {
14554         case MFC2:
14555         case MTC2:
14556         case MFHC2:
14557         case MTHC2:
14558         case CFC2:
14559         case CTC2:
14560             generate_exception_err(ctx, EXCP_CpU, 2);
14561             break;
14562         default:
14563             goto pool32axf_invalid;
14564         }
14565         break;
14566     case 0x3c:
14567         switch (minor) {
14568         case JALR:    /* JALRC */
14569         case JALR_HB: /* JALRC_HB */
14570             if (ctx->insn_flags & ISA_MIPS32R6) {
14571                 /* JALRC, JALRC_HB */
14572                 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
14573             } else {
14574                 /* JALR, JALR_HB */
14575                 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
14576                 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14577             }
14578             break;
14579         case JALRS:
14580         case JALRS_HB:
14581             check_insn_opc_removed(ctx, ISA_MIPS32R6);
14582             gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
14583             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14584             break;
14585         default:
14586             goto pool32axf_invalid;
14587         }
14588         break;
14589     case 0x05:
14590         switch (minor) {
14591         case RDPGPR:
14592             check_cp0_enabled(ctx);
14593             check_insn(ctx, ISA_MIPS32R2);
14594             gen_load_srsgpr(rs, rt);
14595             break;
14596         case WRPGPR:
14597             check_cp0_enabled(ctx);
14598             check_insn(ctx, ISA_MIPS32R2);
14599             gen_store_srsgpr(rs, rt);
14600             break;
14601         default:
14602             goto pool32axf_invalid;
14603         }
14604         break;
14605 #ifndef CONFIG_USER_ONLY
14606     case 0x0d:
14607         switch (minor) {
14608         case TLBP:
14609             mips32_op = OPC_TLBP;
14610             goto do_cp0;
14611         case TLBR:
14612             mips32_op = OPC_TLBR;
14613             goto do_cp0;
14614         case TLBWI:
14615             mips32_op = OPC_TLBWI;
14616             goto do_cp0;
14617         case TLBWR:
14618             mips32_op = OPC_TLBWR;
14619             goto do_cp0;
14620         case TLBINV:
14621             mips32_op = OPC_TLBINV;
14622             goto do_cp0;
14623         case TLBINVF:
14624             mips32_op = OPC_TLBINVF;
14625             goto do_cp0;
14626         case WAIT:
14627             mips32_op = OPC_WAIT;
14628             goto do_cp0;
14629         case DERET:
14630             mips32_op = OPC_DERET;
14631             goto do_cp0;
14632         case ERET:
14633             mips32_op = OPC_ERET;
14634         do_cp0:
14635             gen_cp0(env, ctx, mips32_op, rt, rs);
14636             break;
14637         default:
14638             goto pool32axf_invalid;
14639         }
14640         break;
14641     case 0x1d:
14642         switch (minor) {
14643         case DI:
14644             check_cp0_enabled(ctx);
14645             {
14646                 TCGv t0 = tcg_temp_new();
14647
14648                 save_cpu_state(ctx, 1);
14649                 gen_helper_di(t0, cpu_env);
14650                 gen_store_gpr(t0, rs);
14651                 /* Stop translation as we may have switched the execution mode */
14652                 ctx->base.is_jmp = DISAS_STOP;
14653                 tcg_temp_free(t0);
14654             }
14655             break;
14656         case EI:
14657             check_cp0_enabled(ctx);
14658             {
14659                 TCGv t0 = tcg_temp_new();
14660
14661                 save_cpu_state(ctx, 1);
14662                 gen_helper_ei(t0, cpu_env);
14663                 gen_store_gpr(t0, rs);
14664                 /* DISAS_STOP isn't sufficient, we need to ensure we break out
14665                    of translated code to check for pending interrupts.  */
14666                 gen_save_pc(ctx->base.pc_next + 4);
14667                 ctx->base.is_jmp = DISAS_EXIT;
14668                 tcg_temp_free(t0);
14669             }
14670             break;
14671         default:
14672             goto pool32axf_invalid;
14673         }
14674         break;
14675 #endif
14676     case 0x2d:
14677         switch (minor) {
14678         case SYNC:
14679             gen_sync(extract32(ctx->opcode, 16, 5));
14680             break;
14681         case SYSCALL:
14682             generate_exception_end(ctx, EXCP_SYSCALL);
14683             break;
14684         case SDBBP:
14685             if (is_uhi(extract32(ctx->opcode, 16, 10))) {
14686                 gen_helper_do_semihosting(cpu_env);
14687             } else {
14688                 check_insn(ctx, ISA_MIPS32);
14689                 if (ctx->hflags & MIPS_HFLAG_SBRI) {
14690                     generate_exception_end(ctx, EXCP_RI);
14691                 } else {
14692                     generate_exception_end(ctx, EXCP_DBp);
14693                 }
14694             }
14695             break;
14696         default:
14697             goto pool32axf_invalid;
14698         }
14699         break;
14700     case 0x01:
14701         switch (minor & 3) {
14702         case MFHI_ACC:
14703             gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
14704             break;
14705         case MFLO_ACC:
14706             gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
14707             break;
14708         case MTHI_ACC:
14709             gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
14710             break;
14711         case MTLO_ACC:
14712             gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
14713             break;
14714         default:
14715             goto pool32axf_invalid;
14716         }
14717         break;
14718     case 0x35:
14719         check_insn_opc_removed(ctx, ISA_MIPS32R6);
14720         switch (minor) {
14721         case MFHI32:
14722             gen_HILO(ctx, OPC_MFHI, 0, rs);
14723             break;
14724         case MFLO32:
14725             gen_HILO(ctx, OPC_MFLO, 0, rs);
14726             break;
14727         case MTHI32:
14728             gen_HILO(ctx, OPC_MTHI, 0, rs);
14729             break;
14730         case MTLO32:
14731             gen_HILO(ctx, OPC_MTLO, 0, rs);
14732             break;
14733         default:
14734             goto pool32axf_invalid;
14735         }
14736         break;
14737     default:
14738     pool32axf_invalid:
14739         MIPS_INVAL("pool32axf");
14740         generate_exception_end(ctx, EXCP_RI);
14741         break;
14742     }
14743 }
14744
14745 /* Values for microMIPS fmt field.  Variable-width, depending on which
14746    formats the instruction supports.  */
14747
14748 enum {
14749     FMT_SD_S = 0,
14750     FMT_SD_D = 1,
14751
14752     FMT_SDPS_S = 0,
14753     FMT_SDPS_D = 1,
14754     FMT_SDPS_PS = 2,
14755
14756     FMT_SWL_S = 0,
14757     FMT_SWL_W = 1,
14758     FMT_SWL_L = 2,
14759
14760     FMT_DWL_D = 0,
14761     FMT_DWL_W = 1,
14762     FMT_DWL_L = 2
14763 };
14764
14765 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
14766 {
14767     int extension = (ctx->opcode >> 6) & 0x3ff;
14768     uint32_t mips32_op;
14769
14770 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
14771 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
14772 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
14773
14774     switch (extension) {
14775     case FLOAT_1BIT_FMT(CFC1, 0):
14776         mips32_op = OPC_CFC1;
14777         goto do_cp1;
14778     case FLOAT_1BIT_FMT(CTC1, 0):
14779         mips32_op = OPC_CTC1;
14780         goto do_cp1;
14781     case FLOAT_1BIT_FMT(MFC1, 0):
14782         mips32_op = OPC_MFC1;
14783         goto do_cp1;
14784     case FLOAT_1BIT_FMT(MTC1, 0):
14785         mips32_op = OPC_MTC1;
14786         goto do_cp1;
14787     case FLOAT_1BIT_FMT(MFHC1, 0):
14788         mips32_op = OPC_MFHC1;
14789         goto do_cp1;
14790     case FLOAT_1BIT_FMT(MTHC1, 0):
14791         mips32_op = OPC_MTHC1;
14792     do_cp1:
14793         gen_cp1(ctx, mips32_op, rt, rs);
14794         break;
14795
14796         /* Reciprocal square root */
14797     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
14798         mips32_op = OPC_RSQRT_S;
14799         goto do_unaryfp;
14800     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
14801         mips32_op = OPC_RSQRT_D;
14802         goto do_unaryfp;
14803
14804         /* Square root */
14805     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
14806         mips32_op = OPC_SQRT_S;
14807         goto do_unaryfp;
14808     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
14809         mips32_op = OPC_SQRT_D;
14810         goto do_unaryfp;
14811
14812         /* Reciprocal */
14813     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
14814         mips32_op = OPC_RECIP_S;
14815         goto do_unaryfp;
14816     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
14817         mips32_op = OPC_RECIP_D;
14818         goto do_unaryfp;
14819
14820         /* Floor */
14821     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
14822         mips32_op = OPC_FLOOR_L_S;
14823         goto do_unaryfp;
14824     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
14825         mips32_op = OPC_FLOOR_L_D;
14826         goto do_unaryfp;
14827     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
14828         mips32_op = OPC_FLOOR_W_S;
14829         goto do_unaryfp;
14830     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
14831         mips32_op = OPC_FLOOR_W_D;
14832         goto do_unaryfp;
14833
14834         /* Ceiling */
14835     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
14836         mips32_op = OPC_CEIL_L_S;
14837         goto do_unaryfp;
14838     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
14839         mips32_op = OPC_CEIL_L_D;
14840         goto do_unaryfp;
14841     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
14842         mips32_op = OPC_CEIL_W_S;
14843         goto do_unaryfp;
14844     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
14845         mips32_op = OPC_CEIL_W_D;
14846         goto do_unaryfp;
14847
14848         /* Truncation */
14849     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
14850         mips32_op = OPC_TRUNC_L_S;
14851         goto do_unaryfp;
14852     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
14853         mips32_op = OPC_TRUNC_L_D;
14854         goto do_unaryfp;
14855     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
14856         mips32_op = OPC_TRUNC_W_S;
14857         goto do_unaryfp;
14858     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
14859         mips32_op = OPC_TRUNC_W_D;
14860         goto do_unaryfp;
14861
14862         /* Round */
14863     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
14864         mips32_op = OPC_ROUND_L_S;
14865         goto do_unaryfp;
14866     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
14867         mips32_op = OPC_ROUND_L_D;
14868         goto do_unaryfp;
14869     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
14870         mips32_op = OPC_ROUND_W_S;
14871         goto do_unaryfp;
14872     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
14873         mips32_op = OPC_ROUND_W_D;
14874         goto do_unaryfp;
14875
14876         /* Integer to floating-point conversion */
14877     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
14878         mips32_op = OPC_CVT_L_S;
14879         goto do_unaryfp;
14880     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
14881         mips32_op = OPC_CVT_L_D;
14882         goto do_unaryfp;
14883     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
14884         mips32_op = OPC_CVT_W_S;
14885         goto do_unaryfp;
14886     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
14887         mips32_op = OPC_CVT_W_D;
14888         goto do_unaryfp;
14889
14890         /* Paired-foo conversions */
14891     case FLOAT_1BIT_FMT(CVT_S_PL, 0):
14892         mips32_op = OPC_CVT_S_PL;
14893         goto do_unaryfp;
14894     case FLOAT_1BIT_FMT(CVT_S_PU, 0):
14895         mips32_op = OPC_CVT_S_PU;
14896         goto do_unaryfp;
14897     case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
14898         mips32_op = OPC_CVT_PW_PS;
14899         goto do_unaryfp;
14900     case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
14901         mips32_op = OPC_CVT_PS_PW;
14902         goto do_unaryfp;
14903
14904         /* Floating-point moves */
14905     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
14906         mips32_op = OPC_MOV_S;
14907         goto do_unaryfp;
14908     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
14909         mips32_op = OPC_MOV_D;
14910         goto do_unaryfp;
14911     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
14912         mips32_op = OPC_MOV_PS;
14913         goto do_unaryfp;
14914
14915         /* Absolute value */
14916     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
14917         mips32_op = OPC_ABS_S;
14918         goto do_unaryfp;
14919     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
14920         mips32_op = OPC_ABS_D;
14921         goto do_unaryfp;
14922     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
14923         mips32_op = OPC_ABS_PS;
14924         goto do_unaryfp;
14925
14926         /* Negation */
14927     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
14928         mips32_op = OPC_NEG_S;
14929         goto do_unaryfp;
14930     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
14931         mips32_op = OPC_NEG_D;
14932         goto do_unaryfp;
14933     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
14934         mips32_op = OPC_NEG_PS;
14935         goto do_unaryfp;
14936
14937         /* Reciprocal square root step */
14938     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
14939         mips32_op = OPC_RSQRT1_S;
14940         goto do_unaryfp;
14941     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
14942         mips32_op = OPC_RSQRT1_D;
14943         goto do_unaryfp;
14944     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
14945         mips32_op = OPC_RSQRT1_PS;
14946         goto do_unaryfp;
14947
14948         /* Reciprocal step */
14949     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
14950         mips32_op = OPC_RECIP1_S;
14951         goto do_unaryfp;
14952     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
14953         mips32_op = OPC_RECIP1_S;
14954         goto do_unaryfp;
14955     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
14956         mips32_op = OPC_RECIP1_PS;
14957         goto do_unaryfp;
14958
14959         /* Conversions from double */
14960     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
14961         mips32_op = OPC_CVT_D_S;
14962         goto do_unaryfp;
14963     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
14964         mips32_op = OPC_CVT_D_W;
14965         goto do_unaryfp;
14966     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
14967         mips32_op = OPC_CVT_D_L;
14968         goto do_unaryfp;
14969
14970         /* Conversions from single */
14971     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
14972         mips32_op = OPC_CVT_S_D;
14973         goto do_unaryfp;
14974     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
14975         mips32_op = OPC_CVT_S_W;
14976         goto do_unaryfp;
14977     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
14978         mips32_op = OPC_CVT_S_L;
14979     do_unaryfp:
14980         gen_farith(ctx, mips32_op, -1, rs, rt, 0);
14981         break;
14982
14983         /* Conditional moves on floating-point codes */
14984     case COND_FLOAT_MOV(MOVT, 0):
14985     case COND_FLOAT_MOV(MOVT, 1):
14986     case COND_FLOAT_MOV(MOVT, 2):
14987     case COND_FLOAT_MOV(MOVT, 3):
14988     case COND_FLOAT_MOV(MOVT, 4):
14989     case COND_FLOAT_MOV(MOVT, 5):
14990     case COND_FLOAT_MOV(MOVT, 6):
14991     case COND_FLOAT_MOV(MOVT, 7):
14992         check_insn_opc_removed(ctx, ISA_MIPS32R6);
14993         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
14994         break;
14995     case COND_FLOAT_MOV(MOVF, 0):
14996     case COND_FLOAT_MOV(MOVF, 1):
14997     case COND_FLOAT_MOV(MOVF, 2):
14998     case COND_FLOAT_MOV(MOVF, 3):
14999     case COND_FLOAT_MOV(MOVF, 4):
15000     case COND_FLOAT_MOV(MOVF, 5):
15001     case COND_FLOAT_MOV(MOVF, 6):
15002     case COND_FLOAT_MOV(MOVF, 7):
15003         check_insn_opc_removed(ctx, ISA_MIPS32R6);
15004         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
15005         break;
15006     default:
15007         MIPS_INVAL("pool32fxf");
15008         generate_exception_end(ctx, EXCP_RI);
15009         break;
15010     }
15011 }
15012
15013 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
15014 {
15015     int32_t offset;
15016     uint16_t insn;
15017     int rt, rs, rd, rr;
15018     int16_t imm;
15019     uint32_t op, minor, minor2, mips32_op;
15020     uint32_t cond, fmt, cc;
15021
15022     insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
15023     ctx->opcode = (ctx->opcode << 16) | insn;
15024
15025     rt = (ctx->opcode >> 21) & 0x1f;
15026     rs = (ctx->opcode >> 16) & 0x1f;
15027     rd = (ctx->opcode >> 11) & 0x1f;
15028     rr = (ctx->opcode >> 6) & 0x1f;
15029     imm = (int16_t) ctx->opcode;
15030
15031     op = (ctx->opcode >> 26) & 0x3f;
15032     switch (op) {
15033     case POOL32A:
15034         minor = ctx->opcode & 0x3f;
15035         switch (minor) {
15036         case 0x00:
15037             minor = (ctx->opcode >> 6) & 0xf;
15038             switch (minor) {
15039             case SLL32:
15040                 mips32_op = OPC_SLL;
15041                 goto do_shifti;
15042             case SRA:
15043                 mips32_op = OPC_SRA;
15044                 goto do_shifti;
15045             case SRL32:
15046                 mips32_op = OPC_SRL;
15047                 goto do_shifti;
15048             case ROTR:
15049                 mips32_op = OPC_ROTR;
15050             do_shifti:
15051                 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
15052                 break;
15053             case SELEQZ:
15054                 check_insn(ctx, ISA_MIPS32R6);
15055                 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
15056                 break;
15057             case SELNEZ:
15058                 check_insn(ctx, ISA_MIPS32R6);
15059                 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
15060                 break;
15061             case R6_RDHWR:
15062                 check_insn(ctx, ISA_MIPS32R6);
15063                 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
15064                 break;
15065             default:
15066                 goto pool32a_invalid;
15067             }
15068             break;
15069         case 0x10:
15070             minor = (ctx->opcode >> 6) & 0xf;
15071             switch (minor) {
15072                 /* Arithmetic */
15073             case ADD:
15074                 mips32_op = OPC_ADD;
15075                 goto do_arith;
15076             case ADDU32:
15077                 mips32_op = OPC_ADDU;
15078                 goto do_arith;
15079             case SUB:
15080                 mips32_op = OPC_SUB;
15081                 goto do_arith;
15082             case SUBU32:
15083                 mips32_op = OPC_SUBU;
15084                 goto do_arith;
15085             case MUL:
15086                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15087                 mips32_op = OPC_MUL;
15088             do_arith:
15089                 gen_arith(ctx, mips32_op, rd, rs, rt);
15090                 break;
15091                 /* Shifts */
15092             case SLLV:
15093                 mips32_op = OPC_SLLV;
15094                 goto do_shift;
15095             case SRLV:
15096                 mips32_op = OPC_SRLV;
15097                 goto do_shift;
15098             case SRAV:
15099                 mips32_op = OPC_SRAV;
15100                 goto do_shift;
15101             case ROTRV:
15102                 mips32_op = OPC_ROTRV;
15103             do_shift:
15104                 gen_shift(ctx, mips32_op, rd, rs, rt);
15105                 break;
15106                 /* Logical operations */
15107             case AND:
15108                 mips32_op = OPC_AND;
15109                 goto do_logic;
15110             case OR32:
15111                 mips32_op = OPC_OR;
15112                 goto do_logic;
15113             case NOR:
15114                 mips32_op = OPC_NOR;
15115                 goto do_logic;
15116             case XOR32:
15117                 mips32_op = OPC_XOR;
15118             do_logic:
15119                 gen_logic(ctx, mips32_op, rd, rs, rt);
15120                 break;
15121                 /* Set less than */
15122             case SLT:
15123                 mips32_op = OPC_SLT;
15124                 goto do_slt;
15125             case SLTU:
15126                 mips32_op = OPC_SLTU;
15127             do_slt:
15128                 gen_slt(ctx, mips32_op, rd, rs, rt);
15129                 break;
15130             default:
15131                 goto pool32a_invalid;
15132             }
15133             break;
15134         case 0x18:
15135             minor = (ctx->opcode >> 6) & 0xf;
15136             switch (minor) {
15137                 /* Conditional moves */
15138             case MOVN: /* MUL */
15139                 if (ctx->insn_flags & ISA_MIPS32R6) {
15140                     /* MUL */
15141                     gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
15142                 } else {
15143                     /* MOVN */
15144                     gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
15145                 }
15146                 break;
15147             case MOVZ: /* MUH */
15148                 if (ctx->insn_flags & ISA_MIPS32R6) {
15149                     /* MUH */
15150                     gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
15151                 } else {
15152                     /* MOVZ */
15153                     gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
15154                 }
15155                 break;
15156             case MULU:
15157                 check_insn(ctx, ISA_MIPS32R6);
15158                 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
15159                 break;
15160             case MUHU:
15161                 check_insn(ctx, ISA_MIPS32R6);
15162                 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
15163                 break;
15164             case LWXS: /* DIV */
15165                 if (ctx->insn_flags & ISA_MIPS32R6) {
15166                     /* DIV */
15167                     gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
15168                 } else {
15169                     /* LWXS */
15170                     gen_ldxs(ctx, rs, rt, rd);
15171                 }
15172                 break;
15173             case MOD:
15174                 check_insn(ctx, ISA_MIPS32R6);
15175                 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
15176                 break;
15177             case R6_DIVU:
15178                 check_insn(ctx, ISA_MIPS32R6);
15179                 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
15180                 break;
15181             case MODU:
15182                 check_insn(ctx, ISA_MIPS32R6);
15183                 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
15184                 break;
15185             default:
15186                 goto pool32a_invalid;
15187             }
15188             break;
15189         case INS:
15190             gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
15191             return;
15192         case LSA:
15193             check_insn(ctx, ISA_MIPS32R6);
15194             gen_lsa(ctx, OPC_LSA, rd, rs, rt,
15195                     extract32(ctx->opcode, 9, 2));
15196             break;
15197         case ALIGN:
15198             check_insn(ctx, ISA_MIPS32R6);
15199             gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
15200             break;
15201         case EXT:
15202             gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
15203             return;
15204         case POOL32AXF:
15205             gen_pool32axf(env, ctx, rt, rs);
15206             break;
15207         case BREAK32:
15208             generate_exception_end(ctx, EXCP_BREAK);
15209             break;
15210         case SIGRIE:
15211             check_insn(ctx, ISA_MIPS32R6);
15212             generate_exception_end(ctx, EXCP_RI);
15213             break;
15214         default:
15215         pool32a_invalid:
15216                 MIPS_INVAL("pool32a");
15217                 generate_exception_end(ctx, EXCP_RI);
15218                 break;
15219         }
15220         break;
15221     case POOL32B:
15222         minor = (ctx->opcode >> 12) & 0xf;
15223         switch (minor) {
15224         case CACHE:
15225             check_cp0_enabled(ctx);
15226             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15227                 gen_cache_operation(ctx, rt, rs, imm);
15228             }
15229             break;
15230         case LWC2:
15231         case SWC2:
15232             /* COP2: Not implemented. */
15233             generate_exception_err(ctx, EXCP_CpU, 2);
15234             break;
15235 #ifdef TARGET_MIPS64
15236         case LDP:
15237         case SDP:
15238             check_insn(ctx, ISA_MIPS3);
15239             check_mips_64(ctx);
15240 #endif
15241             /* fall through */
15242         case LWP:
15243         case SWP:
15244             gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15245             break;
15246 #ifdef TARGET_MIPS64
15247         case LDM:
15248         case SDM:
15249             check_insn(ctx, ISA_MIPS3);
15250             check_mips_64(ctx);
15251 #endif
15252             /* fall through */
15253         case LWM32:
15254         case SWM32:
15255             gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15256             break;
15257         default:
15258             MIPS_INVAL("pool32b");
15259             generate_exception_end(ctx, EXCP_RI);
15260             break;
15261         }
15262         break;
15263     case POOL32F:
15264         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
15265             minor = ctx->opcode & 0x3f;
15266             check_cp1_enabled(ctx);
15267             switch (minor) {
15268             case ALNV_PS:
15269                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15270                 mips32_op = OPC_ALNV_PS;
15271                 goto do_madd;
15272             case MADD_S:
15273                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15274                 mips32_op = OPC_MADD_S;
15275                 goto do_madd;
15276             case MADD_D:
15277                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15278                 mips32_op = OPC_MADD_D;
15279                 goto do_madd;
15280             case MADD_PS:
15281                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15282                 mips32_op = OPC_MADD_PS;
15283                 goto do_madd;
15284             case MSUB_S:
15285                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15286                 mips32_op = OPC_MSUB_S;
15287                 goto do_madd;
15288             case MSUB_D:
15289                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15290                 mips32_op = OPC_MSUB_D;
15291                 goto do_madd;
15292             case MSUB_PS:
15293                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15294                 mips32_op = OPC_MSUB_PS;
15295                 goto do_madd;
15296             case NMADD_S:
15297                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15298                 mips32_op = OPC_NMADD_S;
15299                 goto do_madd;
15300             case NMADD_D:
15301                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15302                 mips32_op = OPC_NMADD_D;
15303                 goto do_madd;
15304             case NMADD_PS:
15305                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15306                 mips32_op = OPC_NMADD_PS;
15307                 goto do_madd;
15308             case NMSUB_S:
15309                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15310                 mips32_op = OPC_NMSUB_S;
15311                 goto do_madd;
15312             case NMSUB_D:
15313                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15314                 mips32_op = OPC_NMSUB_D;
15315                 goto do_madd;
15316             case NMSUB_PS:
15317                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15318                 mips32_op = OPC_NMSUB_PS;
15319             do_madd:
15320                 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
15321                 break;
15322             case CABS_COND_FMT:
15323                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15324                 cond = (ctx->opcode >> 6) & 0xf;
15325                 cc = (ctx->opcode >> 13) & 0x7;
15326                 fmt = (ctx->opcode >> 10) & 0x3;
15327                 switch (fmt) {
15328                 case 0x0:
15329                     gen_cmpabs_s(ctx, cond, rt, rs, cc);
15330                     break;
15331                 case 0x1:
15332                     gen_cmpabs_d(ctx, cond, rt, rs, cc);
15333                     break;
15334                 case 0x2:
15335                     gen_cmpabs_ps(ctx, cond, rt, rs, cc);
15336                     break;
15337                 default:
15338                     goto pool32f_invalid;
15339                 }
15340                 break;
15341             case C_COND_FMT:
15342                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15343                 cond = (ctx->opcode >> 6) & 0xf;
15344                 cc = (ctx->opcode >> 13) & 0x7;
15345                 fmt = (ctx->opcode >> 10) & 0x3;
15346                 switch (fmt) {
15347                 case 0x0:
15348                     gen_cmp_s(ctx, cond, rt, rs, cc);
15349                     break;
15350                 case 0x1:
15351                     gen_cmp_d(ctx, cond, rt, rs, cc);
15352                     break;
15353                 case 0x2:
15354                     gen_cmp_ps(ctx, cond, rt, rs, cc);
15355                     break;
15356                 default:
15357                     goto pool32f_invalid;
15358                 }
15359                 break;
15360             case CMP_CONDN_S:
15361                 check_insn(ctx, ISA_MIPS32R6);
15362                 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15363                 break;
15364             case CMP_CONDN_D:
15365                 check_insn(ctx, ISA_MIPS32R6);
15366                 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15367                 break;
15368             case POOL32FXF:
15369                 gen_pool32fxf(ctx, rt, rs);
15370                 break;
15371             case 0x00:
15372                 /* PLL foo */
15373                 switch ((ctx->opcode >> 6) & 0x7) {
15374                 case PLL_PS:
15375                     mips32_op = OPC_PLL_PS;
15376                     goto do_ps;
15377                 case PLU_PS:
15378                     mips32_op = OPC_PLU_PS;
15379                     goto do_ps;
15380                 case PUL_PS:
15381                     mips32_op = OPC_PUL_PS;
15382                     goto do_ps;
15383                 case PUU_PS:
15384                     mips32_op = OPC_PUU_PS;
15385                     goto do_ps;
15386                 case CVT_PS_S:
15387                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15388                     mips32_op = OPC_CVT_PS_S;
15389                 do_ps:
15390                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15391                     break;
15392                 default:
15393                     goto pool32f_invalid;
15394                 }
15395                 break;
15396             case MIN_FMT:
15397                 check_insn(ctx, ISA_MIPS32R6);
15398                 switch ((ctx->opcode >> 9) & 0x3) {
15399                 case FMT_SDPS_S:
15400                     gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
15401                     break;
15402                 case FMT_SDPS_D:
15403                     gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
15404                     break;
15405                 default:
15406                     goto pool32f_invalid;
15407                 }
15408                 break;
15409             case 0x08:
15410                 /* [LS][WDU]XC1 */
15411                 switch ((ctx->opcode >> 6) & 0x7) {
15412                 case LWXC1:
15413                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15414                     mips32_op = OPC_LWXC1;
15415                     goto do_ldst_cp1;
15416                 case SWXC1:
15417                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15418                     mips32_op = OPC_SWXC1;
15419                     goto do_ldst_cp1;
15420                 case LDXC1:
15421                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15422                     mips32_op = OPC_LDXC1;
15423                     goto do_ldst_cp1;
15424                 case SDXC1:
15425                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15426                     mips32_op = OPC_SDXC1;
15427                     goto do_ldst_cp1;
15428                 case LUXC1:
15429                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15430                     mips32_op = OPC_LUXC1;
15431                     goto do_ldst_cp1;
15432                 case SUXC1:
15433                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15434                     mips32_op = OPC_SUXC1;
15435                 do_ldst_cp1:
15436                     gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
15437                     break;
15438                 default:
15439                     goto pool32f_invalid;
15440                 }
15441                 break;
15442             case MAX_FMT:
15443                 check_insn(ctx, ISA_MIPS32R6);
15444                 switch ((ctx->opcode >> 9) & 0x3) {
15445                 case FMT_SDPS_S:
15446                     gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
15447                     break;
15448                 case FMT_SDPS_D:
15449                     gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
15450                     break;
15451                 default:
15452                     goto pool32f_invalid;
15453                 }
15454                 break;
15455             case 0x18:
15456                 /* 3D insns */
15457                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15458                 fmt = (ctx->opcode >> 9) & 0x3;
15459                 switch ((ctx->opcode >> 6) & 0x7) {
15460                 case RSQRT2_FMT:
15461                     switch (fmt) {
15462                     case FMT_SDPS_S:
15463                         mips32_op = OPC_RSQRT2_S;
15464                         goto do_3d;
15465                     case FMT_SDPS_D:
15466                         mips32_op = OPC_RSQRT2_D;
15467                         goto do_3d;
15468                     case FMT_SDPS_PS:
15469                         mips32_op = OPC_RSQRT2_PS;
15470                         goto do_3d;
15471                     default:
15472                         goto pool32f_invalid;
15473                     }
15474                     break;
15475                 case RECIP2_FMT:
15476                     switch (fmt) {
15477                     case FMT_SDPS_S:
15478                         mips32_op = OPC_RECIP2_S;
15479                         goto do_3d;
15480                     case FMT_SDPS_D:
15481                         mips32_op = OPC_RECIP2_D;
15482                         goto do_3d;
15483                     case FMT_SDPS_PS:
15484                         mips32_op = OPC_RECIP2_PS;
15485                         goto do_3d;
15486                     default:
15487                         goto pool32f_invalid;
15488                     }
15489                     break;
15490                 case ADDR_PS:
15491                     mips32_op = OPC_ADDR_PS;
15492                     goto do_3d;
15493                 case MULR_PS:
15494                     mips32_op = OPC_MULR_PS;
15495                 do_3d:
15496                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15497                     break;
15498                 default:
15499                     goto pool32f_invalid;
15500                 }
15501                 break;
15502             case 0x20:
15503                 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
15504                 cc = (ctx->opcode >> 13) & 0x7;
15505                 fmt = (ctx->opcode >> 9) & 0x3;
15506                 switch ((ctx->opcode >> 6) & 0x7) {
15507                 case MOVF_FMT: /* RINT_FMT */
15508                     if (ctx->insn_flags & ISA_MIPS32R6) {
15509                         /* RINT_FMT */
15510                         switch (fmt) {
15511                         case FMT_SDPS_S:
15512                             gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
15513                             break;
15514                         case FMT_SDPS_D:
15515                             gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
15516                             break;
15517                         default:
15518                             goto pool32f_invalid;
15519                         }
15520                     } else {
15521                         /* MOVF_FMT */
15522                         switch (fmt) {
15523                         case FMT_SDPS_S:
15524                             gen_movcf_s(ctx, rs, rt, cc, 0);
15525                             break;
15526                         case FMT_SDPS_D:
15527                             gen_movcf_d(ctx, rs, rt, cc, 0);
15528                             break;
15529                         case FMT_SDPS_PS:
15530                             check_ps(ctx);
15531                             gen_movcf_ps(ctx, rs, rt, cc, 0);
15532                             break;
15533                         default:
15534                             goto pool32f_invalid;
15535                         }
15536                     }
15537                     break;
15538                 case MOVT_FMT: /* CLASS_FMT */
15539                     if (ctx->insn_flags & ISA_MIPS32R6) {
15540                         /* CLASS_FMT */
15541                         switch (fmt) {
15542                         case FMT_SDPS_S:
15543                             gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
15544                             break;
15545                         case FMT_SDPS_D:
15546                             gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
15547                             break;
15548                         default:
15549                             goto pool32f_invalid;
15550                         }
15551                     } else {
15552                         /* MOVT_FMT */
15553                         switch (fmt) {
15554                         case FMT_SDPS_S:
15555                             gen_movcf_s(ctx, rs, rt, cc, 1);
15556                             break;
15557                         case FMT_SDPS_D:
15558                             gen_movcf_d(ctx, rs, rt, cc, 1);
15559                             break;
15560                         case FMT_SDPS_PS:
15561                             check_ps(ctx);
15562                             gen_movcf_ps(ctx, rs, rt, cc, 1);
15563                             break;
15564                         default:
15565                             goto pool32f_invalid;
15566                         }
15567                     }
15568                     break;
15569                 case PREFX:
15570                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15571                     break;
15572                 default:
15573                     goto pool32f_invalid;
15574                 }
15575                 break;
15576 #define FINSN_3ARG_SDPS(prfx)                           \
15577                 switch ((ctx->opcode >> 8) & 0x3) {     \
15578                 case FMT_SDPS_S:                        \
15579                     mips32_op = OPC_##prfx##_S;         \
15580                     goto do_fpop;                       \
15581                 case FMT_SDPS_D:                        \
15582                     mips32_op = OPC_##prfx##_D;         \
15583                     goto do_fpop;                       \
15584                 case FMT_SDPS_PS:                       \
15585                     check_ps(ctx);                      \
15586                     mips32_op = OPC_##prfx##_PS;        \
15587                     goto do_fpop;                       \
15588                 default:                                \
15589                     goto pool32f_invalid;               \
15590                 }
15591             case MINA_FMT:
15592                 check_insn(ctx, ISA_MIPS32R6);
15593                 switch ((ctx->opcode >> 9) & 0x3) {
15594                 case FMT_SDPS_S:
15595                     gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
15596                     break;
15597                 case FMT_SDPS_D:
15598                     gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
15599                     break;
15600                 default:
15601                     goto pool32f_invalid;
15602                 }
15603                 break;
15604             case MAXA_FMT:
15605                 check_insn(ctx, ISA_MIPS32R6);
15606                 switch ((ctx->opcode >> 9) & 0x3) {
15607                 case FMT_SDPS_S:
15608                     gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
15609                     break;
15610                 case FMT_SDPS_D:
15611                     gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
15612                     break;
15613                 default:
15614                     goto pool32f_invalid;
15615                 }
15616                 break;
15617             case 0x30:
15618                 /* regular FP ops */
15619                 switch ((ctx->opcode >> 6) & 0x3) {
15620                 case ADD_FMT:
15621                     FINSN_3ARG_SDPS(ADD);
15622                     break;
15623                 case SUB_FMT:
15624                     FINSN_3ARG_SDPS(SUB);
15625                     break;
15626                 case MUL_FMT:
15627                     FINSN_3ARG_SDPS(MUL);
15628                     break;
15629                 case DIV_FMT:
15630                     fmt = (ctx->opcode >> 8) & 0x3;
15631                     if (fmt == 1) {
15632                         mips32_op = OPC_DIV_D;
15633                     } else if (fmt == 0) {
15634                         mips32_op = OPC_DIV_S;
15635                     } else {
15636                         goto pool32f_invalid;
15637                     }
15638                     goto do_fpop;
15639                 default:
15640                     goto pool32f_invalid;
15641                 }
15642                 break;
15643             case 0x38:
15644                 /* cmovs */
15645                 switch ((ctx->opcode >> 6) & 0x7) {
15646                 case MOVN_FMT: /* SELEQZ_FMT */
15647                     if (ctx->insn_flags & ISA_MIPS32R6) {
15648                         /* SELEQZ_FMT */
15649                         switch ((ctx->opcode >> 9) & 0x3) {
15650                         case FMT_SDPS_S:
15651                             gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
15652                             break;
15653                         case FMT_SDPS_D:
15654                             gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
15655                             break;
15656                         default:
15657                             goto pool32f_invalid;
15658                         }
15659                     } else {
15660                         /* MOVN_FMT */
15661                         FINSN_3ARG_SDPS(MOVN);
15662                     }
15663                     break;
15664                 case MOVN_FMT_04:
15665                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15666                     FINSN_3ARG_SDPS(MOVN);
15667                     break;
15668                 case MOVZ_FMT: /* SELNEZ_FMT */
15669                     if (ctx->insn_flags & ISA_MIPS32R6) {
15670                         /* SELNEZ_FMT */
15671                         switch ((ctx->opcode >> 9) & 0x3) {
15672                         case FMT_SDPS_S:
15673                             gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
15674                             break;
15675                         case FMT_SDPS_D:
15676                             gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
15677                             break;
15678                         default:
15679                             goto pool32f_invalid;
15680                         }
15681                     } else {
15682                         /* MOVZ_FMT */
15683                         FINSN_3ARG_SDPS(MOVZ);
15684                     }
15685                     break;
15686                 case MOVZ_FMT_05:
15687                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
15688                     FINSN_3ARG_SDPS(MOVZ);
15689                     break;
15690                 case SEL_FMT:
15691                     check_insn(ctx, ISA_MIPS32R6);
15692                     switch ((ctx->opcode >> 9) & 0x3) {
15693                     case FMT_SDPS_S:
15694                         gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
15695                         break;
15696                     case FMT_SDPS_D:
15697                         gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
15698                         break;
15699                     default:
15700                         goto pool32f_invalid;
15701                     }
15702                     break;
15703                 case MADDF_FMT:
15704                     check_insn(ctx, ISA_MIPS32R6);
15705                     switch ((ctx->opcode >> 9) & 0x3) {
15706                     case FMT_SDPS_S:
15707                         mips32_op = OPC_MADDF_S;
15708                         goto do_fpop;
15709                     case FMT_SDPS_D:
15710                         mips32_op = OPC_MADDF_D;
15711                         goto do_fpop;
15712                     default:
15713                         goto pool32f_invalid;
15714                     }
15715                     break;
15716                 case MSUBF_FMT:
15717                     check_insn(ctx, ISA_MIPS32R6);
15718                     switch ((ctx->opcode >> 9) & 0x3) {
15719                     case FMT_SDPS_S:
15720                         mips32_op = OPC_MSUBF_S;
15721                         goto do_fpop;
15722                     case FMT_SDPS_D:
15723                         mips32_op = OPC_MSUBF_D;
15724                         goto do_fpop;
15725                     default:
15726                         goto pool32f_invalid;
15727                     }
15728                     break;
15729                 default:
15730                     goto pool32f_invalid;
15731                 }
15732                 break;
15733             do_fpop:
15734                 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15735                 break;
15736             default:
15737             pool32f_invalid:
15738                 MIPS_INVAL("pool32f");
15739                 generate_exception_end(ctx, EXCP_RI);
15740                 break;
15741             }
15742         } else {
15743             generate_exception_err(ctx, EXCP_CpU, 1);
15744         }
15745         break;
15746     case POOL32I:
15747         minor = (ctx->opcode >> 21) & 0x1f;
15748         switch (minor) {
15749         case BLTZ:
15750             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15751             gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
15752             break;
15753         case BLTZAL:
15754             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15755             gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
15756             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15757             break;
15758         case BLTZALS:
15759             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15760             gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
15761             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15762             break;
15763         case BGEZ:
15764             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15765             gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
15766             break;
15767         case BGEZAL:
15768             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15769             gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
15770             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15771             break;
15772         case BGEZALS:
15773             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15774             gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
15775             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15776             break;
15777         case BLEZ:
15778             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15779             gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
15780             break;
15781         case BGTZ:
15782             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15783             gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
15784             break;
15785
15786             /* Traps */
15787         case TLTI: /* BC1EQZC */
15788             if (ctx->insn_flags & ISA_MIPS32R6) {
15789                 /* BC1EQZC */
15790                 check_cp1_enabled(ctx);
15791                 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
15792             } else {
15793                 /* TLTI */
15794                 mips32_op = OPC_TLTI;
15795                 goto do_trapi;
15796             }
15797             break;
15798         case TGEI: /* BC1NEZC */
15799             if (ctx->insn_flags & ISA_MIPS32R6) {
15800                 /* BC1NEZC */
15801                 check_cp1_enabled(ctx);
15802                 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
15803             } else {
15804                 /* TGEI */
15805                 mips32_op = OPC_TGEI;
15806                 goto do_trapi;
15807             }
15808             break;
15809         case TLTIU:
15810             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15811             mips32_op = OPC_TLTIU;
15812             goto do_trapi;
15813         case TGEIU:
15814             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15815             mips32_op = OPC_TGEIU;
15816             goto do_trapi;
15817         case TNEI: /* SYNCI */
15818             if (ctx->insn_flags & ISA_MIPS32R6) {
15819                 /* SYNCI */
15820                 /* Break the TB to be able to sync copied instructions
15821                    immediately */
15822                 ctx->base.is_jmp = DISAS_STOP;
15823             } else {
15824                 /* TNEI */
15825                 mips32_op = OPC_TNEI;
15826                 goto do_trapi;
15827             }
15828             break;
15829         case TEQI:
15830             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15831             mips32_op = OPC_TEQI;
15832         do_trapi:
15833             gen_trap(ctx, mips32_op, rs, -1, imm);
15834             break;
15835
15836         case BNEZC:
15837         case BEQZC:
15838             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15839             gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
15840                                4, rs, 0, imm << 1, 0);
15841             /* Compact branches don't have a delay slot, so just let
15842                the normal delay slot handling take us to the branch
15843                target. */
15844             break;
15845         case LUI:
15846             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15847             gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
15848             break;
15849         case SYNCI:
15850             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15851             /* Break the TB to be able to sync copied instructions
15852                immediately */
15853             ctx->base.is_jmp = DISAS_STOP;
15854             break;
15855         case BC2F:
15856         case BC2T:
15857             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15858             /* COP2: Not implemented. */
15859             generate_exception_err(ctx, EXCP_CpU, 2);
15860             break;
15861         case BC1F:
15862             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15863             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
15864             goto do_cp1branch;
15865         case BC1T:
15866             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15867             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
15868             goto do_cp1branch;
15869         case BC1ANY4F:
15870             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15871             mips32_op = OPC_BC1FANY4;
15872             goto do_cp1mips3d;
15873         case BC1ANY4T:
15874             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15875             mips32_op = OPC_BC1TANY4;
15876         do_cp1mips3d:
15877             check_cop1x(ctx);
15878             check_insn(ctx, ASE_MIPS3D);
15879             /* Fall through */
15880         do_cp1branch:
15881             if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15882                 check_cp1_enabled(ctx);
15883                 gen_compute_branch1(ctx, mips32_op,
15884                                     (ctx->opcode >> 18) & 0x7, imm << 1);
15885             } else {
15886                 generate_exception_err(ctx, EXCP_CpU, 1);
15887             }
15888             break;
15889         case BPOSGE64:
15890         case BPOSGE32:
15891             /* MIPS DSP: not implemented */
15892             /* Fall through */
15893         default:
15894             MIPS_INVAL("pool32i");
15895             generate_exception_end(ctx, EXCP_RI);
15896             break;
15897         }
15898         break;
15899     case POOL32C:
15900         minor = (ctx->opcode >> 12) & 0xf;
15901         offset = sextract32(ctx->opcode, 0,
15902                             (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
15903         switch (minor) {
15904         case LWL:
15905             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15906             mips32_op = OPC_LWL;
15907             goto do_ld_lr;
15908         case SWL:
15909             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15910             mips32_op = OPC_SWL;
15911             goto do_st_lr;
15912         case LWR:
15913             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15914             mips32_op = OPC_LWR;
15915             goto do_ld_lr;
15916         case SWR:
15917             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15918             mips32_op = OPC_SWR;
15919             goto do_st_lr;
15920 #if defined(TARGET_MIPS64)
15921         case LDL:
15922             check_insn(ctx, ISA_MIPS3);
15923             check_mips_64(ctx);
15924             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15925             mips32_op = OPC_LDL;
15926             goto do_ld_lr;
15927         case SDL:
15928             check_insn(ctx, ISA_MIPS3);
15929             check_mips_64(ctx);
15930             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15931             mips32_op = OPC_SDL;
15932             goto do_st_lr;
15933         case LDR:
15934             check_insn(ctx, ISA_MIPS3);
15935             check_mips_64(ctx);
15936             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15937             mips32_op = OPC_LDR;
15938             goto do_ld_lr;
15939         case SDR:
15940             check_insn(ctx, ISA_MIPS3);
15941             check_mips_64(ctx);
15942             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15943             mips32_op = OPC_SDR;
15944             goto do_st_lr;
15945         case LWU:
15946             check_insn(ctx, ISA_MIPS3);
15947             check_mips_64(ctx);
15948             mips32_op = OPC_LWU;
15949             goto do_ld_lr;
15950         case LLD:
15951             check_insn(ctx, ISA_MIPS3);
15952             check_mips_64(ctx);
15953             mips32_op = OPC_LLD;
15954             goto do_ld_lr;
15955 #endif
15956         case LL:
15957             mips32_op = OPC_LL;
15958             goto do_ld_lr;
15959         do_ld_lr:
15960             gen_ld(ctx, mips32_op, rt, rs, offset);
15961             break;
15962         do_st_lr:
15963             gen_st(ctx, mips32_op, rt, rs, offset);
15964             break;
15965         case SC:
15966             gen_st_cond(ctx, OPC_SC, rt, rs, offset);
15967             break;
15968 #if defined(TARGET_MIPS64)
15969         case SCD:
15970             check_insn(ctx, ISA_MIPS3);
15971             check_mips_64(ctx);
15972             gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
15973             break;
15974 #endif
15975         case LD_EVA:
15976             if (!ctx->eva) {
15977                 MIPS_INVAL("pool32c ld-eva");
15978                 generate_exception_end(ctx, EXCP_RI);
15979                 break;
15980             }
15981             check_cp0_enabled(ctx);
15982
15983             minor2 = (ctx->opcode >> 9) & 0x7;
15984             offset = sextract32(ctx->opcode, 0, 9);
15985             switch (minor2) {
15986             case LBUE:
15987                 mips32_op = OPC_LBUE;
15988                 goto do_ld_lr;
15989             case LHUE:
15990                 mips32_op = OPC_LHUE;
15991                 goto do_ld_lr;
15992             case LWLE:
15993                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15994                 mips32_op = OPC_LWLE;
15995                 goto do_ld_lr;
15996             case LWRE:
15997                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15998                 mips32_op = OPC_LWRE;
15999                 goto do_ld_lr;
16000             case LBE:
16001                 mips32_op = OPC_LBE;
16002                 goto do_ld_lr;
16003             case LHE:
16004                 mips32_op = OPC_LHE;
16005                 goto do_ld_lr;
16006             case LLE:
16007                 mips32_op = OPC_LLE;
16008                 goto do_ld_lr;
16009             case LWE:
16010                 mips32_op = OPC_LWE;
16011                 goto do_ld_lr;
16012             };
16013             break;
16014         case ST_EVA:
16015             if (!ctx->eva) {
16016                 MIPS_INVAL("pool32c st-eva");
16017                 generate_exception_end(ctx, EXCP_RI);
16018                 break;
16019             }
16020             check_cp0_enabled(ctx);
16021
16022             minor2 = (ctx->opcode >> 9) & 0x7;
16023             offset = sextract32(ctx->opcode, 0, 9);
16024             switch (minor2) {
16025             case SWLE:
16026                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16027                 mips32_op = OPC_SWLE;
16028                 goto do_st_lr;
16029             case SWRE:
16030                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16031                 mips32_op = OPC_SWRE;
16032                 goto do_st_lr;
16033             case PREFE:
16034                 /* Treat as no-op */
16035                 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16036                     /* hint codes 24-31 are reserved and signal RI */
16037                     generate_exception(ctx, EXCP_RI);
16038                 }
16039                 break;
16040             case CACHEE:
16041                 /* Treat as no-op */
16042                 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16043                     gen_cache_operation(ctx, rt, rs, offset);
16044                 }
16045                 break;
16046             case SBE:
16047                 mips32_op = OPC_SBE;
16048                 goto do_st_lr;
16049             case SHE:
16050                 mips32_op = OPC_SHE;
16051                 goto do_st_lr;
16052             case SCE:
16053                 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
16054                 break;
16055             case SWE:
16056                 mips32_op = OPC_SWE;
16057                 goto do_st_lr;
16058             };
16059             break;
16060         case PREF:
16061             /* Treat as no-op */
16062             if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16063                 /* hint codes 24-31 are reserved and signal RI */
16064                 generate_exception(ctx, EXCP_RI);
16065             }
16066             break;
16067         default:
16068             MIPS_INVAL("pool32c");
16069             generate_exception_end(ctx, EXCP_RI);
16070             break;
16071         }
16072         break;
16073     case ADDI32: /* AUI, LUI */
16074         if (ctx->insn_flags & ISA_MIPS32R6) {
16075             /* AUI, LUI */
16076             gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
16077         } else {
16078             /* ADDI32 */
16079             mips32_op = OPC_ADDI;
16080             goto do_addi;
16081         }
16082         break;
16083     case ADDIU32:
16084         mips32_op = OPC_ADDIU;
16085     do_addi:
16086         gen_arith_imm(ctx, mips32_op, rt, rs, imm);
16087         break;
16088
16089         /* Logical operations */
16090     case ORI32:
16091         mips32_op = OPC_ORI;
16092         goto do_logici;
16093     case XORI32:
16094         mips32_op = OPC_XORI;
16095         goto do_logici;
16096     case ANDI32:
16097         mips32_op = OPC_ANDI;
16098     do_logici:
16099         gen_logic_imm(ctx, mips32_op, rt, rs, imm);
16100         break;
16101
16102         /* Set less than immediate */
16103     case SLTI32:
16104         mips32_op = OPC_SLTI;
16105         goto do_slti;
16106     case SLTIU32:
16107         mips32_op = OPC_SLTIU;
16108     do_slti:
16109         gen_slt_imm(ctx, mips32_op, rt, rs, imm);
16110         break;
16111     case JALX32:
16112         check_insn_opc_removed(ctx, ISA_MIPS32R6);
16113         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
16114         gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
16115         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16116         break;
16117     case JALS32: /* BOVC, BEQC, BEQZALC */
16118         if (ctx->insn_flags & ISA_MIPS32R6) {
16119             if (rs >= rt) {
16120                 /* BOVC */
16121                 mips32_op = OPC_BOVC;
16122             } else if (rs < rt && rs == 0) {
16123                 /* BEQZALC */
16124                 mips32_op = OPC_BEQZALC;
16125             } else {
16126                 /* BEQC */
16127                 mips32_op = OPC_BEQC;
16128             }
16129             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16130         } else {
16131             /* JALS32 */
16132             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
16133             gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
16134             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16135         }
16136         break;
16137     case BEQ32: /* BC */
16138         if (ctx->insn_flags & ISA_MIPS32R6) {
16139             /* BC */
16140             gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
16141                                        sextract32(ctx->opcode << 1, 0, 27));
16142         } else {
16143             /* BEQ32 */
16144             gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
16145         }
16146         break;
16147     case BNE32: /* BALC */
16148         if (ctx->insn_flags & ISA_MIPS32R6) {
16149             /* BALC */
16150             gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
16151                                        sextract32(ctx->opcode << 1, 0, 27));
16152         } else {
16153             /* BNE32 */
16154             gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
16155         }
16156         break;
16157     case J32: /* BGTZC, BLTZC, BLTC */
16158         if (ctx->insn_flags & ISA_MIPS32R6) {
16159             if (rs == 0 && rt != 0) {
16160                 /* BGTZC */
16161                 mips32_op = OPC_BGTZC;
16162             } else if (rs != 0 && rt != 0 && rs == rt) {
16163                 /* BLTZC */
16164                 mips32_op = OPC_BLTZC;
16165             } else {
16166                 /* BLTC */
16167                 mips32_op = OPC_BLTC;
16168             }
16169             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16170         } else {
16171             /* J32 */
16172             gen_compute_branch(ctx, OPC_J, 4, rt, rs,
16173                                (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16174         }
16175         break;
16176     case JAL32: /* BLEZC, BGEZC, BGEC */
16177         if (ctx->insn_flags & ISA_MIPS32R6) {
16178             if (rs == 0 && rt != 0) {
16179                 /* BLEZC */
16180                 mips32_op = OPC_BLEZC;
16181             } else if (rs != 0 && rt != 0 && rs == rt) {
16182                 /* BGEZC */
16183                 mips32_op = OPC_BGEZC;
16184             } else {
16185                 /* BGEC */
16186                 mips32_op = OPC_BGEC;
16187             }
16188             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16189         } else {
16190             /* JAL32 */
16191             gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
16192                                (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16193             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16194         }
16195         break;
16196         /* Floating point (COP1) */
16197     case LWC132:
16198         mips32_op = OPC_LWC1;
16199         goto do_cop1;
16200     case LDC132:
16201         mips32_op = OPC_LDC1;
16202         goto do_cop1;
16203     case SWC132:
16204         mips32_op = OPC_SWC1;
16205         goto do_cop1;
16206     case SDC132:
16207         mips32_op = OPC_SDC1;
16208     do_cop1:
16209         gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
16210         break;
16211     case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16212         if (ctx->insn_flags & ISA_MIPS32R6) {
16213             /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16214             switch ((ctx->opcode >> 16) & 0x1f) {
16215             case ADDIUPC_00:
16216             case ADDIUPC_01:
16217             case ADDIUPC_02:
16218             case ADDIUPC_03:
16219             case ADDIUPC_04:
16220             case ADDIUPC_05:
16221             case ADDIUPC_06:
16222             case ADDIUPC_07:
16223                 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
16224                 break;
16225             case AUIPC:
16226                 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
16227                 break;
16228             case ALUIPC:
16229                 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
16230                 break;
16231             case LWPC_08:
16232             case LWPC_09:
16233             case LWPC_0A:
16234             case LWPC_0B:
16235             case LWPC_0C:
16236             case LWPC_0D:
16237             case LWPC_0E:
16238             case LWPC_0F:
16239                 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
16240                 break;
16241             default:
16242                 generate_exception(ctx, EXCP_RI);
16243                 break;
16244             }
16245         } else {
16246             /* ADDIUPC */
16247             int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
16248             offset = SIMM(ctx->opcode, 0, 23) << 2;
16249
16250             gen_addiupc(ctx, reg, offset, 0, 0);
16251         }
16252         break;
16253     case BNVC: /* BNEC, BNEZALC */
16254         check_insn(ctx, ISA_MIPS32R6);
16255         if (rs >= rt) {
16256             /* BNVC */
16257             mips32_op = OPC_BNVC;
16258         } else if (rs < rt && rs == 0) {
16259             /* BNEZALC */
16260             mips32_op = OPC_BNEZALC;
16261         } else {
16262             /* BNEC */
16263             mips32_op = OPC_BNEC;
16264         }
16265         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16266         break;
16267     case R6_BNEZC: /* JIALC */
16268         check_insn(ctx, ISA_MIPS32R6);
16269         if (rt != 0) {
16270             /* BNEZC */
16271             gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
16272                                        sextract32(ctx->opcode << 1, 0, 22));
16273         } else {
16274             /* JIALC */
16275             gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
16276         }
16277         break;
16278     case R6_BEQZC: /* JIC */
16279         check_insn(ctx, ISA_MIPS32R6);
16280         if (rt != 0) {
16281             /* BEQZC */
16282             gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
16283                                        sextract32(ctx->opcode << 1, 0, 22));
16284         } else {
16285             /* JIC */
16286             gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
16287         }
16288         break;
16289     case BLEZALC: /* BGEZALC, BGEUC */
16290         check_insn(ctx, ISA_MIPS32R6);
16291         if (rs == 0 && rt != 0) {
16292             /* BLEZALC */
16293             mips32_op = OPC_BLEZALC;
16294         } else if (rs != 0 && rt != 0 && rs == rt) {
16295             /* BGEZALC */
16296             mips32_op = OPC_BGEZALC;
16297         } else {
16298             /* BGEUC */
16299             mips32_op = OPC_BGEUC;
16300         }
16301         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16302         break;
16303     case BGTZALC: /* BLTZALC, BLTUC */
16304         check_insn(ctx, ISA_MIPS32R6);
16305         if (rs == 0 && rt != 0) {
16306             /* BGTZALC */
16307             mips32_op = OPC_BGTZALC;
16308         } else if (rs != 0 && rt != 0 && rs == rt) {
16309             /* BLTZALC */
16310             mips32_op = OPC_BLTZALC;
16311         } else {
16312             /* BLTUC */
16313             mips32_op = OPC_BLTUC;
16314         }
16315         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16316         break;
16317         /* Loads and stores */
16318     case LB32:
16319         mips32_op = OPC_LB;
16320         goto do_ld;
16321     case LBU32:
16322         mips32_op = OPC_LBU;
16323         goto do_ld;
16324     case LH32:
16325         mips32_op = OPC_LH;
16326         goto do_ld;
16327     case LHU32:
16328         mips32_op = OPC_LHU;
16329         goto do_ld;
16330     case LW32:
16331         mips32_op = OPC_LW;
16332         goto do_ld;
16333 #ifdef TARGET_MIPS64
16334     case LD32:
16335         check_insn(ctx, ISA_MIPS3);
16336         check_mips_64(ctx);
16337         mips32_op = OPC_LD;
16338         goto do_ld;
16339     case SD32:
16340         check_insn(ctx, ISA_MIPS3);
16341         check_mips_64(ctx);
16342         mips32_op = OPC_SD;
16343         goto do_st;
16344 #endif
16345     case SB32:
16346         mips32_op = OPC_SB;
16347         goto do_st;
16348     case SH32:
16349         mips32_op = OPC_SH;
16350         goto do_st;
16351     case SW32:
16352         mips32_op = OPC_SW;
16353         goto do_st;
16354     do_ld:
16355         gen_ld(ctx, mips32_op, rt, rs, imm);
16356         break;
16357     do_st:
16358         gen_st(ctx, mips32_op, rt, rs, imm);
16359         break;
16360     default:
16361         generate_exception_end(ctx, EXCP_RI);
16362         break;
16363     }
16364 }
16365
16366 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
16367 {
16368     uint32_t op;
16369
16370     /* make sure instructions are on a halfword boundary */
16371     if (ctx->base.pc_next & 0x1) {
16372         env->CP0_BadVAddr = ctx->base.pc_next;
16373         generate_exception_end(ctx, EXCP_AdEL);
16374         return 2;
16375     }
16376
16377     op = (ctx->opcode >> 10) & 0x3f;
16378     /* Enforce properly-sized instructions in a delay slot */
16379     if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
16380         switch (op & 0x7) { /* MSB-3..MSB-5 */
16381         case 0:
16382         /* POOL32A, POOL32B, POOL32I, POOL32C */
16383         case 4:
16384         /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
16385         case 5:
16386         /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
16387         case 6:
16388         /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
16389         case 7:
16390         /* LB32, LH32, LWC132, LDC132, LW32 */
16391             if (ctx->hflags & MIPS_HFLAG_BDS16) {
16392                 generate_exception_end(ctx, EXCP_RI);
16393                 return 2;
16394             }
16395             break;
16396         case 1:
16397         /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
16398         case 2:
16399         /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
16400         case 3:
16401         /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
16402             if (ctx->hflags & MIPS_HFLAG_BDS32) {
16403                 generate_exception_end(ctx, EXCP_RI);
16404                 return 2;
16405             }
16406             break;
16407         }
16408     }
16409
16410     switch (op) {
16411     case POOL16A:
16412         {
16413             int rd = mmreg(uMIPS_RD(ctx->opcode));
16414             int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
16415             int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
16416             uint32_t opc = 0;
16417
16418             switch (ctx->opcode & 0x1) {
16419             case ADDU16:
16420                 opc = OPC_ADDU;
16421                 break;
16422             case SUBU16:
16423                 opc = OPC_SUBU;
16424                 break;
16425             }
16426             if (ctx->insn_flags & ISA_MIPS32R6) {
16427                 /* In the Release 6 the register number location in
16428                  * the instruction encoding has changed.
16429                  */
16430                 gen_arith(ctx, opc, rs1, rd, rs2);
16431             } else {
16432                 gen_arith(ctx, opc, rd, rs1, rs2);
16433             }
16434         }
16435         break;
16436     case POOL16B:
16437         {
16438             int rd = mmreg(uMIPS_RD(ctx->opcode));
16439             int rs = mmreg(uMIPS_RS(ctx->opcode));
16440             int amount = (ctx->opcode >> 1) & 0x7;
16441             uint32_t opc = 0;
16442             amount = amount == 0 ? 8 : amount;
16443
16444             switch (ctx->opcode & 0x1) {
16445             case SLL16:
16446                 opc = OPC_SLL;
16447                 break;
16448             case SRL16:
16449                 opc = OPC_SRL;
16450                 break;
16451             }
16452
16453             gen_shift_imm(ctx, opc, rd, rs, amount);
16454         }
16455         break;
16456     case POOL16C:
16457         if (ctx->insn_flags & ISA_MIPS32R6) {
16458             gen_pool16c_r6_insn(ctx);
16459         } else {
16460             gen_pool16c_insn(ctx);
16461         }
16462         break;
16463     case LWGP16:
16464         {
16465             int rd = mmreg(uMIPS_RD(ctx->opcode));
16466             int rb = 28;            /* GP */
16467             int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
16468
16469             gen_ld(ctx, OPC_LW, rd, rb, offset);
16470         }
16471         break;
16472     case POOL16F:
16473         check_insn_opc_removed(ctx, ISA_MIPS32R6);
16474         if (ctx->opcode & 1) {
16475             generate_exception_end(ctx, EXCP_RI);
16476         } else {
16477             /* MOVEP */
16478             int enc_dest = uMIPS_RD(ctx->opcode);
16479             int enc_rt = uMIPS_RS2(ctx->opcode);
16480             int enc_rs = uMIPS_RS1(ctx->opcode);
16481             gen_movep(ctx, enc_dest, enc_rt, enc_rs);
16482         }
16483         break;
16484     case LBU16:
16485         {
16486             int rd = mmreg(uMIPS_RD(ctx->opcode));
16487             int rb = mmreg(uMIPS_RS(ctx->opcode));
16488             int16_t offset = ZIMM(ctx->opcode, 0, 4);
16489             offset = (offset == 0xf ? -1 : offset);
16490
16491             gen_ld(ctx, OPC_LBU, rd, rb, offset);
16492         }
16493         break;
16494     case LHU16:
16495         {
16496             int rd = mmreg(uMIPS_RD(ctx->opcode));
16497             int rb = mmreg(uMIPS_RS(ctx->opcode));
16498             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
16499
16500             gen_ld(ctx, OPC_LHU, rd, rb, offset);
16501         }
16502         break;
16503     case LWSP16:
16504         {
16505             int rd = (ctx->opcode >> 5) & 0x1f;
16506             int rb = 29;            /* SP */
16507             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
16508
16509             gen_ld(ctx, OPC_LW, rd, rb, offset);
16510         }
16511         break;
16512     case LW16:
16513         {
16514             int rd = mmreg(uMIPS_RD(ctx->opcode));
16515             int rb = mmreg(uMIPS_RS(ctx->opcode));
16516             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
16517
16518             gen_ld(ctx, OPC_LW, rd, rb, offset);
16519         }
16520         break;
16521     case SB16:
16522         {
16523             int rd = mmreg2(uMIPS_RD(ctx->opcode));
16524             int rb = mmreg(uMIPS_RS(ctx->opcode));
16525             int16_t offset = ZIMM(ctx->opcode, 0, 4);
16526
16527             gen_st(ctx, OPC_SB, rd, rb, offset);
16528         }
16529         break;
16530     case SH16:
16531         {
16532             int rd = mmreg2(uMIPS_RD(ctx->opcode));
16533             int rb = mmreg(uMIPS_RS(ctx->opcode));
16534             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
16535
16536             gen_st(ctx, OPC_SH, rd, rb, offset);
16537         }
16538         break;
16539     case SWSP16:
16540         {
16541             int rd = (ctx->opcode >> 5) & 0x1f;
16542             int rb = 29;            /* SP */
16543             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
16544
16545             gen_st(ctx, OPC_SW, rd, rb, offset);
16546         }
16547         break;
16548     case SW16:
16549         {
16550             int rd = mmreg2(uMIPS_RD(ctx->opcode));
16551             int rb = mmreg(uMIPS_RS(ctx->opcode));
16552             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
16553
16554             gen_st(ctx, OPC_SW, rd, rb, offset);
16555         }
16556         break;
16557     case MOVE16:
16558         {
16559             int rd = uMIPS_RD5(ctx->opcode);
16560             int rs = uMIPS_RS5(ctx->opcode);
16561
16562             gen_arith(ctx, OPC_ADDU, rd, rs, 0);
16563         }
16564         break;
16565     case ANDI16:
16566         gen_andi16(ctx);
16567         break;
16568     case POOL16D:
16569         switch (ctx->opcode & 0x1) {
16570         case ADDIUS5:
16571             gen_addius5(ctx);
16572             break;
16573         case ADDIUSP:
16574             gen_addiusp(ctx);
16575             break;
16576         }
16577         break;
16578     case POOL16E:
16579         switch (ctx->opcode & 0x1) {
16580         case ADDIUR2:
16581             gen_addiur2(ctx);
16582             break;
16583         case ADDIUR1SP:
16584             gen_addiur1sp(ctx);
16585             break;
16586         }
16587         break;
16588     case B16: /* BC16 */
16589         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
16590                            sextract32(ctx->opcode, 0, 10) << 1,
16591                            (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
16592         break;
16593     case BNEZ16: /* BNEZC16 */
16594     case BEQZ16: /* BEQZC16 */
16595         gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
16596                            mmreg(uMIPS_RD(ctx->opcode)),
16597                            0, sextract32(ctx->opcode, 0, 7) << 1,
16598                            (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
16599
16600         break;
16601     case LI16:
16602         {
16603             int reg = mmreg(uMIPS_RD(ctx->opcode));
16604             int imm = ZIMM(ctx->opcode, 0, 7);
16605
16606             imm = (imm == 0x7f ? -1 : imm);
16607             tcg_gen_movi_tl(cpu_gpr[reg], imm);
16608         }
16609         break;
16610     case RES_29:
16611     case RES_31:
16612     case RES_39:
16613         generate_exception_end(ctx, EXCP_RI);
16614         break;
16615     default:
16616         decode_micromips32_opc(env, ctx);
16617         return 4;
16618     }
16619
16620     return 2;
16621 }
16622
16623 /*
16624  *
16625  * nanoMIPS opcodes
16626  *
16627  */
16628
16629 /* MAJOR, P16, and P32 pools opcodes */
16630 enum {
16631     NM_P_ADDIU      = 0x00,
16632     NM_ADDIUPC      = 0x01,
16633     NM_MOVE_BALC    = 0x02,
16634     NM_P16_MV       = 0x04,
16635     NM_LW16         = 0x05,
16636     NM_BC16         = 0x06,
16637     NM_P16_SR       = 0x07,
16638
16639     NM_POOL32A      = 0x08,
16640     NM_P_BAL        = 0x0a,
16641     NM_P16_SHIFT    = 0x0c,
16642     NM_LWSP16       = 0x0d,
16643     NM_BALC16       = 0x0e,
16644     NM_P16_4X4      = 0x0f,
16645
16646     NM_P_GP_W       = 0x10,
16647     NM_P_GP_BH      = 0x11,
16648     NM_P_J          = 0x12,
16649     NM_P16C         = 0x14,
16650     NM_LWGP16       = 0x15,
16651     NM_P16_LB       = 0x17,
16652
16653     NM_P48I         = 0x18,
16654     NM_P16_A1       = 0x1c,
16655     NM_LW4X4        = 0x1d,
16656     NM_P16_LH       = 0x1f,
16657
16658     NM_P_U12        = 0x20,
16659     NM_P_LS_U12     = 0x21,
16660     NM_P_BR1        = 0x22,
16661     NM_P16_A2       = 0x24,
16662     NM_SW16         = 0x25,
16663     NM_BEQZC16      = 0x26,
16664
16665     NM_POOL32F      = 0x28,
16666     NM_P_LS_S9      = 0x29,
16667     NM_P_BR2        = 0x2a,
16668
16669     NM_P16_ADDU     = 0x2c,
16670     NM_SWSP16       = 0x2d,
16671     NM_BNEZC16      = 0x2e,
16672     NM_MOVEP        = 0x2f,
16673
16674     NM_POOL32S      = 0x30,
16675     NM_P_BRI        = 0x32,
16676     NM_LI16         = 0x34,
16677     NM_SWGP16       = 0x35,
16678     NM_P16_BR       = 0x36,
16679
16680     NM_P_LUI        = 0x38,
16681     NM_ANDI16       = 0x3c,
16682     NM_SW4X4        = 0x3d,
16683     NM_MOVEPREV     = 0x3f,
16684 };
16685
16686 /* POOL32A instruction pool */
16687 enum {
16688     NM_POOL32A0    = 0x00,
16689     NM_SPECIAL2    = 0x01,
16690     NM_COP2_1      = 0x02,
16691     NM_UDI         = 0x03,
16692     NM_POOL32A5    = 0x05,
16693     NM_POOL32A7    = 0x07,
16694 };
16695
16696 /* P.GP.W instruction pool */
16697 enum {
16698     NM_ADDIUGP_W = 0x00,
16699     NM_LWGP      = 0x02,
16700     NM_SWGP      = 0x03,
16701 };
16702
16703 /* P48I instruction pool */
16704 enum {
16705     NM_LI48        = 0x00,
16706     NM_ADDIU48     = 0x01,
16707     NM_ADDIUGP48   = 0x02,
16708     NM_ADDIUPC48   = 0x03,
16709     NM_LWPC48      = 0x0b,
16710     NM_SWPC48      = 0x0f,
16711 };
16712
16713 /* P.U12 instruction pool */
16714 enum {
16715     NM_ORI      = 0x00,
16716     NM_XORI     = 0x01,
16717     NM_ANDI     = 0x02,
16718     NM_P_SR     = 0x03,
16719     NM_SLTI     = 0x04,
16720     NM_SLTIU    = 0x05,
16721     NM_SEQI     = 0x06,
16722     NM_ADDIUNEG = 0x08,
16723     NM_P_SHIFT  = 0x0c,
16724     NM_P_ROTX   = 0x0d,
16725     NM_P_INS    = 0x0e,
16726     NM_P_EXT    = 0x0f,
16727 };
16728
16729 /* POOL32F instruction pool */
16730 enum {
16731     NM_POOL32F_0   = 0x00,
16732     NM_POOL32F_3   = 0x03,
16733     NM_POOL32F_5   = 0x05,
16734 };
16735
16736 /* POOL32S instruction pool */
16737 enum {
16738     NM_POOL32S_0   = 0x00,
16739     NM_POOL32S_4   = 0x04,
16740 };
16741
16742 /* P.LUI instruction pool */
16743 enum {
16744     NM_LUI      = 0x00,
16745     NM_ALUIPC   = 0x01,
16746 };
16747
16748 /* P.GP.BH instruction pool */
16749 enum {
16750     NM_LBGP      = 0x00,
16751     NM_SBGP      = 0x01,
16752     NM_LBUGP     = 0x02,
16753     NM_ADDIUGP_B = 0x03,
16754     NM_P_GP_LH   = 0x04,
16755     NM_P_GP_SH   = 0x05,
16756     NM_P_GP_CP1  = 0x06,
16757 };
16758
16759 /* P.LS.U12 instruction pool */
16760 enum {
16761     NM_LB        = 0x00,
16762     NM_SB        = 0x01,
16763     NM_LBU       = 0x02,
16764     NM_P_PREFU12 = 0x03,
16765     NM_LH        = 0x04,
16766     NM_SH        = 0x05,
16767     NM_LHU       = 0x06,
16768     NM_LWU       = 0x07,
16769     NM_LW        = 0x08,
16770     NM_SW        = 0x09,
16771     NM_LWC1      = 0x0a,
16772     NM_SWC1      = 0x0b,
16773     NM_LDC1      = 0x0e,
16774     NM_SDC1      = 0x0f,
16775 };
16776
16777 /* P.LS.S9 instruction pool */
16778 enum {
16779     NM_P_LS_S0         = 0x00,
16780     NM_P_LS_S1         = 0x01,
16781     NM_P_LS_E0         = 0x02,
16782     NM_P_LS_WM         = 0x04,
16783     NM_P_LS_UAWM       = 0x05,
16784 };
16785
16786 /* P.BAL instruction pool */
16787 enum {
16788     NM_BC       = 0x00,
16789     NM_BALC     = 0x01,
16790 };
16791
16792 /* P.J instruction pool */
16793 enum {
16794     NM_JALRC    = 0x00,
16795     NM_JALRC_HB = 0x01,
16796     NM_P_BALRSC = 0x08,
16797 };
16798
16799 /* P.BR1 instruction pool */
16800 enum {
16801     NM_BEQC     = 0x00,
16802     NM_P_BR3A   = 0x01,
16803     NM_BGEC     = 0x02,
16804     NM_BGEUC    = 0x03,
16805 };
16806
16807 /* P.BR2 instruction pool */
16808 enum {
16809     NM_BNEC     = 0x00,
16810     NM_BLTC     = 0x02,
16811     NM_BLTUC    = 0x03,
16812 };
16813
16814 /* P.BRI instruction pool */
16815 enum {
16816     NM_BEQIC    = 0x00,
16817     NM_BBEQZC   = 0x01,
16818     NM_BGEIC    = 0x02,
16819     NM_BGEIUC   = 0x03,
16820     NM_BNEIC    = 0x04,
16821     NM_BBNEZC   = 0x05,
16822     NM_BLTIC    = 0x06,
16823     NM_BLTIUC   = 0x07,
16824 };
16825
16826 /* P16.SHIFT instruction pool */
16827 enum {
16828     NM_SLL16    = 0x00,
16829     NM_SRL16    = 0x01,
16830 };
16831
16832 /* POOL16C instruction pool */
16833 enum {
16834     NM_POOL16C_0  = 0x00,
16835     NM_LWXS16     = 0x01,
16836 };
16837
16838 /* P16.A1 instruction pool */
16839 enum {
16840     NM_ADDIUR1SP = 0x01,
16841 };
16842
16843 /* P16.A2 instruction pool */
16844 enum {
16845     NM_ADDIUR2  = 0x00,
16846     NM_P_ADDIURS5  = 0x01,
16847 };
16848
16849 /* P16.ADDU instruction pool */
16850 enum {
16851     NM_ADDU16     = 0x00,
16852     NM_SUBU16     = 0x01,
16853 };
16854
16855 /* P16.SR instruction pool */
16856 enum {
16857     NM_SAVE16        = 0x00,
16858     NM_RESTORE_JRC16 = 0x01,
16859 };
16860
16861 /* P16.4X4 instruction pool */
16862 enum {
16863     NM_ADDU4X4      = 0x00,
16864     NM_MUL4X4       = 0x01,
16865 };
16866
16867 /* P16.LB instruction pool */
16868 enum {
16869     NM_LB16       = 0x00,
16870     NM_SB16       = 0x01,
16871     NM_LBU16      = 0x02,
16872 };
16873
16874 /* P16.LH  instruction pool */
16875 enum {
16876     NM_LH16     = 0x00,
16877     NM_SH16     = 0x01,
16878     NM_LHU16    = 0x02,
16879 };
16880
16881 /* P.RI instruction pool */
16882 enum {
16883     NM_SIGRIE       = 0x00,
16884     NM_P_SYSCALL    = 0x01,
16885     NM_BREAK        = 0x02,
16886     NM_SDBBP        = 0x03,
16887 };
16888
16889 /* POOL32A0 instruction pool */
16890 enum {
16891     NM_P_TRAP   = 0x00,
16892     NM_SEB      = 0x01,
16893     NM_SLLV     = 0x02,
16894     NM_MUL      = 0x03,
16895     NM_MFC0     = 0x06,
16896     NM_MFHC0    = 0x07,
16897     NM_SEH      = 0x09,
16898     NM_SRLV     = 0x0a,
16899     NM_MUH      = 0x0b,
16900     NM_MTC0     = 0x0e,
16901     NM_MTHC0    = 0x0f,
16902     NM_SRAV     = 0x12,
16903     NM_MULU     = 0x13,
16904     NM_ROTRV    = 0x1a,
16905     NM_MUHU     = 0x1b,
16906     NM_ADD      = 0x22,
16907     NM_DIV      = 0x23,
16908     NM_ADDU     = 0x2a,
16909     NM_MOD      = 0x2b,
16910     NM_SUB      = 0x32,
16911     NM_DIVU     = 0x33,
16912     NM_RDHWR    = 0x38,
16913     NM_SUBU     = 0x3a,
16914     NM_MODU     = 0x3b,
16915     NM_P_CMOVE  = 0x42,
16916     NM_FORK     = 0x45,
16917     NM_MFTR     = 0x46,
16918     NM_MFHTR    = 0x47,
16919     NM_AND      = 0x4a,
16920     NM_YIELD    = 0x4d,
16921     NM_MTTR     = 0x4e,
16922     NM_MTHTR    = 0x4f,
16923     NM_OR       = 0x52,
16924     NM_D_E_MT_VPE = 0x56,
16925     NM_NOR      = 0x5a,
16926     NM_XOR      = 0x62,
16927     NM_SLT      = 0x6a,
16928     NM_P_SLTU   = 0x72,
16929     NM_SOV      = 0x7a,
16930 };
16931
16932 /* POOL32A5 instruction pool */
16933 enum {
16934     NM_CMP_EQ_PH        = 0x00,
16935     NM_CMP_LT_PH        = 0x08,
16936     NM_CMP_LE_PH        = 0x10,
16937     NM_CMPGU_EQ_QB      = 0x18,
16938     NM_CMPGU_LT_QB      = 0x20,
16939     NM_CMPGU_LE_QB      = 0x28,
16940     NM_CMPGDU_EQ_QB     = 0x30,
16941     NM_CMPGDU_LT_QB     = 0x38,
16942     NM_CMPGDU_LE_QB     = 0x40,
16943     NM_CMPU_EQ_QB       = 0x48,
16944     NM_CMPU_LT_QB       = 0x50,
16945     NM_CMPU_LE_QB       = 0x58,
16946     NM_ADDQ_S_W         = 0x60,
16947     NM_SUBQ_S_W         = 0x68,
16948     NM_ADDSC            = 0x70,
16949     NM_ADDWC            = 0x78,
16950
16951     NM_ADDQ_S_PH   = 0x01,
16952     NM_ADDQH_R_PH  = 0x09,
16953     NM_ADDQH_R_W   = 0x11,
16954     NM_ADDU_S_QB   = 0x19,
16955     NM_ADDU_S_PH   = 0x21,
16956     NM_ADDUH_R_QB  = 0x29,
16957     NM_SHRAV_R_PH  = 0x31,
16958     NM_SHRAV_R_QB  = 0x39,
16959     NM_SUBQ_S_PH   = 0x41,
16960     NM_SUBQH_R_PH  = 0x49,
16961     NM_SUBQH_R_W   = 0x51,
16962     NM_SUBU_S_QB   = 0x59,
16963     NM_SUBU_S_PH   = 0x61,
16964     NM_SUBUH_R_QB  = 0x69,
16965     NM_SHLLV_S_PH  = 0x71,
16966     NM_PRECR_SRA_R_PH_W = 0x79,
16967
16968     NM_MULEU_S_PH_QBL   = 0x12,
16969     NM_MULEU_S_PH_QBR   = 0x1a,
16970     NM_MULQ_RS_PH       = 0x22,
16971     NM_MULQ_S_PH        = 0x2a,
16972     NM_MULQ_RS_W        = 0x32,
16973     NM_MULQ_S_W         = 0x3a,
16974     NM_APPEND           = 0x42,
16975     NM_MODSUB           = 0x52,
16976     NM_SHRAV_R_W        = 0x5a,
16977     NM_SHRLV_PH         = 0x62,
16978     NM_SHRLV_QB         = 0x6a,
16979     NM_SHLLV_QB         = 0x72,
16980     NM_SHLLV_S_W        = 0x7a,
16981
16982     NM_SHILO            = 0x03,
16983
16984     NM_MULEQ_S_W_PHL    = 0x04,
16985     NM_MULEQ_S_W_PHR    = 0x0c,
16986
16987     NM_MUL_S_PH         = 0x05,
16988     NM_PRECR_QB_PH      = 0x0d,
16989     NM_PRECRQ_QB_PH     = 0x15,
16990     NM_PRECRQ_PH_W      = 0x1d,
16991     NM_PRECRQ_RS_PH_W   = 0x25,
16992     NM_PRECRQU_S_QB_PH  = 0x2d,
16993     NM_PACKRL_PH        = 0x35,
16994     NM_PICK_QB          = 0x3d,
16995     NM_PICK_PH          = 0x45,
16996
16997     NM_SHRA_R_W         = 0x5e,
16998     NM_SHRA_R_PH        = 0x66,
16999     NM_SHLL_S_PH        = 0x76,
17000     NM_SHLL_S_W         = 0x7e,
17001
17002     NM_REPL_PH          = 0x07
17003 };
17004
17005 /* POOL32A7 instruction pool */
17006 enum {
17007     NM_P_LSX        = 0x00,
17008     NM_LSA          = 0x01,
17009     NM_EXTW         = 0x03,
17010     NM_POOL32AXF    = 0x07,
17011 };
17012
17013 /* P.SR instruction pool */
17014 enum {
17015     NM_PP_SR           = 0x00,
17016     NM_P_SR_F          = 0x01,
17017 };
17018
17019 /* P.SHIFT instruction pool */
17020 enum {
17021     NM_P_SLL        = 0x00,
17022     NM_SRL          = 0x02,
17023     NM_SRA          = 0x04,
17024     NM_ROTR         = 0x06,
17025 };
17026
17027 /* P.ROTX instruction pool */
17028 enum {
17029     NM_ROTX         = 0x00,
17030 };
17031
17032 /* P.INS instruction pool */
17033 enum {
17034     NM_INS          = 0x00,
17035 };
17036
17037 /* P.EXT instruction pool */
17038 enum {
17039     NM_EXT          = 0x00,
17040 };
17041
17042 /* POOL32F_0 (fmt) instruction pool */
17043 enum {
17044     NM_RINT_S              = 0x04,
17045     NM_RINT_D              = 0x44,
17046     NM_ADD_S               = 0x06,
17047     NM_SELEQZ_S            = 0x07,
17048     NM_SELEQZ_D            = 0x47,
17049     NM_CLASS_S             = 0x0c,
17050     NM_CLASS_D             = 0x4c,
17051     NM_SUB_S               = 0x0e,
17052     NM_SELNEZ_S            = 0x0f,
17053     NM_SELNEZ_D            = 0x4f,
17054     NM_MUL_S               = 0x16,
17055     NM_SEL_S               = 0x17,
17056     NM_SEL_D               = 0x57,
17057     NM_DIV_S               = 0x1e,
17058     NM_ADD_D               = 0x26,
17059     NM_SUB_D               = 0x2e,
17060     NM_MUL_D               = 0x36,
17061     NM_MADDF_S             = 0x37,
17062     NM_MADDF_D             = 0x77,
17063     NM_DIV_D               = 0x3e,
17064     NM_MSUBF_S             = 0x3f,
17065     NM_MSUBF_D             = 0x7f,
17066 };
17067
17068 /* POOL32F_3  instruction pool */
17069 enum {
17070     NM_MIN_FMT         = 0x00,
17071     NM_MAX_FMT         = 0x01,
17072     NM_MINA_FMT        = 0x04,
17073     NM_MAXA_FMT        = 0x05,
17074     NM_POOL32FXF       = 0x07,
17075 };
17076
17077 /* POOL32F_5  instruction pool */
17078 enum {
17079     NM_CMP_CONDN_S     = 0x00,
17080     NM_CMP_CONDN_D     = 0x02,
17081 };
17082
17083 /* P.GP.LH instruction pool */
17084 enum {
17085     NM_LHGP    = 0x00,
17086     NM_LHUGP   = 0x01,
17087 };
17088
17089 /* P.GP.SH instruction pool */
17090 enum {
17091     NM_SHGP    = 0x00,
17092 };
17093
17094 /* P.GP.CP1 instruction pool */
17095 enum {
17096     NM_LWC1GP       = 0x00,
17097     NM_SWC1GP       = 0x01,
17098     NM_LDC1GP       = 0x02,
17099     NM_SDC1GP       = 0x03,
17100 };
17101
17102 /* P.LS.S0 instruction pool */
17103 enum {
17104     NM_LBS9     = 0x00,
17105     NM_LHS9     = 0x04,
17106     NM_LWS9     = 0x08,
17107     NM_LDS9     = 0x0c,
17108
17109     NM_SBS9     = 0x01,
17110     NM_SHS9     = 0x05,
17111     NM_SWS9     = 0x09,
17112     NM_SDS9     = 0x0d,
17113
17114     NM_LBUS9    = 0x02,
17115     NM_LHUS9    = 0x06,
17116     NM_LWC1S9   = 0x0a,
17117     NM_LDC1S9   = 0x0e,
17118
17119     NM_P_PREFS9 = 0x03,
17120     NM_LWUS9    = 0x07,
17121     NM_SWC1S9   = 0x0b,
17122     NM_SDC1S9   = 0x0f,
17123 };
17124
17125 /* P.LS.S1 instruction pool */
17126 enum {
17127     NM_ASET_ACLR = 0x02,
17128     NM_UALH      = 0x04,
17129     NM_UASH      = 0x05,
17130     NM_CACHE     = 0x07,
17131     NM_P_LL      = 0x0a,
17132     NM_P_SC      = 0x0b,
17133 };
17134
17135 /* P.LS.WM instruction pool */
17136 enum {
17137     NM_LWM       = 0x00,
17138     NM_SWM       = 0x01,
17139 };
17140
17141 /* P.LS.UAWM instruction pool */
17142 enum {
17143     NM_UALWM       = 0x00,
17144     NM_UASWM       = 0x01,
17145 };
17146
17147 /* P.BR3A instruction pool */
17148 enum {
17149     NM_BC1EQZC          = 0x00,
17150     NM_BC1NEZC          = 0x01,
17151     NM_BC2EQZC          = 0x02,
17152     NM_BC2NEZC          = 0x03,
17153     NM_BPOSGE32C        = 0x04,
17154 };
17155
17156 /* P16.RI instruction pool */
17157 enum {
17158     NM_P16_SYSCALL  = 0x01,
17159     NM_BREAK16      = 0x02,
17160     NM_SDBBP16      = 0x03,
17161 };
17162
17163 /* POOL16C_0 instruction pool */
17164 enum {
17165     NM_POOL16C_00      = 0x00,
17166 };
17167
17168 /* P16.JRC instruction pool */
17169 enum {
17170     NM_JRC          = 0x00,
17171     NM_JALRC16      = 0x01,
17172 };
17173
17174 /* P.SYSCALL instruction pool */
17175 enum {
17176     NM_SYSCALL      = 0x00,
17177     NM_HYPCALL      = 0x01,
17178 };
17179
17180 /* P.TRAP instruction pool */
17181 enum {
17182     NM_TEQ          = 0x00,
17183     NM_TNE          = 0x01,
17184 };
17185
17186 /* P.CMOVE instruction pool */
17187 enum {
17188     NM_MOVZ            = 0x00,
17189     NM_MOVN            = 0x01,
17190 };
17191
17192 /* POOL32Axf instruction pool */
17193 enum {
17194     NM_POOL32AXF_1 = 0x01,
17195     NM_POOL32AXF_2 = 0x02,
17196     NM_POOL32AXF_4 = 0x04,
17197     NM_POOL32AXF_5 = 0x05,
17198     NM_POOL32AXF_7 = 0x07,
17199 };
17200
17201 /* POOL32Axf_1 instruction pool */
17202 enum {
17203     NM_POOL32AXF_1_0 = 0x00,
17204     NM_POOL32AXF_1_1 = 0x01,
17205     NM_POOL32AXF_1_3 = 0x03,
17206     NM_POOL32AXF_1_4 = 0x04,
17207     NM_POOL32AXF_1_5 = 0x05,
17208     NM_POOL32AXF_1_7 = 0x07,
17209 };
17210
17211 /* POOL32Axf_2 instruction pool */
17212 enum {
17213     NM_POOL32AXF_2_0_7     = 0x00,
17214     NM_POOL32AXF_2_8_15    = 0x01,
17215     NM_POOL32AXF_2_16_23   = 0x02,
17216     NM_POOL32AXF_2_24_31   = 0x03,
17217 };
17218
17219 /* POOL32Axf_7 instruction pool */
17220 enum {
17221     NM_SHRA_R_QB    = 0x0,
17222     NM_SHRL_PH      = 0x1,
17223     NM_REPL_QB      = 0x2,
17224 };
17225
17226 /* POOL32Axf_1_0 instruction pool */
17227 enum {
17228     NM_MFHI = 0x0,
17229     NM_MFLO = 0x1,
17230     NM_MTHI = 0x2,
17231     NM_MTLO = 0x3,
17232 };
17233
17234 /* POOL32Axf_1_1 instruction pool */
17235 enum {
17236     NM_MTHLIP = 0x0,
17237     NM_SHILOV = 0x1,
17238 };
17239
17240 /* POOL32Axf_1_3 instruction pool */
17241 enum {
17242     NM_RDDSP    = 0x0,
17243     NM_WRDSP    = 0x1,
17244     NM_EXTP     = 0x2,
17245     NM_EXTPDP   = 0x3,
17246 };
17247
17248 /* POOL32Axf_1_4 instruction pool */
17249 enum {
17250     NM_SHLL_QB  = 0x0,
17251     NM_SHRL_QB  = 0x1,
17252 };
17253
17254 /* POOL32Axf_1_5 instruction pool */
17255 enum {
17256     NM_MAQ_S_W_PHR   = 0x0,
17257     NM_MAQ_S_W_PHL   = 0x1,
17258     NM_MAQ_SA_W_PHR  = 0x2,
17259     NM_MAQ_SA_W_PHL  = 0x3,
17260 };
17261
17262 /* POOL32Axf_1_7 instruction pool */
17263 enum {
17264     NM_EXTR_W       = 0x0,
17265     NM_EXTR_R_W     = 0x1,
17266     NM_EXTR_RS_W    = 0x2,
17267     NM_EXTR_S_H     = 0x3,
17268 };
17269
17270 /* POOL32Axf_2_0_7 instruction pool */
17271 enum {
17272     NM_DPA_W_PH     = 0x0,
17273     NM_DPAQ_S_W_PH  = 0x1,
17274     NM_DPS_W_PH     = 0x2,
17275     NM_DPSQ_S_W_PH  = 0x3,
17276     NM_BALIGN       = 0x4,
17277     NM_MADD         = 0x5,
17278     NM_MULT         = 0x6,
17279     NM_EXTRV_W      = 0x7,
17280 };
17281
17282 /* POOL32Axf_2_8_15 instruction pool */
17283 enum {
17284     NM_DPAX_W_PH    = 0x0,
17285     NM_DPAQ_SA_L_W  = 0x1,
17286     NM_DPSX_W_PH    = 0x2,
17287     NM_DPSQ_SA_L_W  = 0x3,
17288     NM_MADDU        = 0x5,
17289     NM_MULTU        = 0x6,
17290     NM_EXTRV_R_W    = 0x7,
17291 };
17292
17293 /* POOL32Axf_2_16_23 instruction pool */
17294 enum {
17295     NM_DPAU_H_QBL       = 0x0,
17296     NM_DPAQX_S_W_PH     = 0x1,
17297     NM_DPSU_H_QBL       = 0x2,
17298     NM_DPSQX_S_W_PH     = 0x3,
17299     NM_EXTPV            = 0x4,
17300     NM_MSUB             = 0x5,
17301     NM_MULSA_W_PH       = 0x6,
17302     NM_EXTRV_RS_W       = 0x7,
17303 };
17304
17305 /* POOL32Axf_2_24_31 instruction pool */
17306 enum {
17307     NM_DPAU_H_QBR       = 0x0,
17308     NM_DPAQX_SA_W_PH    = 0x1,
17309     NM_DPSU_H_QBR       = 0x2,
17310     NM_DPSQX_SA_W_PH    = 0x3,
17311     NM_EXTPDPV          = 0x4,
17312     NM_MSUBU            = 0x5,
17313     NM_MULSAQ_S_W_PH    = 0x6,
17314     NM_EXTRV_S_H        = 0x7,
17315 };
17316
17317 /* POOL32Axf_{4, 5} instruction pool */
17318 enum {
17319     NM_CLO      = 0x25,
17320     NM_CLZ      = 0x2d,
17321
17322     NM_TLBP     = 0x01,
17323     NM_TLBR     = 0x09,
17324     NM_TLBWI    = 0x11,
17325     NM_TLBWR    = 0x19,
17326     NM_TLBINV   = 0x03,
17327     NM_TLBINVF  = 0x0b,
17328     NM_DI       = 0x23,
17329     NM_EI       = 0x2b,
17330     NM_RDPGPR   = 0x70,
17331     NM_WRPGPR   = 0x78,
17332     NM_WAIT     = 0x61,
17333     NM_DERET    = 0x71,
17334     NM_ERETX    = 0x79,
17335
17336     /* nanoMIPS DSP instructions */
17337     NM_ABSQ_S_QB        = 0x00,
17338     NM_ABSQ_S_PH        = 0x08,
17339     NM_ABSQ_S_W         = 0x10,
17340     NM_PRECEQ_W_PHL     = 0x28,
17341     NM_PRECEQ_W_PHR     = 0x30,
17342     NM_PRECEQU_PH_QBL   = 0x38,
17343     NM_PRECEQU_PH_QBR   = 0x48,
17344     NM_PRECEU_PH_QBL    = 0x58,
17345     NM_PRECEU_PH_QBR    = 0x68,
17346     NM_PRECEQU_PH_QBLA  = 0x39,
17347     NM_PRECEQU_PH_QBRA  = 0x49,
17348     NM_PRECEU_PH_QBLA   = 0x59,
17349     NM_PRECEU_PH_QBRA   = 0x69,
17350     NM_REPLV_PH         = 0x01,
17351     NM_REPLV_QB         = 0x09,
17352     NM_BITREV           = 0x18,
17353     NM_INSV             = 0x20,
17354     NM_RADDU_W_QB       = 0x78,
17355
17356     NM_BITSWAP          = 0x05,
17357     NM_WSBH             = 0x3d,
17358 };
17359
17360 /* PP.SR instruction pool */
17361 enum {
17362     NM_SAVE         = 0x00,
17363     NM_RESTORE      = 0x02,
17364     NM_RESTORE_JRC  = 0x03,
17365 };
17366
17367 /* P.SR.F instruction pool */
17368 enum {
17369     NM_SAVEF        = 0x00,
17370     NM_RESTOREF     = 0x01,
17371 };
17372
17373 /* P16.SYSCALL  instruction pool */
17374 enum {
17375     NM_SYSCALL16     = 0x00,
17376     NM_HYPCALL16     = 0x01,
17377 };
17378
17379 /* POOL16C_00 instruction pool */
17380 enum {
17381     NM_NOT16           = 0x00,
17382     NM_XOR16           = 0x01,
17383     NM_AND16           = 0x02,
17384     NM_OR16            = 0x03,
17385 };
17386
17387 /* PP.LSX and PP.LSXS instruction pool */
17388 enum {
17389     NM_LBX      = 0x00,
17390     NM_LHX      = 0x04,
17391     NM_LWX      = 0x08,
17392     NM_LDX      = 0x0c,
17393
17394     NM_SBX      = 0x01,
17395     NM_SHX      = 0x05,
17396     NM_SWX      = 0x09,
17397     NM_SDX      = 0x0d,
17398
17399     NM_LBUX     = 0x02,
17400     NM_LHUX     = 0x06,
17401     NM_LWC1X    = 0x0a,
17402     NM_LDC1X    = 0x0e,
17403
17404     NM_LWUX     = 0x07,
17405     NM_SWC1X    = 0x0b,
17406     NM_SDC1X    = 0x0f,
17407
17408     NM_LHXS     = 0x04,
17409     NM_LWXS     = 0x08,
17410     NM_LDXS     = 0x0c,
17411
17412     NM_SHXS     = 0x05,
17413     NM_SWXS     = 0x09,
17414     NM_SDXS     = 0x0d,
17415
17416     NM_LHUXS    = 0x06,
17417     NM_LWC1XS   = 0x0a,
17418     NM_LDC1XS   = 0x0e,
17419
17420     NM_LWUXS    = 0x07,
17421     NM_SWC1XS   = 0x0b,
17422     NM_SDC1XS   = 0x0f,
17423 };
17424
17425 /* ERETx instruction pool */
17426 enum {
17427     NM_ERET     = 0x00,
17428     NM_ERETNC   = 0x01,
17429 };
17430
17431 /* POOL32FxF_{0, 1} insturction pool */
17432 enum {
17433     NM_CFC1     = 0x40,
17434     NM_CTC1     = 0x60,
17435     NM_MFC1     = 0x80,
17436     NM_MTC1     = 0xa0,
17437     NM_MFHC1    = 0xc0,
17438     NM_MTHC1    = 0xe0,
17439
17440     NM_CVT_S_PL = 0x84,
17441     NM_CVT_S_PU = 0xa4,
17442
17443     NM_CVT_L_S     = 0x004,
17444     NM_CVT_L_D     = 0x104,
17445     NM_CVT_W_S     = 0x024,
17446     NM_CVT_W_D     = 0x124,
17447
17448     NM_RSQRT_S     = 0x008,
17449     NM_RSQRT_D     = 0x108,
17450
17451     NM_SQRT_S      = 0x028,
17452     NM_SQRT_D      = 0x128,
17453
17454     NM_RECIP_S     = 0x048,
17455     NM_RECIP_D     = 0x148,
17456
17457     NM_FLOOR_L_S   = 0x00c,
17458     NM_FLOOR_L_D   = 0x10c,
17459
17460     NM_FLOOR_W_S   = 0x02c,
17461     NM_FLOOR_W_D   = 0x12c,
17462
17463     NM_CEIL_L_S    = 0x04c,
17464     NM_CEIL_L_D    = 0x14c,
17465     NM_CEIL_W_S    = 0x06c,
17466     NM_CEIL_W_D    = 0x16c,
17467     NM_TRUNC_L_S   = 0x08c,
17468     NM_TRUNC_L_D   = 0x18c,
17469     NM_TRUNC_W_S   = 0x0ac,
17470     NM_TRUNC_W_D   = 0x1ac,
17471     NM_ROUND_L_S   = 0x0cc,
17472     NM_ROUND_L_D   = 0x1cc,
17473     NM_ROUND_W_S   = 0x0ec,
17474     NM_ROUND_W_D   = 0x1ec,
17475
17476     NM_MOV_S       = 0x01,
17477     NM_MOV_D       = 0x81,
17478     NM_ABS_S       = 0x0d,
17479     NM_ABS_D       = 0x8d,
17480     NM_NEG_S       = 0x2d,
17481     NM_NEG_D       = 0xad,
17482     NM_CVT_D_S     = 0x04d,
17483     NM_CVT_D_W     = 0x0cd,
17484     NM_CVT_D_L     = 0x14d,
17485     NM_CVT_S_D     = 0x06d,
17486     NM_CVT_S_W     = 0x0ed,
17487     NM_CVT_S_L     = 0x16d,
17488 };
17489
17490 /* P.LL instruction pool */
17491 enum {
17492     NM_LL       = 0x00,
17493     NM_LLWP     = 0x01,
17494 };
17495
17496 /* P.SC instruction pool */
17497 enum {
17498     NM_SC       = 0x00,
17499     NM_SCWP     = 0x01,
17500 };
17501
17502 /* P.DVP instruction pool */
17503 enum {
17504     NM_DVP      = 0x00,
17505     NM_EVP      = 0x01,
17506 };
17507
17508
17509 /*
17510  *
17511  * nanoMIPS decoding engine
17512  *
17513  */
17514
17515
17516 /* extraction utilities */
17517
17518 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
17519 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
17520 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
17521 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
17522 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
17523 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
17524
17525 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
17526 static inline int decode_gpr_gpr3(int r)
17527 {
17528     static const int map[] = { 16, 17, 18, 19,  4,  5,  6,  7 };
17529
17530     return map[r & 0x7];
17531 }
17532
17533 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
17534 static inline int decode_gpr_gpr3_src_store(int r)
17535 {
17536     static const int map[] = {  0, 17, 18, 19,  4,  5,  6,  7 };
17537
17538     return map[r & 0x7];
17539 }
17540
17541 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
17542 static inline int decode_gpr_gpr4(int r)
17543 {
17544     static const int map[] = {  8,  9, 10, 11,  4,  5,  6,  7,
17545                                16, 17, 18, 19, 20, 21, 22, 23 };
17546
17547     return map[r & 0xf];
17548 }
17549
17550 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
17551 static inline int decode_gpr_gpr4_zero(int r)
17552 {
17553     static const int map[] = {  8,  9, 10,  0,  4,  5,  6,  7,
17554                                16, 17, 18, 19, 20, 21, 22, 23 };
17555
17556     return map[r & 0xf];
17557 }
17558
17559
17560 /* extraction utilities */
17561
17562 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
17563 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
17564 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
17565 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
17566 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
17567 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
17568
17569
17570 static void gen_adjust_sp(DisasContext *ctx, int u)
17571 {
17572     gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
17573 }
17574
17575 static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
17576                      uint8_t gp, uint16_t u)
17577 {
17578     int counter = 0;
17579     TCGv va = tcg_temp_new();
17580     TCGv t0 = tcg_temp_new();
17581
17582     while (counter != count) {
17583         bool use_gp = gp && (counter == count - 1);
17584         int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
17585         int this_offset = -((counter + 1) << 2);
17586         gen_base_offset_addr(ctx, va, 29, this_offset);
17587         gen_load_gpr(t0, this_rt);
17588         tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
17589                            (MO_TEUL | ctx->default_tcg_memop_mask));
17590         counter++;
17591     }
17592
17593     /* adjust stack pointer */
17594     gen_adjust_sp(ctx, -u);
17595
17596     tcg_temp_free(t0);
17597     tcg_temp_free(va);
17598 }
17599
17600 static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
17601                         uint8_t gp, uint16_t u)
17602 {
17603     int counter = 0;
17604     TCGv va = tcg_temp_new();
17605     TCGv t0 = tcg_temp_new();
17606
17607     while (counter != count) {
17608         bool use_gp = gp && (counter == count - 1);
17609         int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
17610         int this_offset = u - ((counter + 1) << 2);
17611         gen_base_offset_addr(ctx, va, 29, this_offset);
17612         tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
17613                         ctx->default_tcg_memop_mask);
17614         tcg_gen_ext32s_tl(t0, t0);
17615         gen_store_gpr(t0, this_rt);
17616         counter++;
17617     }
17618
17619     /* adjust stack pointer */
17620     gen_adjust_sp(ctx, u);
17621
17622     tcg_temp_free(t0);
17623     tcg_temp_free(va);
17624 }
17625
17626 static void gen_pool16c_nanomips_insn(DisasContext *ctx)
17627 {
17628     int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
17629     int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
17630
17631     switch (extract32(ctx->opcode, 2, 2)) {
17632     case NM_NOT16:
17633         gen_logic(ctx, OPC_NOR, rt, rs, 0);
17634         break;
17635     case NM_AND16:
17636         gen_logic(ctx, OPC_AND, rt, rt, rs);
17637         break;
17638     case NM_XOR16:
17639         gen_logic(ctx, OPC_XOR, rt, rt, rs);
17640         break;
17641     case NM_OR16:
17642         gen_logic(ctx, OPC_OR, rt, rt, rs);
17643         break;
17644     }
17645 }
17646
17647 static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
17648 {
17649     int rt = extract32(ctx->opcode, 21, 5);
17650     int rs = extract32(ctx->opcode, 16, 5);
17651     int rd = extract32(ctx->opcode, 11, 5);
17652
17653     switch (extract32(ctx->opcode, 3, 7)) {
17654     case NM_P_TRAP:
17655         switch (extract32(ctx->opcode, 10, 1)) {
17656         case NM_TEQ:
17657             check_nms(ctx);
17658             gen_trap(ctx, OPC_TEQ, rs, rt, -1);
17659             break;
17660         case NM_TNE:
17661             check_nms(ctx);
17662             gen_trap(ctx, OPC_TNE, rs, rt, -1);
17663             break;
17664         }
17665         break;
17666     case NM_RDHWR:
17667         check_nms(ctx);
17668         gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
17669         break;
17670     case NM_SEB:
17671         check_nms(ctx);
17672         gen_bshfl(ctx, OPC_SEB, rs, rt);
17673         break;
17674     case NM_SEH:
17675         gen_bshfl(ctx, OPC_SEH, rs, rt);
17676         break;
17677     case NM_SLLV:
17678         gen_shift(ctx, OPC_SLLV, rd, rt, rs);
17679         break;
17680     case NM_SRLV:
17681         gen_shift(ctx, OPC_SRLV, rd, rt, rs);
17682         break;
17683     case NM_SRAV:
17684         gen_shift(ctx, OPC_SRAV, rd, rt, rs);
17685         break;
17686     case NM_ROTRV:
17687         gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
17688         break;
17689     case NM_ADD:
17690         gen_arith(ctx, OPC_ADD, rd, rs, rt);
17691         break;
17692     case NM_ADDU:
17693         gen_arith(ctx, OPC_ADDU, rd, rs, rt);
17694         break;
17695     case NM_SUB:
17696         check_nms(ctx);
17697         gen_arith(ctx, OPC_SUB, rd, rs, rt);
17698         break;
17699     case NM_SUBU:
17700         gen_arith(ctx, OPC_SUBU, rd, rs, rt);
17701         break;
17702     case NM_P_CMOVE:
17703         switch (extract32(ctx->opcode, 10, 1)) {
17704         case NM_MOVZ:
17705             gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
17706             break;
17707         case NM_MOVN:
17708             gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
17709             break;
17710         }
17711         break;
17712     case NM_AND:
17713         gen_logic(ctx, OPC_AND, rd, rs, rt);
17714         break;
17715     case NM_OR:
17716         gen_logic(ctx, OPC_OR, rd, rs, rt);
17717         break;
17718     case NM_NOR:
17719         gen_logic(ctx, OPC_NOR, rd, rs, rt);
17720         break;
17721     case NM_XOR:
17722         gen_logic(ctx, OPC_XOR, rd, rs, rt);
17723         break;
17724     case NM_SLT:
17725         gen_slt(ctx, OPC_SLT, rd, rs, rt);
17726         break;
17727     case NM_P_SLTU:
17728         if (rd == 0) {
17729             /* P_DVP */
17730 #ifndef CONFIG_USER_ONLY
17731             TCGv t0 = tcg_temp_new();
17732             switch (extract32(ctx->opcode, 10, 1)) {
17733             case NM_DVP:
17734                 if (ctx->vp) {
17735                     check_cp0_enabled(ctx);
17736                     gen_helper_dvp(t0, cpu_env);
17737                     gen_store_gpr(t0, rt);
17738                 }
17739                 break;
17740             case NM_EVP:
17741                 if (ctx->vp) {
17742                     check_cp0_enabled(ctx);
17743                     gen_helper_evp(t0, cpu_env);
17744                     gen_store_gpr(t0, rt);
17745                 }
17746                 break;
17747             }
17748             tcg_temp_free(t0);
17749 #endif
17750         } else {
17751             gen_slt(ctx, OPC_SLTU, rd, rs, rt);
17752         }
17753         break;
17754     case NM_SOV:
17755         {
17756             TCGv t0 = tcg_temp_new();
17757             TCGv t1 = tcg_temp_new();
17758             TCGv t2 = tcg_temp_new();
17759
17760             gen_load_gpr(t1, rs);
17761             gen_load_gpr(t2, rt);
17762             tcg_gen_add_tl(t0, t1, t2);
17763             tcg_gen_ext32s_tl(t0, t0);
17764             tcg_gen_xor_tl(t1, t1, t2);
17765             tcg_gen_xor_tl(t2, t0, t2);
17766             tcg_gen_andc_tl(t1, t2, t1);
17767
17768             /* operands of same sign, result different sign */
17769             tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
17770             gen_store_gpr(t0, rd);
17771
17772             tcg_temp_free(t0);
17773             tcg_temp_free(t1);
17774             tcg_temp_free(t2);
17775         }
17776         break;
17777     case NM_MUL:
17778         gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
17779         break;
17780     case NM_MUH:
17781         gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
17782         break;
17783     case NM_MULU:
17784         gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
17785         break;
17786     case NM_MUHU:
17787         gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
17788         break;
17789     case NM_DIV:
17790         gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
17791         break;
17792     case NM_MOD:
17793         gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
17794         break;
17795     case NM_DIVU:
17796         gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
17797         break;
17798     case NM_MODU:
17799         gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
17800         break;
17801 #ifndef CONFIG_USER_ONLY
17802     case NM_MFC0:
17803         check_cp0_enabled(ctx);
17804         if (rt == 0) {
17805             /* Treat as NOP. */
17806             break;
17807         }
17808         gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
17809         break;
17810     case NM_MTC0:
17811         check_cp0_enabled(ctx);
17812         {
17813             TCGv t0 = tcg_temp_new();
17814
17815             gen_load_gpr(t0, rt);
17816             gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
17817             tcg_temp_free(t0);
17818         }
17819         break;
17820     case NM_D_E_MT_VPE:
17821         {
17822             uint8_t sc = extract32(ctx->opcode, 10, 1);
17823             TCGv t0 = tcg_temp_new();
17824
17825             switch (sc) {
17826             case 0:
17827                 if (rs == 1) {
17828                     /* DMT */
17829                     check_cp0_mt(ctx);
17830                     gen_helper_dmt(t0);
17831                     gen_store_gpr(t0, rt);
17832                 } else if (rs == 0) {
17833                     /* DVPE */
17834                     check_cp0_mt(ctx);
17835                     gen_helper_dvpe(t0, cpu_env);
17836                     gen_store_gpr(t0, rt);
17837                 } else {
17838                     generate_exception_end(ctx, EXCP_RI);
17839                 }
17840                 break;
17841             case 1:
17842                 if (rs == 1) {
17843                     /* EMT */
17844                     check_cp0_mt(ctx);
17845                     gen_helper_emt(t0);
17846                     gen_store_gpr(t0, rt);
17847                 } else if (rs == 0) {
17848                     /* EVPE */
17849                     check_cp0_mt(ctx);
17850                     gen_helper_evpe(t0, cpu_env);
17851                     gen_store_gpr(t0, rt);
17852                 } else {
17853                     generate_exception_end(ctx, EXCP_RI);
17854                 }
17855                 break;
17856             }
17857
17858             tcg_temp_free(t0);
17859         }
17860         break;
17861     case NM_FORK:
17862         check_mt(ctx);
17863         {
17864             TCGv t0 = tcg_temp_new();
17865             TCGv t1 = tcg_temp_new();
17866
17867             gen_load_gpr(t0, rt);
17868             gen_load_gpr(t1, rs);
17869             gen_helper_fork(t0, t1);
17870             tcg_temp_free(t0);
17871             tcg_temp_free(t1);
17872         }
17873         break;
17874     case NM_MFTR:
17875     case NM_MFHTR:
17876         check_cp0_enabled(ctx);
17877         if (rd == 0) {
17878             /* Treat as NOP. */
17879             return;
17880         }
17881         gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
17882                  extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
17883         break;
17884     case NM_MTTR:
17885     case NM_MTHTR:
17886         check_cp0_enabled(ctx);
17887         gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
17888                  extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
17889         break;
17890     case NM_YIELD:
17891         check_mt(ctx);
17892         {
17893             TCGv t0 = tcg_temp_new();
17894
17895             gen_load_gpr(t0, rs);
17896             gen_helper_yield(t0, cpu_env, t0);
17897             gen_store_gpr(t0, rt);
17898             tcg_temp_free(t0);
17899         }
17900         break;
17901 #endif
17902     default:
17903         generate_exception_end(ctx, EXCP_RI);
17904         break;
17905     }
17906 }
17907
17908 /* dsp */
17909 static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
17910                                             int ret, int v1, int v2)
17911 {
17912     TCGv_i32 t0;
17913     TCGv v0_t;
17914     TCGv v1_t;
17915
17916     t0 = tcg_temp_new_i32();
17917
17918     v0_t = tcg_temp_new();
17919     v1_t = tcg_temp_new();
17920
17921     tcg_gen_movi_i32(t0, v2 >> 3);
17922
17923     gen_load_gpr(v0_t, ret);
17924     gen_load_gpr(v1_t, v1);
17925
17926     switch (opc) {
17927     case NM_MAQ_S_W_PHR:
17928         check_dsp(ctx);
17929         gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
17930         break;
17931     case NM_MAQ_S_W_PHL:
17932         check_dsp(ctx);
17933         gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
17934         break;
17935     case NM_MAQ_SA_W_PHR:
17936         check_dsp(ctx);
17937         gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
17938         break;
17939     case NM_MAQ_SA_W_PHL:
17940         check_dsp(ctx);
17941         gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
17942         break;
17943     default:
17944         generate_exception_end(ctx, EXCP_RI);
17945         break;
17946     }
17947
17948     tcg_temp_free_i32(t0);
17949
17950     tcg_temp_free(v0_t);
17951     tcg_temp_free(v1_t);
17952 }
17953
17954
17955 static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
17956                                     int ret, int v1, int v2)
17957 {
17958     int16_t imm;
17959     TCGv t0 = tcg_temp_new();
17960     TCGv t1 = tcg_temp_new();
17961     TCGv v0_t = tcg_temp_new();
17962
17963     gen_load_gpr(v0_t, v1);
17964
17965     switch (opc) {
17966     case NM_POOL32AXF_1_0:
17967         check_dsp(ctx);
17968         switch (extract32(ctx->opcode, 12, 2)) {
17969         case NM_MFHI:
17970             gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
17971             break;
17972         case NM_MFLO:
17973             gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
17974             break;
17975         case NM_MTHI:
17976             gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
17977             break;
17978         case NM_MTLO:
17979             gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
17980             break;
17981         }
17982         break;
17983     case NM_POOL32AXF_1_1:
17984         check_dsp(ctx);
17985         switch (extract32(ctx->opcode, 12, 2)) {
17986         case NM_MTHLIP:
17987             tcg_gen_movi_tl(t0, v2);
17988             gen_helper_mthlip(t0, v0_t, cpu_env);
17989             break;
17990         case NM_SHILOV:
17991             tcg_gen_movi_tl(t0, v2 >> 3);
17992             gen_helper_shilo(t0, v0_t, cpu_env);
17993             break;
17994         default:
17995             generate_exception_end(ctx, EXCP_RI);
17996             break;
17997         }
17998         break;
17999     case NM_POOL32AXF_1_3:
18000         check_dsp(ctx);
18001         imm = extract32(ctx->opcode, 14, 7);
18002         switch (extract32(ctx->opcode, 12, 2)) {
18003         case NM_RDDSP:
18004             tcg_gen_movi_tl(t0, imm);
18005             gen_helper_rddsp(t0, t0, cpu_env);
18006             gen_store_gpr(t0, ret);
18007             break;
18008         case NM_WRDSP:
18009             gen_load_gpr(t0, ret);
18010             tcg_gen_movi_tl(t1, imm);
18011             gen_helper_wrdsp(t0, t1, cpu_env);
18012             break;
18013         case NM_EXTP:
18014             tcg_gen_movi_tl(t0, v2 >> 3);
18015             tcg_gen_movi_tl(t1, v1);
18016             gen_helper_extp(t0, t0, t1, cpu_env);
18017             gen_store_gpr(t0, ret);
18018             break;
18019         case NM_EXTPDP:
18020             tcg_gen_movi_tl(t0, v2 >> 3);
18021             tcg_gen_movi_tl(t1, v1);
18022             gen_helper_extpdp(t0, t0, t1, cpu_env);
18023             gen_store_gpr(t0, ret);
18024             break;
18025         }
18026         break;
18027     case NM_POOL32AXF_1_4:
18028         check_dsp(ctx);
18029         tcg_gen_movi_tl(t0, v2 >> 2);
18030         switch (extract32(ctx->opcode, 12, 1)) {
18031         case NM_SHLL_QB:
18032             gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
18033             gen_store_gpr(t0, ret);
18034             break;
18035         case NM_SHRL_QB:
18036             gen_helper_shrl_qb(t0, t0, v0_t);
18037             gen_store_gpr(t0, ret);
18038             break;
18039         }
18040         break;
18041     case NM_POOL32AXF_1_5:
18042         opc = extract32(ctx->opcode, 12, 2);
18043         gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
18044         break;
18045     case NM_POOL32AXF_1_7:
18046         check_dsp(ctx);
18047         tcg_gen_movi_tl(t0, v2 >> 3);
18048         tcg_gen_movi_tl(t1, v1);
18049         switch (extract32(ctx->opcode, 12, 2)) {
18050         case NM_EXTR_W:
18051             gen_helper_extr_w(t0, t0, t1, cpu_env);
18052             gen_store_gpr(t0, ret);
18053             break;
18054         case NM_EXTR_R_W:
18055             gen_helper_extr_r_w(t0, t0, t1, cpu_env);
18056             gen_store_gpr(t0, ret);
18057             break;
18058         case NM_EXTR_RS_W:
18059             gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
18060             gen_store_gpr(t0, ret);
18061             break;
18062         case NM_EXTR_S_H:
18063             gen_helper_extr_s_h(t0, t0, t1, cpu_env);
18064             gen_store_gpr(t0, ret);
18065             break;
18066         }
18067         break;
18068     default:
18069         generate_exception_end(ctx, EXCP_RI);
18070         break;
18071     }
18072
18073     tcg_temp_free(t0);
18074     tcg_temp_free(t1);
18075     tcg_temp_free(v0_t);
18076 }
18077
18078 static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
18079                                     TCGv v0, TCGv v1, int rd)
18080 {
18081     TCGv_i32 t0;
18082
18083     t0 = tcg_temp_new_i32();
18084
18085     tcg_gen_movi_i32(t0, rd >> 3);
18086
18087     switch (opc) {
18088     case NM_POOL32AXF_2_0_7:
18089         switch (extract32(ctx->opcode, 9, 3)) {
18090         case NM_DPA_W_PH:
18091             check_dsp_r2(ctx);
18092             gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
18093             break;
18094         case NM_DPAQ_S_W_PH:
18095             check_dsp(ctx);
18096             gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
18097             break;
18098         case NM_DPS_W_PH:
18099             check_dsp_r2(ctx);
18100             gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
18101             break;
18102         case NM_DPSQ_S_W_PH:
18103             check_dsp(ctx);
18104             gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
18105             break;
18106         default:
18107             generate_exception_end(ctx, EXCP_RI);
18108             break;
18109         }
18110         break;
18111     case NM_POOL32AXF_2_8_15:
18112         switch (extract32(ctx->opcode, 9, 3)) {
18113         case NM_DPAX_W_PH:
18114             check_dsp_r2(ctx);
18115             gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
18116             break;
18117         case NM_DPAQ_SA_L_W:
18118             check_dsp(ctx);
18119             gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
18120             break;
18121         case NM_DPSX_W_PH:
18122             check_dsp_r2(ctx);
18123             gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
18124             break;
18125         case NM_DPSQ_SA_L_W:
18126             check_dsp(ctx);
18127             gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
18128             break;
18129         default:
18130             generate_exception_end(ctx, EXCP_RI);
18131             break;
18132         }
18133         break;
18134     case NM_POOL32AXF_2_16_23:
18135         switch (extract32(ctx->opcode, 9, 3)) {
18136         case NM_DPAU_H_QBL:
18137             check_dsp(ctx);
18138             gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
18139             break;
18140         case NM_DPAQX_S_W_PH:
18141             check_dsp_r2(ctx);
18142             gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
18143             break;
18144         case NM_DPSU_H_QBL:
18145             check_dsp(ctx);
18146             gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
18147             break;
18148         case NM_DPSQX_S_W_PH:
18149             check_dsp_r2(ctx);
18150             gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
18151             break;
18152         case NM_MULSA_W_PH:
18153             check_dsp_r2(ctx);
18154             gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
18155             break;
18156         default:
18157             generate_exception_end(ctx, EXCP_RI);
18158             break;
18159         }
18160         break;
18161     case NM_POOL32AXF_2_24_31:
18162         switch (extract32(ctx->opcode, 9, 3)) {
18163         case NM_DPAU_H_QBR:
18164             check_dsp(ctx);
18165             gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
18166             break;
18167         case NM_DPAQX_SA_W_PH:
18168             check_dsp_r2(ctx);
18169             gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
18170             break;
18171         case NM_DPSU_H_QBR:
18172             check_dsp(ctx);
18173             gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
18174             break;
18175         case NM_DPSQX_SA_W_PH:
18176             check_dsp_r2(ctx);
18177             gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
18178             break;
18179         case NM_MULSAQ_S_W_PH:
18180             check_dsp(ctx);
18181             gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
18182             break;
18183         default:
18184             generate_exception_end(ctx, EXCP_RI);
18185             break;
18186         }
18187         break;
18188     default:
18189         generate_exception_end(ctx, EXCP_RI);
18190         break;
18191     }
18192
18193     tcg_temp_free_i32(t0);
18194 }
18195
18196 static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
18197                                           int rt, int rs, int rd)
18198 {
18199     int ret = rt;
18200     TCGv t0 = tcg_temp_new();
18201     TCGv t1 = tcg_temp_new();
18202     TCGv v0_t = tcg_temp_new();
18203     TCGv v1_t = tcg_temp_new();
18204
18205     gen_load_gpr(v0_t, rt);
18206     gen_load_gpr(v1_t, rs);
18207
18208     switch (opc) {
18209     case NM_POOL32AXF_2_0_7:
18210         switch (extract32(ctx->opcode, 9, 3)) {
18211         case NM_DPA_W_PH:
18212         case NM_DPAQ_S_W_PH:
18213         case NM_DPS_W_PH:
18214         case NM_DPSQ_S_W_PH:
18215             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18216             break;
18217         case NM_BALIGN:
18218             check_dsp_r2(ctx);
18219             if (rt != 0) {
18220                 gen_load_gpr(t0, rs);
18221                 rd &= 3;
18222                 if (rd != 0 && rd != 2) {
18223                     tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
18224                     tcg_gen_ext32u_tl(t0, t0);
18225                     tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
18226                     tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
18227                 }
18228                 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
18229             }
18230             break;
18231         case NM_MADD:
18232             check_dsp(ctx);
18233             {
18234                 int acc = extract32(ctx->opcode, 14, 2);
18235                 TCGv_i64 t2 = tcg_temp_new_i64();
18236                 TCGv_i64 t3 = tcg_temp_new_i64();
18237
18238                 gen_load_gpr(t0, rt);
18239                 gen_load_gpr(t1, rs);
18240                 tcg_gen_ext_tl_i64(t2, t0);
18241                 tcg_gen_ext_tl_i64(t3, t1);
18242                 tcg_gen_mul_i64(t2, t2, t3);
18243                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18244                 tcg_gen_add_i64(t2, t2, t3);
18245                 tcg_temp_free_i64(t3);
18246                 gen_move_low32(cpu_LO[acc], t2);
18247                 gen_move_high32(cpu_HI[acc], t2);
18248                 tcg_temp_free_i64(t2);
18249             }
18250             break;
18251         case NM_MULT:
18252             check_dsp(ctx);
18253             {
18254                 int acc = extract32(ctx->opcode, 14, 2);
18255                 TCGv_i32 t2 = tcg_temp_new_i32();
18256                 TCGv_i32 t3 = tcg_temp_new_i32();
18257
18258                 gen_load_gpr(t0, rs);
18259                 gen_load_gpr(t1, rt);
18260                 tcg_gen_trunc_tl_i32(t2, t0);
18261                 tcg_gen_trunc_tl_i32(t3, t1);
18262                 tcg_gen_muls2_i32(t2, t3, t2, t3);
18263                 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18264                 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18265                 tcg_temp_free_i32(t2);
18266                 tcg_temp_free_i32(t3);
18267             }
18268             break;
18269         case NM_EXTRV_W:
18270             check_dsp(ctx);
18271             gen_load_gpr(v1_t, rs);
18272             tcg_gen_movi_tl(t0, rd >> 3);
18273             gen_helper_extr_w(t0, t0, v1_t, cpu_env);
18274             gen_store_gpr(t0, ret);
18275             break;
18276         }
18277         break;
18278     case NM_POOL32AXF_2_8_15:
18279         switch (extract32(ctx->opcode, 9, 3)) {
18280         case NM_DPAX_W_PH:
18281         case NM_DPAQ_SA_L_W:
18282         case NM_DPSX_W_PH:
18283         case NM_DPSQ_SA_L_W:
18284             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18285             break;
18286         case NM_MADDU:
18287             check_dsp(ctx);
18288             {
18289                 int acc = extract32(ctx->opcode, 14, 2);
18290                 TCGv_i64 t2 = tcg_temp_new_i64();
18291                 TCGv_i64 t3 = tcg_temp_new_i64();
18292
18293                 gen_load_gpr(t0, rs);
18294                 gen_load_gpr(t1, rt);
18295                 tcg_gen_ext32u_tl(t0, t0);
18296                 tcg_gen_ext32u_tl(t1, t1);
18297                 tcg_gen_extu_tl_i64(t2, t0);
18298                 tcg_gen_extu_tl_i64(t3, t1);
18299                 tcg_gen_mul_i64(t2, t2, t3);
18300                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18301                 tcg_gen_add_i64(t2, t2, t3);
18302                 tcg_temp_free_i64(t3);
18303                 gen_move_low32(cpu_LO[acc], t2);
18304                 gen_move_high32(cpu_HI[acc], t2);
18305                 tcg_temp_free_i64(t2);
18306             }
18307             break;
18308         case NM_MULTU:
18309             check_dsp(ctx);
18310             {
18311                 int acc = extract32(ctx->opcode, 14, 2);
18312                 TCGv_i32 t2 = tcg_temp_new_i32();
18313                 TCGv_i32 t3 = tcg_temp_new_i32();
18314
18315                 gen_load_gpr(t0, rs);
18316                 gen_load_gpr(t1, rt);
18317                 tcg_gen_trunc_tl_i32(t2, t0);
18318                 tcg_gen_trunc_tl_i32(t3, t1);
18319                 tcg_gen_mulu2_i32(t2, t3, t2, t3);
18320                 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18321                 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18322                 tcg_temp_free_i32(t2);
18323                 tcg_temp_free_i32(t3);
18324             }
18325             break;
18326         case NM_EXTRV_R_W:
18327             check_dsp(ctx);
18328             tcg_gen_movi_tl(t0, rd >> 3);
18329             gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
18330             gen_store_gpr(t0, ret);
18331             break;
18332         default:
18333             generate_exception_end(ctx, EXCP_RI);
18334             break;
18335         }
18336         break;
18337     case NM_POOL32AXF_2_16_23:
18338         switch (extract32(ctx->opcode, 9, 3)) {
18339         case NM_DPAU_H_QBL:
18340         case NM_DPAQX_S_W_PH:
18341         case NM_DPSU_H_QBL:
18342         case NM_DPSQX_S_W_PH:
18343         case NM_MULSA_W_PH:
18344             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18345             break;
18346         case NM_EXTPV:
18347             check_dsp(ctx);
18348             tcg_gen_movi_tl(t0, rd >> 3);
18349             gen_helper_extp(t0, t0, v1_t, cpu_env);
18350             gen_store_gpr(t0, ret);
18351             break;
18352         case NM_MSUB:
18353             check_dsp(ctx);
18354             {
18355                 int acc = extract32(ctx->opcode, 14, 2);
18356                 TCGv_i64 t2 = tcg_temp_new_i64();
18357                 TCGv_i64 t3 = tcg_temp_new_i64();
18358
18359                 gen_load_gpr(t0, rs);
18360                 gen_load_gpr(t1, rt);
18361                 tcg_gen_ext_tl_i64(t2, t0);
18362                 tcg_gen_ext_tl_i64(t3, t1);
18363                 tcg_gen_mul_i64(t2, t2, t3);
18364                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18365                 tcg_gen_sub_i64(t2, t3, t2);
18366                 tcg_temp_free_i64(t3);
18367                 gen_move_low32(cpu_LO[acc], t2);
18368                 gen_move_high32(cpu_HI[acc], t2);
18369                 tcg_temp_free_i64(t2);
18370             }
18371             break;
18372         case NM_EXTRV_RS_W:
18373             check_dsp(ctx);
18374             tcg_gen_movi_tl(t0, rd >> 3);
18375             gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
18376             gen_store_gpr(t0, ret);
18377             break;
18378         }
18379         break;
18380     case NM_POOL32AXF_2_24_31:
18381         switch (extract32(ctx->opcode, 9, 3)) {
18382         case NM_DPAU_H_QBR:
18383         case NM_DPAQX_SA_W_PH:
18384         case NM_DPSU_H_QBR:
18385         case NM_DPSQX_SA_W_PH:
18386         case NM_MULSAQ_S_W_PH:
18387             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18388             break;
18389         case NM_EXTPDPV:
18390             check_dsp(ctx);
18391             tcg_gen_movi_tl(t0, rd >> 3);
18392             gen_helper_extpdp(t0, t0, v1_t, cpu_env);
18393             gen_store_gpr(t0, ret);
18394             break;
18395         case NM_MSUBU:
18396             check_dsp(ctx);
18397             {
18398                 int acc = extract32(ctx->opcode, 14, 2);
18399                 TCGv_i64 t2 = tcg_temp_new_i64();
18400                 TCGv_i64 t3 = tcg_temp_new_i64();
18401
18402                 gen_load_gpr(t0, rs);
18403                 gen_load_gpr(t1, rt);
18404                 tcg_gen_ext32u_tl(t0, t0);
18405                 tcg_gen_ext32u_tl(t1, t1);
18406                 tcg_gen_extu_tl_i64(t2, t0);
18407                 tcg_gen_extu_tl_i64(t3, t1);
18408                 tcg_gen_mul_i64(t2, t2, t3);
18409                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18410                 tcg_gen_sub_i64(t2, t3, t2);
18411                 tcg_temp_free_i64(t3);
18412                 gen_move_low32(cpu_LO[acc], t2);
18413                 gen_move_high32(cpu_HI[acc], t2);
18414                 tcg_temp_free_i64(t2);
18415             }
18416             break;
18417         case NM_EXTRV_S_H:
18418             check_dsp(ctx);
18419             tcg_gen_movi_tl(t0, rd >> 3);
18420             gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
18421             gen_store_gpr(t0, ret);
18422             break;
18423         }
18424         break;
18425     default:
18426         generate_exception_end(ctx, EXCP_RI);
18427         break;
18428     }
18429
18430     tcg_temp_free(t0);
18431     tcg_temp_free(t1);
18432
18433     tcg_temp_free(v0_t);
18434     tcg_temp_free(v1_t);
18435 }
18436
18437 static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
18438                                           int rt, int rs)
18439 {
18440     int ret = rt;
18441     TCGv t0 = tcg_temp_new();
18442     TCGv v0_t = tcg_temp_new();
18443
18444     gen_load_gpr(v0_t, rs);
18445
18446     switch (opc) {
18447     case NM_ABSQ_S_QB:
18448         check_dsp_r2(ctx);
18449         gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
18450         gen_store_gpr(v0_t, ret);
18451         break;
18452     case NM_ABSQ_S_PH:
18453         check_dsp(ctx);
18454         gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
18455         gen_store_gpr(v0_t, ret);
18456         break;
18457     case NM_ABSQ_S_W:
18458         check_dsp(ctx);
18459         gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
18460         gen_store_gpr(v0_t, ret);
18461         break;
18462     case NM_PRECEQ_W_PHL:
18463         check_dsp(ctx);
18464         tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
18465         tcg_gen_ext32s_tl(v0_t, v0_t);
18466         gen_store_gpr(v0_t, ret);
18467         break;
18468     case NM_PRECEQ_W_PHR:
18469         check_dsp(ctx);
18470         tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
18471         tcg_gen_shli_tl(v0_t, v0_t, 16);
18472         tcg_gen_ext32s_tl(v0_t, v0_t);
18473         gen_store_gpr(v0_t, ret);
18474         break;
18475     case NM_PRECEQU_PH_QBL:
18476         check_dsp(ctx);
18477         gen_helper_precequ_ph_qbl(v0_t, v0_t);
18478         gen_store_gpr(v0_t, ret);
18479         break;
18480     case NM_PRECEQU_PH_QBR:
18481         check_dsp(ctx);
18482         gen_helper_precequ_ph_qbr(v0_t, v0_t);
18483         gen_store_gpr(v0_t, ret);
18484         break;
18485     case NM_PRECEQU_PH_QBLA:
18486         check_dsp(ctx);
18487         gen_helper_precequ_ph_qbla(v0_t, v0_t);
18488         gen_store_gpr(v0_t, ret);
18489         break;
18490     case NM_PRECEQU_PH_QBRA:
18491         check_dsp(ctx);
18492         gen_helper_precequ_ph_qbra(v0_t, v0_t);
18493         gen_store_gpr(v0_t, ret);
18494         break;
18495     case NM_PRECEU_PH_QBL:
18496         check_dsp(ctx);
18497         gen_helper_preceu_ph_qbl(v0_t, v0_t);
18498         gen_store_gpr(v0_t, ret);
18499         break;
18500     case NM_PRECEU_PH_QBR:
18501         check_dsp(ctx);
18502         gen_helper_preceu_ph_qbr(v0_t, v0_t);
18503         gen_store_gpr(v0_t, ret);
18504         break;
18505     case NM_PRECEU_PH_QBLA:
18506         check_dsp(ctx);
18507         gen_helper_preceu_ph_qbla(v0_t, v0_t);
18508         gen_store_gpr(v0_t, ret);
18509         break;
18510     case NM_PRECEU_PH_QBRA:
18511         check_dsp(ctx);
18512         gen_helper_preceu_ph_qbra(v0_t, v0_t);
18513         gen_store_gpr(v0_t, ret);
18514         break;
18515     case NM_REPLV_PH:
18516         check_dsp(ctx);
18517         tcg_gen_ext16u_tl(v0_t, v0_t);
18518         tcg_gen_shli_tl(t0, v0_t, 16);
18519         tcg_gen_or_tl(v0_t, v0_t, t0);
18520         tcg_gen_ext32s_tl(v0_t, v0_t);
18521         gen_store_gpr(v0_t, ret);
18522         break;
18523     case NM_REPLV_QB:
18524         check_dsp(ctx);
18525         tcg_gen_ext8u_tl(v0_t, v0_t);
18526         tcg_gen_shli_tl(t0, v0_t, 8);
18527         tcg_gen_or_tl(v0_t, v0_t, t0);
18528         tcg_gen_shli_tl(t0, v0_t, 16);
18529         tcg_gen_or_tl(v0_t, v0_t, t0);
18530         tcg_gen_ext32s_tl(v0_t, v0_t);
18531         gen_store_gpr(v0_t, ret);
18532         break;
18533     case NM_BITREV:
18534         check_dsp(ctx);
18535         gen_helper_bitrev(v0_t, v0_t);
18536         gen_store_gpr(v0_t, ret);
18537         break;
18538     case NM_INSV:
18539         check_dsp(ctx);
18540         {
18541             TCGv tv0 = tcg_temp_new();
18542
18543             gen_load_gpr(tv0, rt);
18544             gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
18545             gen_store_gpr(v0_t, ret);
18546             tcg_temp_free(tv0);
18547         }
18548         break;
18549     case NM_RADDU_W_QB:
18550         check_dsp(ctx);
18551         gen_helper_raddu_w_qb(v0_t, v0_t);
18552         gen_store_gpr(v0_t, ret);
18553         break;
18554     case NM_BITSWAP:
18555         gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
18556         break;
18557     case NM_CLO:
18558         check_nms(ctx);
18559         gen_cl(ctx, OPC_CLO, ret, rs);
18560         break;
18561     case NM_CLZ:
18562         check_nms(ctx);
18563         gen_cl(ctx, OPC_CLZ, ret, rs);
18564         break;
18565     case NM_WSBH:
18566         gen_bshfl(ctx, OPC_WSBH, ret, rs);
18567         break;
18568     default:
18569         generate_exception_end(ctx, EXCP_RI);
18570         break;
18571     }
18572
18573     tcg_temp_free(v0_t);
18574     tcg_temp_free(t0);
18575 }
18576
18577 static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
18578                                           int rt, int rs, int rd)
18579 {
18580     TCGv t0 = tcg_temp_new();
18581     TCGv rs_t = tcg_temp_new();
18582
18583     gen_load_gpr(rs_t, rs);
18584
18585     switch (opc) {
18586     case NM_SHRA_R_QB:
18587         check_dsp_r2(ctx);
18588         tcg_gen_movi_tl(t0, rd >> 2);
18589         switch (extract32(ctx->opcode, 12, 1)) {
18590         case 0:
18591             /* NM_SHRA_QB */
18592             gen_helper_shra_qb(t0, t0, rs_t);
18593             gen_store_gpr(t0, rt);
18594             break;
18595         case 1:
18596             /* NM_SHRA_R_QB */
18597             gen_helper_shra_r_qb(t0, t0, rs_t);
18598             gen_store_gpr(t0, rt);
18599             break;
18600         }
18601         break;
18602     case NM_SHRL_PH:
18603         check_dsp_r2(ctx);
18604         tcg_gen_movi_tl(t0, rd >> 1);
18605         gen_helper_shrl_ph(t0, t0, rs_t);
18606         gen_store_gpr(t0, rt);
18607         break;
18608     case NM_REPL_QB:
18609         check_dsp(ctx);
18610         {
18611             int16_t imm;
18612             target_long result;
18613             imm = extract32(ctx->opcode, 13, 8);
18614             result = (uint32_t)imm << 24 |
18615                      (uint32_t)imm << 16 |
18616                      (uint32_t)imm << 8  |
18617                      (uint32_t)imm;
18618             result = (int32_t)result;
18619             tcg_gen_movi_tl(t0, result);
18620             gen_store_gpr(t0, rt);
18621         }
18622         break;
18623     default:
18624         generate_exception_end(ctx, EXCP_RI);
18625         break;
18626     }
18627     tcg_temp_free(t0);
18628     tcg_temp_free(rs_t);
18629 }
18630
18631
18632 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18633 {
18634     int rt = extract32(ctx->opcode, 21, 5);
18635     int rs = extract32(ctx->opcode, 16, 5);
18636     int rd = extract32(ctx->opcode, 11, 5);
18637
18638     switch (extract32(ctx->opcode, 6, 3)) {
18639     case NM_POOL32AXF_1:
18640         {
18641             int32_t op1 = extract32(ctx->opcode, 9, 3);
18642             gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
18643         }
18644         break;
18645     case NM_POOL32AXF_2:
18646         {
18647             int32_t op1 = extract32(ctx->opcode, 12, 2);
18648             gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
18649         }
18650         break;
18651     case NM_POOL32AXF_4:
18652         {
18653             int32_t op1 = extract32(ctx->opcode, 9, 7);
18654             gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
18655         }
18656         break;
18657     case NM_POOL32AXF_5:
18658         switch (extract32(ctx->opcode, 9, 7)) {
18659 #ifndef CONFIG_USER_ONLY
18660         case NM_TLBP:
18661             gen_cp0(env, ctx, OPC_TLBP, 0, 0);
18662             break;
18663         case NM_TLBR:
18664             gen_cp0(env, ctx, OPC_TLBR, 0, 0);
18665             break;
18666         case NM_TLBWI:
18667             gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
18668             break;
18669         case NM_TLBWR:
18670             gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
18671             break;
18672         case NM_TLBINV:
18673             gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
18674             break;
18675         case NM_TLBINVF:
18676             gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
18677             break;
18678         case NM_DI:
18679             check_cp0_enabled(ctx);
18680             {
18681                 TCGv t0 = tcg_temp_new();
18682
18683                 save_cpu_state(ctx, 1);
18684                 gen_helper_di(t0, cpu_env);
18685                 gen_store_gpr(t0, rt);
18686             /* Stop translation as we may have switched the execution mode */
18687                 ctx->base.is_jmp = DISAS_STOP;
18688                 tcg_temp_free(t0);
18689             }
18690             break;
18691         case NM_EI:
18692             check_cp0_enabled(ctx);
18693             {
18694                 TCGv t0 = tcg_temp_new();
18695
18696                 save_cpu_state(ctx, 1);
18697                 gen_helper_ei(t0, cpu_env);
18698                 gen_store_gpr(t0, rt);
18699             /* Stop translation as we may have switched the execution mode */
18700                 ctx->base.is_jmp = DISAS_STOP;
18701                 tcg_temp_free(t0);
18702             }
18703             break;
18704         case NM_RDPGPR:
18705             gen_load_srsgpr(rs, rt);
18706             break;
18707         case NM_WRPGPR:
18708             gen_store_srsgpr(rs, rt);
18709             break;
18710         case NM_WAIT:
18711             gen_cp0(env, ctx, OPC_WAIT, 0, 0);
18712             break;
18713         case NM_DERET:
18714             gen_cp0(env, ctx, OPC_DERET, 0, 0);
18715             break;
18716         case NM_ERETX:
18717             gen_cp0(env, ctx, OPC_ERET, 0, 0);
18718             break;
18719 #endif
18720         default:
18721             generate_exception_end(ctx, EXCP_RI);
18722             break;
18723         }
18724         break;
18725     case NM_POOL32AXF_7:
18726         {
18727             int32_t op1 = extract32(ctx->opcode, 9, 3);
18728             gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
18729         }
18730         break;
18731     default:
18732         generate_exception_end(ctx, EXCP_RI);
18733         break;
18734     }
18735 }
18736
18737 /* Immediate Value Compact Branches */
18738 static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
18739                                    int rt, int32_t imm, int32_t offset)
18740 {
18741     TCGCond cond;
18742     int bcond_compute = 0;
18743     TCGv t0 = tcg_temp_new();
18744     TCGv t1 = tcg_temp_new();
18745
18746     gen_load_gpr(t0, rt);
18747     tcg_gen_movi_tl(t1, imm);
18748     ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18749
18750     /* Load needed operands and calculate btarget */
18751     switch (opc) {
18752     case NM_BEQIC:
18753         if (rt == 0 && imm == 0) {
18754             /* Unconditional branch */
18755         } else if (rt == 0 && imm != 0) {
18756             /* Treat as NOP */
18757             goto out;
18758         } else {
18759             bcond_compute = 1;
18760             cond = TCG_COND_EQ;
18761         }
18762         break;
18763     case NM_BBEQZC:
18764     case NM_BBNEZC:
18765         check_nms(ctx);
18766         if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
18767             generate_exception_end(ctx, EXCP_RI);
18768             goto out;
18769         } else if (rt == 0 && opc == NM_BBEQZC) {
18770             /* Unconditional branch */
18771         } else if (rt == 0 && opc == NM_BBNEZC) {
18772             /* Treat as NOP */
18773             goto out;
18774         } else {
18775             tcg_gen_shri_tl(t0, t0, imm);
18776             tcg_gen_andi_tl(t0, t0, 1);
18777             tcg_gen_movi_tl(t1, 0);
18778             bcond_compute = 1;
18779             if (opc == NM_BBEQZC) {
18780                 cond = TCG_COND_EQ;
18781             } else {
18782                 cond = TCG_COND_NE;
18783             }
18784         }
18785         break;
18786     case NM_BNEIC:
18787         if (rt == 0 && imm == 0) {
18788             /* Treat as NOP */
18789             goto out;
18790         } else if (rt == 0 && imm != 0) {
18791             /* Unconditional branch */
18792         } else {
18793             bcond_compute = 1;
18794             cond = TCG_COND_NE;
18795         }
18796         break;
18797     case NM_BGEIC:
18798         if (rt == 0 && imm == 0) {
18799             /* Unconditional branch */
18800         } else  {
18801             bcond_compute = 1;
18802             cond = TCG_COND_GE;
18803         }
18804         break;
18805     case NM_BLTIC:
18806         bcond_compute = 1;
18807         cond = TCG_COND_LT;
18808         break;
18809     case NM_BGEIUC:
18810         if (rt == 0 && imm == 0) {
18811             /* Unconditional branch */
18812         } else  {
18813             bcond_compute = 1;
18814             cond = TCG_COND_GEU;
18815         }
18816         break;
18817     case NM_BLTIUC:
18818         bcond_compute = 1;
18819         cond = TCG_COND_LTU;
18820         break;
18821     default:
18822         MIPS_INVAL("Immediate Value Compact branch");
18823         generate_exception_end(ctx, EXCP_RI);
18824         goto out;
18825     }
18826
18827     if (bcond_compute == 0) {
18828         /* Uncoditional compact branch */
18829         gen_goto_tb(ctx, 0, ctx->btarget);
18830     } else {
18831         /* Conditional compact branch */
18832         TCGLabel *fs = gen_new_label();
18833
18834         tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
18835
18836         gen_goto_tb(ctx, 1, ctx->btarget);
18837         gen_set_label(fs);
18838
18839         gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
18840     }
18841
18842 out:
18843     tcg_temp_free(t0);
18844     tcg_temp_free(t1);
18845 }
18846
18847 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
18848 static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
18849                                                 int rt)
18850 {
18851     TCGv t0 = tcg_temp_new();
18852     TCGv t1 = tcg_temp_new();
18853
18854     /* load rs */
18855     gen_load_gpr(t0, rs);
18856
18857     /* link */
18858     if (rt != 0) {
18859         tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
18860     }
18861
18862     /* calculate btarget */
18863     tcg_gen_shli_tl(t0, t0, 1);
18864     tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
18865     gen_op_addr_add(ctx, btarget, t1, t0);
18866
18867     /* unconditional branch to register */
18868     tcg_gen_mov_tl(cpu_PC, btarget);
18869     tcg_gen_lookup_and_goto_ptr();
18870
18871     tcg_temp_free(t0);
18872     tcg_temp_free(t1);
18873 }
18874
18875 /* nanoMIPS Branches */
18876 static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
18877                                        int rs, int rt, int32_t offset)
18878 {
18879     int bcond_compute = 0;
18880     TCGv t0 = tcg_temp_new();
18881     TCGv t1 = tcg_temp_new();
18882
18883     /* Load needed operands and calculate btarget */
18884     switch (opc) {
18885     /* compact branch */
18886     case OPC_BGEC:
18887     case OPC_BLTC:
18888         gen_load_gpr(t0, rs);
18889         gen_load_gpr(t1, rt);
18890         bcond_compute = 1;
18891         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18892         break;
18893     case OPC_BGEUC:
18894     case OPC_BLTUC:
18895         if (rs == 0 || rs == rt) {
18896             /* OPC_BLEZALC, OPC_BGEZALC */
18897             /* OPC_BGTZALC, OPC_BLTZALC */
18898             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
18899         }
18900         gen_load_gpr(t0, rs);
18901         gen_load_gpr(t1, rt);
18902         bcond_compute = 1;
18903         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18904         break;
18905     case OPC_BC:
18906         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18907         break;
18908     case OPC_BEQZC:
18909         if (rs != 0) {
18910             /* OPC_BEQZC, OPC_BNEZC */
18911             gen_load_gpr(t0, rs);
18912             bcond_compute = 1;
18913             ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
18914         } else {
18915             /* OPC_JIC, OPC_JIALC */
18916             TCGv tbase = tcg_temp_new();
18917             TCGv toffset = tcg_temp_new();
18918
18919             gen_load_gpr(tbase, rt);
18920             tcg_gen_movi_tl(toffset, offset);
18921             gen_op_addr_add(ctx, btarget, tbase, toffset);
18922             tcg_temp_free(tbase);
18923             tcg_temp_free(toffset);
18924         }
18925         break;
18926     default:
18927         MIPS_INVAL("Compact branch/jump");
18928         generate_exception_end(ctx, EXCP_RI);
18929         goto out;
18930     }
18931
18932     if (bcond_compute == 0) {
18933         /* Uncoditional compact branch */
18934         switch (opc) {
18935         case OPC_BC:
18936             gen_goto_tb(ctx, 0, ctx->btarget);
18937             break;
18938         default:
18939             MIPS_INVAL("Compact branch/jump");
18940             generate_exception_end(ctx, EXCP_RI);
18941             goto out;
18942         }
18943     } else {
18944         /* Conditional compact branch */
18945         TCGLabel *fs = gen_new_label();
18946
18947         switch (opc) {
18948         case OPC_BGEUC:
18949             if (rs == 0 && rt != 0) {
18950                 /* OPC_BLEZALC */
18951                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
18952             } else if (rs != 0 && rt != 0 && rs == rt) {
18953                 /* OPC_BGEZALC */
18954                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
18955             } else {
18956                 /* OPC_BGEUC */
18957                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
18958             }
18959             break;
18960         case OPC_BLTUC:
18961             if (rs == 0 && rt != 0) {
18962                 /* OPC_BGTZALC */
18963                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
18964             } else if (rs != 0 && rt != 0 && rs == rt) {
18965                 /* OPC_BLTZALC */
18966                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
18967             } else {
18968                 /* OPC_BLTUC */
18969                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
18970             }
18971             break;
18972         case OPC_BGEC:
18973             if (rs == 0 && rt != 0) {
18974                 /* OPC_BLEZC */
18975                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
18976             } else if (rs != 0 && rt != 0 && rs == rt) {
18977                 /* OPC_BGEZC */
18978                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
18979             } else {
18980                 /* OPC_BGEC */
18981                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
18982             }
18983             break;
18984         case OPC_BLTC:
18985             if (rs == 0 && rt != 0) {
18986                 /* OPC_BGTZC */
18987                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
18988             } else if (rs != 0 && rt != 0 && rs == rt) {
18989                 /* OPC_BLTZC */
18990                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
18991             } else {
18992                 /* OPC_BLTC */
18993                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
18994             }
18995             break;
18996         case OPC_BEQZC:
18997             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
18998             break;
18999         default:
19000             MIPS_INVAL("Compact conditional branch/jump");
19001             generate_exception_end(ctx, EXCP_RI);
19002             goto out;
19003         }
19004
19005         /* Generating branch here as compact branches don't have delay slot */
19006         gen_goto_tb(ctx, 1, ctx->btarget);
19007         gen_set_label(fs);
19008
19009         gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19010     }
19011
19012 out:
19013     tcg_temp_free(t0);
19014     tcg_temp_free(t1);
19015 }
19016
19017
19018 /* nanoMIPS CP1 Branches */
19019 static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
19020                                    int32_t ft, int32_t offset)
19021 {
19022     target_ulong btarget;
19023     TCGv_i64 t0 = tcg_temp_new_i64();
19024
19025     gen_load_fpr64(ctx, t0, ft);
19026     tcg_gen_andi_i64(t0, t0, 1);
19027
19028     btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19029
19030     switch (op) {
19031     case NM_BC1EQZC:
19032         tcg_gen_xori_i64(t0, t0, 1);
19033         ctx->hflags |= MIPS_HFLAG_BC;
19034         break;
19035     case NM_BC1NEZC:
19036         /* t0 already set */
19037         ctx->hflags |= MIPS_HFLAG_BC;
19038         break;
19039     default:
19040         MIPS_INVAL("cp1 cond branch");
19041         generate_exception_end(ctx, EXCP_RI);
19042         goto out;
19043     }
19044
19045     tcg_gen_trunc_i64_tl(bcond, t0);
19046
19047     ctx->btarget = btarget;
19048
19049 out:
19050     tcg_temp_free_i64(t0);
19051 }
19052
19053
19054 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
19055 {
19056     TCGv t0, t1;
19057     t0 = tcg_temp_new();
19058     t1 = tcg_temp_new();
19059
19060     gen_load_gpr(t0, rs);
19061     gen_load_gpr(t1, rt);
19062
19063     if ((extract32(ctx->opcode, 6, 1)) == 1) {
19064         /* PP.LSXS instructions require shifting */
19065         switch (extract32(ctx->opcode, 7, 4)) {
19066         case NM_SHXS:
19067             check_nms(ctx);
19068         case NM_LHXS:
19069         case NM_LHUXS:
19070             tcg_gen_shli_tl(t0, t0, 1);
19071             break;
19072         case NM_SWXS:
19073             check_nms(ctx);
19074         case NM_LWXS:
19075         case NM_LWC1XS:
19076         case NM_SWC1XS:
19077             tcg_gen_shli_tl(t0, t0, 2);
19078             break;
19079         case NM_LDC1XS:
19080         case NM_SDC1XS:
19081             tcg_gen_shli_tl(t0, t0, 3);
19082             break;
19083         }
19084     }
19085     gen_op_addr_add(ctx, t0, t0, t1);
19086
19087     switch (extract32(ctx->opcode, 7, 4)) {
19088     case NM_LBX:
19089         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19090                            MO_SB);
19091         gen_store_gpr(t0, rd);
19092         break;
19093     case NM_LHX:
19094     /*case NM_LHXS:*/
19095         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19096                            MO_TESW);
19097         gen_store_gpr(t0, rd);
19098         break;
19099     case NM_LWX:
19100     /*case NM_LWXS:*/
19101         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19102                            MO_TESL);
19103         gen_store_gpr(t0, rd);
19104         break;
19105     case NM_LBUX:
19106         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19107                            MO_UB);
19108         gen_store_gpr(t0, rd);
19109         break;
19110     case NM_LHUX:
19111     /*case NM_LHUXS:*/
19112         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19113                            MO_TEUW);
19114         gen_store_gpr(t0, rd);
19115         break;
19116     case NM_SBX:
19117         check_nms(ctx);
19118         gen_load_gpr(t1, rd);
19119         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19120                            MO_8);
19121         break;
19122     case NM_SHX:
19123     /*case NM_SHXS:*/
19124         check_nms(ctx);
19125         gen_load_gpr(t1, rd);
19126         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19127                            MO_TEUW);
19128         break;
19129     case NM_SWX:
19130     /*case NM_SWXS:*/
19131         check_nms(ctx);
19132         gen_load_gpr(t1, rd);
19133         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19134                            MO_TEUL);
19135         break;
19136     case NM_LWC1X:
19137     /*case NM_LWC1XS:*/
19138     case NM_LDC1X:
19139     /*case NM_LDC1XS:*/
19140     case NM_SWC1X:
19141     /*case NM_SWC1XS:*/
19142     case NM_SDC1X:
19143     /*case NM_SDC1XS:*/
19144         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19145             check_cp1_enabled(ctx);
19146             switch (extract32(ctx->opcode, 7, 4)) {
19147             case NM_LWC1X:
19148             /*case NM_LWC1XS:*/
19149                 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
19150                 break;
19151             case NM_LDC1X:
19152             /*case NM_LDC1XS:*/
19153                 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
19154                 break;
19155             case NM_SWC1X:
19156             /*case NM_SWC1XS:*/
19157                 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
19158                 break;
19159             case NM_SDC1X:
19160             /*case NM_SDC1XS:*/
19161                 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
19162                 break;
19163             }
19164         } else {
19165             generate_exception_err(ctx, EXCP_CpU, 1);
19166         }
19167         break;
19168     default:
19169         generate_exception_end(ctx, EXCP_RI);
19170         break;
19171     }
19172
19173     tcg_temp_free(t0);
19174     tcg_temp_free(t1);
19175 }
19176
19177 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
19178 {
19179     int rt, rs, rd;
19180
19181     rt = extract32(ctx->opcode, 21, 5);
19182     rs = extract32(ctx->opcode, 16, 5);
19183     rd = extract32(ctx->opcode, 11, 5);
19184
19185     if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
19186         generate_exception_end(ctx, EXCP_RI);
19187         return;
19188     }
19189     check_cp1_enabled(ctx);
19190     switch (extract32(ctx->opcode, 0, 3)) {
19191     case NM_POOL32F_0:
19192         switch (extract32(ctx->opcode, 3, 7)) {
19193         case NM_RINT_S:
19194             gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
19195             break;
19196         case NM_RINT_D:
19197             gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
19198             break;
19199         case NM_CLASS_S:
19200             gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
19201             break;
19202         case NM_CLASS_D:
19203             gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
19204             break;
19205         case NM_ADD_S:
19206             gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
19207             break;
19208         case NM_ADD_D:
19209             gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
19210             break;
19211         case NM_SUB_S:
19212             gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
19213             break;
19214         case NM_SUB_D:
19215             gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
19216             break;
19217         case NM_MUL_S:
19218             gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
19219             break;
19220         case NM_MUL_D:
19221             gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
19222             break;
19223         case NM_DIV_S:
19224             gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
19225             break;
19226         case NM_DIV_D:
19227             gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
19228             break;
19229         case NM_SELEQZ_S:
19230             gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
19231             break;
19232         case NM_SELEQZ_D:
19233             gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
19234             break;
19235         case NM_SELNEZ_S:
19236             gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
19237             break;
19238         case NM_SELNEZ_D:
19239             gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
19240             break;
19241         case NM_SEL_S:
19242             gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
19243             break;
19244         case NM_SEL_D:
19245             gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
19246             break;
19247         case NM_MADDF_S:
19248             gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
19249             break;
19250         case NM_MADDF_D:
19251             gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
19252             break;
19253         case NM_MSUBF_S:
19254             gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
19255             break;
19256         case NM_MSUBF_D:
19257             gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
19258             break;
19259         default:
19260             generate_exception_end(ctx, EXCP_RI);
19261             break;
19262         }
19263         break;
19264     case NM_POOL32F_3:
19265         switch (extract32(ctx->opcode, 3, 3)) {
19266         case NM_MIN_FMT:
19267             switch (extract32(ctx->opcode, 9, 1)) {
19268             case FMT_SDPS_S:
19269                 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
19270                 break;
19271             case FMT_SDPS_D:
19272                 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
19273                 break;
19274             }
19275             break;
19276         case NM_MAX_FMT:
19277             switch (extract32(ctx->opcode, 9, 1)) {
19278             case FMT_SDPS_S:
19279                 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
19280                 break;
19281             case FMT_SDPS_D:
19282                 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
19283                 break;
19284             }
19285             break;
19286         case NM_MINA_FMT:
19287             switch (extract32(ctx->opcode, 9, 1)) {
19288             case FMT_SDPS_S:
19289                 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
19290                 break;
19291             case FMT_SDPS_D:
19292                 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
19293                 break;
19294             }
19295             break;
19296         case NM_MAXA_FMT:
19297             switch (extract32(ctx->opcode, 9, 1)) {
19298             case FMT_SDPS_S:
19299                 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
19300                 break;
19301             case FMT_SDPS_D:
19302                 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
19303                 break;
19304             }
19305             break;
19306         case NM_POOL32FXF:
19307             switch (extract32(ctx->opcode, 6, 8)) {
19308             case NM_CFC1:
19309                 gen_cp1(ctx, OPC_CFC1, rt, rs);
19310                 break;
19311             case NM_CTC1:
19312                 gen_cp1(ctx, OPC_CTC1, rt, rs);
19313                 break;
19314             case NM_MFC1:
19315                 gen_cp1(ctx, OPC_MFC1, rt, rs);
19316                 break;
19317             case NM_MTC1:
19318                 gen_cp1(ctx, OPC_MTC1, rt, rs);
19319                 break;
19320             case NM_MFHC1:
19321                 gen_cp1(ctx, OPC_MFHC1, rt, rs);
19322                 break;
19323             case NM_MTHC1:
19324                 gen_cp1(ctx, OPC_MTHC1, rt, rs);
19325                 break;
19326             case NM_CVT_S_PL:
19327                 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
19328                 break;
19329             case NM_CVT_S_PU:
19330                 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
19331                 break;
19332             default:
19333                 switch (extract32(ctx->opcode, 6, 9)) {
19334                 case NM_CVT_L_S:
19335                     gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
19336                     break;
19337                 case NM_CVT_L_D:
19338                     gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
19339                     break;
19340                 case NM_CVT_W_S:
19341                     gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
19342                     break;
19343                 case NM_CVT_W_D:
19344                     gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
19345                     break;
19346                 case NM_RSQRT_S:
19347                     gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
19348                     break;
19349                 case NM_RSQRT_D:
19350                     gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
19351                     break;
19352                 case NM_SQRT_S:
19353                     gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
19354                     break;
19355                 case NM_SQRT_D:
19356                     gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
19357                     break;
19358                 case NM_RECIP_S:
19359                     gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
19360                     break;
19361                 case NM_RECIP_D:
19362                     gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
19363                     break;
19364                 case NM_FLOOR_L_S:
19365                     gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
19366                     break;
19367                 case NM_FLOOR_L_D:
19368                     gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
19369                     break;
19370                 case NM_FLOOR_W_S:
19371                     gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
19372                     break;
19373                 case NM_FLOOR_W_D:
19374                     gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
19375                     break;
19376                 case NM_CEIL_L_S:
19377                     gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
19378                     break;
19379                 case NM_CEIL_L_D:
19380                     gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
19381                     break;
19382                 case NM_CEIL_W_S:
19383                     gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
19384                     break;
19385                 case NM_CEIL_W_D:
19386                     gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
19387                     break;
19388                 case NM_TRUNC_L_S:
19389                     gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
19390                     break;
19391                 case NM_TRUNC_L_D:
19392                     gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
19393                     break;
19394                 case NM_TRUNC_W_S:
19395                     gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
19396                     break;
19397                 case NM_TRUNC_W_D:
19398                     gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
19399                     break;
19400                 case NM_ROUND_L_S:
19401                     gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
19402                     break;
19403                 case NM_ROUND_L_D:
19404                     gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
19405                     break;
19406                 case NM_ROUND_W_S:
19407                     gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
19408                     break;
19409                 case NM_ROUND_W_D:
19410                     gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
19411                     break;
19412                 case NM_MOV_S:
19413                     gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
19414                     break;
19415                 case NM_MOV_D:
19416                     gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
19417                     break;
19418                 case NM_ABS_S:
19419                     gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
19420                     break;
19421                 case NM_ABS_D:
19422                     gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
19423                     break;
19424                 case NM_NEG_S:
19425                     gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
19426                     break;
19427                 case NM_NEG_D:
19428                     gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
19429                     break;
19430                 case NM_CVT_D_S:
19431                     gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
19432                     break;
19433                 case NM_CVT_D_W:
19434                     gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
19435                     break;
19436                 case NM_CVT_D_L:
19437                     gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
19438                     break;
19439                 case NM_CVT_S_D:
19440                     gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
19441                     break;
19442                 case NM_CVT_S_W:
19443                     gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
19444                     break;
19445                 case NM_CVT_S_L:
19446                     gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
19447                     break;
19448                 default:
19449                     generate_exception_end(ctx, EXCP_RI);
19450                     break;
19451                 }
19452                 break;
19453             }
19454             break;
19455         }
19456         break;
19457     case NM_POOL32F_5:
19458         switch (extract32(ctx->opcode, 3, 3)) {
19459         case NM_CMP_CONDN_S:
19460             gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
19461             break;
19462         case NM_CMP_CONDN_D:
19463             gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
19464             break;
19465         default:
19466             generate_exception_end(ctx, EXCP_RI);
19467             break;
19468         }
19469         break;
19470     default:
19471         generate_exception_end(ctx, EXCP_RI);
19472         break;
19473     }
19474 }
19475
19476 static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
19477                                        int rd, int rs, int rt)
19478 {
19479     int ret = rd;
19480     TCGv t0 = tcg_temp_new();
19481     TCGv v1_t = tcg_temp_new();
19482     TCGv v2_t = tcg_temp_new();
19483
19484     gen_load_gpr(v1_t, rs);
19485     gen_load_gpr(v2_t, rt);
19486
19487     switch (opc) {
19488     case NM_CMP_EQ_PH:
19489         check_dsp(ctx);
19490         gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
19491         break;
19492     case NM_CMP_LT_PH:
19493         check_dsp(ctx);
19494         gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
19495         break;
19496     case NM_CMP_LE_PH:
19497         check_dsp(ctx);
19498         gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
19499         break;
19500     case NM_CMPU_EQ_QB:
19501         check_dsp(ctx);
19502         gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
19503         break;
19504     case NM_CMPU_LT_QB:
19505         check_dsp(ctx);
19506         gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
19507         break;
19508     case NM_CMPU_LE_QB:
19509         check_dsp(ctx);
19510         gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
19511         break;
19512     case NM_CMPGU_EQ_QB:
19513         check_dsp(ctx);
19514         gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
19515         gen_store_gpr(v1_t, ret);
19516         break;
19517     case NM_CMPGU_LT_QB:
19518         check_dsp(ctx);
19519         gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
19520         gen_store_gpr(v1_t, ret);
19521         break;
19522     case NM_CMPGU_LE_QB:
19523         check_dsp(ctx);
19524         gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
19525         gen_store_gpr(v1_t, ret);
19526         break;
19527     case NM_CMPGDU_EQ_QB:
19528         check_dsp_r2(ctx);
19529         gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
19530         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19531         gen_store_gpr(v1_t, ret);
19532         break;
19533     case NM_CMPGDU_LT_QB:
19534         check_dsp_r2(ctx);
19535         gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
19536         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19537         gen_store_gpr(v1_t, ret);
19538         break;
19539     case NM_CMPGDU_LE_QB:
19540         check_dsp_r2(ctx);
19541         gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
19542         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19543         gen_store_gpr(v1_t, ret);
19544         break;
19545     case NM_PACKRL_PH:
19546         check_dsp(ctx);
19547         gen_helper_packrl_ph(v1_t, v1_t, v2_t);
19548         gen_store_gpr(v1_t, ret);
19549         break;
19550     case NM_PICK_QB:
19551         check_dsp(ctx);
19552         gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
19553         gen_store_gpr(v1_t, ret);
19554         break;
19555     case NM_PICK_PH:
19556         check_dsp(ctx);
19557         gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
19558         gen_store_gpr(v1_t, ret);
19559         break;
19560     case NM_ADDQ_S_W:
19561         check_dsp(ctx);
19562         gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
19563         gen_store_gpr(v1_t, ret);
19564         break;
19565     case NM_SUBQ_S_W:
19566         check_dsp(ctx);
19567         gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
19568         gen_store_gpr(v1_t, ret);
19569         break;
19570     case NM_ADDSC:
19571         check_dsp(ctx);
19572         gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
19573         gen_store_gpr(v1_t, ret);
19574         break;
19575     case NM_ADDWC:
19576         check_dsp(ctx);
19577         gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
19578         gen_store_gpr(v1_t, ret);
19579         break;
19580     case NM_ADDQ_S_PH:
19581         check_dsp(ctx);
19582         switch (extract32(ctx->opcode, 10, 1)) {
19583         case 0:
19584             /* ADDQ_PH */
19585             gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
19586             gen_store_gpr(v1_t, ret);
19587             break;
19588         case 1:
19589             /* ADDQ_S_PH */
19590             gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
19591             gen_store_gpr(v1_t, ret);
19592             break;
19593         }
19594         break;
19595     case NM_ADDQH_R_PH:
19596         check_dsp_r2(ctx);
19597         switch (extract32(ctx->opcode, 10, 1)) {
19598         case 0:
19599             /* ADDQH_PH */
19600             gen_helper_addqh_ph(v1_t, v1_t, v2_t);
19601             gen_store_gpr(v1_t, ret);
19602             break;
19603         case 1:
19604             /* ADDQH_R_PH */
19605             gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
19606             gen_store_gpr(v1_t, ret);
19607             break;
19608         }
19609         break;
19610     case NM_ADDQH_R_W:
19611         check_dsp_r2(ctx);
19612         switch (extract32(ctx->opcode, 10, 1)) {
19613         case 0:
19614             /* ADDQH_W */
19615             gen_helper_addqh_w(v1_t, v1_t, v2_t);
19616             gen_store_gpr(v1_t, ret);
19617             break;
19618         case 1:
19619             /* ADDQH_R_W */
19620             gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
19621             gen_store_gpr(v1_t, ret);
19622             break;
19623         }
19624         break;
19625     case NM_ADDU_S_QB:
19626         check_dsp(ctx);
19627         switch (extract32(ctx->opcode, 10, 1)) {
19628         case 0:
19629             /* ADDU_QB */
19630             gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
19631             gen_store_gpr(v1_t, ret);
19632             break;
19633         case 1:
19634             /* ADDU_S_QB */
19635             gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
19636             gen_store_gpr(v1_t, ret);
19637             break;
19638         }
19639         break;
19640     case NM_ADDU_S_PH:
19641         check_dsp_r2(ctx);
19642         switch (extract32(ctx->opcode, 10, 1)) {
19643         case 0:
19644             /* ADDU_PH */
19645             gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
19646             gen_store_gpr(v1_t, ret);
19647             break;
19648         case 1:
19649             /* ADDU_S_PH */
19650             gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
19651             gen_store_gpr(v1_t, ret);
19652             break;
19653         }
19654         break;
19655     case NM_ADDUH_R_QB:
19656         check_dsp_r2(ctx);
19657         switch (extract32(ctx->opcode, 10, 1)) {
19658         case 0:
19659             /* ADDUH_QB */
19660             gen_helper_adduh_qb(v1_t, v1_t, v2_t);
19661             gen_store_gpr(v1_t, ret);
19662             break;
19663         case 1:
19664             /* ADDUH_R_QB */
19665             gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
19666             gen_store_gpr(v1_t, ret);
19667             break;
19668         }
19669         break;
19670     case NM_SHRAV_R_PH:
19671         check_dsp(ctx);
19672         switch (extract32(ctx->opcode, 10, 1)) {
19673         case 0:
19674             /* SHRAV_PH */
19675             gen_helper_shra_ph(v1_t, v1_t, v2_t);
19676             gen_store_gpr(v1_t, ret);
19677             break;
19678         case 1:
19679             /* SHRAV_R_PH */
19680             gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
19681             gen_store_gpr(v1_t, ret);
19682             break;
19683         }
19684         break;
19685     case NM_SHRAV_R_QB:
19686         check_dsp_r2(ctx);
19687         switch (extract32(ctx->opcode, 10, 1)) {
19688         case 0:
19689             /* SHRAV_QB */
19690             gen_helper_shra_qb(v1_t, v1_t, v2_t);
19691             gen_store_gpr(v1_t, ret);
19692             break;
19693         case 1:
19694             /* SHRAV_R_QB */
19695             gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
19696             gen_store_gpr(v1_t, ret);
19697             break;
19698         }
19699         break;
19700     case NM_SUBQ_S_PH:
19701         check_dsp(ctx);
19702         switch (extract32(ctx->opcode, 10, 1)) {
19703         case 0:
19704             /* SUBQ_PH */
19705             gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
19706             gen_store_gpr(v1_t, ret);
19707             break;
19708         case 1:
19709             /* SUBQ_S_PH */
19710             gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
19711             gen_store_gpr(v1_t, ret);
19712             break;
19713         }
19714         break;
19715     case NM_SUBQH_R_PH:
19716         check_dsp_r2(ctx);
19717         switch (extract32(ctx->opcode, 10, 1)) {
19718         case 0:
19719             /* SUBQH_PH */
19720             gen_helper_subqh_ph(v1_t, v1_t, v2_t);
19721             gen_store_gpr(v1_t, ret);
19722             break;
19723         case 1:
19724             /* SUBQH_R_PH */
19725             gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
19726             gen_store_gpr(v1_t, ret);
19727             break;
19728         }
19729         break;
19730     case NM_SUBQH_R_W:
19731         check_dsp_r2(ctx);
19732         switch (extract32(ctx->opcode, 10, 1)) {
19733         case 0:
19734             /* SUBQH_W */
19735             gen_helper_subqh_w(v1_t, v1_t, v2_t);
19736             gen_store_gpr(v1_t, ret);
19737             break;
19738         case 1:
19739             /* SUBQH_R_W */
19740             gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
19741             gen_store_gpr(v1_t, ret);
19742             break;
19743         }
19744         break;
19745     case NM_SUBU_S_QB:
19746         check_dsp(ctx);
19747         switch (extract32(ctx->opcode, 10, 1)) {
19748         case 0:
19749             /* SUBU_QB */
19750             gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
19751             gen_store_gpr(v1_t, ret);
19752             break;
19753         case 1:
19754             /* SUBU_S_QB */
19755             gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
19756             gen_store_gpr(v1_t, ret);
19757             break;
19758         }
19759         break;
19760     case NM_SUBU_S_PH:
19761         check_dsp_r2(ctx);
19762         switch (extract32(ctx->opcode, 10, 1)) {
19763         case 0:
19764             /* SUBU_PH */
19765             gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
19766             gen_store_gpr(v1_t, ret);
19767             break;
19768         case 1:
19769             /* SUBU_S_PH */
19770             gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
19771             gen_store_gpr(v1_t, ret);
19772             break;
19773         }
19774         break;
19775     case NM_SUBUH_R_QB:
19776         check_dsp_r2(ctx);
19777         switch (extract32(ctx->opcode, 10, 1)) {
19778         case 0:
19779             /* SUBUH_QB */
19780             gen_helper_subuh_qb(v1_t, v1_t, v2_t);
19781             gen_store_gpr(v1_t, ret);
19782             break;
19783         case 1:
19784             /* SUBUH_R_QB */
19785             gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
19786             gen_store_gpr(v1_t, ret);
19787             break;
19788         }
19789         break;
19790     case NM_SHLLV_S_PH:
19791         check_dsp(ctx);
19792         switch (extract32(ctx->opcode, 10, 1)) {
19793         case 0:
19794             /* SHLLV_PH */
19795             gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
19796             gen_store_gpr(v1_t, ret);
19797             break;
19798         case 1:
19799             /* SHLLV_S_PH */
19800             gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
19801             gen_store_gpr(v1_t, ret);
19802             break;
19803         }
19804         break;
19805     case NM_PRECR_SRA_R_PH_W:
19806         check_dsp_r2(ctx);
19807         switch (extract32(ctx->opcode, 10, 1)) {
19808         case 0:
19809             /* PRECR_SRA_PH_W */
19810             {
19811                 TCGv_i32 sa_t = tcg_const_i32(rd);
19812                 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
19813                                           cpu_gpr[rt]);
19814                 gen_store_gpr(v1_t, rt);
19815                 tcg_temp_free_i32(sa_t);
19816             }
19817             break;
19818         case 1:
19819             /* PRECR_SRA_R_PH_W */
19820             {
19821                 TCGv_i32 sa_t = tcg_const_i32(rd);
19822                 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
19823                                             cpu_gpr[rt]);
19824                 gen_store_gpr(v1_t, rt);
19825                 tcg_temp_free_i32(sa_t);
19826             }
19827             break;
19828        }
19829         break;
19830     case NM_MULEU_S_PH_QBL:
19831         check_dsp(ctx);
19832         gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
19833         gen_store_gpr(v1_t, ret);
19834         break;
19835     case NM_MULEU_S_PH_QBR:
19836         check_dsp(ctx);
19837         gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
19838         gen_store_gpr(v1_t, ret);
19839         break;
19840     case NM_MULQ_RS_PH:
19841         check_dsp(ctx);
19842         gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
19843         gen_store_gpr(v1_t, ret);
19844         break;
19845     case NM_MULQ_S_PH:
19846         check_dsp_r2(ctx);
19847         gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
19848         gen_store_gpr(v1_t, ret);
19849         break;
19850     case NM_MULQ_RS_W:
19851         check_dsp_r2(ctx);
19852         gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
19853         gen_store_gpr(v1_t, ret);
19854         break;
19855     case NM_MULQ_S_W:
19856         check_dsp_r2(ctx);
19857         gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
19858         gen_store_gpr(v1_t, ret);
19859         break;
19860     case NM_APPEND:
19861         check_dsp_r2(ctx);
19862         gen_load_gpr(t0, rs);
19863         if (rd != 0) {
19864             tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
19865         }
19866         tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
19867         break;
19868     case NM_MODSUB:
19869         check_dsp(ctx);
19870         gen_helper_modsub(v1_t, v1_t, v2_t);
19871         gen_store_gpr(v1_t, ret);
19872         break;
19873     case NM_SHRAV_R_W:
19874         check_dsp(ctx);
19875         gen_helper_shra_r_w(v1_t, v1_t, v2_t);
19876         gen_store_gpr(v1_t, ret);
19877         break;
19878     case NM_SHRLV_PH:
19879         check_dsp_r2(ctx);
19880         gen_helper_shrl_ph(v1_t, v1_t, v2_t);
19881         gen_store_gpr(v1_t, ret);
19882         break;
19883     case NM_SHRLV_QB:
19884         check_dsp(ctx);
19885         gen_helper_shrl_qb(v1_t, v1_t, v2_t);
19886         gen_store_gpr(v1_t, ret);
19887         break;
19888     case NM_SHLLV_QB:
19889         check_dsp(ctx);
19890         gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
19891         gen_store_gpr(v1_t, ret);
19892         break;
19893     case NM_SHLLV_S_W:
19894         check_dsp(ctx);
19895         gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
19896         gen_store_gpr(v1_t, ret);
19897         break;
19898     case NM_SHILO:
19899         check_dsp(ctx);
19900         {
19901             TCGv tv0 = tcg_temp_new();
19902             TCGv tv1 = tcg_temp_new();
19903             int16_t imm = extract32(ctx->opcode, 16, 7);
19904
19905             tcg_gen_movi_tl(tv0, rd >> 3);
19906             tcg_gen_movi_tl(tv1, imm);
19907             gen_helper_shilo(tv0, tv1, cpu_env);
19908         }
19909         break;
19910     case NM_MULEQ_S_W_PHL:
19911         check_dsp(ctx);
19912         gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
19913         gen_store_gpr(v1_t, ret);
19914         break;
19915     case NM_MULEQ_S_W_PHR:
19916         check_dsp(ctx);
19917         gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
19918         gen_store_gpr(v1_t, ret);
19919         break;
19920     case NM_MUL_S_PH:
19921         check_dsp_r2(ctx);
19922         switch (extract32(ctx->opcode, 10, 1)) {
19923         case 0:
19924             /* MUL_PH */
19925             gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
19926             gen_store_gpr(v1_t, ret);
19927             break;
19928         case 1:
19929             /* MUL_S_PH */
19930             gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
19931             gen_store_gpr(v1_t, ret);
19932             break;
19933         }
19934         break;
19935     case NM_PRECR_QB_PH:
19936         check_dsp_r2(ctx);
19937         gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
19938         gen_store_gpr(v1_t, ret);
19939         break;
19940     case NM_PRECRQ_QB_PH:
19941         check_dsp(ctx);
19942         gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
19943         gen_store_gpr(v1_t, ret);
19944         break;
19945     case NM_PRECRQ_PH_W:
19946         check_dsp(ctx);
19947         gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
19948         gen_store_gpr(v1_t, ret);
19949         break;
19950     case NM_PRECRQ_RS_PH_W:
19951         check_dsp(ctx);
19952         gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
19953         gen_store_gpr(v1_t, ret);
19954         break;
19955     case NM_PRECRQU_S_QB_PH:
19956         check_dsp(ctx);
19957         gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
19958         gen_store_gpr(v1_t, ret);
19959         break;
19960     case NM_SHRA_R_W:
19961         check_dsp(ctx);
19962         tcg_gen_movi_tl(t0, rd);
19963         gen_helper_shra_r_w(v1_t, t0, v1_t);
19964         gen_store_gpr(v1_t, rt);
19965         break;
19966     case NM_SHRA_R_PH:
19967         check_dsp(ctx);
19968         tcg_gen_movi_tl(t0, rd >> 1);
19969         switch (extract32(ctx->opcode, 10, 1)) {
19970         case 0:
19971             /* SHRA_PH */
19972             gen_helper_shra_ph(v1_t, t0, v1_t);
19973             break;
19974             gen_store_gpr(v1_t, rt);
19975         case 1:
19976             /* SHRA_R_PH */
19977             gen_helper_shra_r_ph(v1_t, t0, v1_t);
19978             gen_store_gpr(v1_t, rt);
19979             break;
19980         }
19981         break;
19982     case NM_SHLL_S_PH:
19983         check_dsp(ctx);
19984         tcg_gen_movi_tl(t0, rd >> 1);
19985         switch (extract32(ctx->opcode, 10, 2)) {
19986         case 0:
19987             /* SHLL_PH */
19988             gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
19989             gen_store_gpr(v1_t, rt);
19990             break;
19991         case 2:
19992             /* SHLL_S_PH */
19993             gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
19994             gen_store_gpr(v1_t, rt);
19995             break;
19996         default:
19997             generate_exception_end(ctx, EXCP_RI);
19998             break;
19999         }
20000         break;
20001     case NM_SHLL_S_W:
20002         check_dsp(ctx);
20003         tcg_gen_movi_tl(t0, rd);
20004         gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
20005         gen_store_gpr(v1_t, rt);
20006         break;
20007     case NM_REPL_PH:
20008         check_dsp(ctx);
20009         {
20010             int16_t imm;
20011             imm = sextract32(ctx->opcode, 11, 11);
20012             imm = (int16_t)(imm << 6) >> 6;
20013             if (rt != 0) {
20014                 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
20015             }
20016         }
20017         break;
20018     default:
20019         generate_exception_end(ctx, EXCP_RI);
20020         break;
20021     }
20022 }
20023
20024 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
20025 {
20026     uint16_t insn;
20027     uint32_t op;
20028     int rt, rs, rd;
20029     int offset;
20030     int imm;
20031
20032     insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
20033     ctx->opcode = (ctx->opcode << 16) | insn;
20034
20035     rt = extract32(ctx->opcode, 21, 5);
20036     rs = extract32(ctx->opcode, 16, 5);
20037     rd = extract32(ctx->opcode, 11, 5);
20038
20039     op = extract32(ctx->opcode, 26, 6);
20040     switch (op) {
20041     case NM_P_ADDIU:
20042         if (rt == 0) {
20043             /* P.RI */
20044             switch (extract32(ctx->opcode, 19, 2)) {
20045             case NM_SIGRIE:
20046             default:
20047                 generate_exception_end(ctx, EXCP_RI);
20048                 break;
20049             case NM_P_SYSCALL:
20050                 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
20051                     generate_exception_end(ctx, EXCP_SYSCALL);
20052                 } else {
20053                     generate_exception_end(ctx, EXCP_RI);
20054                 }
20055                 break;
20056             case NM_BREAK:
20057                 generate_exception_end(ctx, EXCP_BREAK);
20058                 break;
20059             case NM_SDBBP:
20060                 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
20061                     gen_helper_do_semihosting(cpu_env);
20062                 } else {
20063                     if (ctx->hflags & MIPS_HFLAG_SBRI) {
20064                         generate_exception_end(ctx, EXCP_RI);
20065                     } else {
20066                         generate_exception_end(ctx, EXCP_DBp);
20067                     }
20068                 }
20069                 break;
20070             }
20071         } else {
20072             /* NM_ADDIU */
20073             imm = extract32(ctx->opcode, 0, 16);
20074             if (rs != 0) {
20075                 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
20076             } else {
20077                 tcg_gen_movi_tl(cpu_gpr[rt], imm);
20078             }
20079             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20080         }
20081         break;
20082     case NM_ADDIUPC:
20083         if (rt != 0) {
20084             offset = sextract32(ctx->opcode, 0, 1) << 21 |
20085                      extract32(ctx->opcode, 1, 20) << 1;
20086             target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
20087             tcg_gen_movi_tl(cpu_gpr[rt], addr);
20088         }
20089         break;
20090     case NM_POOL32A:
20091         switch (ctx->opcode & 0x07) {
20092         case NM_POOL32A0:
20093             gen_pool32a0_nanomips_insn(env, ctx);
20094             break;
20095         case NM_POOL32A5:
20096             {
20097                 int32_t op1 = extract32(ctx->opcode, 3, 7);
20098                 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
20099             }
20100             break;
20101         case NM_POOL32A7:
20102             switch (extract32(ctx->opcode, 3, 3)) {
20103             case NM_P_LSX:
20104                 gen_p_lsx(ctx, rd, rs, rt);
20105                 break;
20106             case NM_LSA:
20107                 /* In nanoMIPS, the shift field directly encodes the shift
20108                  * amount, meaning that the supported shift values are in
20109                  * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
20110                 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
20111                         extract32(ctx->opcode, 9, 2) - 1);
20112                 break;
20113             case NM_EXTW:
20114                 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
20115                 break;
20116             case NM_POOL32AXF:
20117                 gen_pool32axf_nanomips_insn(env, ctx);
20118                 break;
20119             default:
20120                 generate_exception_end(ctx, EXCP_RI);
20121                 break;
20122             }
20123             break;
20124         default:
20125             generate_exception_end(ctx, EXCP_RI);
20126             break;
20127         }
20128         break;
20129     case NM_P_GP_W:
20130         switch (ctx->opcode & 0x03) {
20131         case NM_ADDIUGP_W:
20132             if (rt != 0) {
20133                 offset = extract32(ctx->opcode, 0, 21);
20134                 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
20135             }
20136             break;
20137         case NM_LWGP:
20138             gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20139             break;
20140         case NM_SWGP:
20141             gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20142             break;
20143         default:
20144             generate_exception_end(ctx, EXCP_RI);
20145             break;
20146         }
20147         break;
20148     case NM_P48I:
20149         {
20150             insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
20151             target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
20152             switch (extract32(ctx->opcode, 16, 5)) {
20153             case NM_LI48:
20154                 check_nms(ctx);
20155                 if (rt != 0) {
20156                     tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
20157                 }
20158                 break;
20159             case NM_ADDIU48:
20160                 check_nms(ctx);
20161                 if (rt != 0) {
20162                     tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
20163                     tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20164                 }
20165                 break;
20166             case NM_ADDIUGP48:
20167                 check_nms(ctx);
20168                 if (rt != 0) {
20169                     gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
20170                 }
20171                 break;
20172             case NM_ADDIUPC48:
20173                 check_nms(ctx);
20174                 if (rt != 0) {
20175                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20176                                                 addr_off);
20177
20178                     tcg_gen_movi_tl(cpu_gpr[rt], addr);
20179                 }
20180                 break;
20181             case NM_LWPC48:
20182                 check_nms(ctx);
20183                 if (rt != 0) {
20184                     TCGv t0;
20185                     t0 = tcg_temp_new();
20186
20187                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20188                                                 addr_off);
20189
20190                     tcg_gen_movi_tl(t0, addr);
20191                     tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
20192                     tcg_temp_free(t0);
20193                 }
20194                 break;
20195             case NM_SWPC48:
20196                 check_nms(ctx);
20197                 {
20198                     TCGv t0, t1;
20199                     t0 = tcg_temp_new();
20200                     t1 = tcg_temp_new();
20201
20202                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20203                                                 addr_off);
20204
20205                     tcg_gen_movi_tl(t0, addr);
20206                     gen_load_gpr(t1, rt);
20207
20208                     tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
20209
20210                     tcg_temp_free(t0);
20211                     tcg_temp_free(t1);
20212                 }
20213                 break;
20214             default:
20215                 generate_exception_end(ctx, EXCP_RI);
20216                 break;
20217             }
20218             return 6;
20219         }
20220     case NM_P_U12:
20221         switch (extract32(ctx->opcode, 12, 4)) {
20222         case NM_ORI:
20223             gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
20224             break;
20225         case NM_XORI:
20226             gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
20227             break;
20228         case NM_ANDI:
20229             gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
20230             break;
20231         case NM_P_SR:
20232             switch (extract32(ctx->opcode, 20, 1)) {
20233             case NM_PP_SR:
20234                 switch (ctx->opcode & 3) {
20235                 case NM_SAVE:
20236                     gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
20237                              extract32(ctx->opcode, 2, 1),
20238                              extract32(ctx->opcode, 3, 9) << 3);
20239                     break;
20240                 case NM_RESTORE:
20241                 case NM_RESTORE_JRC:
20242                     gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
20243                                 extract32(ctx->opcode, 2, 1),
20244                                 extract32(ctx->opcode, 3, 9) << 3);
20245                     if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
20246                         gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
20247                     }
20248                     break;
20249                 default:
20250                     generate_exception_end(ctx, EXCP_RI);
20251                     break;
20252                 }
20253                 break;
20254             case NM_P_SR_F:
20255                 generate_exception_end(ctx, EXCP_RI);
20256                 break;
20257             }
20258             break;
20259         case NM_SLTI:
20260             gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
20261             break;
20262         case NM_SLTIU:
20263             gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
20264             break;
20265         case NM_SEQI:
20266             {
20267                 TCGv t0 = tcg_temp_new();
20268
20269                 imm = extract32(ctx->opcode, 0, 12);
20270                 gen_load_gpr(t0, rs);
20271                 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
20272                 gen_store_gpr(t0, rt);
20273
20274                 tcg_temp_free(t0);
20275             }
20276             break;
20277         case NM_ADDIUNEG:
20278             imm = (int16_t) extract32(ctx->opcode, 0, 12);
20279             gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
20280             break;
20281         case NM_P_SHIFT:
20282             {
20283                 int shift = extract32(ctx->opcode, 0, 5);
20284                 switch (extract32(ctx->opcode, 5, 4)) {
20285                 case NM_P_SLL:
20286                     if (rt == 0 && shift == 0) {
20287                         /* NOP */
20288                     } else if (rt == 0 && shift == 3) {
20289                         /* EHB - treat as NOP */
20290                     } else if (rt == 0 && shift == 5) {
20291                         /* PAUSE - treat as NOP */
20292                     } else if (rt == 0 && shift == 6) {
20293                         /* SYNC */
20294                         gen_sync(extract32(ctx->opcode, 16, 5));
20295                     } else {
20296                         /* SLL */
20297                         gen_shift_imm(ctx, OPC_SLL, rt, rs,
20298                                       extract32(ctx->opcode, 0, 5));
20299                     }
20300                     break;
20301                 case NM_SRL:
20302                     gen_shift_imm(ctx, OPC_SRL, rt, rs,
20303                                   extract32(ctx->opcode, 0, 5));
20304                     break;
20305                 case NM_SRA:
20306                     gen_shift_imm(ctx, OPC_SRA, rt, rs,
20307                                   extract32(ctx->opcode, 0, 5));
20308                     break;
20309                 case NM_ROTR:
20310                     gen_shift_imm(ctx, OPC_ROTR, rt, rs,
20311                                   extract32(ctx->opcode, 0, 5));
20312                     break;
20313                 }
20314             }
20315             break;
20316         case NM_P_ROTX:
20317             check_nms(ctx);
20318             if (rt != 0) {
20319                 TCGv t0 = tcg_temp_new();
20320                 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
20321                 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
20322                                                 << 1);
20323                 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
20324
20325                 gen_load_gpr(t0, rs);
20326                 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
20327                 tcg_temp_free(t0);
20328
20329                 tcg_temp_free_i32(shift);
20330                 tcg_temp_free_i32(shiftx);
20331                 tcg_temp_free_i32(stripe);
20332             }
20333             break;
20334         case NM_P_INS:
20335             switch (((ctx->opcode >> 10) & 2) |
20336                     (extract32(ctx->opcode, 5, 1))) {
20337             case NM_INS:
20338                 check_nms(ctx);
20339                 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
20340                            extract32(ctx->opcode, 6, 5));
20341                 break;
20342             default:
20343                 generate_exception_end(ctx, EXCP_RI);
20344                 break;
20345             }
20346             break;
20347         case NM_P_EXT:
20348             switch (((ctx->opcode >> 10) & 2) |
20349                     (extract32(ctx->opcode, 5, 1))) {
20350             case NM_EXT:
20351                 check_nms(ctx);
20352                 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
20353                            extract32(ctx->opcode, 6, 5));
20354                 break;
20355             default:
20356                 generate_exception_end(ctx, EXCP_RI);
20357                 break;
20358             }
20359             break;
20360         default:
20361             generate_exception_end(ctx, EXCP_RI);
20362             break;
20363         }
20364         break;
20365     case NM_POOL32F:
20366         gen_pool32f_nanomips_insn(ctx);
20367         break;
20368     case NM_POOL32S:
20369         break;
20370     case NM_P_LUI:
20371         switch (extract32(ctx->opcode, 1, 1)) {
20372         case NM_LUI:
20373             if (rt != 0) {
20374                 tcg_gen_movi_tl(cpu_gpr[rt],
20375                                 sextract32(ctx->opcode, 0, 1) << 31 |
20376                                 extract32(ctx->opcode, 2, 10) << 21 |
20377                                 extract32(ctx->opcode, 12, 9) << 12);
20378             }
20379             break;
20380         case NM_ALUIPC:
20381             if (rt != 0) {
20382                 offset = sextract32(ctx->opcode, 0, 1) << 31 |
20383                          extract32(ctx->opcode, 2, 10) << 21 |
20384                          extract32(ctx->opcode, 12, 9) << 12;
20385                 target_long addr;
20386                 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
20387                 tcg_gen_movi_tl(cpu_gpr[rt], addr);
20388             }
20389             break;
20390         }
20391         break;
20392     case NM_P_GP_BH:
20393         {
20394             uint32_t u = extract32(ctx->opcode, 0, 18);
20395
20396             switch (extract32(ctx->opcode, 18, 3)) {
20397             case NM_LBGP:
20398                 gen_ld(ctx, OPC_LB, rt, 28, u);
20399                 break;
20400             case NM_SBGP:
20401                 gen_st(ctx, OPC_SB, rt, 28, u);
20402                 break;
20403             case NM_LBUGP:
20404                 gen_ld(ctx, OPC_LBU, rt, 28, u);
20405                 break;
20406             case NM_ADDIUGP_B:
20407                 if (rt != 0) {
20408                     gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
20409                 }
20410                 break;
20411             case NM_P_GP_LH:
20412                 u &= ~1;
20413                 switch (ctx->opcode & 1) {
20414                 case NM_LHGP:
20415                     gen_ld(ctx, OPC_LH, rt, 28, u);
20416                     break;
20417                 case NM_LHUGP:
20418                     gen_ld(ctx, OPC_LHU, rt, 28, u);
20419                     break;
20420                 }
20421                 break;
20422             case NM_P_GP_SH:
20423                 u &= ~1;
20424                 switch (ctx->opcode & 1) {
20425                 case NM_SHGP:
20426                     gen_st(ctx, OPC_SH, rt, 28, u);
20427                     break;
20428                 default:
20429                     generate_exception_end(ctx, EXCP_RI);
20430                     break;
20431                 }
20432                 break;
20433             case NM_P_GP_CP1:
20434                 u &= ~0x3;
20435                 switch (ctx->opcode & 0x3) {
20436                 case NM_LWC1GP:
20437                     gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
20438                     break;
20439                 case NM_LDC1GP:
20440                     gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
20441                     break;
20442                 case NM_SWC1GP:
20443                     gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
20444                     break;
20445                 case NM_SDC1GP:
20446                     gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
20447                     break;
20448                 }
20449                 break;
20450             default:
20451                 generate_exception_end(ctx, EXCP_RI);
20452                 break;
20453             }
20454         }
20455         break;
20456     case NM_P_LS_U12:
20457         {
20458             uint32_t u = extract32(ctx->opcode, 0, 12);
20459
20460             switch (extract32(ctx->opcode, 12, 4)) {
20461             case NM_P_PREFU12:
20462                 if (rt == 31) {
20463                     /* SYNCI */
20464                     /* Break the TB to be able to sync copied instructions
20465                        immediately */
20466                     ctx->base.is_jmp = DISAS_STOP;
20467                 } else {
20468                     /* PREF */
20469                     /* Treat as NOP. */
20470                 }
20471                 break;
20472             case NM_LB:
20473                 gen_ld(ctx, OPC_LB, rt, rs, u);
20474                 break;
20475             case NM_LH:
20476                 gen_ld(ctx, OPC_LH, rt, rs, u);
20477                 break;
20478             case NM_LW:
20479                 gen_ld(ctx, OPC_LW, rt, rs, u);
20480                 break;
20481             case NM_LBU:
20482                 gen_ld(ctx, OPC_LBU, rt, rs, u);
20483                 break;
20484             case NM_LHU:
20485                 gen_ld(ctx, OPC_LHU, rt, rs, u);
20486                 break;
20487             case NM_SB:
20488                 gen_st(ctx, OPC_SB, rt, rs, u);
20489                 break;
20490             case NM_SH:
20491                 gen_st(ctx, OPC_SH, rt, rs, u);
20492                 break;
20493             case NM_SW:
20494                 gen_st(ctx, OPC_SW, rt, rs, u);
20495                 break;
20496             case NM_LWC1:
20497                 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
20498                 break;
20499             case NM_LDC1:
20500                 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
20501                 break;
20502             case NM_SWC1:
20503                 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
20504                 break;
20505             case NM_SDC1:
20506                 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
20507                 break;
20508             default:
20509                 generate_exception_end(ctx, EXCP_RI);
20510                 break;
20511             }
20512         }
20513         break;
20514     case NM_P_LS_S9:
20515         {
20516             int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
20517                         extract32(ctx->opcode, 0, 8);
20518
20519             switch (extract32(ctx->opcode, 8, 3)) {
20520             case NM_P_LS_S0:
20521                 switch (extract32(ctx->opcode, 11, 4)) {
20522                 case NM_LBS9:
20523                     gen_ld(ctx, OPC_LB, rt, rs, s);
20524                     break;
20525                 case NM_LHS9:
20526                     gen_ld(ctx, OPC_LH, rt, rs, s);
20527                     break;
20528                 case NM_LWS9:
20529                     gen_ld(ctx, OPC_LW, rt, rs, s);
20530                     break;
20531                 case NM_LBUS9:
20532                     gen_ld(ctx, OPC_LBU, rt, rs, s);
20533                     break;
20534                 case NM_LHUS9:
20535                     gen_ld(ctx, OPC_LHU, rt, rs, s);
20536                     break;
20537                 case NM_SBS9:
20538                     gen_st(ctx, OPC_SB, rt, rs, s);
20539                     break;
20540                 case NM_SHS9:
20541                     gen_st(ctx, OPC_SH, rt, rs, s);
20542                     break;
20543                 case NM_SWS9:
20544                     gen_st(ctx, OPC_SW, rt, rs, s);
20545                     break;
20546                 case NM_LWC1S9:
20547                     gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
20548                     break;
20549                 case NM_LDC1S9:
20550                     gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
20551                     break;
20552                 case NM_SWC1S9:
20553                     gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
20554                     break;
20555                 case NM_SDC1S9:
20556                     gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
20557                     break;
20558                 case NM_P_PREFS9:
20559                     if (rt == 31) {
20560                         /* SYNCI */
20561                         /* Break the TB to be able to sync copied instructions
20562                            immediately */
20563                         ctx->base.is_jmp = DISAS_STOP;
20564                     } else {
20565                         /* PREF */
20566                         /* Treat as NOP. */
20567                     }
20568                     break;
20569                 default:
20570                     generate_exception_end(ctx, EXCP_RI);
20571                     break;
20572                 }
20573                 break;
20574             case NM_P_LS_S1:
20575                 switch (extract32(ctx->opcode, 11, 4)) {
20576                 case NM_UALH:
20577                 case NM_UASH:
20578                     check_nms(ctx);
20579                     {
20580                         TCGv t0 = tcg_temp_new();
20581                         TCGv t1 = tcg_temp_new();
20582
20583                         gen_base_offset_addr(ctx, t0, rs, s);
20584
20585                         switch (extract32(ctx->opcode, 11, 4)) {
20586                         case NM_UALH:
20587                             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
20588                                                MO_UNALN);
20589                             gen_store_gpr(t0, rt);
20590                             break;
20591                         case NM_UASH:
20592                             gen_load_gpr(t1, rt);
20593                             tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
20594                                                MO_UNALN);
20595                             break;
20596                         }
20597                         tcg_temp_free(t0);
20598                         tcg_temp_free(t1);
20599                     }
20600                     break;
20601                 case NM_P_LL:
20602                     switch (ctx->opcode & 0x03) {
20603                     case NM_LL:
20604                         gen_ld(ctx, OPC_LL, rt, rs, s);
20605                         break;
20606                     case NM_LLWP:
20607                         check_xnp(ctx);
20608                         gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
20609                         break;
20610                     }
20611                     break;
20612                 case NM_P_SC:
20613                     switch (ctx->opcode & 0x03) {
20614                     case NM_SC:
20615                         gen_st_cond(ctx, OPC_SC, rt, rs, s);
20616                         break;
20617                     case NM_SCWP:
20618                         check_xnp(ctx);
20619                         gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
20620                         break;
20621                     }
20622                     break;
20623                 case NM_CACHE:
20624                     check_cp0_enabled(ctx);
20625                     if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
20626                         gen_cache_operation(ctx, rt, rs, s);
20627                     }
20628                     break;
20629                 }
20630                 break;
20631             case NM_P_LS_WM:
20632             case NM_P_LS_UAWM:
20633                 check_nms(ctx);
20634                 {
20635                     int count = extract32(ctx->opcode, 12, 3);
20636                     int counter = 0;
20637
20638                     offset = sextract32(ctx->opcode, 15, 1) << 8 |
20639                              extract32(ctx->opcode, 0, 8);
20640                     TCGv va = tcg_temp_new();
20641                     TCGv t1 = tcg_temp_new();
20642                     TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
20643                                       NM_P_LS_UAWM ? MO_UNALN : 0;
20644
20645                     count = (count == 0) ? 8 : count;
20646                     while (counter != count) {
20647                         int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
20648                         int this_offset = offset + (counter << 2);
20649
20650                         gen_base_offset_addr(ctx, va, rs, this_offset);
20651
20652                         switch (extract32(ctx->opcode, 11, 1)) {
20653                         case NM_LWM:
20654                             tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
20655                                                memop | MO_TESL);
20656                             gen_store_gpr(t1, this_rt);
20657                             if ((this_rt == rs) &&
20658                                 (counter != (count - 1))) {
20659                                 /* UNPREDICTABLE */
20660                             }
20661                             break;
20662                         case NM_SWM:
20663                             this_rt = (rt == 0) ? 0 : this_rt;
20664                             gen_load_gpr(t1, this_rt);
20665                             tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
20666                                                memop | MO_TEUL);
20667                             break;
20668                         }
20669                         counter++;
20670                     }
20671                     tcg_temp_free(va);
20672                     tcg_temp_free(t1);
20673                 }
20674                 break;
20675             default:
20676                 generate_exception_end(ctx, EXCP_RI);
20677                 break;
20678             }
20679         }
20680         break;
20681     case NM_MOVE_BALC:
20682         check_nms(ctx);
20683         {
20684             TCGv t0 = tcg_temp_new();
20685             int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
20686                         extract32(ctx->opcode, 1, 20) << 1;
20687             rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
20688             rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
20689                             extract32(ctx->opcode, 21, 3));
20690             gen_load_gpr(t0, rt);
20691             tcg_gen_mov_tl(cpu_gpr[rd], t0);
20692             gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
20693             tcg_temp_free(t0);
20694         }
20695         break;
20696     case NM_P_BAL:
20697         {
20698             int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
20699                         extract32(ctx->opcode, 1, 24) << 1;
20700
20701             if ((extract32(ctx->opcode, 25, 1)) == 0) {
20702                 /* BC */
20703                 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
20704             } else {
20705                 /* BALC */
20706                 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
20707             }
20708         }
20709         break;
20710     case NM_P_J:
20711         switch (extract32(ctx->opcode, 12, 4)) {
20712         case NM_JALRC:
20713         case NM_JALRC_HB:
20714             gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
20715             break;
20716         case NM_P_BALRSC:
20717             gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
20718             break;
20719         default:
20720             generate_exception_end(ctx, EXCP_RI);
20721             break;
20722         }
20723         break;
20724     case NM_P_BR1:
20725         {
20726             int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
20727                         extract32(ctx->opcode, 1, 13) << 1;
20728             switch (extract32(ctx->opcode, 14, 2)) {
20729             case NM_BEQC:
20730                 check_nms(ctx);
20731                 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
20732                 break;
20733             case NM_P_BR3A:
20734                 s = sextract32(ctx->opcode, 0, 1) << 14 |
20735                     extract32(ctx->opcode, 1, 13) << 1;
20736                 check_cp1_enabled(ctx);
20737                 switch (extract32(ctx->opcode, 16, 5)) {
20738                 case NM_BC1EQZC:
20739                     gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
20740                     break;
20741                 case NM_BC1NEZC:
20742                     gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
20743                     break;
20744                 case NM_BPOSGE32C:
20745                     check_dsp_r3(ctx);
20746                     {
20747                         int32_t imm = extract32(ctx->opcode, 1, 13) |
20748                                       extract32(ctx->opcode, 0, 1) << 13;
20749
20750                         gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
20751                                               imm);
20752                     }
20753                     break;
20754                 default:
20755                     generate_exception_end(ctx, EXCP_RI);
20756                     break;
20757                 }
20758                 break;
20759             case NM_BGEC:
20760                 if (rs == rt) {
20761                     gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
20762                 } else {
20763                     gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
20764                 }
20765                 break;
20766             case NM_BGEUC:
20767                 if (rs == rt || rt == 0) {
20768                     gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
20769                 } else if (rs == 0) {
20770                     gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
20771                 } else {
20772                     gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
20773                 }
20774                 break;
20775             }
20776         }
20777         break;
20778     case NM_P_BR2:
20779         {
20780             int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
20781                         extract32(ctx->opcode, 1, 13) << 1;
20782             switch (extract32(ctx->opcode, 14, 2)) {
20783             case NM_BNEC:
20784                 check_nms(ctx);
20785                 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
20786                 break;
20787             case NM_BLTC:
20788                 if (rs != 0 && rt != 0 && rs == rt) {
20789                     /* NOP */
20790                     ctx->hflags |= MIPS_HFLAG_FBNSLOT;
20791                 } else {
20792                     gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
20793                 }
20794                 break;
20795             case NM_BLTUC:
20796                 if (rs == 0 || rs == rt) {
20797                     /* NOP */
20798                     ctx->hflags |= MIPS_HFLAG_FBNSLOT;
20799                 } else {
20800                     gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
20801                 }
20802                 break;
20803             default:
20804                 generate_exception_end(ctx, EXCP_RI);
20805                 break;
20806             }
20807         }
20808         break;
20809     case NM_P_BRI:
20810         {
20811             int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
20812                         extract32(ctx->opcode, 1, 10) << 1;
20813             uint32_t u = extract32(ctx->opcode, 11, 7);
20814
20815             gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
20816                                    rt, u, s);
20817         }
20818         break;
20819     default:
20820         generate_exception_end(ctx, EXCP_RI);
20821         break;
20822     }
20823     return 4;
20824 }
20825
20826 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
20827 {
20828     uint32_t op;
20829     int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
20830     int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
20831     int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
20832     int offset;
20833     int imm;
20834
20835     /* make sure instructions are on a halfword boundary */
20836     if (ctx->base.pc_next & 0x1) {
20837         TCGv tmp = tcg_const_tl(ctx->base.pc_next);
20838         tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
20839         tcg_temp_free(tmp);
20840         generate_exception_end(ctx, EXCP_AdEL);
20841         return 2;
20842     }
20843
20844     op = extract32(ctx->opcode, 10, 6);
20845     switch (op) {
20846     case NM_P16_MV:
20847         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
20848         if (rt != 0) {
20849             /* MOVE */
20850             rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
20851             gen_arith(ctx, OPC_ADDU, rt, rs, 0);
20852         } else {
20853             /* P16.RI */
20854             switch (extract32(ctx->opcode, 3, 2)) {
20855             case NM_P16_SYSCALL:
20856                 if (extract32(ctx->opcode, 2, 1) == 0) {
20857                     generate_exception_end(ctx, EXCP_SYSCALL);
20858                 } else {
20859                     generate_exception_end(ctx, EXCP_RI);
20860                 }
20861                 break;
20862             case NM_BREAK16:
20863                 generate_exception_end(ctx, EXCP_BREAK);
20864                 break;
20865             case NM_SDBBP16:
20866                 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
20867                     gen_helper_do_semihosting(cpu_env);
20868                 } else {
20869                     if (ctx->hflags & MIPS_HFLAG_SBRI) {
20870                         generate_exception_end(ctx, EXCP_RI);
20871                     } else {
20872                         generate_exception_end(ctx, EXCP_DBp);
20873                     }
20874                 }
20875                 break;
20876             default:
20877                 generate_exception_end(ctx, EXCP_RI);
20878                 break;
20879             }
20880         }
20881         break;
20882     case NM_P16_SHIFT:
20883         {
20884             int shift = extract32(ctx->opcode, 0, 3);
20885             uint32_t opc = 0;
20886             shift = (shift == 0) ? 8 : shift;
20887
20888             switch (extract32(ctx->opcode, 3, 1)) {
20889             case NM_SLL16:
20890                 opc = OPC_SLL;
20891                 break;
20892             case NM_SRL16:
20893                 opc = OPC_SRL;
20894                 break;
20895             }
20896             gen_shift_imm(ctx, opc, rt, rs, shift);
20897         }
20898         break;
20899     case NM_P16C:
20900         switch (ctx->opcode & 1) {
20901         case NM_POOL16C_0:
20902             gen_pool16c_nanomips_insn(ctx);
20903             break;
20904         case NM_LWXS16:
20905             gen_ldxs(ctx, rt, rs, rd);
20906             break;
20907         }
20908         break;
20909     case NM_P16_A1:
20910         switch (extract32(ctx->opcode, 6, 1)) {
20911         case NM_ADDIUR1SP:
20912             imm = extract32(ctx->opcode, 0, 6) << 2;
20913             gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
20914             break;
20915         default:
20916             generate_exception_end(ctx, EXCP_RI);
20917             break;
20918         }
20919         break;
20920     case NM_P16_A2:
20921         switch (extract32(ctx->opcode, 3, 1)) {
20922         case NM_ADDIUR2:
20923             imm = extract32(ctx->opcode, 0, 3) << 2;
20924             gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
20925             break;
20926         case NM_P_ADDIURS5:
20927             rt = extract32(ctx->opcode, 5, 5);
20928             if (rt != 0) {
20929                 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
20930                 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
20931                       (extract32(ctx->opcode, 0, 3));
20932                 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
20933             }
20934             break;
20935         }
20936         break;
20937     case NM_P16_ADDU:
20938         switch (ctx->opcode & 0x1) {
20939         case NM_ADDU16:
20940             gen_arith(ctx, OPC_ADDU, rd, rs, rt);
20941             break;
20942         case NM_SUBU16:
20943             gen_arith(ctx, OPC_SUBU, rd, rs, rt);
20944             break;
20945         }
20946         break;
20947     case NM_P16_4X4:
20948         rt = (extract32(ctx->opcode, 9, 1) << 3) |
20949               extract32(ctx->opcode, 5, 3);
20950         rs = (extract32(ctx->opcode, 4, 1) << 3) |
20951               extract32(ctx->opcode, 0, 3);
20952         rt = decode_gpr_gpr4(rt);
20953         rs = decode_gpr_gpr4(rs);
20954         switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
20955                 (extract32(ctx->opcode, 3, 1))) {
20956         case NM_ADDU4X4:
20957             check_nms(ctx);
20958             gen_arith(ctx, OPC_ADDU, rt, rs, rt);
20959             break;
20960         case NM_MUL4X4:
20961             check_nms(ctx);
20962             gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
20963             break;
20964         default:
20965             generate_exception_end(ctx, EXCP_RI);
20966             break;
20967         }
20968         break;
20969     case NM_LI16:
20970         {
20971             int imm = extract32(ctx->opcode, 0, 7);
20972             imm = (imm == 0x7f ? -1 : imm);
20973             if (rt != 0) {
20974                 tcg_gen_movi_tl(cpu_gpr[rt], imm);
20975             }
20976         }
20977         break;
20978     case NM_ANDI16:
20979         {
20980             uint32_t u = extract32(ctx->opcode, 0, 4);
20981             u = (u == 12) ? 0xff :
20982                 (u == 13) ? 0xffff : u;
20983             gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
20984         }
20985         break;
20986     case NM_P16_LB:
20987         offset = extract32(ctx->opcode, 0, 2);
20988         switch (extract32(ctx->opcode, 2, 2)) {
20989         case NM_LB16:
20990             gen_ld(ctx, OPC_LB, rt, rs, offset);
20991             break;
20992         case NM_SB16:
20993             rt = decode_gpr_gpr3_src_store(
20994                      NANOMIPS_EXTRACT_RD(ctx->opcode));
20995             gen_st(ctx, OPC_SB, rt, rs, offset);
20996             break;
20997         case NM_LBU16:
20998             gen_ld(ctx, OPC_LBU, rt, rs, offset);
20999             break;
21000         default:
21001             generate_exception_end(ctx, EXCP_RI);
21002             break;
21003         }
21004         break;
21005     case NM_P16_LH:
21006         offset = extract32(ctx->opcode, 1, 2) << 1;
21007         switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
21008         case NM_LH16:
21009             gen_ld(ctx, OPC_LH, rt, rs, offset);
21010             break;
21011         case NM_SH16:
21012             rt = decode_gpr_gpr3_src_store(
21013                      NANOMIPS_EXTRACT_RD(ctx->opcode));
21014             gen_st(ctx, OPC_SH, rt, rs, offset);
21015             break;
21016         case NM_LHU16:
21017             gen_ld(ctx, OPC_LHU, rt, rs, offset);
21018             break;
21019         default:
21020             generate_exception_end(ctx, EXCP_RI);
21021             break;
21022         }
21023         break;
21024     case NM_LW16:
21025         offset = extract32(ctx->opcode, 0, 4) << 2;
21026         gen_ld(ctx, OPC_LW, rt, rs, offset);
21027         break;
21028     case NM_LWSP16:
21029         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21030         offset = extract32(ctx->opcode, 0, 5) << 2;
21031         gen_ld(ctx, OPC_LW, rt, 29, offset);
21032         break;
21033     case NM_LW4X4:
21034         check_nms(ctx);
21035         rt = (extract32(ctx->opcode, 9, 1) << 3) |
21036              extract32(ctx->opcode, 5, 3);
21037         rs = (extract32(ctx->opcode, 4, 1) << 3) |
21038              extract32(ctx->opcode, 0, 3);
21039         offset = (extract32(ctx->opcode, 3, 1) << 3) |
21040                  (extract32(ctx->opcode, 8, 1) << 2);
21041         rt = decode_gpr_gpr4(rt);
21042         rs = decode_gpr_gpr4(rs);
21043         gen_ld(ctx, OPC_LW, rt, rs, offset);
21044         break;
21045     case NM_SW4X4:
21046         check_nms(ctx);
21047         rt = (extract32(ctx->opcode, 9, 1) << 3) |
21048              extract32(ctx->opcode, 5, 3);
21049         rs = (extract32(ctx->opcode, 4, 1) << 3) |
21050              extract32(ctx->opcode, 0, 3);
21051         offset = (extract32(ctx->opcode, 3, 1) << 3) |
21052                  (extract32(ctx->opcode, 8, 1) << 2);
21053         rt = decode_gpr_gpr4_zero(rt);
21054         rs = decode_gpr_gpr4(rs);
21055         gen_st(ctx, OPC_SW, rt, rs, offset);
21056         break;
21057     case NM_LWGP16:
21058         offset = extract32(ctx->opcode, 0, 7) << 2;
21059         gen_ld(ctx, OPC_LW, rt, 28, offset);
21060         break;
21061     case NM_SWSP16:
21062         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21063         offset = extract32(ctx->opcode, 0, 5) << 2;
21064         gen_st(ctx, OPC_SW, rt, 29, offset);
21065         break;
21066     case NM_SW16:
21067         rt = decode_gpr_gpr3_src_store(
21068                  NANOMIPS_EXTRACT_RD(ctx->opcode));
21069         rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21070         offset = extract32(ctx->opcode, 0, 4) << 2;
21071         gen_st(ctx, OPC_SW, rt, rs, offset);
21072         break;
21073     case NM_SWGP16:
21074         rt = decode_gpr_gpr3_src_store(
21075                  NANOMIPS_EXTRACT_RD(ctx->opcode));
21076         offset = extract32(ctx->opcode, 0, 7) << 2;
21077         gen_st(ctx, OPC_SW, rt, 28, offset);
21078         break;
21079     case NM_BC16:
21080         gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
21081                            (sextract32(ctx->opcode, 0, 1) << 10) |
21082                            (extract32(ctx->opcode, 1, 9) << 1));
21083         break;
21084     case NM_BALC16:
21085         gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
21086                            (sextract32(ctx->opcode, 0, 1) << 10) |
21087                            (extract32(ctx->opcode, 1, 9) << 1));
21088         break;
21089     case NM_BEQZC16:
21090         gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
21091                            (sextract32(ctx->opcode, 0, 1) << 7) |
21092                            (extract32(ctx->opcode, 1, 6) << 1));
21093         break;
21094     case NM_BNEZC16:
21095         gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
21096                            (sextract32(ctx->opcode, 0, 1) << 7) |
21097                            (extract32(ctx->opcode, 1, 6) << 1));
21098         break;
21099     case NM_P16_BR:
21100         switch (ctx->opcode & 0xf) {
21101         case 0:
21102             /* P16.JRC */
21103             switch (extract32(ctx->opcode, 4, 1)) {
21104             case NM_JRC:
21105                 gen_compute_branch_nm(ctx, OPC_JR, 2,
21106                                    extract32(ctx->opcode, 5, 5), 0, 0);
21107                 break;
21108             case NM_JALRC16:
21109                 gen_compute_branch_nm(ctx, OPC_JALR, 2,
21110                                    extract32(ctx->opcode, 5, 5), 31, 0);
21111                 break;
21112             }
21113             break;
21114         default:
21115             {
21116                 /* P16.BRI */
21117                 uint32_t opc = extract32(ctx->opcode, 4, 3) <
21118                                extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
21119                 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
21120                                    extract32(ctx->opcode, 0, 4) << 1);
21121             }
21122             break;
21123         }
21124         break;
21125     case NM_P16_SR:
21126         {
21127             int count = extract32(ctx->opcode, 0, 4);
21128             int u = extract32(ctx->opcode, 4, 4) << 4;
21129
21130             rt = 30 + extract32(ctx->opcode, 9, 1);
21131             switch (extract32(ctx->opcode, 8, 1)) {
21132             case NM_SAVE16:
21133                 gen_save(ctx, rt, count, 0, u);
21134                 break;
21135             case NM_RESTORE_JRC16:
21136                 gen_restore(ctx, rt, count, 0, u);
21137                 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21138                 break;
21139             }
21140         }
21141         break;
21142     case NM_MOVEP:
21143     case NM_MOVEPREV:
21144         check_nms(ctx);
21145         {
21146             static const int gpr2reg1[] = {4, 5, 6, 7};
21147             static const int gpr2reg2[] = {5, 6, 7, 8};
21148             int re;
21149             int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
21150                       extract32(ctx->opcode, 8, 1);
21151             int r1 = gpr2reg1[rd2];
21152             int r2 = gpr2reg2[rd2];
21153             int r3 = extract32(ctx->opcode, 4, 1) << 3 |
21154                      extract32(ctx->opcode, 0, 3);
21155             int r4 = extract32(ctx->opcode, 9, 1) << 3 |
21156                      extract32(ctx->opcode, 5, 3);
21157             TCGv t0 = tcg_temp_new();
21158             TCGv t1 = tcg_temp_new();
21159             if (op == NM_MOVEP) {
21160                 rd = r1;
21161                 re = r2;
21162                 rs = decode_gpr_gpr4_zero(r3);
21163                 rt = decode_gpr_gpr4_zero(r4);
21164             } else {
21165                 rd = decode_gpr_gpr4(r3);
21166                 re = decode_gpr_gpr4(r4);
21167                 rs = r1;
21168                 rt = r2;
21169             }
21170             gen_load_gpr(t0, rs);
21171             gen_load_gpr(t1, rt);
21172             tcg_gen_mov_tl(cpu_gpr[rd], t0);
21173             tcg_gen_mov_tl(cpu_gpr[re], t1);
21174             tcg_temp_free(t0);
21175             tcg_temp_free(t1);
21176         }
21177         break;
21178     default:
21179         return decode_nanomips_32_48_opc(env, ctx);
21180     }
21181
21182     return 2;
21183 }
21184
21185
21186 /* SmartMIPS extension to MIPS32 */
21187
21188 #if defined(TARGET_MIPS64)
21189
21190 /* MDMX extension to MIPS64 */
21191
21192 #endif
21193
21194 /* MIPSDSP functions. */
21195 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
21196                            int rd, int base, int offset)
21197 {
21198     TCGv t0;
21199
21200     check_dsp(ctx);
21201     t0 = tcg_temp_new();
21202
21203     if (base == 0) {
21204         gen_load_gpr(t0, offset);
21205     } else if (offset == 0) {
21206         gen_load_gpr(t0, base);
21207     } else {
21208         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
21209     }
21210
21211     switch (opc) {
21212     case OPC_LBUX:
21213         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
21214         gen_store_gpr(t0, rd);
21215         break;
21216     case OPC_LHX:
21217         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
21218         gen_store_gpr(t0, rd);
21219         break;
21220     case OPC_LWX:
21221         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
21222         gen_store_gpr(t0, rd);
21223         break;
21224 #if defined(TARGET_MIPS64)
21225     case OPC_LDX:
21226         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
21227         gen_store_gpr(t0, rd);
21228         break;
21229 #endif
21230     }
21231     tcg_temp_free(t0);
21232 }
21233
21234 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
21235                               int ret, int v1, int v2)
21236 {
21237     TCGv v1_t;
21238     TCGv v2_t;
21239
21240     if (ret == 0) {
21241         /* Treat as NOP. */
21242         return;
21243     }
21244
21245     v1_t = tcg_temp_new();
21246     v2_t = tcg_temp_new();
21247
21248     gen_load_gpr(v1_t, v1);
21249     gen_load_gpr(v2_t, v2);
21250
21251     switch (op1) {
21252     /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
21253     case OPC_MULT_G_2E:
21254         check_dsp_r2(ctx);
21255         switch (op2) {
21256         case OPC_ADDUH_QB:
21257             gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
21258             break;
21259         case OPC_ADDUH_R_QB:
21260             gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21261             break;
21262         case OPC_ADDQH_PH:
21263             gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
21264             break;
21265         case OPC_ADDQH_R_PH:
21266             gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
21267             break;
21268         case OPC_ADDQH_W:
21269             gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
21270             break;
21271         case OPC_ADDQH_R_W:
21272             gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
21273             break;
21274         case OPC_SUBUH_QB:
21275             gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
21276             break;
21277         case OPC_SUBUH_R_QB:
21278             gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21279             break;
21280         case OPC_SUBQH_PH:
21281             gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
21282             break;
21283         case OPC_SUBQH_R_PH:
21284             gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
21285             break;
21286         case OPC_SUBQH_W:
21287             gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
21288             break;
21289         case OPC_SUBQH_R_W:
21290             gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
21291             break;
21292         }
21293         break;
21294     case OPC_ABSQ_S_PH_DSP:
21295         switch (op2) {
21296         case OPC_ABSQ_S_QB:
21297             check_dsp_r2(ctx);
21298             gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
21299             break;
21300         case OPC_ABSQ_S_PH:
21301             check_dsp(ctx);
21302             gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
21303             break;
21304         case OPC_ABSQ_S_W:
21305             check_dsp(ctx);
21306             gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
21307             break;
21308         case OPC_PRECEQ_W_PHL:
21309             check_dsp(ctx);
21310             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
21311             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
21312             break;
21313         case OPC_PRECEQ_W_PHR:
21314             check_dsp(ctx);
21315             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
21316             tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
21317             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
21318             break;
21319         case OPC_PRECEQU_PH_QBL:
21320             check_dsp(ctx);
21321             gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
21322             break;
21323         case OPC_PRECEQU_PH_QBR:
21324             check_dsp(ctx);
21325             gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
21326             break;
21327         case OPC_PRECEQU_PH_QBLA:
21328             check_dsp(ctx);
21329             gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
21330             break;
21331         case OPC_PRECEQU_PH_QBRA:
21332             check_dsp(ctx);
21333             gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
21334             break;
21335         case OPC_PRECEU_PH_QBL:
21336             check_dsp(ctx);
21337             gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
21338             break;
21339         case OPC_PRECEU_PH_QBR:
21340             check_dsp(ctx);
21341             gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
21342             break;
21343         case OPC_PRECEU_PH_QBLA:
21344             check_dsp(ctx);
21345             gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
21346             break;
21347         case OPC_PRECEU_PH_QBRA:
21348             check_dsp(ctx);
21349             gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
21350             break;
21351         }
21352         break;
21353     case OPC_ADDU_QB_DSP:
21354         switch (op2) {
21355         case OPC_ADDQ_PH:
21356             check_dsp(ctx);
21357             gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21358             break;
21359         case OPC_ADDQ_S_PH:
21360             check_dsp(ctx);
21361             gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21362             break;
21363         case OPC_ADDQ_S_W:
21364             check_dsp(ctx);
21365             gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21366             break;
21367         case OPC_ADDU_QB:
21368             check_dsp(ctx);
21369             gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21370             break;
21371         case OPC_ADDU_S_QB:
21372             check_dsp(ctx);
21373             gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21374             break;
21375         case OPC_ADDU_PH:
21376             check_dsp_r2(ctx);
21377             gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21378             break;
21379         case OPC_ADDU_S_PH:
21380             check_dsp_r2(ctx);
21381             gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21382             break;
21383         case OPC_SUBQ_PH:
21384             check_dsp(ctx);
21385             gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21386             break;
21387         case OPC_SUBQ_S_PH:
21388             check_dsp(ctx);
21389             gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21390             break;
21391         case OPC_SUBQ_S_W:
21392             check_dsp(ctx);
21393             gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21394             break;
21395         case OPC_SUBU_QB:
21396             check_dsp(ctx);
21397             gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21398             break;
21399         case OPC_SUBU_S_QB:
21400             check_dsp(ctx);
21401             gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21402             break;
21403         case OPC_SUBU_PH:
21404             check_dsp_r2(ctx);
21405             gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21406             break;
21407         case OPC_SUBU_S_PH:
21408             check_dsp_r2(ctx);
21409             gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21410             break;
21411         case OPC_ADDSC:
21412             check_dsp(ctx);
21413             gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21414             break;
21415         case OPC_ADDWC:
21416             check_dsp(ctx);
21417             gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21418             break;
21419         case OPC_MODSUB:
21420             check_dsp(ctx);
21421             gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
21422             break;
21423         case OPC_RADDU_W_QB:
21424             check_dsp(ctx);
21425             gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
21426             break;
21427         }
21428         break;
21429     case OPC_CMPU_EQ_QB_DSP:
21430         switch (op2) {
21431         case OPC_PRECR_QB_PH:
21432             check_dsp_r2(ctx);
21433             gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
21434             break;
21435         case OPC_PRECRQ_QB_PH:
21436             check_dsp(ctx);
21437             gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
21438             break;
21439         case OPC_PRECR_SRA_PH_W:
21440             check_dsp_r2(ctx);
21441             {
21442                 TCGv_i32 sa_t = tcg_const_i32(v2);
21443                 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
21444                                           cpu_gpr[ret]);
21445                 tcg_temp_free_i32(sa_t);
21446                 break;
21447             }
21448         case OPC_PRECR_SRA_R_PH_W:
21449             check_dsp_r2(ctx);
21450             {
21451                 TCGv_i32 sa_t = tcg_const_i32(v2);
21452                 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
21453                                             cpu_gpr[ret]);
21454                 tcg_temp_free_i32(sa_t);
21455                 break;
21456             }
21457         case OPC_PRECRQ_PH_W:
21458             check_dsp(ctx);
21459             gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
21460             break;
21461         case OPC_PRECRQ_RS_PH_W:
21462             check_dsp(ctx);
21463             gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21464             break;
21465         case OPC_PRECRQU_S_QB_PH:
21466             check_dsp(ctx);
21467             gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21468             break;
21469         }
21470         break;
21471 #ifdef TARGET_MIPS64
21472     case OPC_ABSQ_S_QH_DSP:
21473         switch (op2) {
21474         case OPC_PRECEQ_L_PWL:
21475             check_dsp(ctx);
21476             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
21477             break;
21478         case OPC_PRECEQ_L_PWR:
21479             check_dsp(ctx);
21480             tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
21481             break;
21482         case OPC_PRECEQ_PW_QHL:
21483             check_dsp(ctx);
21484             gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
21485             break;
21486         case OPC_PRECEQ_PW_QHR:
21487             check_dsp(ctx);
21488             gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
21489             break;
21490         case OPC_PRECEQ_PW_QHLA:
21491             check_dsp(ctx);
21492             gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
21493             break;
21494         case OPC_PRECEQ_PW_QHRA:
21495             check_dsp(ctx);
21496             gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
21497             break;
21498         case OPC_PRECEQU_QH_OBL:
21499             check_dsp(ctx);
21500             gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
21501             break;
21502         case OPC_PRECEQU_QH_OBR:
21503             check_dsp(ctx);
21504             gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
21505             break;
21506         case OPC_PRECEQU_QH_OBLA:
21507             check_dsp(ctx);
21508             gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
21509             break;
21510         case OPC_PRECEQU_QH_OBRA:
21511             check_dsp(ctx);
21512             gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
21513             break;
21514         case OPC_PRECEU_QH_OBL:
21515             check_dsp(ctx);
21516             gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
21517             break;
21518         case OPC_PRECEU_QH_OBR:
21519             check_dsp(ctx);
21520             gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
21521             break;
21522         case OPC_PRECEU_QH_OBLA:
21523             check_dsp(ctx);
21524             gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
21525             break;
21526         case OPC_PRECEU_QH_OBRA:
21527             check_dsp(ctx);
21528             gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
21529             break;
21530         case OPC_ABSQ_S_OB:
21531             check_dsp_r2(ctx);
21532             gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
21533             break;
21534         case OPC_ABSQ_S_PW:
21535             check_dsp(ctx);
21536             gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
21537             break;
21538         case OPC_ABSQ_S_QH:
21539             check_dsp(ctx);
21540             gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
21541             break;
21542         }
21543         break;
21544     case OPC_ADDU_OB_DSP:
21545         switch (op2) {
21546         case OPC_RADDU_L_OB:
21547             check_dsp(ctx);
21548             gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
21549             break;
21550         case OPC_SUBQ_PW:
21551             check_dsp(ctx);
21552             gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21553             break;
21554         case OPC_SUBQ_S_PW:
21555             check_dsp(ctx);
21556             gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21557             break;
21558         case OPC_SUBQ_QH:
21559             check_dsp(ctx);
21560             gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21561             break;
21562         case OPC_SUBQ_S_QH:
21563             check_dsp(ctx);
21564             gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21565             break;
21566         case OPC_SUBU_OB:
21567             check_dsp(ctx);
21568             gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21569             break;
21570         case OPC_SUBU_S_OB:
21571             check_dsp(ctx);
21572             gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21573             break;
21574         case OPC_SUBU_QH:
21575             check_dsp_r2(ctx);
21576             gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21577             break;
21578         case OPC_SUBU_S_QH:
21579             check_dsp_r2(ctx);
21580             gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21581             break;
21582         case OPC_SUBUH_OB:
21583             check_dsp_r2(ctx);
21584             gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
21585             break;
21586         case OPC_SUBUH_R_OB:
21587             check_dsp_r2(ctx);
21588             gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
21589             break;
21590         case OPC_ADDQ_PW:
21591             check_dsp(ctx);
21592             gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21593             break;
21594         case OPC_ADDQ_S_PW:
21595             check_dsp(ctx);
21596             gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21597             break;
21598         case OPC_ADDQ_QH:
21599             check_dsp(ctx);
21600             gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21601             break;
21602         case OPC_ADDQ_S_QH:
21603             check_dsp(ctx);
21604             gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21605             break;
21606         case OPC_ADDU_OB:
21607             check_dsp(ctx);
21608             gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21609             break;
21610         case OPC_ADDU_S_OB:
21611             check_dsp(ctx);
21612             gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21613             break;
21614         case OPC_ADDU_QH:
21615             check_dsp_r2(ctx);
21616             gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21617             break;
21618         case OPC_ADDU_S_QH:
21619             check_dsp_r2(ctx);
21620             gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21621             break;
21622         case OPC_ADDUH_OB:
21623             check_dsp_r2(ctx);
21624             gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
21625             break;
21626         case OPC_ADDUH_R_OB:
21627             check_dsp_r2(ctx);
21628             gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
21629             break;
21630         }
21631         break;
21632     case OPC_CMPU_EQ_OB_DSP:
21633         switch (op2) {
21634         case OPC_PRECR_OB_QH:
21635             check_dsp_r2(ctx);
21636             gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
21637             break;
21638         case OPC_PRECR_SRA_QH_PW:
21639             check_dsp_r2(ctx);
21640             {
21641                 TCGv_i32 ret_t = tcg_const_i32(ret);
21642                 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
21643                 tcg_temp_free_i32(ret_t);
21644                 break;
21645             }
21646         case OPC_PRECR_SRA_R_QH_PW:
21647             check_dsp_r2(ctx);
21648             {
21649                 TCGv_i32 sa_v = tcg_const_i32(ret);
21650                 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
21651                 tcg_temp_free_i32(sa_v);
21652                 break;
21653             }
21654         case OPC_PRECRQ_OB_QH:
21655             check_dsp(ctx);
21656             gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
21657             break;
21658         case OPC_PRECRQ_PW_L:
21659             check_dsp(ctx);
21660             gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
21661             break;
21662         case OPC_PRECRQ_QH_PW:
21663             check_dsp(ctx);
21664             gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
21665             break;
21666         case OPC_PRECRQ_RS_QH_PW:
21667             check_dsp(ctx);
21668             gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21669             break;
21670         case OPC_PRECRQU_S_OB_QH:
21671             check_dsp(ctx);
21672             gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21673             break;
21674         }
21675         break;
21676 #endif
21677     }
21678
21679     tcg_temp_free(v1_t);
21680     tcg_temp_free(v2_t);
21681 }
21682
21683 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
21684                               int ret, int v1, int v2)
21685 {
21686     uint32_t op2;
21687     TCGv t0;
21688     TCGv v1_t;
21689     TCGv v2_t;
21690
21691     if (ret == 0) {
21692         /* Treat as NOP. */
21693         return;
21694     }
21695
21696     t0 = tcg_temp_new();
21697     v1_t = tcg_temp_new();
21698     v2_t = tcg_temp_new();
21699
21700     tcg_gen_movi_tl(t0, v1);
21701     gen_load_gpr(v1_t, v1);
21702     gen_load_gpr(v2_t, v2);
21703
21704     switch (opc) {
21705     case OPC_SHLL_QB_DSP:
21706         {
21707             op2 = MASK_SHLL_QB(ctx->opcode);
21708             switch (op2) {
21709             case OPC_SHLL_QB:
21710                 check_dsp(ctx);
21711                 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
21712                 break;
21713             case OPC_SHLLV_QB:
21714                 check_dsp(ctx);
21715                 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21716                 break;
21717             case OPC_SHLL_PH:
21718                 check_dsp(ctx);
21719                 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
21720                 break;
21721             case OPC_SHLLV_PH:
21722                 check_dsp(ctx);
21723                 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21724                 break;
21725             case OPC_SHLL_S_PH:
21726                 check_dsp(ctx);
21727                 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
21728                 break;
21729             case OPC_SHLLV_S_PH:
21730                 check_dsp(ctx);
21731                 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21732                 break;
21733             case OPC_SHLL_S_W:
21734                 check_dsp(ctx);
21735                 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
21736                 break;
21737             case OPC_SHLLV_S_W:
21738                 check_dsp(ctx);
21739                 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21740                 break;
21741             case OPC_SHRL_QB:
21742                 check_dsp(ctx);
21743                 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
21744                 break;
21745             case OPC_SHRLV_QB:
21746                 check_dsp(ctx);
21747                 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
21748                 break;
21749             case OPC_SHRL_PH:
21750                 check_dsp_r2(ctx);
21751                 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
21752                 break;
21753             case OPC_SHRLV_PH:
21754                 check_dsp_r2(ctx);
21755                 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
21756                 break;
21757             case OPC_SHRA_QB:
21758                 check_dsp_r2(ctx);
21759                 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
21760                 break;
21761             case OPC_SHRA_R_QB:
21762                 check_dsp_r2(ctx);
21763                 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
21764                 break;
21765             case OPC_SHRAV_QB:
21766                 check_dsp_r2(ctx);
21767                 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
21768                 break;
21769             case OPC_SHRAV_R_QB:
21770                 check_dsp_r2(ctx);
21771                 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
21772                 break;
21773             case OPC_SHRA_PH:
21774                 check_dsp(ctx);
21775                 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
21776                 break;
21777             case OPC_SHRA_R_PH:
21778                 check_dsp(ctx);
21779                 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
21780                 break;
21781             case OPC_SHRAV_PH:
21782                 check_dsp(ctx);
21783                 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
21784                 break;
21785             case OPC_SHRAV_R_PH:
21786                 check_dsp(ctx);
21787                 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
21788                 break;
21789             case OPC_SHRA_R_W:
21790                 check_dsp(ctx);
21791                 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
21792                 break;
21793             case OPC_SHRAV_R_W:
21794                 check_dsp(ctx);
21795                 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
21796                 break;
21797             default:            /* Invalid */
21798                 MIPS_INVAL("MASK SHLL.QB");
21799                 generate_exception_end(ctx, EXCP_RI);
21800                 break;
21801             }
21802             break;
21803         }
21804 #ifdef TARGET_MIPS64
21805     case OPC_SHLL_OB_DSP:
21806         op2 = MASK_SHLL_OB(ctx->opcode);
21807         switch (op2) {
21808         case OPC_SHLL_PW:
21809             check_dsp(ctx);
21810             gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
21811             break;
21812         case OPC_SHLLV_PW:
21813             check_dsp(ctx);
21814             gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21815             break;
21816         case OPC_SHLL_S_PW:
21817             check_dsp(ctx);
21818             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
21819             break;
21820         case OPC_SHLLV_S_PW:
21821             check_dsp(ctx);
21822             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21823             break;
21824         case OPC_SHLL_OB:
21825             check_dsp(ctx);
21826             gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
21827             break;
21828         case OPC_SHLLV_OB:
21829             check_dsp(ctx);
21830             gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21831             break;
21832         case OPC_SHLL_QH:
21833             check_dsp(ctx);
21834             gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
21835             break;
21836         case OPC_SHLLV_QH:
21837             check_dsp(ctx);
21838             gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21839             break;
21840         case OPC_SHLL_S_QH:
21841             check_dsp(ctx);
21842             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
21843             break;
21844         case OPC_SHLLV_S_QH:
21845             check_dsp(ctx);
21846             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
21847             break;
21848         case OPC_SHRA_OB:
21849             check_dsp_r2(ctx);
21850             gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
21851             break;
21852         case OPC_SHRAV_OB:
21853             check_dsp_r2(ctx);
21854             gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
21855             break;
21856         case OPC_SHRA_R_OB:
21857             check_dsp_r2(ctx);
21858             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
21859             break;
21860         case OPC_SHRAV_R_OB:
21861             check_dsp_r2(ctx);
21862             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
21863             break;
21864         case OPC_SHRA_PW:
21865             check_dsp(ctx);
21866             gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
21867             break;
21868         case OPC_SHRAV_PW:
21869             check_dsp(ctx);
21870             gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
21871             break;
21872         case OPC_SHRA_R_PW:
21873             check_dsp(ctx);
21874             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
21875             break;
21876         case OPC_SHRAV_R_PW:
21877             check_dsp(ctx);
21878             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
21879             break;
21880         case OPC_SHRA_QH:
21881             check_dsp(ctx);
21882             gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
21883             break;
21884         case OPC_SHRAV_QH:
21885             check_dsp(ctx);
21886             gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
21887             break;
21888         case OPC_SHRA_R_QH:
21889             check_dsp(ctx);
21890             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
21891             break;
21892         case OPC_SHRAV_R_QH:
21893             check_dsp(ctx);
21894             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
21895             break;
21896         case OPC_SHRL_OB:
21897             check_dsp(ctx);
21898             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
21899             break;
21900         case OPC_SHRLV_OB:
21901             check_dsp(ctx);
21902             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
21903             break;
21904         case OPC_SHRL_QH:
21905             check_dsp_r2(ctx);
21906             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
21907             break;
21908         case OPC_SHRLV_QH:
21909             check_dsp_r2(ctx);
21910             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
21911             break;
21912         default:            /* Invalid */
21913             MIPS_INVAL("MASK SHLL.OB");
21914             generate_exception_end(ctx, EXCP_RI);
21915             break;
21916         }
21917         break;
21918 #endif
21919     }
21920
21921     tcg_temp_free(t0);
21922     tcg_temp_free(v1_t);
21923     tcg_temp_free(v2_t);
21924 }
21925
21926 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
21927                                  int ret, int v1, int v2, int check_ret)
21928 {
21929     TCGv_i32 t0;
21930     TCGv v1_t;
21931     TCGv v2_t;
21932
21933     if ((ret == 0) && (check_ret == 1)) {
21934         /* Treat as NOP. */
21935         return;
21936     }
21937
21938     t0 = tcg_temp_new_i32();
21939     v1_t = tcg_temp_new();
21940     v2_t = tcg_temp_new();
21941
21942     tcg_gen_movi_i32(t0, ret);
21943     gen_load_gpr(v1_t, v1);
21944     gen_load_gpr(v2_t, v2);
21945
21946     switch (op1) {
21947     /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
21948      * the same mask and op1. */
21949     case OPC_MULT_G_2E:
21950         check_dsp_r2(ctx);
21951         switch (op2) {
21952         case  OPC_MUL_PH:
21953             gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21954             break;
21955         case  OPC_MUL_S_PH:
21956             gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21957             break;
21958         case OPC_MULQ_S_W:
21959             gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21960             break;
21961         case OPC_MULQ_RS_W:
21962             gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21963             break;
21964         }
21965         break;
21966     case OPC_DPA_W_PH_DSP:
21967         switch (op2) {
21968         case OPC_DPAU_H_QBL:
21969             check_dsp(ctx);
21970             gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
21971             break;
21972         case OPC_DPAU_H_QBR:
21973             check_dsp(ctx);
21974             gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
21975             break;
21976         case OPC_DPSU_H_QBL:
21977             check_dsp(ctx);
21978             gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
21979             break;
21980         case OPC_DPSU_H_QBR:
21981             check_dsp(ctx);
21982             gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
21983             break;
21984         case OPC_DPA_W_PH:
21985             check_dsp_r2(ctx);
21986             gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
21987             break;
21988         case OPC_DPAX_W_PH:
21989             check_dsp_r2(ctx);
21990             gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
21991             break;
21992         case OPC_DPAQ_S_W_PH:
21993             check_dsp(ctx);
21994             gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
21995             break;
21996         case OPC_DPAQX_S_W_PH:
21997             check_dsp_r2(ctx);
21998             gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
21999             break;
22000         case OPC_DPAQX_SA_W_PH:
22001             check_dsp_r2(ctx);
22002             gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22003             break;
22004         case OPC_DPS_W_PH:
22005             check_dsp_r2(ctx);
22006             gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
22007             break;
22008         case OPC_DPSX_W_PH:
22009             check_dsp_r2(ctx);
22010             gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
22011             break;
22012         case OPC_DPSQ_S_W_PH:
22013             check_dsp(ctx);
22014             gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22015             break;
22016         case OPC_DPSQX_S_W_PH:
22017             check_dsp_r2(ctx);
22018             gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22019             break;
22020         case OPC_DPSQX_SA_W_PH:
22021             check_dsp_r2(ctx);
22022             gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22023             break;
22024         case OPC_MULSAQ_S_W_PH:
22025             check_dsp(ctx);
22026             gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22027             break;
22028         case OPC_DPAQ_SA_L_W:
22029             check_dsp(ctx);
22030             gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22031             break;
22032         case OPC_DPSQ_SA_L_W:
22033             check_dsp(ctx);
22034             gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22035             break;
22036         case OPC_MAQ_S_W_PHL:
22037             check_dsp(ctx);
22038             gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
22039             break;
22040         case OPC_MAQ_S_W_PHR:
22041             check_dsp(ctx);
22042             gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
22043             break;
22044         case OPC_MAQ_SA_W_PHL:
22045             check_dsp(ctx);
22046             gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
22047             break;
22048         case OPC_MAQ_SA_W_PHR:
22049             check_dsp(ctx);
22050             gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
22051             break;
22052         case OPC_MULSA_W_PH:
22053             check_dsp_r2(ctx);
22054             gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
22055             break;
22056         }
22057         break;
22058 #ifdef TARGET_MIPS64
22059     case OPC_DPAQ_W_QH_DSP:
22060         {
22061             int ac = ret & 0x03;
22062             tcg_gen_movi_i32(t0, ac);
22063
22064             switch (op2) {
22065             case OPC_DMADD:
22066                 check_dsp(ctx);
22067                 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
22068                 break;
22069             case OPC_DMADDU:
22070                 check_dsp(ctx);
22071                 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
22072                 break;
22073             case OPC_DMSUB:
22074                 check_dsp(ctx);
22075                 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
22076                 break;
22077             case OPC_DMSUBU:
22078                 check_dsp(ctx);
22079                 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
22080                 break;
22081             case OPC_DPA_W_QH:
22082                 check_dsp_r2(ctx);
22083                 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
22084                 break;
22085             case OPC_DPAQ_S_W_QH:
22086                 check_dsp(ctx);
22087                 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22088                 break;
22089             case OPC_DPAQ_SA_L_PW:
22090                 check_dsp(ctx);
22091                 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22092                 break;
22093             case OPC_DPAU_H_OBL:
22094                 check_dsp(ctx);
22095                 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
22096                 break;
22097             case OPC_DPAU_H_OBR:
22098                 check_dsp(ctx);
22099                 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
22100                 break;
22101             case OPC_DPS_W_QH:
22102                 check_dsp_r2(ctx);
22103                 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
22104                 break;
22105             case OPC_DPSQ_S_W_QH:
22106                 check_dsp(ctx);
22107                 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22108                 break;
22109             case OPC_DPSQ_SA_L_PW:
22110                 check_dsp(ctx);
22111                 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22112                 break;
22113             case OPC_DPSU_H_OBL:
22114                 check_dsp(ctx);
22115                 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
22116                 break;
22117             case OPC_DPSU_H_OBR:
22118                 check_dsp(ctx);
22119                 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
22120                 break;
22121             case OPC_MAQ_S_L_PWL:
22122                 check_dsp(ctx);
22123                 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
22124                 break;
22125             case OPC_MAQ_S_L_PWR:
22126                 check_dsp(ctx);
22127                 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
22128                 break;
22129             case OPC_MAQ_S_W_QHLL:
22130                 check_dsp(ctx);
22131                 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
22132                 break;
22133             case OPC_MAQ_SA_W_QHLL:
22134                 check_dsp(ctx);
22135                 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
22136                 break;
22137             case OPC_MAQ_S_W_QHLR:
22138                 check_dsp(ctx);
22139                 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
22140                 break;
22141             case OPC_MAQ_SA_W_QHLR:
22142                 check_dsp(ctx);
22143                 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
22144                 break;
22145             case OPC_MAQ_S_W_QHRL:
22146                 check_dsp(ctx);
22147                 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
22148                 break;
22149             case OPC_MAQ_SA_W_QHRL:
22150                 check_dsp(ctx);
22151                 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
22152                 break;
22153             case OPC_MAQ_S_W_QHRR:
22154                 check_dsp(ctx);
22155                 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
22156                 break;
22157             case OPC_MAQ_SA_W_QHRR:
22158                 check_dsp(ctx);
22159                 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
22160                 break;
22161             case OPC_MULSAQ_S_L_PW:
22162                 check_dsp(ctx);
22163                 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
22164                 break;
22165             case OPC_MULSAQ_S_W_QH:
22166                 check_dsp(ctx);
22167                 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22168                 break;
22169             }
22170         }
22171         break;
22172 #endif
22173     case OPC_ADDU_QB_DSP:
22174         switch (op2) {
22175         case OPC_MULEU_S_PH_QBL:
22176             check_dsp(ctx);
22177             gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22178             break;
22179         case OPC_MULEU_S_PH_QBR:
22180             check_dsp(ctx);
22181             gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22182             break;
22183         case OPC_MULQ_RS_PH:
22184             check_dsp(ctx);
22185             gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22186             break;
22187         case OPC_MULEQ_S_W_PHL:
22188             check_dsp(ctx);
22189             gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22190             break;
22191         case OPC_MULEQ_S_W_PHR:
22192             check_dsp(ctx);
22193             gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22194             break;
22195         case OPC_MULQ_S_PH:
22196             check_dsp_r2(ctx);
22197             gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22198             break;
22199         }
22200         break;
22201 #ifdef TARGET_MIPS64
22202     case OPC_ADDU_OB_DSP:
22203         switch (op2) {
22204         case OPC_MULEQ_S_PW_QHL:
22205             check_dsp(ctx);
22206             gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22207             break;
22208         case OPC_MULEQ_S_PW_QHR:
22209             check_dsp(ctx);
22210             gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22211             break;
22212         case OPC_MULEU_S_QH_OBL:
22213             check_dsp(ctx);
22214             gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22215             break;
22216         case OPC_MULEU_S_QH_OBR:
22217             check_dsp(ctx);
22218             gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22219             break;
22220         case OPC_MULQ_RS_QH:
22221             check_dsp(ctx);
22222             gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22223             break;
22224         }
22225         break;
22226 #endif
22227     }
22228
22229     tcg_temp_free_i32(t0);
22230     tcg_temp_free(v1_t);
22231     tcg_temp_free(v2_t);
22232 }
22233
22234 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
22235                                 int ret, int val)
22236 {
22237     int16_t imm;
22238     TCGv t0;
22239     TCGv val_t;
22240
22241     if (ret == 0) {
22242         /* Treat as NOP. */
22243         return;
22244     }
22245
22246     t0 = tcg_temp_new();
22247     val_t = tcg_temp_new();
22248     gen_load_gpr(val_t, val);
22249
22250     switch (op1) {
22251     case OPC_ABSQ_S_PH_DSP:
22252         switch (op2) {
22253         case OPC_BITREV:
22254             check_dsp(ctx);
22255             gen_helper_bitrev(cpu_gpr[ret], val_t);
22256             break;
22257         case OPC_REPL_QB:
22258             check_dsp(ctx);
22259             {
22260                 target_long result;
22261                 imm = (ctx->opcode >> 16) & 0xFF;
22262                 result = (uint32_t)imm << 24 |
22263                          (uint32_t)imm << 16 |
22264                          (uint32_t)imm << 8  |
22265                          (uint32_t)imm;
22266                 result = (int32_t)result;
22267                 tcg_gen_movi_tl(cpu_gpr[ret], result);
22268             }
22269             break;
22270         case OPC_REPLV_QB:
22271             check_dsp(ctx);
22272             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
22273             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
22274             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22275             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22276             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22277             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22278             break;
22279         case OPC_REPL_PH:
22280             check_dsp(ctx);
22281             {
22282                 imm = (ctx->opcode >> 16) & 0x03FF;
22283                 imm = (int16_t)(imm << 6) >> 6;
22284                 tcg_gen_movi_tl(cpu_gpr[ret], \
22285                                 (target_long)((int32_t)imm << 16 | \
22286                                 (uint16_t)imm));
22287             }
22288             break;
22289         case OPC_REPLV_PH:
22290             check_dsp(ctx);
22291             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
22292             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22293             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22294             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22295             break;
22296         }
22297         break;
22298 #ifdef TARGET_MIPS64
22299     case OPC_ABSQ_S_QH_DSP:
22300         switch (op2) {
22301         case OPC_REPL_OB:
22302             check_dsp(ctx);
22303             {
22304                 target_long temp;
22305
22306                 imm = (ctx->opcode >> 16) & 0xFF;
22307                 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
22308                 temp = (temp << 16) | temp;
22309                 temp = (temp << 32) | temp;
22310                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22311                 break;
22312             }
22313         case OPC_REPL_PW:
22314             check_dsp(ctx);
22315             {
22316                 target_long temp;
22317
22318                 imm = (ctx->opcode >> 16) & 0x03FF;
22319                 imm = (int16_t)(imm << 6) >> 6;
22320                 temp = ((target_long)imm << 32) \
22321                        | ((target_long)imm & 0xFFFFFFFF);
22322                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22323                 break;
22324             }
22325         case OPC_REPL_QH:
22326             check_dsp(ctx);
22327             {
22328                 target_long temp;
22329
22330                 imm = (ctx->opcode >> 16) & 0x03FF;
22331                 imm = (int16_t)(imm << 6) >> 6;
22332
22333                 temp = ((uint64_t)(uint16_t)imm << 48) |
22334                        ((uint64_t)(uint16_t)imm << 32) |
22335                        ((uint64_t)(uint16_t)imm << 16) |
22336                        (uint64_t)(uint16_t)imm;
22337                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
22338                 break;
22339             }
22340         case OPC_REPLV_OB:
22341             check_dsp(ctx);
22342             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
22343             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
22344             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22345             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22346             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22347             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22348             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22349             break;
22350         case OPC_REPLV_PW:
22351             check_dsp(ctx);
22352             tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
22353             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22354             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22355             break;
22356         case OPC_REPLV_QH:
22357             check_dsp(ctx);
22358             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
22359             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22360             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22361             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22362             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22363             break;
22364         }
22365         break;
22366 #endif
22367     }
22368     tcg_temp_free(t0);
22369     tcg_temp_free(val_t);
22370 }
22371
22372 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
22373                                      uint32_t op1, uint32_t op2,
22374                                      int ret, int v1, int v2, int check_ret)
22375 {
22376     TCGv t1;
22377     TCGv v1_t;
22378     TCGv v2_t;
22379
22380     if ((ret == 0) && (check_ret == 1)) {
22381         /* Treat as NOP. */
22382         return;
22383     }
22384
22385     t1 = tcg_temp_new();
22386     v1_t = tcg_temp_new();
22387     v2_t = tcg_temp_new();
22388
22389     gen_load_gpr(v1_t, v1);
22390     gen_load_gpr(v2_t, v2);
22391
22392     switch (op1) {
22393     case OPC_CMPU_EQ_QB_DSP:
22394         switch (op2) {
22395         case OPC_CMPU_EQ_QB:
22396             check_dsp(ctx);
22397             gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
22398             break;
22399         case OPC_CMPU_LT_QB:
22400             check_dsp(ctx);
22401             gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
22402             break;
22403         case OPC_CMPU_LE_QB:
22404             check_dsp(ctx);
22405             gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
22406             break;
22407         case OPC_CMPGU_EQ_QB:
22408             check_dsp(ctx);
22409             gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
22410             break;
22411         case OPC_CMPGU_LT_QB:
22412             check_dsp(ctx);
22413             gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
22414             break;
22415         case OPC_CMPGU_LE_QB:
22416             check_dsp(ctx);
22417             gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
22418             break;
22419         case OPC_CMPGDU_EQ_QB:
22420             check_dsp_r2(ctx);
22421             gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
22422             tcg_gen_mov_tl(cpu_gpr[ret], t1);
22423             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22424             tcg_gen_shli_tl(t1, t1, 24);
22425             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22426             break;
22427         case OPC_CMPGDU_LT_QB:
22428             check_dsp_r2(ctx);
22429             gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
22430             tcg_gen_mov_tl(cpu_gpr[ret], t1);
22431             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22432             tcg_gen_shli_tl(t1, t1, 24);
22433             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22434             break;
22435         case OPC_CMPGDU_LE_QB:
22436             check_dsp_r2(ctx);
22437             gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
22438             tcg_gen_mov_tl(cpu_gpr[ret], t1);
22439             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22440             tcg_gen_shli_tl(t1, t1, 24);
22441             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22442             break;
22443         case OPC_CMP_EQ_PH:
22444             check_dsp(ctx);
22445             gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
22446             break;
22447         case OPC_CMP_LT_PH:
22448             check_dsp(ctx);
22449             gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
22450             break;
22451         case OPC_CMP_LE_PH:
22452             check_dsp(ctx);
22453             gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
22454             break;
22455         case OPC_PICK_QB:
22456             check_dsp(ctx);
22457             gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22458             break;
22459         case OPC_PICK_PH:
22460             check_dsp(ctx);
22461             gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22462             break;
22463         case OPC_PACKRL_PH:
22464             check_dsp(ctx);
22465             gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
22466             break;
22467         }
22468         break;
22469 #ifdef TARGET_MIPS64
22470     case OPC_CMPU_EQ_OB_DSP:
22471         switch (op2) {
22472         case OPC_CMP_EQ_PW:
22473             check_dsp(ctx);
22474             gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
22475             break;
22476         case OPC_CMP_LT_PW:
22477             check_dsp(ctx);
22478             gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
22479             break;
22480         case OPC_CMP_LE_PW:
22481             check_dsp(ctx);
22482             gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
22483             break;
22484         case OPC_CMP_EQ_QH:
22485             check_dsp(ctx);
22486             gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
22487             break;
22488         case OPC_CMP_LT_QH:
22489             check_dsp(ctx);
22490             gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
22491             break;
22492         case OPC_CMP_LE_QH:
22493             check_dsp(ctx);
22494             gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
22495             break;
22496         case OPC_CMPGDU_EQ_OB:
22497             check_dsp_r2(ctx);
22498             gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22499             break;
22500         case OPC_CMPGDU_LT_OB:
22501             check_dsp_r2(ctx);
22502             gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22503             break;
22504         case OPC_CMPGDU_LE_OB:
22505             check_dsp_r2(ctx);
22506             gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22507             break;
22508         case OPC_CMPGU_EQ_OB:
22509             check_dsp(ctx);
22510             gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
22511             break;
22512         case OPC_CMPGU_LT_OB:
22513             check_dsp(ctx);
22514             gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
22515             break;
22516         case OPC_CMPGU_LE_OB:
22517             check_dsp(ctx);
22518             gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
22519             break;
22520         case OPC_CMPU_EQ_OB:
22521             check_dsp(ctx);
22522             gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
22523             break;
22524         case OPC_CMPU_LT_OB:
22525             check_dsp(ctx);
22526             gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
22527             break;
22528         case OPC_CMPU_LE_OB:
22529             check_dsp(ctx);
22530             gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
22531             break;
22532         case OPC_PACKRL_PW:
22533             check_dsp(ctx);
22534             gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
22535             break;
22536         case OPC_PICK_OB:
22537             check_dsp(ctx);
22538             gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22539             break;
22540         case OPC_PICK_PW:
22541             check_dsp(ctx);
22542             gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22543             break;
22544         case OPC_PICK_QH:
22545             check_dsp(ctx);
22546             gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22547             break;
22548         }
22549         break;
22550 #endif
22551     }
22552
22553     tcg_temp_free(t1);
22554     tcg_temp_free(v1_t);
22555     tcg_temp_free(v2_t);
22556 }
22557
22558 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
22559                                uint32_t op1, int rt, int rs, int sa)
22560 {
22561     TCGv t0;
22562
22563     check_dsp_r2(ctx);
22564
22565     if (rt == 0) {
22566         /* Treat as NOP. */
22567         return;
22568     }
22569
22570     t0 = tcg_temp_new();
22571     gen_load_gpr(t0, rs);
22572
22573     switch (op1) {
22574     case OPC_APPEND_DSP:
22575         switch (MASK_APPEND(ctx->opcode)) {
22576         case OPC_APPEND:
22577             if (sa != 0) {
22578                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
22579             }
22580             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
22581             break;
22582         case OPC_PREPEND:
22583             if (sa != 0) {
22584                 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
22585                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
22586                 tcg_gen_shli_tl(t0, t0, 32 - sa);
22587                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22588             }
22589             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
22590             break;
22591         case OPC_BALIGN:
22592             sa &= 3;
22593             if (sa != 0 && sa != 2) {
22594                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
22595                 tcg_gen_ext32u_tl(t0, t0);
22596                 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
22597                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22598             }
22599             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
22600             break;
22601         default:            /* Invalid */
22602             MIPS_INVAL("MASK APPEND");
22603             generate_exception_end(ctx, EXCP_RI);
22604             break;
22605         }
22606         break;
22607 #ifdef TARGET_MIPS64
22608     case OPC_DAPPEND_DSP:
22609         switch (MASK_DAPPEND(ctx->opcode)) {
22610         case OPC_DAPPEND:
22611             if (sa != 0) {
22612                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
22613             }
22614             break;
22615         case OPC_PREPENDD:
22616             tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
22617             tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
22618             tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
22619             break;
22620         case OPC_PREPENDW:
22621             if (sa != 0) {
22622                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
22623                 tcg_gen_shli_tl(t0, t0, 64 - sa);
22624                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22625             }
22626             break;
22627         case OPC_DBALIGN:
22628             sa &= 7;
22629             if (sa != 0 && sa != 2 && sa != 4) {
22630                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
22631                 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
22632                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22633             }
22634             break;
22635         default:            /* Invalid */
22636             MIPS_INVAL("MASK DAPPEND");
22637             generate_exception_end(ctx, EXCP_RI);
22638             break;
22639         }
22640         break;
22641 #endif
22642     }
22643     tcg_temp_free(t0);
22644 }
22645
22646 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
22647                                 int ret, int v1, int v2, int check_ret)
22648
22649 {
22650     TCGv t0;
22651     TCGv t1;
22652     TCGv v1_t;
22653     TCGv v2_t;
22654     int16_t imm;
22655
22656     if ((ret == 0) && (check_ret == 1)) {
22657         /* Treat as NOP. */
22658         return;
22659     }
22660
22661     t0 = tcg_temp_new();
22662     t1 = tcg_temp_new();
22663     v1_t = tcg_temp_new();
22664     v2_t = tcg_temp_new();
22665
22666     gen_load_gpr(v1_t, v1);
22667     gen_load_gpr(v2_t, v2);
22668
22669     switch (op1) {
22670     case OPC_EXTR_W_DSP:
22671         check_dsp(ctx);
22672         switch (op2) {
22673         case OPC_EXTR_W:
22674             tcg_gen_movi_tl(t0, v2);
22675             tcg_gen_movi_tl(t1, v1);
22676             gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
22677             break;
22678         case OPC_EXTR_R_W:
22679             tcg_gen_movi_tl(t0, v2);
22680             tcg_gen_movi_tl(t1, v1);
22681             gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
22682             break;
22683         case OPC_EXTR_RS_W:
22684             tcg_gen_movi_tl(t0, v2);
22685             tcg_gen_movi_tl(t1, v1);
22686             gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
22687             break;
22688         case OPC_EXTR_S_H:
22689             tcg_gen_movi_tl(t0, v2);
22690             tcg_gen_movi_tl(t1, v1);
22691             gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
22692             break;
22693         case OPC_EXTRV_S_H:
22694             tcg_gen_movi_tl(t0, v2);
22695             gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
22696             break;
22697         case OPC_EXTRV_W:
22698             tcg_gen_movi_tl(t0, v2);
22699             gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22700             break;
22701         case OPC_EXTRV_R_W:
22702             tcg_gen_movi_tl(t0, v2);
22703             gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22704             break;
22705         case OPC_EXTRV_RS_W:
22706             tcg_gen_movi_tl(t0, v2);
22707             gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22708             break;
22709         case OPC_EXTP:
22710             tcg_gen_movi_tl(t0, v2);
22711             tcg_gen_movi_tl(t1, v1);
22712             gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
22713             break;
22714         case OPC_EXTPV:
22715             tcg_gen_movi_tl(t0, v2);
22716             gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
22717             break;
22718         case OPC_EXTPDP:
22719             tcg_gen_movi_tl(t0, v2);
22720             tcg_gen_movi_tl(t1, v1);
22721             gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
22722             break;
22723         case OPC_EXTPDPV:
22724             tcg_gen_movi_tl(t0, v2);
22725             gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
22726             break;
22727         case OPC_SHILO:
22728             imm = (ctx->opcode >> 20) & 0x3F;
22729             tcg_gen_movi_tl(t0, ret);
22730             tcg_gen_movi_tl(t1, imm);
22731             gen_helper_shilo(t0, t1, cpu_env);
22732             break;
22733         case OPC_SHILOV:
22734             tcg_gen_movi_tl(t0, ret);
22735             gen_helper_shilo(t0, v1_t, cpu_env);
22736             break;
22737         case OPC_MTHLIP:
22738             tcg_gen_movi_tl(t0, ret);
22739             gen_helper_mthlip(t0, v1_t, cpu_env);
22740             break;
22741         case OPC_WRDSP:
22742             imm = (ctx->opcode >> 11) & 0x3FF;
22743             tcg_gen_movi_tl(t0, imm);
22744             gen_helper_wrdsp(v1_t, t0, cpu_env);
22745             break;
22746         case OPC_RDDSP:
22747             imm = (ctx->opcode >> 16) & 0x03FF;
22748             tcg_gen_movi_tl(t0, imm);
22749             gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
22750             break;
22751         }
22752         break;
22753 #ifdef TARGET_MIPS64
22754     case OPC_DEXTR_W_DSP:
22755         check_dsp(ctx);
22756         switch (op2) {
22757         case OPC_DMTHLIP:
22758             tcg_gen_movi_tl(t0, ret);
22759             gen_helper_dmthlip(v1_t, t0, cpu_env);
22760             break;
22761         case OPC_DSHILO:
22762             {
22763                 int shift = (ctx->opcode >> 19) & 0x7F;
22764                 int ac = (ctx->opcode >> 11) & 0x03;
22765                 tcg_gen_movi_tl(t0, shift);
22766                 tcg_gen_movi_tl(t1, ac);
22767                 gen_helper_dshilo(t0, t1, cpu_env);
22768                 break;
22769             }
22770         case OPC_DSHILOV:
22771             {
22772                 int ac = (ctx->opcode >> 11) & 0x03;
22773                 tcg_gen_movi_tl(t0, ac);
22774                 gen_helper_dshilo(v1_t, t0, cpu_env);
22775                 break;
22776             }
22777         case OPC_DEXTP:
22778             tcg_gen_movi_tl(t0, v2);
22779             tcg_gen_movi_tl(t1, v1);
22780
22781             gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
22782             break;
22783         case OPC_DEXTPV:
22784             tcg_gen_movi_tl(t0, v2);
22785             gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
22786             break;
22787         case OPC_DEXTPDP:
22788             tcg_gen_movi_tl(t0, v2);
22789             tcg_gen_movi_tl(t1, v1);
22790             gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
22791             break;
22792         case OPC_DEXTPDPV:
22793             tcg_gen_movi_tl(t0, v2);
22794             gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
22795             break;
22796         case OPC_DEXTR_L:
22797             tcg_gen_movi_tl(t0, v2);
22798             tcg_gen_movi_tl(t1, v1);
22799             gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
22800             break;
22801         case OPC_DEXTR_R_L:
22802             tcg_gen_movi_tl(t0, v2);
22803             tcg_gen_movi_tl(t1, v1);
22804             gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
22805             break;
22806         case OPC_DEXTR_RS_L:
22807             tcg_gen_movi_tl(t0, v2);
22808             tcg_gen_movi_tl(t1, v1);
22809             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
22810             break;
22811         case OPC_DEXTR_W:
22812             tcg_gen_movi_tl(t0, v2);
22813             tcg_gen_movi_tl(t1, v1);
22814             gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
22815             break;
22816         case OPC_DEXTR_R_W:
22817             tcg_gen_movi_tl(t0, v2);
22818             tcg_gen_movi_tl(t1, v1);
22819             gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
22820             break;
22821         case OPC_DEXTR_RS_W:
22822             tcg_gen_movi_tl(t0, v2);
22823             tcg_gen_movi_tl(t1, v1);
22824             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
22825             break;
22826         case OPC_DEXTR_S_H:
22827             tcg_gen_movi_tl(t0, v2);
22828             tcg_gen_movi_tl(t1, v1);
22829             gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
22830             break;
22831         case OPC_DEXTRV_S_H:
22832             tcg_gen_movi_tl(t0, v2);
22833             tcg_gen_movi_tl(t1, v1);
22834             gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
22835             break;
22836         case OPC_DEXTRV_L:
22837             tcg_gen_movi_tl(t0, v2);
22838             gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
22839             break;
22840         case OPC_DEXTRV_R_L:
22841             tcg_gen_movi_tl(t0, v2);
22842             gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
22843             break;
22844         case OPC_DEXTRV_RS_L:
22845             tcg_gen_movi_tl(t0, v2);
22846             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
22847             break;
22848         case OPC_DEXTRV_W:
22849             tcg_gen_movi_tl(t0, v2);
22850             gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22851             break;
22852         case OPC_DEXTRV_R_W:
22853             tcg_gen_movi_tl(t0, v2);
22854             gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22855             break;
22856         case OPC_DEXTRV_RS_W:
22857             tcg_gen_movi_tl(t0, v2);
22858             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
22859             break;
22860         }
22861         break;
22862 #endif
22863     }
22864
22865     tcg_temp_free(t0);
22866     tcg_temp_free(t1);
22867     tcg_temp_free(v1_t);
22868     tcg_temp_free(v2_t);
22869 }
22870
22871 /* End MIPSDSP functions. */
22872
22873 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
22874 {
22875     int rs, rt, rd, sa;
22876     uint32_t op1, op2;
22877
22878     rs = (ctx->opcode >> 21) & 0x1f;
22879     rt = (ctx->opcode >> 16) & 0x1f;
22880     rd = (ctx->opcode >> 11) & 0x1f;
22881     sa = (ctx->opcode >> 6) & 0x1f;
22882
22883     op1 = MASK_SPECIAL(ctx->opcode);
22884     switch (op1) {
22885     case OPC_LSA:
22886         gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
22887         break;
22888     case OPC_MULT:
22889     case OPC_MULTU:
22890     case OPC_DIV:
22891     case OPC_DIVU:
22892         op2 = MASK_R6_MULDIV(ctx->opcode);
22893         switch (op2) {
22894         case R6_OPC_MUL:
22895         case R6_OPC_MUH:
22896         case R6_OPC_MULU:
22897         case R6_OPC_MUHU:
22898         case R6_OPC_DIV:
22899         case R6_OPC_MOD:
22900         case R6_OPC_DIVU:
22901         case R6_OPC_MODU:
22902             gen_r6_muldiv(ctx, op2, rd, rs, rt);
22903             break;
22904         default:
22905             MIPS_INVAL("special_r6 muldiv");
22906             generate_exception_end(ctx, EXCP_RI);
22907             break;
22908         }
22909         break;
22910     case OPC_SELEQZ:
22911     case OPC_SELNEZ:
22912         gen_cond_move(ctx, op1, rd, rs, rt);
22913         break;
22914     case R6_OPC_CLO:
22915     case R6_OPC_CLZ:
22916         if (rt == 0 && sa == 1) {
22917             /* Major opcode and function field is shared with preR6 MFHI/MTHI.
22918                We need additionally to check other fields */
22919             gen_cl(ctx, op1, rd, rs);
22920         } else {
22921             generate_exception_end(ctx, EXCP_RI);
22922         }
22923         break;
22924     case R6_OPC_SDBBP:
22925         if (is_uhi(extract32(ctx->opcode, 6, 20))) {
22926             gen_helper_do_semihosting(cpu_env);
22927         } else {
22928             if (ctx->hflags & MIPS_HFLAG_SBRI) {
22929                 generate_exception_end(ctx, EXCP_RI);
22930             } else {
22931                 generate_exception_end(ctx, EXCP_DBp);
22932             }
22933         }
22934         break;
22935 #if defined(TARGET_MIPS64)
22936     case OPC_DLSA:
22937         check_mips_64(ctx);
22938         gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
22939         break;
22940     case R6_OPC_DCLO:
22941     case R6_OPC_DCLZ:
22942         if (rt == 0 && sa == 1) {
22943             /* Major opcode and function field is shared with preR6 MFHI/MTHI.
22944                We need additionally to check other fields */
22945             check_mips_64(ctx);
22946             gen_cl(ctx, op1, rd, rs);
22947         } else {
22948             generate_exception_end(ctx, EXCP_RI);
22949         }
22950         break;
22951     case OPC_DMULT:
22952     case OPC_DMULTU:
22953     case OPC_DDIV:
22954     case OPC_DDIVU:
22955
22956         op2 = MASK_R6_MULDIV(ctx->opcode);
22957         switch (op2) {
22958         case R6_OPC_DMUL:
22959         case R6_OPC_DMUH:
22960         case R6_OPC_DMULU:
22961         case R6_OPC_DMUHU:
22962         case R6_OPC_DDIV:
22963         case R6_OPC_DMOD:
22964         case R6_OPC_DDIVU:
22965         case R6_OPC_DMODU:
22966             check_mips_64(ctx);
22967             gen_r6_muldiv(ctx, op2, rd, rs, rt);
22968             break;
22969         default:
22970             MIPS_INVAL("special_r6 muldiv");
22971             generate_exception_end(ctx, EXCP_RI);
22972             break;
22973         }
22974         break;
22975 #endif
22976     default:            /* Invalid */
22977         MIPS_INVAL("special_r6");
22978         generate_exception_end(ctx, EXCP_RI);
22979         break;
22980     }
22981 }
22982
22983 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
22984 {
22985     int rs, rt, rd, sa;
22986     uint32_t op1;
22987
22988     rs = (ctx->opcode >> 21) & 0x1f;
22989     rt = (ctx->opcode >> 16) & 0x1f;
22990     rd = (ctx->opcode >> 11) & 0x1f;
22991     sa = (ctx->opcode >> 6) & 0x1f;
22992
22993     op1 = MASK_SPECIAL(ctx->opcode);
22994     switch (op1) {
22995     case OPC_MOVN:         /* Conditional move */
22996     case OPC_MOVZ:
22997         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
22998                    INSN_LOONGSON2E | INSN_LOONGSON2F);
22999         gen_cond_move(ctx, op1, rd, rs, rt);
23000         break;
23001     case OPC_MFHI:          /* Move from HI/LO */
23002     case OPC_MFLO:
23003         gen_HILO(ctx, op1, rs & 3, rd);
23004         break;
23005     case OPC_MTHI:
23006     case OPC_MTLO:          /* Move to HI/LO */
23007         gen_HILO(ctx, op1, rd & 3, rs);
23008         break;
23009     case OPC_MOVCI:
23010         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
23011         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
23012             check_cp1_enabled(ctx);
23013             gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
23014                       (ctx->opcode >> 16) & 1);
23015         } else {
23016             generate_exception_err(ctx, EXCP_CpU, 1);
23017         }
23018         break;
23019     case OPC_MULT:
23020     case OPC_MULTU:
23021         if (sa) {
23022             check_insn(ctx, INSN_VR54XX);
23023             op1 = MASK_MUL_VR54XX(ctx->opcode);
23024             gen_mul_vr54xx(ctx, op1, rd, rs, rt);
23025         } else {
23026             gen_muldiv(ctx, op1, rd & 3, rs, rt);
23027         }
23028         break;
23029     case OPC_DIV:
23030     case OPC_DIVU:
23031         gen_muldiv(ctx, op1, 0, rs, rt);
23032         break;
23033 #if defined(TARGET_MIPS64)
23034     case OPC_DMULT:
23035     case OPC_DMULTU:
23036     case OPC_DDIV:
23037     case OPC_DDIVU:
23038         check_insn(ctx, ISA_MIPS3);
23039         check_mips_64(ctx);
23040         gen_muldiv(ctx, op1, 0, rs, rt);
23041         break;
23042 #endif
23043     case OPC_JR:
23044         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
23045         break;
23046     case OPC_SPIM:
23047 #ifdef MIPS_STRICT_STANDARD
23048         MIPS_INVAL("SPIM");
23049         generate_exception_end(ctx, EXCP_RI);
23050 #else
23051         /* Implemented as RI exception for now. */
23052         MIPS_INVAL("spim (unofficial)");
23053         generate_exception_end(ctx, EXCP_RI);
23054 #endif
23055         break;
23056     default:            /* Invalid */
23057         MIPS_INVAL("special_legacy");
23058         generate_exception_end(ctx, EXCP_RI);
23059         break;
23060     }
23061 }
23062
23063 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
23064 {
23065     int rs, rt, rd, sa;
23066     uint32_t op1;
23067
23068     rs = (ctx->opcode >> 21) & 0x1f;
23069     rt = (ctx->opcode >> 16) & 0x1f;
23070     rd = (ctx->opcode >> 11) & 0x1f;
23071     sa = (ctx->opcode >> 6) & 0x1f;
23072
23073     op1 = MASK_SPECIAL(ctx->opcode);
23074     switch (op1) {
23075     case OPC_SLL:          /* Shift with immediate */
23076         if (sa == 5 && rd == 0 &&
23077             rs == 0 && rt == 0) { /* PAUSE */
23078             if ((ctx->insn_flags & ISA_MIPS32R6) &&
23079                 (ctx->hflags & MIPS_HFLAG_BMASK)) {
23080                 generate_exception_end(ctx, EXCP_RI);
23081                 break;
23082             }
23083         }
23084         /* Fallthrough */
23085     case OPC_SRA:
23086         gen_shift_imm(ctx, op1, rd, rt, sa);
23087         break;
23088     case OPC_SRL:
23089         switch ((ctx->opcode >> 21) & 0x1f) {
23090         case 1:
23091             /* rotr is decoded as srl on non-R2 CPUs */
23092             if (ctx->insn_flags & ISA_MIPS32R2) {
23093                 op1 = OPC_ROTR;
23094             }
23095             /* Fallthrough */
23096         case 0:
23097             gen_shift_imm(ctx, op1, rd, rt, sa);
23098             break;
23099         default:
23100             generate_exception_end(ctx, EXCP_RI);
23101             break;
23102         }
23103         break;
23104     case OPC_ADD:
23105     case OPC_ADDU:
23106     case OPC_SUB:
23107     case OPC_SUBU:
23108         gen_arith(ctx, op1, rd, rs, rt);
23109         break;
23110     case OPC_SLLV:         /* Shifts */
23111     case OPC_SRAV:
23112         gen_shift(ctx, op1, rd, rs, rt);
23113         break;
23114     case OPC_SRLV:
23115         switch ((ctx->opcode >> 6) & 0x1f) {
23116         case 1:
23117             /* rotrv is decoded as srlv on non-R2 CPUs */
23118             if (ctx->insn_flags & ISA_MIPS32R2) {
23119                 op1 = OPC_ROTRV;
23120             }
23121             /* Fallthrough */
23122         case 0:
23123             gen_shift(ctx, op1, rd, rs, rt);
23124             break;
23125         default:
23126             generate_exception_end(ctx, EXCP_RI);
23127             break;
23128         }
23129         break;
23130     case OPC_SLT:          /* Set on less than */
23131     case OPC_SLTU:
23132         gen_slt(ctx, op1, rd, rs, rt);
23133         break;
23134     case OPC_AND:          /* Logic*/
23135     case OPC_OR:
23136     case OPC_NOR:
23137     case OPC_XOR:
23138         gen_logic(ctx, op1, rd, rs, rt);
23139         break;
23140     case OPC_JALR:
23141         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
23142         break;
23143     case OPC_TGE: /* Traps */
23144     case OPC_TGEU:
23145     case OPC_TLT:
23146     case OPC_TLTU:
23147     case OPC_TEQ:
23148     case OPC_TNE:
23149         check_insn(ctx, ISA_MIPS2);
23150         gen_trap(ctx, op1, rs, rt, -1);
23151         break;
23152     case OPC_LSA: /* OPC_PMON */
23153         if ((ctx->insn_flags & ISA_MIPS32R6) ||
23154             (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
23155             decode_opc_special_r6(env, ctx);
23156         } else {
23157             /* Pmon entry point, also R4010 selsl */
23158 #ifdef MIPS_STRICT_STANDARD
23159             MIPS_INVAL("PMON / selsl");
23160             generate_exception_end(ctx, EXCP_RI);
23161 #else
23162             gen_helper_0e0i(pmon, sa);
23163 #endif
23164         }
23165         break;
23166     case OPC_SYSCALL:
23167         generate_exception_end(ctx, EXCP_SYSCALL);
23168         break;
23169     case OPC_BREAK:
23170         generate_exception_end(ctx, EXCP_BREAK);
23171         break;
23172     case OPC_SYNC:
23173         check_insn(ctx, ISA_MIPS2);
23174         gen_sync(extract32(ctx->opcode, 6, 5));
23175         break;
23176
23177 #if defined(TARGET_MIPS64)
23178         /* MIPS64 specific opcodes */
23179     case OPC_DSLL:
23180     case OPC_DSRA:
23181     case OPC_DSLL32:
23182     case OPC_DSRA32:
23183         check_insn(ctx, ISA_MIPS3);
23184         check_mips_64(ctx);
23185         gen_shift_imm(ctx, op1, rd, rt, sa);
23186         break;
23187     case OPC_DSRL:
23188         switch ((ctx->opcode >> 21) & 0x1f) {
23189         case 1:
23190             /* drotr is decoded as dsrl on non-R2 CPUs */
23191             if (ctx->insn_flags & ISA_MIPS32R2) {
23192                 op1 = OPC_DROTR;
23193             }
23194             /* Fallthrough */
23195         case 0:
23196             check_insn(ctx, ISA_MIPS3);
23197             check_mips_64(ctx);
23198             gen_shift_imm(ctx, op1, rd, rt, sa);
23199             break;
23200         default:
23201             generate_exception_end(ctx, EXCP_RI);
23202             break;
23203         }
23204         break;
23205     case OPC_DSRL32:
23206         switch ((ctx->opcode >> 21) & 0x1f) {
23207         case 1:
23208             /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
23209             if (ctx->insn_flags & ISA_MIPS32R2) {
23210                 op1 = OPC_DROTR32;
23211             }
23212             /* Fallthrough */
23213         case 0:
23214             check_insn(ctx, ISA_MIPS3);
23215             check_mips_64(ctx);
23216             gen_shift_imm(ctx, op1, rd, rt, sa);
23217             break;
23218         default:
23219             generate_exception_end(ctx, EXCP_RI);
23220             break;
23221         }
23222         break;
23223     case OPC_DADD:
23224     case OPC_DADDU:
23225     case OPC_DSUB:
23226     case OPC_DSUBU:
23227         check_insn(ctx, ISA_MIPS3);
23228         check_mips_64(ctx);
23229         gen_arith(ctx, op1, rd, rs, rt);
23230         break;
23231     case OPC_DSLLV:
23232     case OPC_DSRAV:
23233         check_insn(ctx, ISA_MIPS3);
23234         check_mips_64(ctx);
23235         gen_shift(ctx, op1, rd, rs, rt);
23236         break;
23237     case OPC_DSRLV:
23238         switch ((ctx->opcode >> 6) & 0x1f) {
23239         case 1:
23240             /* drotrv is decoded as dsrlv on non-R2 CPUs */
23241             if (ctx->insn_flags & ISA_MIPS32R2) {
23242                 op1 = OPC_DROTRV;
23243             }
23244             /* Fallthrough */
23245         case 0:
23246             check_insn(ctx, ISA_MIPS3);
23247             check_mips_64(ctx);
23248             gen_shift(ctx, op1, rd, rs, rt);
23249             break;
23250         default:
23251             generate_exception_end(ctx, EXCP_RI);
23252             break;
23253         }
23254         break;
23255     case OPC_DLSA:
23256         if ((ctx->insn_flags & ISA_MIPS32R6) ||
23257             (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
23258             decode_opc_special_r6(env, ctx);
23259         }
23260         break;
23261 #endif
23262     default:
23263         if (ctx->insn_flags & ISA_MIPS32R6) {
23264             decode_opc_special_r6(env, ctx);
23265         } else {
23266             decode_opc_special_legacy(env, ctx);
23267         }
23268     }
23269 }
23270
23271 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
23272 {
23273     int rs, rt, rd;
23274     uint32_t op1;
23275
23276     check_insn_opc_removed(ctx, ISA_MIPS32R6);
23277
23278     rs = (ctx->opcode >> 21) & 0x1f;
23279     rt = (ctx->opcode >> 16) & 0x1f;
23280     rd = (ctx->opcode >> 11) & 0x1f;
23281
23282     op1 = MASK_SPECIAL2(ctx->opcode);
23283     switch (op1) {
23284     case OPC_MADD: /* Multiply and add/sub */
23285     case OPC_MADDU:
23286     case OPC_MSUB:
23287     case OPC_MSUBU:
23288         check_insn(ctx, ISA_MIPS32);
23289         gen_muldiv(ctx, op1, rd & 3, rs, rt);
23290         break;
23291     case OPC_MUL:
23292         gen_arith(ctx, op1, rd, rs, rt);
23293         break;
23294     case OPC_DIV_G_2F:
23295     case OPC_DIVU_G_2F:
23296     case OPC_MULT_G_2F:
23297     case OPC_MULTU_G_2F:
23298     case OPC_MOD_G_2F:
23299     case OPC_MODU_G_2F:
23300         check_insn(ctx, INSN_LOONGSON2F);
23301         gen_loongson_integer(ctx, op1, rd, rs, rt);
23302         break;
23303     case OPC_CLO:
23304     case OPC_CLZ:
23305         check_insn(ctx, ISA_MIPS32);
23306         gen_cl(ctx, op1, rd, rs);
23307         break;
23308     case OPC_SDBBP:
23309         if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23310             gen_helper_do_semihosting(cpu_env);
23311         } else {
23312             /* XXX: not clear which exception should be raised
23313              *      when in debug mode...
23314              */
23315             check_insn(ctx, ISA_MIPS32);
23316             generate_exception_end(ctx, EXCP_DBp);
23317         }
23318         break;
23319 #if defined(TARGET_MIPS64)
23320     case OPC_DCLO:
23321     case OPC_DCLZ:
23322         check_insn(ctx, ISA_MIPS64);
23323         check_mips_64(ctx);
23324         gen_cl(ctx, op1, rd, rs);
23325         break;
23326     case OPC_DMULT_G_2F:
23327     case OPC_DMULTU_G_2F:
23328     case OPC_DDIV_G_2F:
23329     case OPC_DDIVU_G_2F:
23330     case OPC_DMOD_G_2F:
23331     case OPC_DMODU_G_2F:
23332         check_insn(ctx, INSN_LOONGSON2F);
23333         gen_loongson_integer(ctx, op1, rd, rs, rt);
23334         break;
23335 #endif
23336     default:            /* Invalid */
23337         MIPS_INVAL("special2_legacy");
23338         generate_exception_end(ctx, EXCP_RI);
23339         break;
23340     }
23341 }
23342
23343 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
23344 {
23345     int rs, rt, rd, sa;
23346     uint32_t op1, op2;
23347     int16_t imm;
23348
23349     rs = (ctx->opcode >> 21) & 0x1f;
23350     rt = (ctx->opcode >> 16) & 0x1f;
23351     rd = (ctx->opcode >> 11) & 0x1f;
23352     sa = (ctx->opcode >> 6) & 0x1f;
23353     imm = (int16_t)ctx->opcode >> 7;
23354
23355     op1 = MASK_SPECIAL3(ctx->opcode);
23356     switch (op1) {
23357     case R6_OPC_PREF:
23358         if (rt >= 24) {
23359             /* hint codes 24-31 are reserved and signal RI */
23360             generate_exception_end(ctx, EXCP_RI);
23361         }
23362         /* Treat as NOP. */
23363         break;
23364     case R6_OPC_CACHE:
23365         check_cp0_enabled(ctx);
23366         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
23367             gen_cache_operation(ctx, rt, rs, imm);
23368         }
23369         break;
23370     case R6_OPC_SC:
23371         gen_st_cond(ctx, op1, rt, rs, imm);
23372         break;
23373     case R6_OPC_LL:
23374         gen_ld(ctx, op1, rt, rs, imm);
23375         break;
23376     case OPC_BSHFL:
23377         {
23378             if (rd == 0) {
23379                 /* Treat as NOP. */
23380                 break;
23381             }
23382             op2 = MASK_BSHFL(ctx->opcode);
23383             switch (op2) {
23384             case OPC_ALIGN:
23385             case OPC_ALIGN_END:
23386                 gen_align(ctx, 32, rd, rs, rt, sa & 3);
23387                 break;
23388             case OPC_BITSWAP:
23389                 gen_bitswap(ctx, op2, rd, rt);
23390                 break;
23391             }
23392         }
23393         break;
23394 #if defined(TARGET_MIPS64)
23395     case R6_OPC_SCD:
23396         gen_st_cond(ctx, op1, rt, rs, imm);
23397         break;
23398     case R6_OPC_LLD:
23399         gen_ld(ctx, op1, rt, rs, imm);
23400         break;
23401     case OPC_DBSHFL:
23402         check_mips_64(ctx);
23403         {
23404             if (rd == 0) {
23405                 /* Treat as NOP. */
23406                 break;
23407             }
23408             op2 = MASK_DBSHFL(ctx->opcode);
23409             switch (op2) {
23410             case OPC_DALIGN:
23411             case OPC_DALIGN_END:
23412                 gen_align(ctx, 64, rd, rs, rt, sa & 7);
23413                 break;
23414             case OPC_DBITSWAP:
23415                 gen_bitswap(ctx, op2, rd, rt);
23416                 break;
23417             }
23418
23419         }
23420         break;
23421 #endif
23422     default:            /* Invalid */
23423         MIPS_INVAL("special3_r6");
23424         generate_exception_end(ctx, EXCP_RI);
23425         break;
23426     }
23427 }
23428
23429 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
23430 {
23431     int rs, rt, rd;
23432     uint32_t op1, op2;
23433
23434     rs = (ctx->opcode >> 21) & 0x1f;
23435     rt = (ctx->opcode >> 16) & 0x1f;
23436     rd = (ctx->opcode >> 11) & 0x1f;
23437
23438     op1 = MASK_SPECIAL3(ctx->opcode);
23439     switch (op1) {
23440     case OPC_DIV_G_2E:
23441     case OPC_DIVU_G_2E:
23442     case OPC_MOD_G_2E:
23443     case OPC_MODU_G_2E:
23444     case OPC_MULT_G_2E:
23445     case OPC_MULTU_G_2E:
23446         /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23447          * the same mask and op1. */
23448         if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
23449             op2 = MASK_ADDUH_QB(ctx->opcode);
23450             switch (op2) {
23451             case OPC_ADDUH_QB:
23452             case OPC_ADDUH_R_QB:
23453             case OPC_ADDQH_PH:
23454             case OPC_ADDQH_R_PH:
23455             case OPC_ADDQH_W:
23456             case OPC_ADDQH_R_W:
23457             case OPC_SUBUH_QB:
23458             case OPC_SUBUH_R_QB:
23459             case OPC_SUBQH_PH:
23460             case OPC_SUBQH_R_PH:
23461             case OPC_SUBQH_W:
23462             case OPC_SUBQH_R_W:
23463                 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23464                 break;
23465             case OPC_MUL_PH:
23466             case OPC_MUL_S_PH:
23467             case OPC_MULQ_S_W:
23468             case OPC_MULQ_RS_W:
23469                 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
23470                 break;
23471             default:
23472                 MIPS_INVAL("MASK ADDUH.QB");
23473                 generate_exception_end(ctx, EXCP_RI);
23474                 break;
23475             }
23476         } else if (ctx->insn_flags & INSN_LOONGSON2E) {
23477             gen_loongson_integer(ctx, op1, rd, rs, rt);
23478         } else {
23479             generate_exception_end(ctx, EXCP_RI);
23480         }
23481         break;
23482     case OPC_LX_DSP:
23483         op2 = MASK_LX(ctx->opcode);
23484         switch (op2) {
23485 #if defined(TARGET_MIPS64)
23486         case OPC_LDX:
23487 #endif
23488         case OPC_LBUX:
23489         case OPC_LHX:
23490         case OPC_LWX:
23491             gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
23492             break;
23493         default:            /* Invalid */
23494             MIPS_INVAL("MASK LX");
23495             generate_exception_end(ctx, EXCP_RI);
23496             break;
23497         }
23498         break;
23499     case OPC_ABSQ_S_PH_DSP:
23500         op2 = MASK_ABSQ_S_PH(ctx->opcode);
23501         switch (op2) {
23502         case OPC_ABSQ_S_QB:
23503         case OPC_ABSQ_S_PH:
23504         case OPC_ABSQ_S_W:
23505         case OPC_PRECEQ_W_PHL:
23506         case OPC_PRECEQ_W_PHR:
23507         case OPC_PRECEQU_PH_QBL:
23508         case OPC_PRECEQU_PH_QBR:
23509         case OPC_PRECEQU_PH_QBLA:
23510         case OPC_PRECEQU_PH_QBRA:
23511         case OPC_PRECEU_PH_QBL:
23512         case OPC_PRECEU_PH_QBR:
23513         case OPC_PRECEU_PH_QBLA:
23514         case OPC_PRECEU_PH_QBRA:
23515             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23516             break;
23517         case OPC_BITREV:
23518         case OPC_REPL_QB:
23519         case OPC_REPLV_QB:
23520         case OPC_REPL_PH:
23521         case OPC_REPLV_PH:
23522             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
23523             break;
23524         default:
23525             MIPS_INVAL("MASK ABSQ_S.PH");
23526             generate_exception_end(ctx, EXCP_RI);
23527             break;
23528         }
23529         break;
23530     case OPC_ADDU_QB_DSP:
23531         op2 = MASK_ADDU_QB(ctx->opcode);
23532         switch (op2) {
23533         case OPC_ADDQ_PH:
23534         case OPC_ADDQ_S_PH:
23535         case OPC_ADDQ_S_W:
23536         case OPC_ADDU_QB:
23537         case OPC_ADDU_S_QB:
23538         case OPC_ADDU_PH:
23539         case OPC_ADDU_S_PH:
23540         case OPC_SUBQ_PH:
23541         case OPC_SUBQ_S_PH:
23542         case OPC_SUBQ_S_W:
23543         case OPC_SUBU_QB:
23544         case OPC_SUBU_S_QB:
23545         case OPC_SUBU_PH:
23546         case OPC_SUBU_S_PH:
23547         case OPC_ADDSC:
23548         case OPC_ADDWC:
23549         case OPC_MODSUB:
23550         case OPC_RADDU_W_QB:
23551             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23552             break;
23553         case OPC_MULEU_S_PH_QBL:
23554         case OPC_MULEU_S_PH_QBR:
23555         case OPC_MULQ_RS_PH:
23556         case OPC_MULEQ_S_W_PHL:
23557         case OPC_MULEQ_S_W_PHR:
23558         case OPC_MULQ_S_PH:
23559             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
23560             break;
23561         default:            /* Invalid */
23562             MIPS_INVAL("MASK ADDU.QB");
23563             generate_exception_end(ctx, EXCP_RI);
23564             break;
23565
23566         }
23567         break;
23568     case OPC_CMPU_EQ_QB_DSP:
23569         op2 = MASK_CMPU_EQ_QB(ctx->opcode);
23570         switch (op2) {
23571         case OPC_PRECR_SRA_PH_W:
23572         case OPC_PRECR_SRA_R_PH_W:
23573             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
23574             break;
23575         case OPC_PRECR_QB_PH:
23576         case OPC_PRECRQ_QB_PH:
23577         case OPC_PRECRQ_PH_W:
23578         case OPC_PRECRQ_RS_PH_W:
23579         case OPC_PRECRQU_S_QB_PH:
23580             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23581             break;
23582         case OPC_CMPU_EQ_QB:
23583         case OPC_CMPU_LT_QB:
23584         case OPC_CMPU_LE_QB:
23585         case OPC_CMP_EQ_PH:
23586         case OPC_CMP_LT_PH:
23587         case OPC_CMP_LE_PH:
23588             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
23589             break;
23590         case OPC_CMPGU_EQ_QB:
23591         case OPC_CMPGU_LT_QB:
23592         case OPC_CMPGU_LE_QB:
23593         case OPC_CMPGDU_EQ_QB:
23594         case OPC_CMPGDU_LT_QB:
23595         case OPC_CMPGDU_LE_QB:
23596         case OPC_PICK_QB:
23597         case OPC_PICK_PH:
23598         case OPC_PACKRL_PH:
23599             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
23600             break;
23601         default:            /* Invalid */
23602             MIPS_INVAL("MASK CMPU.EQ.QB");
23603             generate_exception_end(ctx, EXCP_RI);
23604             break;
23605         }
23606         break;
23607     case OPC_SHLL_QB_DSP:
23608         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
23609         break;
23610     case OPC_DPA_W_PH_DSP:
23611         op2 = MASK_DPA_W_PH(ctx->opcode);
23612         switch (op2) {
23613         case OPC_DPAU_H_QBL:
23614         case OPC_DPAU_H_QBR:
23615         case OPC_DPSU_H_QBL:
23616         case OPC_DPSU_H_QBR:
23617         case OPC_DPA_W_PH:
23618         case OPC_DPAX_W_PH:
23619         case OPC_DPAQ_S_W_PH:
23620         case OPC_DPAQX_S_W_PH:
23621         case OPC_DPAQX_SA_W_PH:
23622         case OPC_DPS_W_PH:
23623         case OPC_DPSX_W_PH:
23624         case OPC_DPSQ_S_W_PH:
23625         case OPC_DPSQX_S_W_PH:
23626         case OPC_DPSQX_SA_W_PH:
23627         case OPC_MULSAQ_S_W_PH:
23628         case OPC_DPAQ_SA_L_W:
23629         case OPC_DPSQ_SA_L_W:
23630         case OPC_MAQ_S_W_PHL:
23631         case OPC_MAQ_S_W_PHR:
23632         case OPC_MAQ_SA_W_PHL:
23633         case OPC_MAQ_SA_W_PHR:
23634         case OPC_MULSA_W_PH:
23635             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
23636             break;
23637         default:            /* Invalid */
23638             MIPS_INVAL("MASK DPAW.PH");
23639             generate_exception_end(ctx, EXCP_RI);
23640             break;
23641         }
23642         break;
23643     case OPC_INSV_DSP:
23644         op2 = MASK_INSV(ctx->opcode);
23645         switch (op2) {
23646         case OPC_INSV:
23647             check_dsp(ctx);
23648             {
23649                 TCGv t0, t1;
23650
23651                 if (rt == 0) {
23652                     break;
23653                 }
23654
23655                 t0 = tcg_temp_new();
23656                 t1 = tcg_temp_new();
23657
23658                 gen_load_gpr(t0, rt);
23659                 gen_load_gpr(t1, rs);
23660
23661                 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
23662
23663                 tcg_temp_free(t0);
23664                 tcg_temp_free(t1);
23665                 break;
23666             }
23667         default:            /* Invalid */
23668             MIPS_INVAL("MASK INSV");
23669             generate_exception_end(ctx, EXCP_RI);
23670             break;
23671         }
23672         break;
23673     case OPC_APPEND_DSP:
23674         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
23675         break;
23676     case OPC_EXTR_W_DSP:
23677         op2 = MASK_EXTR_W(ctx->opcode);
23678         switch (op2) {
23679         case OPC_EXTR_W:
23680         case OPC_EXTR_R_W:
23681         case OPC_EXTR_RS_W:
23682         case OPC_EXTR_S_H:
23683         case OPC_EXTRV_S_H:
23684         case OPC_EXTRV_W:
23685         case OPC_EXTRV_R_W:
23686         case OPC_EXTRV_RS_W:
23687         case OPC_EXTP:
23688         case OPC_EXTPV:
23689         case OPC_EXTPDP:
23690         case OPC_EXTPDPV:
23691             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
23692             break;
23693         case OPC_RDDSP:
23694             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
23695             break;
23696         case OPC_SHILO:
23697         case OPC_SHILOV:
23698         case OPC_MTHLIP:
23699         case OPC_WRDSP:
23700             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
23701             break;
23702         default:            /* Invalid */
23703             MIPS_INVAL("MASK EXTR.W");
23704             generate_exception_end(ctx, EXCP_RI);
23705             break;
23706         }
23707         break;
23708 #if defined(TARGET_MIPS64)
23709     case OPC_DDIV_G_2E:
23710     case OPC_DDIVU_G_2E:
23711     case OPC_DMULT_G_2E:
23712     case OPC_DMULTU_G_2E:
23713     case OPC_DMOD_G_2E:
23714     case OPC_DMODU_G_2E:
23715         check_insn(ctx, INSN_LOONGSON2E);
23716         gen_loongson_integer(ctx, op1, rd, rs, rt);
23717         break;
23718     case OPC_ABSQ_S_QH_DSP:
23719         op2 = MASK_ABSQ_S_QH(ctx->opcode);
23720         switch (op2) {
23721         case OPC_PRECEQ_L_PWL:
23722         case OPC_PRECEQ_L_PWR:
23723         case OPC_PRECEQ_PW_QHL:
23724         case OPC_PRECEQ_PW_QHR:
23725         case OPC_PRECEQ_PW_QHLA:
23726         case OPC_PRECEQ_PW_QHRA:
23727         case OPC_PRECEQU_QH_OBL:
23728         case OPC_PRECEQU_QH_OBR:
23729         case OPC_PRECEQU_QH_OBLA:
23730         case OPC_PRECEQU_QH_OBRA:
23731         case OPC_PRECEU_QH_OBL:
23732         case OPC_PRECEU_QH_OBR:
23733         case OPC_PRECEU_QH_OBLA:
23734         case OPC_PRECEU_QH_OBRA:
23735         case OPC_ABSQ_S_OB:
23736         case OPC_ABSQ_S_PW:
23737         case OPC_ABSQ_S_QH:
23738             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23739             break;
23740         case OPC_REPL_OB:
23741         case OPC_REPL_PW:
23742         case OPC_REPL_QH:
23743         case OPC_REPLV_OB:
23744         case OPC_REPLV_PW:
23745         case OPC_REPLV_QH:
23746             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
23747             break;
23748         default:            /* Invalid */
23749             MIPS_INVAL("MASK ABSQ_S.QH");
23750             generate_exception_end(ctx, EXCP_RI);
23751             break;
23752         }
23753         break;
23754     case OPC_ADDU_OB_DSP:
23755         op2 = MASK_ADDU_OB(ctx->opcode);
23756         switch (op2) {
23757         case OPC_RADDU_L_OB:
23758         case OPC_SUBQ_PW:
23759         case OPC_SUBQ_S_PW:
23760         case OPC_SUBQ_QH:
23761         case OPC_SUBQ_S_QH:
23762         case OPC_SUBU_OB:
23763         case OPC_SUBU_S_OB:
23764         case OPC_SUBU_QH:
23765         case OPC_SUBU_S_QH:
23766         case OPC_SUBUH_OB:
23767         case OPC_SUBUH_R_OB:
23768         case OPC_ADDQ_PW:
23769         case OPC_ADDQ_S_PW:
23770         case OPC_ADDQ_QH:
23771         case OPC_ADDQ_S_QH:
23772         case OPC_ADDU_OB:
23773         case OPC_ADDU_S_OB:
23774         case OPC_ADDU_QH:
23775         case OPC_ADDU_S_QH:
23776         case OPC_ADDUH_OB:
23777         case OPC_ADDUH_R_OB:
23778             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23779             break;
23780         case OPC_MULEQ_S_PW_QHL:
23781         case OPC_MULEQ_S_PW_QHR:
23782         case OPC_MULEU_S_QH_OBL:
23783         case OPC_MULEU_S_QH_OBR:
23784         case OPC_MULQ_RS_QH:
23785             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
23786             break;
23787         default:            /* Invalid */
23788             MIPS_INVAL("MASK ADDU.OB");
23789             generate_exception_end(ctx, EXCP_RI);
23790             break;
23791         }
23792         break;
23793     case OPC_CMPU_EQ_OB_DSP:
23794         op2 = MASK_CMPU_EQ_OB(ctx->opcode);
23795         switch (op2) {
23796         case OPC_PRECR_SRA_QH_PW:
23797         case OPC_PRECR_SRA_R_QH_PW:
23798             /* Return value is rt. */
23799             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
23800             break;
23801         case OPC_PRECR_OB_QH:
23802         case OPC_PRECRQ_OB_QH:
23803         case OPC_PRECRQ_PW_L:
23804         case OPC_PRECRQ_QH_PW:
23805         case OPC_PRECRQ_RS_QH_PW:
23806         case OPC_PRECRQU_S_OB_QH:
23807             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23808             break;
23809         case OPC_CMPU_EQ_OB:
23810         case OPC_CMPU_LT_OB:
23811         case OPC_CMPU_LE_OB:
23812         case OPC_CMP_EQ_QH:
23813         case OPC_CMP_LT_QH:
23814         case OPC_CMP_LE_QH:
23815         case OPC_CMP_EQ_PW:
23816         case OPC_CMP_LT_PW:
23817         case OPC_CMP_LE_PW:
23818             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
23819             break;
23820         case OPC_CMPGDU_EQ_OB:
23821         case OPC_CMPGDU_LT_OB:
23822         case OPC_CMPGDU_LE_OB:
23823         case OPC_CMPGU_EQ_OB:
23824         case OPC_CMPGU_LT_OB:
23825         case OPC_CMPGU_LE_OB:
23826         case OPC_PACKRL_PW:
23827         case OPC_PICK_OB:
23828         case OPC_PICK_PW:
23829         case OPC_PICK_QH:
23830             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
23831             break;
23832         default:            /* Invalid */
23833             MIPS_INVAL("MASK CMPU_EQ.OB");
23834             generate_exception_end(ctx, EXCP_RI);
23835             break;
23836         }
23837         break;
23838     case OPC_DAPPEND_DSP:
23839         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
23840         break;
23841     case OPC_DEXTR_W_DSP:
23842         op2 = MASK_DEXTR_W(ctx->opcode);
23843         switch (op2) {
23844         case OPC_DEXTP:
23845         case OPC_DEXTPDP:
23846         case OPC_DEXTPDPV:
23847         case OPC_DEXTPV:
23848         case OPC_DEXTR_L:
23849         case OPC_DEXTR_R_L:
23850         case OPC_DEXTR_RS_L:
23851         case OPC_DEXTR_W:
23852         case OPC_DEXTR_R_W:
23853         case OPC_DEXTR_RS_W:
23854         case OPC_DEXTR_S_H:
23855         case OPC_DEXTRV_L:
23856         case OPC_DEXTRV_R_L:
23857         case OPC_DEXTRV_RS_L:
23858         case OPC_DEXTRV_S_H:
23859         case OPC_DEXTRV_W:
23860         case OPC_DEXTRV_R_W:
23861         case OPC_DEXTRV_RS_W:
23862             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
23863             break;
23864         case OPC_DMTHLIP:
23865         case OPC_DSHILO:
23866         case OPC_DSHILOV:
23867             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
23868             break;
23869         default:            /* Invalid */
23870             MIPS_INVAL("MASK EXTR.W");
23871             generate_exception_end(ctx, EXCP_RI);
23872             break;
23873         }
23874         break;
23875     case OPC_DPAQ_W_QH_DSP:
23876         op2 = MASK_DPAQ_W_QH(ctx->opcode);
23877         switch (op2) {
23878         case OPC_DPAU_H_OBL:
23879         case OPC_DPAU_H_OBR:
23880         case OPC_DPSU_H_OBL:
23881         case OPC_DPSU_H_OBR:
23882         case OPC_DPA_W_QH:
23883         case OPC_DPAQ_S_W_QH:
23884         case OPC_DPS_W_QH:
23885         case OPC_DPSQ_S_W_QH:
23886         case OPC_MULSAQ_S_W_QH:
23887         case OPC_DPAQ_SA_L_PW:
23888         case OPC_DPSQ_SA_L_PW:
23889         case OPC_MULSAQ_S_L_PW:
23890             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
23891             break;
23892         case OPC_MAQ_S_W_QHLL:
23893         case OPC_MAQ_S_W_QHLR:
23894         case OPC_MAQ_S_W_QHRL:
23895         case OPC_MAQ_S_W_QHRR:
23896         case OPC_MAQ_SA_W_QHLL:
23897         case OPC_MAQ_SA_W_QHLR:
23898         case OPC_MAQ_SA_W_QHRL:
23899         case OPC_MAQ_SA_W_QHRR:
23900         case OPC_MAQ_S_L_PWL:
23901         case OPC_MAQ_S_L_PWR:
23902         case OPC_DMADD:
23903         case OPC_DMADDU:
23904         case OPC_DMSUB:
23905         case OPC_DMSUBU:
23906             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
23907             break;
23908         default:            /* Invalid */
23909             MIPS_INVAL("MASK DPAQ.W.QH");
23910             generate_exception_end(ctx, EXCP_RI);
23911             break;
23912         }
23913         break;
23914     case OPC_DINSV_DSP:
23915         op2 = MASK_INSV(ctx->opcode);
23916         switch (op2) {
23917         case OPC_DINSV:
23918         {
23919             TCGv t0, t1;
23920
23921             if (rt == 0) {
23922                 break;
23923             }
23924             check_dsp(ctx);
23925
23926             t0 = tcg_temp_new();
23927             t1 = tcg_temp_new();
23928
23929             gen_load_gpr(t0, rt);
23930             gen_load_gpr(t1, rs);
23931
23932             gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
23933
23934             tcg_temp_free(t0);
23935             tcg_temp_free(t1);
23936             break;
23937         }
23938         default:            /* Invalid */
23939             MIPS_INVAL("MASK DINSV");
23940             generate_exception_end(ctx, EXCP_RI);
23941             break;
23942         }
23943         break;
23944     case OPC_SHLL_OB_DSP:
23945         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
23946         break;
23947 #endif
23948     default:            /* Invalid */
23949         MIPS_INVAL("special3_legacy");
23950         generate_exception_end(ctx, EXCP_RI);
23951         break;
23952     }
23953 }
23954
23955 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
23956 {
23957     int rs, rt, rd, sa;
23958     uint32_t op1, op2;
23959     int16_t imm;
23960
23961     rs = (ctx->opcode >> 21) & 0x1f;
23962     rt = (ctx->opcode >> 16) & 0x1f;
23963     rd = (ctx->opcode >> 11) & 0x1f;
23964     sa = (ctx->opcode >> 6) & 0x1f;
23965     imm = sextract32(ctx->opcode, 7, 9);
23966
23967     op1 = MASK_SPECIAL3(ctx->opcode);
23968
23969     /*
23970      * EVA loads and stores overlap Loongson 2E instructions decoded by
23971      * decode_opc_special3_legacy(), so be careful to allow their decoding when
23972      * EVA is absent.
23973      */
23974     if (ctx->eva) {
23975         switch (op1) {
23976         case OPC_LWLE:
23977         case OPC_LWRE:
23978             check_insn_opc_removed(ctx, ISA_MIPS32R6);
23979             /* fall through */
23980         case OPC_LBUE:
23981         case OPC_LHUE:
23982         case OPC_LBE:
23983         case OPC_LHE:
23984         case OPC_LLE:
23985         case OPC_LWE:
23986             check_cp0_enabled(ctx);
23987             gen_ld(ctx, op1, rt, rs, imm);
23988             return;
23989         case OPC_SWLE:
23990         case OPC_SWRE:
23991             check_insn_opc_removed(ctx, ISA_MIPS32R6);
23992             /* fall through */
23993         case OPC_SBE:
23994         case OPC_SHE:
23995         case OPC_SWE:
23996             check_cp0_enabled(ctx);
23997             gen_st(ctx, op1, rt, rs, imm);
23998             return;
23999         case OPC_SCE:
24000             check_cp0_enabled(ctx);
24001             gen_st_cond(ctx, op1, rt, rs, imm);
24002             return;
24003         case OPC_CACHEE:
24004             check_cp0_enabled(ctx);
24005             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
24006                 gen_cache_operation(ctx, rt, rs, imm);
24007             }
24008             /* Treat as NOP. */
24009             return;
24010         case OPC_PREFE:
24011             check_cp0_enabled(ctx);
24012             /* Treat as NOP. */
24013             return;
24014         }
24015     }
24016
24017     switch (op1) {
24018     case OPC_EXT:
24019     case OPC_INS:
24020         check_insn(ctx, ISA_MIPS32R2);
24021         gen_bitops(ctx, op1, rt, rs, sa, rd);
24022         break;
24023     case OPC_BSHFL:
24024         op2 = MASK_BSHFL(ctx->opcode);
24025         switch (op2) {
24026         case OPC_ALIGN:
24027         case OPC_ALIGN_END:
24028         case OPC_BITSWAP:
24029             check_insn(ctx, ISA_MIPS32R6);
24030             decode_opc_special3_r6(env, ctx);
24031             break;
24032         default:
24033             check_insn(ctx, ISA_MIPS32R2);
24034             gen_bshfl(ctx, op2, rt, rd);
24035             break;
24036         }
24037         break;
24038 #if defined(TARGET_MIPS64)
24039     case OPC_DEXTM:
24040     case OPC_DEXTU:
24041     case OPC_DEXT:
24042     case OPC_DINSM:
24043     case OPC_DINSU:
24044     case OPC_DINS:
24045         check_insn(ctx, ISA_MIPS64R2);
24046         check_mips_64(ctx);
24047         gen_bitops(ctx, op1, rt, rs, sa, rd);
24048         break;
24049     case OPC_DBSHFL:
24050         op2 = MASK_DBSHFL(ctx->opcode);
24051         switch (op2) {
24052         case OPC_DALIGN:
24053         case OPC_DALIGN_END:
24054         case OPC_DBITSWAP:
24055             check_insn(ctx, ISA_MIPS32R6);
24056             decode_opc_special3_r6(env, ctx);
24057             break;
24058         default:
24059             check_insn(ctx, ISA_MIPS64R2);
24060             check_mips_64(ctx);
24061             op2 = MASK_DBSHFL(ctx->opcode);
24062             gen_bshfl(ctx, op2, rt, rd);
24063             break;
24064         }
24065         break;
24066 #endif
24067     case OPC_RDHWR:
24068         gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
24069         break;
24070     case OPC_FORK:
24071         check_mt(ctx);
24072         {
24073             TCGv t0 = tcg_temp_new();
24074             TCGv t1 = tcg_temp_new();
24075
24076             gen_load_gpr(t0, rt);
24077             gen_load_gpr(t1, rs);
24078             gen_helper_fork(t0, t1);
24079             tcg_temp_free(t0);
24080             tcg_temp_free(t1);
24081         }
24082         break;
24083     case OPC_YIELD:
24084         check_mt(ctx);
24085         {
24086             TCGv t0 = tcg_temp_new();
24087
24088             gen_load_gpr(t0, rs);
24089             gen_helper_yield(t0, cpu_env, t0);
24090             gen_store_gpr(t0, rd);
24091             tcg_temp_free(t0);
24092         }
24093         break;
24094     default:
24095         if (ctx->insn_flags & ISA_MIPS32R6) {
24096             decode_opc_special3_r6(env, ctx);
24097         } else {
24098             decode_opc_special3_legacy(env, ctx);
24099         }
24100     }
24101 }
24102
24103 /* MIPS SIMD Architecture (MSA)  */
24104 static inline int check_msa_access(DisasContext *ctx)
24105 {
24106     if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
24107                  !(ctx->hflags & MIPS_HFLAG_F64))) {
24108         generate_exception_end(ctx, EXCP_RI);
24109         return 0;
24110     }
24111
24112     if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
24113         if (ctx->insn_flags & ASE_MSA) {
24114             generate_exception_end(ctx, EXCP_MSADIS);
24115             return 0;
24116         } else {
24117             generate_exception_end(ctx, EXCP_RI);
24118             return 0;
24119         }
24120     }
24121     return 1;
24122 }
24123
24124 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
24125 {
24126     /* generates tcg ops to check if any element is 0 */
24127     /* Note this function only works with MSA_WRLEN = 128 */
24128     uint64_t eval_zero_or_big = 0;
24129     uint64_t eval_big = 0;
24130     TCGv_i64 t0 = tcg_temp_new_i64();
24131     TCGv_i64 t1 = tcg_temp_new_i64();
24132     switch (df) {
24133     case DF_BYTE:
24134         eval_zero_or_big = 0x0101010101010101ULL;
24135         eval_big = 0x8080808080808080ULL;
24136         break;
24137     case DF_HALF:
24138         eval_zero_or_big = 0x0001000100010001ULL;
24139         eval_big = 0x8000800080008000ULL;
24140         break;
24141     case DF_WORD:
24142         eval_zero_or_big = 0x0000000100000001ULL;
24143         eval_big = 0x8000000080000000ULL;
24144         break;
24145     case DF_DOUBLE:
24146         eval_zero_or_big = 0x0000000000000001ULL;
24147         eval_big = 0x8000000000000000ULL;
24148         break;
24149     }
24150     tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
24151     tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
24152     tcg_gen_andi_i64(t0, t0, eval_big);
24153     tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
24154     tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
24155     tcg_gen_andi_i64(t1, t1, eval_big);
24156     tcg_gen_or_i64(t0, t0, t1);
24157     /* if all bits are zero then all elements are not zero */
24158     /* if some bit is non-zero then some element is zero */
24159     tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
24160     tcg_gen_trunc_i64_tl(tresult, t0);
24161     tcg_temp_free_i64(t0);
24162     tcg_temp_free_i64(t1);
24163 }
24164
24165 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
24166 {
24167     uint8_t df = (ctx->opcode >> 21) & 0x3;
24168     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24169     int64_t s16 = (int16_t)ctx->opcode;
24170
24171     check_msa_access(ctx);
24172
24173     if (ctx->hflags & MIPS_HFLAG_BMASK) {
24174         generate_exception_end(ctx, EXCP_RI);
24175         return;
24176     }
24177     switch (op1) {
24178     case OPC_BZ_V:
24179     case OPC_BNZ_V:
24180         {
24181             TCGv_i64 t0 = tcg_temp_new_i64();
24182             tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
24183             tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
24184                     TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
24185             tcg_gen_trunc_i64_tl(bcond, t0);
24186             tcg_temp_free_i64(t0);
24187         }
24188         break;
24189     case OPC_BZ_B:
24190     case OPC_BZ_H:
24191     case OPC_BZ_W:
24192     case OPC_BZ_D:
24193         gen_check_zero_element(bcond, df, wt);
24194         break;
24195     case OPC_BNZ_B:
24196     case OPC_BNZ_H:
24197     case OPC_BNZ_W:
24198     case OPC_BNZ_D:
24199         gen_check_zero_element(bcond, df, wt);
24200         tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
24201         break;
24202     }
24203
24204     ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
24205
24206     ctx->hflags |= MIPS_HFLAG_BC;
24207     ctx->hflags |= MIPS_HFLAG_BDS32;
24208 }
24209
24210 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
24211 {
24212 #define MASK_MSA_I8(op)    (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
24213     uint8_t i8 = (ctx->opcode >> 16) & 0xff;
24214     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24215     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24216
24217     TCGv_i32 twd = tcg_const_i32(wd);
24218     TCGv_i32 tws = tcg_const_i32(ws);
24219     TCGv_i32 ti8 = tcg_const_i32(i8);
24220
24221     switch (MASK_MSA_I8(ctx->opcode)) {
24222     case OPC_ANDI_B:
24223         gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
24224         break;
24225     case OPC_ORI_B:
24226         gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
24227         break;
24228     case OPC_NORI_B:
24229         gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
24230         break;
24231     case OPC_XORI_B:
24232         gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
24233         break;
24234     case OPC_BMNZI_B:
24235         gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
24236         break;
24237     case OPC_BMZI_B:
24238         gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
24239         break;
24240     case OPC_BSELI_B:
24241         gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
24242         break;
24243     case OPC_SHF_B:
24244     case OPC_SHF_H:
24245     case OPC_SHF_W:
24246         {
24247             uint8_t df = (ctx->opcode >> 24) & 0x3;
24248             if (df == DF_DOUBLE) {
24249                 generate_exception_end(ctx, EXCP_RI);
24250             } else {
24251                 TCGv_i32 tdf = tcg_const_i32(df);
24252                 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
24253                 tcg_temp_free_i32(tdf);
24254             }
24255         }
24256         break;
24257     default:
24258         MIPS_INVAL("MSA instruction");
24259         generate_exception_end(ctx, EXCP_RI);
24260         break;
24261     }
24262
24263     tcg_temp_free_i32(twd);
24264     tcg_temp_free_i32(tws);
24265     tcg_temp_free_i32(ti8);
24266 }
24267
24268 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
24269 {
24270 #define MASK_MSA_I5(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
24271     uint8_t df = (ctx->opcode >> 21) & 0x3;
24272     int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
24273     uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
24274     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24275     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24276
24277     TCGv_i32 tdf = tcg_const_i32(df);
24278     TCGv_i32 twd = tcg_const_i32(wd);
24279     TCGv_i32 tws = tcg_const_i32(ws);
24280     TCGv_i32 timm = tcg_temp_new_i32();
24281     tcg_gen_movi_i32(timm, u5);
24282
24283     switch (MASK_MSA_I5(ctx->opcode)) {
24284     case OPC_ADDVI_df:
24285         gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
24286         break;
24287     case OPC_SUBVI_df:
24288         gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
24289         break;
24290     case OPC_MAXI_S_df:
24291         tcg_gen_movi_i32(timm, s5);
24292         gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
24293         break;
24294     case OPC_MAXI_U_df:
24295         gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
24296         break;
24297     case OPC_MINI_S_df:
24298         tcg_gen_movi_i32(timm, s5);
24299         gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
24300         break;
24301     case OPC_MINI_U_df:
24302         gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
24303         break;
24304     case OPC_CEQI_df:
24305         tcg_gen_movi_i32(timm, s5);
24306         gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
24307         break;
24308     case OPC_CLTI_S_df:
24309         tcg_gen_movi_i32(timm, s5);
24310         gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
24311         break;
24312     case OPC_CLTI_U_df:
24313         gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
24314         break;
24315     case OPC_CLEI_S_df:
24316         tcg_gen_movi_i32(timm, s5);
24317         gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
24318         break;
24319     case OPC_CLEI_U_df:
24320         gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
24321         break;
24322     case OPC_LDI_df:
24323         {
24324             int32_t s10 = sextract32(ctx->opcode, 11, 10);
24325             tcg_gen_movi_i32(timm, s10);
24326             gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
24327         }
24328         break;
24329     default:
24330         MIPS_INVAL("MSA instruction");
24331         generate_exception_end(ctx, EXCP_RI);
24332         break;
24333     }
24334
24335     tcg_temp_free_i32(tdf);
24336     tcg_temp_free_i32(twd);
24337     tcg_temp_free_i32(tws);
24338     tcg_temp_free_i32(timm);
24339 }
24340
24341 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
24342 {
24343 #define MASK_MSA_BIT(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
24344     uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
24345     uint32_t df = 0, m = 0;
24346     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24347     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24348
24349     TCGv_i32 tdf;
24350     TCGv_i32 tm;
24351     TCGv_i32 twd;
24352     TCGv_i32 tws;
24353
24354     if ((dfm & 0x40) == 0x00) {
24355         m = dfm & 0x3f;
24356         df = DF_DOUBLE;
24357     } else if ((dfm & 0x60) == 0x40) {
24358         m = dfm & 0x1f;
24359         df = DF_WORD;
24360     } else if ((dfm & 0x70) == 0x60) {
24361         m = dfm & 0x0f;
24362         df = DF_HALF;
24363     } else if ((dfm & 0x78) == 0x70) {
24364         m = dfm & 0x7;
24365         df = DF_BYTE;
24366     } else {
24367         generate_exception_end(ctx, EXCP_RI);
24368         return;
24369     }
24370
24371     tdf = tcg_const_i32(df);
24372     tm  = tcg_const_i32(m);
24373     twd = tcg_const_i32(wd);
24374     tws = tcg_const_i32(ws);
24375
24376     switch (MASK_MSA_BIT(ctx->opcode)) {
24377     case OPC_SLLI_df:
24378         gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
24379         break;
24380     case OPC_SRAI_df:
24381         gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
24382         break;
24383     case OPC_SRLI_df:
24384         gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
24385         break;
24386     case OPC_BCLRI_df:
24387         gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
24388         break;
24389     case OPC_BSETI_df:
24390         gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
24391         break;
24392     case OPC_BNEGI_df:
24393         gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
24394         break;
24395     case OPC_BINSLI_df:
24396         gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
24397         break;
24398     case OPC_BINSRI_df:
24399         gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
24400         break;
24401     case OPC_SAT_S_df:
24402         gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
24403         break;
24404     case OPC_SAT_U_df:
24405         gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
24406         break;
24407     case OPC_SRARI_df:
24408         gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
24409         break;
24410     case OPC_SRLRI_df:
24411         gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
24412         break;
24413     default:
24414         MIPS_INVAL("MSA instruction");
24415         generate_exception_end(ctx, EXCP_RI);
24416         break;
24417     }
24418
24419     tcg_temp_free_i32(tdf);
24420     tcg_temp_free_i32(tm);
24421     tcg_temp_free_i32(twd);
24422     tcg_temp_free_i32(tws);
24423 }
24424
24425 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
24426 {
24427 #define MASK_MSA_3R(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
24428     uint8_t df = (ctx->opcode >> 21) & 0x3;
24429     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24430     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24431     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24432
24433     TCGv_i32 tdf = tcg_const_i32(df);
24434     TCGv_i32 twd = tcg_const_i32(wd);
24435     TCGv_i32 tws = tcg_const_i32(ws);
24436     TCGv_i32 twt = tcg_const_i32(wt);
24437
24438     switch (MASK_MSA_3R(ctx->opcode)) {
24439     case OPC_SLL_df:
24440         gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
24441         break;
24442     case OPC_ADDV_df:
24443         gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
24444         break;
24445     case OPC_CEQ_df:
24446         gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
24447         break;
24448     case OPC_ADD_A_df:
24449         gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
24450         break;
24451     case OPC_SUBS_S_df:
24452         gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
24453         break;
24454     case OPC_MULV_df:
24455         gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
24456         break;
24457     case OPC_SLD_df:
24458         gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
24459         break;
24460     case OPC_VSHF_df:
24461         gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
24462         break;
24463     case OPC_SRA_df:
24464         gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
24465         break;
24466     case OPC_SUBV_df:
24467         gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
24468         break;
24469     case OPC_ADDS_A_df:
24470         gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
24471         break;
24472     case OPC_SUBS_U_df:
24473         gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
24474         break;
24475     case OPC_MADDV_df:
24476         gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
24477         break;
24478     case OPC_SPLAT_df:
24479         gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
24480         break;
24481     case OPC_SRAR_df:
24482         gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
24483         break;
24484     case OPC_SRL_df:
24485         gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
24486         break;
24487     case OPC_MAX_S_df:
24488         gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
24489         break;
24490     case OPC_CLT_S_df:
24491         gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
24492         break;
24493     case OPC_ADDS_S_df:
24494         gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
24495         break;
24496     case OPC_SUBSUS_U_df:
24497         gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
24498         break;
24499     case OPC_MSUBV_df:
24500         gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
24501         break;
24502     case OPC_PCKEV_df:
24503         gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
24504         break;
24505     case OPC_SRLR_df:
24506         gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
24507         break;
24508     case OPC_BCLR_df:
24509         gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
24510         break;
24511     case OPC_MAX_U_df:
24512         gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
24513         break;
24514     case OPC_CLT_U_df:
24515         gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
24516         break;
24517     case OPC_ADDS_U_df:
24518         gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
24519         break;
24520     case OPC_SUBSUU_S_df:
24521         gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
24522         break;
24523     case OPC_PCKOD_df:
24524         gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
24525         break;
24526     case OPC_BSET_df:
24527         gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
24528         break;
24529     case OPC_MIN_S_df:
24530         gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
24531         break;
24532     case OPC_CLE_S_df:
24533         gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
24534         break;
24535     case OPC_AVE_S_df:
24536         gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
24537         break;
24538     case OPC_ASUB_S_df:
24539         gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
24540         break;
24541     case OPC_DIV_S_df:
24542         gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
24543         break;
24544     case OPC_ILVL_df:
24545         gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
24546         break;
24547     case OPC_BNEG_df:
24548         gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
24549         break;
24550     case OPC_MIN_U_df:
24551         gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
24552         break;
24553     case OPC_CLE_U_df:
24554         gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
24555         break;
24556     case OPC_AVE_U_df:
24557         gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
24558         break;
24559     case OPC_ASUB_U_df:
24560         gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
24561         break;
24562     case OPC_DIV_U_df:
24563         gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
24564         break;
24565     case OPC_ILVR_df:
24566         gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
24567         break;
24568     case OPC_BINSL_df:
24569         gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
24570         break;
24571     case OPC_MAX_A_df:
24572         gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
24573         break;
24574     case OPC_AVER_S_df:
24575         gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
24576         break;
24577     case OPC_MOD_S_df:
24578         gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
24579         break;
24580     case OPC_ILVEV_df:
24581         gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
24582         break;
24583     case OPC_BINSR_df:
24584         gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
24585         break;
24586     case OPC_MIN_A_df:
24587         gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
24588         break;
24589     case OPC_AVER_U_df:
24590         gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
24591         break;
24592     case OPC_MOD_U_df:
24593         gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
24594         break;
24595     case OPC_ILVOD_df:
24596         gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
24597         break;
24598
24599     case OPC_DOTP_S_df:
24600     case OPC_DOTP_U_df:
24601     case OPC_DPADD_S_df:
24602     case OPC_DPADD_U_df:
24603     case OPC_DPSUB_S_df:
24604     case OPC_HADD_S_df:
24605     case OPC_DPSUB_U_df:
24606     case OPC_HADD_U_df:
24607     case OPC_HSUB_S_df:
24608     case OPC_HSUB_U_df:
24609         if (df == DF_BYTE) {
24610             generate_exception_end(ctx, EXCP_RI);
24611             break;
24612         }
24613         switch (MASK_MSA_3R(ctx->opcode)) {
24614         case OPC_DOTP_S_df:
24615             gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
24616             break;
24617         case OPC_DOTP_U_df:
24618             gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
24619             break;
24620         case OPC_DPADD_S_df:
24621             gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
24622             break;
24623         case OPC_DPADD_U_df:
24624             gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
24625             break;
24626         case OPC_DPSUB_S_df:
24627             gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
24628             break;
24629         case OPC_HADD_S_df:
24630             gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
24631             break;
24632         case OPC_DPSUB_U_df:
24633             gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
24634             break;
24635         case OPC_HADD_U_df:
24636             gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
24637             break;
24638         case OPC_HSUB_S_df:
24639             gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
24640             break;
24641         case OPC_HSUB_U_df:
24642             gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
24643             break;
24644         }
24645         break;
24646     default:
24647         MIPS_INVAL("MSA instruction");
24648         generate_exception_end(ctx, EXCP_RI);
24649         break;
24650     }
24651     tcg_temp_free_i32(twd);
24652     tcg_temp_free_i32(tws);
24653     tcg_temp_free_i32(twt);
24654     tcg_temp_free_i32(tdf);
24655 }
24656
24657 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
24658 {
24659 #define MASK_MSA_ELM_DF3E(op)   (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
24660     uint8_t source = (ctx->opcode >> 11) & 0x1f;
24661     uint8_t dest = (ctx->opcode >> 6) & 0x1f;
24662     TCGv telm = tcg_temp_new();
24663     TCGv_i32 tsr = tcg_const_i32(source);
24664     TCGv_i32 tdt = tcg_const_i32(dest);
24665
24666     switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
24667     case OPC_CTCMSA:
24668         gen_load_gpr(telm, source);
24669         gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
24670         break;
24671     case OPC_CFCMSA:
24672         gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
24673         gen_store_gpr(telm, dest);
24674         break;
24675     case OPC_MOVE_V:
24676         gen_helper_msa_move_v(cpu_env, tdt, tsr);
24677         break;
24678     default:
24679         MIPS_INVAL("MSA instruction");
24680         generate_exception_end(ctx, EXCP_RI);
24681         break;
24682     }
24683
24684     tcg_temp_free(telm);
24685     tcg_temp_free_i32(tdt);
24686     tcg_temp_free_i32(tsr);
24687 }
24688
24689 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
24690         uint32_t n)
24691 {
24692 #define MASK_MSA_ELM(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
24693     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24694     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24695
24696     TCGv_i32 tws = tcg_const_i32(ws);
24697     TCGv_i32 twd = tcg_const_i32(wd);
24698     TCGv_i32 tn  = tcg_const_i32(n);
24699     TCGv_i32 tdf = tcg_const_i32(df);
24700
24701     switch (MASK_MSA_ELM(ctx->opcode)) {
24702     case OPC_SLDI_df:
24703         gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
24704         break;
24705     case OPC_SPLATI_df:
24706         gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
24707         break;
24708     case OPC_INSVE_df:
24709         gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
24710         break;
24711     case OPC_COPY_S_df:
24712     case OPC_COPY_U_df:
24713     case OPC_INSERT_df:
24714 #if !defined(TARGET_MIPS64)
24715         /* Double format valid only for MIPS64 */
24716         if (df == DF_DOUBLE) {
24717             generate_exception_end(ctx, EXCP_RI);
24718             break;
24719         }
24720 #endif
24721         switch (MASK_MSA_ELM(ctx->opcode)) {
24722         case OPC_COPY_S_df:
24723             if (likely(wd != 0)) {
24724                 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
24725             }
24726             break;
24727         case OPC_COPY_U_df:
24728             if (likely(wd != 0)) {
24729                 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
24730             }
24731             break;
24732         case OPC_INSERT_df:
24733             gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
24734             break;
24735         }
24736         break;
24737     default:
24738         MIPS_INVAL("MSA instruction");
24739         generate_exception_end(ctx, EXCP_RI);
24740     }
24741     tcg_temp_free_i32(twd);
24742     tcg_temp_free_i32(tws);
24743     tcg_temp_free_i32(tn);
24744     tcg_temp_free_i32(tdf);
24745 }
24746
24747 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
24748 {
24749     uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
24750     uint32_t df = 0, n = 0;
24751
24752     if ((dfn & 0x30) == 0x00) {
24753         n = dfn & 0x0f;
24754         df = DF_BYTE;
24755     } else if ((dfn & 0x38) == 0x20) {
24756         n = dfn & 0x07;
24757         df = DF_HALF;
24758     } else if ((dfn & 0x3c) == 0x30) {
24759         n = dfn & 0x03;
24760         df = DF_WORD;
24761     } else if ((dfn & 0x3e) == 0x38) {
24762         n = dfn & 0x01;
24763         df = DF_DOUBLE;
24764     } else if (dfn == 0x3E) {
24765         /* CTCMSA, CFCMSA, MOVE.V */
24766         gen_msa_elm_3e(env, ctx);
24767         return;
24768     } else {
24769         generate_exception_end(ctx, EXCP_RI);
24770         return;
24771     }
24772
24773     gen_msa_elm_df(env, ctx, df, n);
24774 }
24775
24776 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
24777 {
24778 #define MASK_MSA_3RF(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
24779     uint8_t df = (ctx->opcode >> 21) & 0x1;
24780     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24781     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24782     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24783
24784     TCGv_i32 twd = tcg_const_i32(wd);
24785     TCGv_i32 tws = tcg_const_i32(ws);
24786     TCGv_i32 twt = tcg_const_i32(wt);
24787     TCGv_i32 tdf = tcg_temp_new_i32();
24788
24789     /* adjust df value for floating-point instruction */
24790     tcg_gen_movi_i32(tdf, df + 2);
24791
24792     switch (MASK_MSA_3RF(ctx->opcode)) {
24793     case OPC_FCAF_df:
24794         gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
24795         break;
24796     case OPC_FADD_df:
24797         gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
24798         break;
24799     case OPC_FCUN_df:
24800         gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
24801         break;
24802     case OPC_FSUB_df:
24803         gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
24804         break;
24805     case OPC_FCOR_df:
24806         gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
24807         break;
24808     case OPC_FCEQ_df:
24809         gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
24810         break;
24811     case OPC_FMUL_df:
24812         gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
24813         break;
24814     case OPC_FCUNE_df:
24815         gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
24816         break;
24817     case OPC_FCUEQ_df:
24818         gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
24819         break;
24820     case OPC_FDIV_df:
24821         gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
24822         break;
24823     case OPC_FCNE_df:
24824         gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
24825         break;
24826     case OPC_FCLT_df:
24827         gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
24828         break;
24829     case OPC_FMADD_df:
24830         gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
24831         break;
24832     case OPC_MUL_Q_df:
24833         tcg_gen_movi_i32(tdf, df + 1);
24834         gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
24835         break;
24836     case OPC_FCULT_df:
24837         gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
24838         break;
24839     case OPC_FMSUB_df:
24840         gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
24841         break;
24842     case OPC_MADD_Q_df:
24843         tcg_gen_movi_i32(tdf, df + 1);
24844         gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
24845         break;
24846     case OPC_FCLE_df:
24847         gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
24848         break;
24849     case OPC_MSUB_Q_df:
24850         tcg_gen_movi_i32(tdf, df + 1);
24851         gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
24852         break;
24853     case OPC_FCULE_df:
24854         gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
24855         break;
24856     case OPC_FEXP2_df:
24857         gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
24858         break;
24859     case OPC_FSAF_df:
24860         gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
24861         break;
24862     case OPC_FEXDO_df:
24863         gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
24864         break;
24865     case OPC_FSUN_df:
24866         gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
24867         break;
24868     case OPC_FSOR_df:
24869         gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
24870         break;
24871     case OPC_FSEQ_df:
24872         gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
24873         break;
24874     case OPC_FTQ_df:
24875         gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
24876         break;
24877     case OPC_FSUNE_df:
24878         gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
24879         break;
24880     case OPC_FSUEQ_df:
24881         gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
24882         break;
24883     case OPC_FSNE_df:
24884         gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
24885         break;
24886     case OPC_FSLT_df:
24887         gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
24888         break;
24889     case OPC_FMIN_df:
24890         gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
24891         break;
24892     case OPC_MULR_Q_df:
24893         tcg_gen_movi_i32(tdf, df + 1);
24894         gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
24895         break;
24896     case OPC_FSULT_df:
24897         gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
24898         break;
24899     case OPC_FMIN_A_df:
24900         gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
24901         break;
24902     case OPC_MADDR_Q_df:
24903         tcg_gen_movi_i32(tdf, df + 1);
24904         gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
24905         break;
24906     case OPC_FSLE_df:
24907         gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
24908         break;
24909     case OPC_FMAX_df:
24910         gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
24911         break;
24912     case OPC_MSUBR_Q_df:
24913         tcg_gen_movi_i32(tdf, df + 1);
24914         gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
24915         break;
24916     case OPC_FSULE_df:
24917         gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
24918         break;
24919     case OPC_FMAX_A_df:
24920         gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
24921         break;
24922     default:
24923         MIPS_INVAL("MSA instruction");
24924         generate_exception_end(ctx, EXCP_RI);
24925         break;
24926     }
24927
24928     tcg_temp_free_i32(twd);
24929     tcg_temp_free_i32(tws);
24930     tcg_temp_free_i32(twt);
24931     tcg_temp_free_i32(tdf);
24932 }
24933
24934 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
24935 {
24936 #define MASK_MSA_2R(op)     (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
24937                             (op & (0x7 << 18)))
24938     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24939     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24940     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24941     uint8_t df = (ctx->opcode >> 16) & 0x3;
24942     TCGv_i32 twd = tcg_const_i32(wd);
24943     TCGv_i32 tws = tcg_const_i32(ws);
24944     TCGv_i32 twt = tcg_const_i32(wt);
24945     TCGv_i32 tdf = tcg_const_i32(df);
24946
24947     switch (MASK_MSA_2R(ctx->opcode)) {
24948     case OPC_FILL_df:
24949 #if !defined(TARGET_MIPS64)
24950         /* Double format valid only for MIPS64 */
24951         if (df == DF_DOUBLE) {
24952             generate_exception_end(ctx, EXCP_RI);
24953             break;
24954         }
24955 #endif
24956         gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
24957         break;
24958     case OPC_PCNT_df:
24959         gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
24960         break;
24961     case OPC_NLOC_df:
24962         gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
24963         break;
24964     case OPC_NLZC_df:
24965         gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
24966         break;
24967     default:
24968         MIPS_INVAL("MSA instruction");
24969         generate_exception_end(ctx, EXCP_RI);
24970         break;
24971     }
24972
24973     tcg_temp_free_i32(twd);
24974     tcg_temp_free_i32(tws);
24975     tcg_temp_free_i32(twt);
24976     tcg_temp_free_i32(tdf);
24977 }
24978
24979 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
24980 {
24981 #define MASK_MSA_2RF(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
24982                             (op & (0xf << 17)))
24983     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
24984     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
24985     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
24986     uint8_t df = (ctx->opcode >> 16) & 0x1;
24987     TCGv_i32 twd = tcg_const_i32(wd);
24988     TCGv_i32 tws = tcg_const_i32(ws);
24989     TCGv_i32 twt = tcg_const_i32(wt);
24990     /* adjust df value for floating-point instruction */
24991     TCGv_i32 tdf = tcg_const_i32(df + 2);
24992
24993     switch (MASK_MSA_2RF(ctx->opcode)) {
24994     case OPC_FCLASS_df:
24995         gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
24996         break;
24997     case OPC_FTRUNC_S_df:
24998         gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
24999         break;
25000     case OPC_FTRUNC_U_df:
25001         gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
25002         break;
25003     case OPC_FSQRT_df:
25004         gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
25005         break;
25006     case OPC_FRSQRT_df:
25007         gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
25008         break;
25009     case OPC_FRCP_df:
25010         gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
25011         break;
25012     case OPC_FRINT_df:
25013         gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
25014         break;
25015     case OPC_FLOG2_df:
25016         gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
25017         break;
25018     case OPC_FEXUPL_df:
25019         gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
25020         break;
25021     case OPC_FEXUPR_df:
25022         gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
25023         break;
25024     case OPC_FFQL_df:
25025         gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
25026         break;
25027     case OPC_FFQR_df:
25028         gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
25029         break;
25030     case OPC_FTINT_S_df:
25031         gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
25032         break;
25033     case OPC_FTINT_U_df:
25034         gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
25035         break;
25036     case OPC_FFINT_S_df:
25037         gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
25038         break;
25039     case OPC_FFINT_U_df:
25040         gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
25041         break;
25042     }
25043
25044     tcg_temp_free_i32(twd);
25045     tcg_temp_free_i32(tws);
25046     tcg_temp_free_i32(twt);
25047     tcg_temp_free_i32(tdf);
25048 }
25049
25050 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
25051 {
25052 #define MASK_MSA_VEC(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
25053     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
25054     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
25055     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25056     TCGv_i32 twd = tcg_const_i32(wd);
25057     TCGv_i32 tws = tcg_const_i32(ws);
25058     TCGv_i32 twt = tcg_const_i32(wt);
25059
25060     switch (MASK_MSA_VEC(ctx->opcode)) {
25061     case OPC_AND_V:
25062         gen_helper_msa_and_v(cpu_env, twd, tws, twt);
25063         break;
25064     case OPC_OR_V:
25065         gen_helper_msa_or_v(cpu_env, twd, tws, twt);
25066         break;
25067     case OPC_NOR_V:
25068         gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
25069         break;
25070     case OPC_XOR_V:
25071         gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
25072         break;
25073     case OPC_BMNZ_V:
25074         gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
25075         break;
25076     case OPC_BMZ_V:
25077         gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
25078         break;
25079     case OPC_BSEL_V:
25080         gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
25081         break;
25082     default:
25083         MIPS_INVAL("MSA instruction");
25084         generate_exception_end(ctx, EXCP_RI);
25085         break;
25086     }
25087
25088     tcg_temp_free_i32(twd);
25089     tcg_temp_free_i32(tws);
25090     tcg_temp_free_i32(twt);
25091 }
25092
25093 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
25094 {
25095     switch (MASK_MSA_VEC(ctx->opcode)) {
25096     case OPC_AND_V:
25097     case OPC_OR_V:
25098     case OPC_NOR_V:
25099     case OPC_XOR_V:
25100     case OPC_BMNZ_V:
25101     case OPC_BMZ_V:
25102     case OPC_BSEL_V:
25103         gen_msa_vec_v(env, ctx);
25104         break;
25105     case OPC_MSA_2R:
25106         gen_msa_2r(env, ctx);
25107         break;
25108     case OPC_MSA_2RF:
25109         gen_msa_2rf(env, ctx);
25110         break;
25111     default:
25112         MIPS_INVAL("MSA instruction");
25113         generate_exception_end(ctx, EXCP_RI);
25114         break;
25115     }
25116 }
25117
25118 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
25119 {
25120     uint32_t opcode = ctx->opcode;
25121     check_insn(ctx, ASE_MSA);
25122     check_msa_access(ctx);
25123
25124     switch (MASK_MSA_MINOR(opcode)) {
25125     case OPC_MSA_I8_00:
25126     case OPC_MSA_I8_01:
25127     case OPC_MSA_I8_02:
25128         gen_msa_i8(env, ctx);
25129         break;
25130     case OPC_MSA_I5_06:
25131     case OPC_MSA_I5_07:
25132         gen_msa_i5(env, ctx);
25133         break;
25134     case OPC_MSA_BIT_09:
25135     case OPC_MSA_BIT_0A:
25136         gen_msa_bit(env, ctx);
25137         break;
25138     case OPC_MSA_3R_0D:
25139     case OPC_MSA_3R_0E:
25140     case OPC_MSA_3R_0F:
25141     case OPC_MSA_3R_10:
25142     case OPC_MSA_3R_11:
25143     case OPC_MSA_3R_12:
25144     case OPC_MSA_3R_13:
25145     case OPC_MSA_3R_14:
25146     case OPC_MSA_3R_15:
25147         gen_msa_3r(env, ctx);
25148         break;
25149     case OPC_MSA_ELM:
25150         gen_msa_elm(env, ctx);
25151         break;
25152     case OPC_MSA_3RF_1A:
25153     case OPC_MSA_3RF_1B:
25154     case OPC_MSA_3RF_1C:
25155         gen_msa_3rf(env, ctx);
25156         break;
25157     case OPC_MSA_VEC:
25158         gen_msa_vec(env, ctx);
25159         break;
25160     case OPC_LD_B:
25161     case OPC_LD_H:
25162     case OPC_LD_W:
25163     case OPC_LD_D:
25164     case OPC_ST_B:
25165     case OPC_ST_H:
25166     case OPC_ST_W:
25167     case OPC_ST_D:
25168         {
25169             int32_t s10 = sextract32(ctx->opcode, 16, 10);
25170             uint8_t rs = (ctx->opcode >> 11) & 0x1f;
25171             uint8_t wd = (ctx->opcode >> 6) & 0x1f;
25172             uint8_t df = (ctx->opcode >> 0) & 0x3;
25173
25174             TCGv_i32 twd = tcg_const_i32(wd);
25175             TCGv taddr = tcg_temp_new();
25176             gen_base_offset_addr(ctx, taddr, rs, s10 << df);
25177
25178             switch (MASK_MSA_MINOR(opcode)) {
25179             case OPC_LD_B:
25180                 gen_helper_msa_ld_b(cpu_env, twd, taddr);
25181                 break;
25182             case OPC_LD_H:
25183                 gen_helper_msa_ld_h(cpu_env, twd, taddr);
25184                 break;
25185             case OPC_LD_W:
25186                 gen_helper_msa_ld_w(cpu_env, twd, taddr);
25187                 break;
25188             case OPC_LD_D:
25189                 gen_helper_msa_ld_d(cpu_env, twd, taddr);
25190                 break;
25191             case OPC_ST_B:
25192                 gen_helper_msa_st_b(cpu_env, twd, taddr);
25193                 break;
25194             case OPC_ST_H:
25195                 gen_helper_msa_st_h(cpu_env, twd, taddr);
25196                 break;
25197             case OPC_ST_W:
25198                 gen_helper_msa_st_w(cpu_env, twd, taddr);
25199                 break;
25200             case OPC_ST_D:
25201                 gen_helper_msa_st_d(cpu_env, twd, taddr);
25202                 break;
25203             }
25204
25205             tcg_temp_free_i32(twd);
25206             tcg_temp_free(taddr);
25207         }
25208         break;
25209     default:
25210         MIPS_INVAL("MSA instruction");
25211         generate_exception_end(ctx, EXCP_RI);
25212         break;
25213     }
25214
25215 }
25216
25217 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
25218 {
25219     int32_t offset;
25220     int rs, rt, rd, sa;
25221     uint32_t op, op1;
25222     int16_t imm;
25223
25224     /* make sure instructions are on a word boundary */
25225     if (ctx->base.pc_next & 0x3) {
25226         env->CP0_BadVAddr = ctx->base.pc_next;
25227         generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
25228         return;
25229     }
25230
25231     /* Handle blikely not taken case */
25232     if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
25233         TCGLabel *l1 = gen_new_label();
25234
25235         tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
25236         tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
25237         gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
25238         gen_set_label(l1);
25239     }
25240
25241     op = MASK_OP_MAJOR(ctx->opcode);
25242     rs = (ctx->opcode >> 21) & 0x1f;
25243     rt = (ctx->opcode >> 16) & 0x1f;
25244     rd = (ctx->opcode >> 11) & 0x1f;
25245     sa = (ctx->opcode >> 6) & 0x1f;
25246     imm = (int16_t)ctx->opcode;
25247     switch (op) {
25248     case OPC_SPECIAL:
25249         decode_opc_special(env, ctx);
25250         break;
25251     case OPC_SPECIAL2:
25252         decode_opc_special2_legacy(env, ctx);
25253         break;
25254     case OPC_SPECIAL3:
25255         decode_opc_special3(env, ctx);
25256         break;
25257     case OPC_REGIMM:
25258         op1 = MASK_REGIMM(ctx->opcode);
25259         switch (op1) {
25260         case OPC_BLTZL: /* REGIMM branches */
25261         case OPC_BGEZL:
25262         case OPC_BLTZALL:
25263         case OPC_BGEZALL:
25264             check_insn(ctx, ISA_MIPS2);
25265             check_insn_opc_removed(ctx, ISA_MIPS32R6);
25266             /* Fallthrough */
25267         case OPC_BLTZ:
25268         case OPC_BGEZ:
25269             gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
25270             break;
25271         case OPC_BLTZAL:
25272         case OPC_BGEZAL:
25273             if (ctx->insn_flags & ISA_MIPS32R6) {
25274                 if (rs == 0) {
25275                     /* OPC_NAL, OPC_BAL */
25276                     gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
25277                 } else {
25278                     generate_exception_end(ctx, EXCP_RI);
25279                 }
25280             } else {
25281                 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
25282             }
25283             break;
25284         case OPC_TGEI: /* REGIMM traps */
25285         case OPC_TGEIU:
25286         case OPC_TLTI:
25287         case OPC_TLTIU:
25288         case OPC_TEQI:
25289
25290         case OPC_TNEI:
25291             check_insn(ctx, ISA_MIPS2);
25292             check_insn_opc_removed(ctx, ISA_MIPS32R6);
25293             gen_trap(ctx, op1, rs, -1, imm);
25294             break;
25295         case OPC_SIGRIE:
25296             check_insn(ctx, ISA_MIPS32R6);
25297             generate_exception_end(ctx, EXCP_RI);
25298             break;
25299         case OPC_SYNCI:
25300             check_insn(ctx, ISA_MIPS32R2);
25301             /* Break the TB to be able to sync copied instructions
25302                immediately */
25303             ctx->base.is_jmp = DISAS_STOP;
25304             break;
25305         case OPC_BPOSGE32:    /* MIPS DSP branch */
25306 #if defined(TARGET_MIPS64)
25307         case OPC_BPOSGE64:
25308 #endif
25309             check_dsp(ctx);
25310             gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
25311             break;
25312 #if defined(TARGET_MIPS64)
25313         case OPC_DAHI:
25314             check_insn(ctx, ISA_MIPS32R6);
25315             check_mips_64(ctx);
25316             if (rs != 0) {
25317                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
25318             }
25319             break;
25320         case OPC_DATI:
25321             check_insn(ctx, ISA_MIPS32R6);
25322             check_mips_64(ctx);
25323             if (rs != 0) {
25324                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
25325             }
25326             break;
25327 #endif
25328         default:            /* Invalid */
25329             MIPS_INVAL("regimm");
25330             generate_exception_end(ctx, EXCP_RI);
25331             break;
25332         }
25333         break;
25334     case OPC_CP0:
25335         check_cp0_enabled(ctx);
25336         op1 = MASK_CP0(ctx->opcode);
25337         switch (op1) {
25338         case OPC_MFC0:
25339         case OPC_MTC0:
25340         case OPC_MFTR:
25341         case OPC_MTTR:
25342         case OPC_MFHC0:
25343         case OPC_MTHC0:
25344 #if defined(TARGET_MIPS64)
25345         case OPC_DMFC0:
25346         case OPC_DMTC0:
25347 #endif
25348 #ifndef CONFIG_USER_ONLY
25349             gen_cp0(env, ctx, op1, rt, rd);
25350 #endif /* !CONFIG_USER_ONLY */
25351             break;
25352         case OPC_C0:
25353         case OPC_C0_1:
25354         case OPC_C0_2:
25355         case OPC_C0_3:
25356         case OPC_C0_4:
25357         case OPC_C0_5:
25358         case OPC_C0_6:
25359         case OPC_C0_7:
25360         case OPC_C0_8:
25361         case OPC_C0_9:
25362         case OPC_C0_A:
25363         case OPC_C0_B:
25364         case OPC_C0_C:
25365         case OPC_C0_D:
25366         case OPC_C0_E:
25367         case OPC_C0_F:
25368 #ifndef CONFIG_USER_ONLY
25369             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
25370 #endif /* !CONFIG_USER_ONLY */
25371             break;
25372         case OPC_MFMC0:
25373 #ifndef CONFIG_USER_ONLY
25374             {
25375                 uint32_t op2;
25376                 TCGv t0 = tcg_temp_new();
25377
25378                 op2 = MASK_MFMC0(ctx->opcode);
25379                 switch (op2) {
25380                 case OPC_DMT:
25381                     check_cp0_mt(ctx);
25382                     gen_helper_dmt(t0);
25383                     gen_store_gpr(t0, rt);
25384                     break;
25385                 case OPC_EMT:
25386                     check_cp0_mt(ctx);
25387                     gen_helper_emt(t0);
25388                     gen_store_gpr(t0, rt);
25389                     break;
25390                 case OPC_DVPE:
25391                     check_cp0_mt(ctx);
25392                     gen_helper_dvpe(t0, cpu_env);
25393                     gen_store_gpr(t0, rt);
25394                     break;
25395                 case OPC_EVPE:
25396                     check_cp0_mt(ctx);
25397                     gen_helper_evpe(t0, cpu_env);
25398                     gen_store_gpr(t0, rt);
25399                     break;
25400                 case OPC_DVP:
25401                     check_insn(ctx, ISA_MIPS32R6);
25402                     if (ctx->vp) {
25403                         gen_helper_dvp(t0, cpu_env);
25404                         gen_store_gpr(t0, rt);
25405                     }
25406                     break;
25407                 case OPC_EVP:
25408                     check_insn(ctx, ISA_MIPS32R6);
25409                     if (ctx->vp) {
25410                         gen_helper_evp(t0, cpu_env);
25411                         gen_store_gpr(t0, rt);
25412                     }
25413                     break;
25414                 case OPC_DI:
25415                     check_insn(ctx, ISA_MIPS32R2);
25416                     save_cpu_state(ctx, 1);
25417                     gen_helper_di(t0, cpu_env);
25418                     gen_store_gpr(t0, rt);
25419                     /* Stop translation as we may have switched
25420                        the execution mode.  */
25421                     ctx->base.is_jmp = DISAS_STOP;
25422                     break;
25423                 case OPC_EI:
25424                     check_insn(ctx, ISA_MIPS32R2);
25425                     save_cpu_state(ctx, 1);
25426                     gen_helper_ei(t0, cpu_env);
25427                     gen_store_gpr(t0, rt);
25428                     /* DISAS_STOP isn't sufficient, we need to ensure we break
25429                        out of translated code to check for pending interrupts */
25430                     gen_save_pc(ctx->base.pc_next + 4);
25431                     ctx->base.is_jmp = DISAS_EXIT;
25432                     break;
25433                 default:            /* Invalid */
25434                     MIPS_INVAL("mfmc0");
25435                     generate_exception_end(ctx, EXCP_RI);
25436                     break;
25437                 }
25438                 tcg_temp_free(t0);
25439             }
25440 #endif /* !CONFIG_USER_ONLY */
25441             break;
25442         case OPC_RDPGPR:
25443             check_insn(ctx, ISA_MIPS32R2);
25444             gen_load_srsgpr(rt, rd);
25445             break;
25446         case OPC_WRPGPR:
25447             check_insn(ctx, ISA_MIPS32R2);
25448             gen_store_srsgpr(rt, rd);
25449             break;
25450         default:
25451             MIPS_INVAL("cp0");
25452             generate_exception_end(ctx, EXCP_RI);
25453             break;
25454         }
25455         break;
25456     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
25457         if (ctx->insn_flags & ISA_MIPS32R6) {
25458             /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
25459             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25460         } else {
25461             /* OPC_ADDI */
25462             /* Arithmetic with immediate opcode */
25463             gen_arith_imm(ctx, op, rt, rs, imm);
25464         }
25465         break;
25466     case OPC_ADDIU:
25467          gen_arith_imm(ctx, op, rt, rs, imm);
25468          break;
25469     case OPC_SLTI: /* Set on less than with immediate opcode */
25470     case OPC_SLTIU:
25471          gen_slt_imm(ctx, op, rt, rs, imm);
25472          break;
25473     case OPC_ANDI: /* Arithmetic with immediate opcode */
25474     case OPC_LUI: /* OPC_AUI */
25475     case OPC_ORI:
25476     case OPC_XORI:
25477          gen_logic_imm(ctx, op, rt, rs, imm);
25478          break;
25479     case OPC_J: /* Jump */
25480     case OPC_JAL:
25481          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
25482          gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
25483          break;
25484     /* Branch */
25485     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
25486         if (ctx->insn_flags & ISA_MIPS32R6) {
25487             if (rt == 0) {
25488                 generate_exception_end(ctx, EXCP_RI);
25489                 break;
25490             }
25491             /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
25492             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25493         } else {
25494             /* OPC_BLEZL */
25495             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25496         }
25497         break;
25498     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
25499         if (ctx->insn_flags & ISA_MIPS32R6) {
25500             if (rt == 0) {
25501                 generate_exception_end(ctx, EXCP_RI);
25502                 break;
25503             }
25504             /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
25505             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25506         } else {
25507             /* OPC_BGTZL */
25508             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25509         }
25510         break;
25511     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
25512         if (rt == 0) {
25513             /* OPC_BLEZ */
25514             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25515         } else {
25516             check_insn(ctx, ISA_MIPS32R6);
25517             /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
25518             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25519         }
25520         break;
25521     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
25522         if (rt == 0) {
25523             /* OPC_BGTZ */
25524             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25525         } else {
25526             check_insn(ctx, ISA_MIPS32R6);
25527             /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
25528             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25529         }
25530         break;
25531     case OPC_BEQL:
25532     case OPC_BNEL:
25533         check_insn(ctx, ISA_MIPS2);
25534          check_insn_opc_removed(ctx, ISA_MIPS32R6);
25535         /* Fallthrough */
25536     case OPC_BEQ:
25537     case OPC_BNE:
25538          gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
25539          break;
25540     case OPC_LL: /* Load and stores */
25541         check_insn(ctx, ISA_MIPS2);
25542         /* Fallthrough */
25543     case OPC_LWL:
25544     case OPC_LWR:
25545         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25546          /* Fallthrough */
25547     case OPC_LB:
25548     case OPC_LH:
25549     case OPC_LW:
25550     case OPC_LWPC:
25551     case OPC_LBU:
25552     case OPC_LHU:
25553          gen_ld(ctx, op, rt, rs, imm);
25554          break;
25555     case OPC_SWL:
25556     case OPC_SWR:
25557         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25558         /* fall through */
25559     case OPC_SB:
25560     case OPC_SH:
25561     case OPC_SW:
25562          gen_st(ctx, op, rt, rs, imm);
25563          break;
25564     case OPC_SC:
25565         check_insn(ctx, ISA_MIPS2);
25566          check_insn_opc_removed(ctx, ISA_MIPS32R6);
25567          gen_st_cond(ctx, op, rt, rs, imm);
25568          break;
25569     case OPC_CACHE:
25570         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25571         check_cp0_enabled(ctx);
25572         check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
25573         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
25574             gen_cache_operation(ctx, rt, rs, imm);
25575         }
25576         /* Treat as NOP. */
25577         break;
25578     case OPC_PREF:
25579         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25580         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
25581         /* Treat as NOP. */
25582         break;
25583
25584     /* Floating point (COP1). */
25585     case OPC_LWC1:
25586     case OPC_LDC1:
25587     case OPC_SWC1:
25588     case OPC_SDC1:
25589         gen_cop1_ldst(ctx, op, rt, rs, imm);
25590         break;
25591
25592     case OPC_CP1:
25593         op1 = MASK_CP1(ctx->opcode);
25594
25595         switch (op1) {
25596         case OPC_MFHC1:
25597         case OPC_MTHC1:
25598             check_cp1_enabled(ctx);
25599             check_insn(ctx, ISA_MIPS32R2);
25600             /* fall through */
25601         case OPC_MFC1:
25602         case OPC_CFC1:
25603         case OPC_MTC1:
25604         case OPC_CTC1:
25605             check_cp1_enabled(ctx);
25606             gen_cp1(ctx, op1, rt, rd);
25607             break;
25608 #if defined(TARGET_MIPS64)
25609         case OPC_DMFC1:
25610         case OPC_DMTC1:
25611             check_cp1_enabled(ctx);
25612             check_insn(ctx, ISA_MIPS3);
25613             check_mips_64(ctx);
25614             gen_cp1(ctx, op1, rt, rd);
25615             break;
25616 #endif
25617         case OPC_BC1EQZ: /* OPC_BC1ANY2 */
25618             check_cp1_enabled(ctx);
25619             if (ctx->insn_flags & ISA_MIPS32R6) {
25620                 /* OPC_BC1EQZ */
25621                 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
25622                                        rt, imm << 2, 4);
25623             } else {
25624                 /* OPC_BC1ANY2 */
25625                 check_cop1x(ctx);
25626                 check_insn(ctx, ASE_MIPS3D);
25627                 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
25628                                     (rt >> 2) & 0x7, imm << 2);
25629             }
25630             break;
25631         case OPC_BC1NEZ:
25632             check_cp1_enabled(ctx);
25633             check_insn(ctx, ISA_MIPS32R6);
25634             gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
25635                                    rt, imm << 2, 4);
25636             break;
25637         case OPC_BC1ANY4:
25638             check_cp1_enabled(ctx);
25639             check_insn_opc_removed(ctx, ISA_MIPS32R6);
25640             check_cop1x(ctx);
25641             check_insn(ctx, ASE_MIPS3D);
25642             /* fall through */
25643         case OPC_BC1:
25644             check_cp1_enabled(ctx);
25645             check_insn_opc_removed(ctx, ISA_MIPS32R6);
25646             gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
25647                                 (rt >> 2) & 0x7, imm << 2);
25648             break;
25649         case OPC_PS_FMT:
25650             check_ps(ctx);
25651             /* fall through */
25652         case OPC_S_FMT:
25653         case OPC_D_FMT:
25654             check_cp1_enabled(ctx);
25655             gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
25656                        (imm >> 8) & 0x7);
25657             break;
25658         case OPC_W_FMT:
25659         case OPC_L_FMT:
25660         {
25661             int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
25662             check_cp1_enabled(ctx);
25663             if (ctx->insn_flags & ISA_MIPS32R6) {
25664                 switch (r6_op) {
25665                 case R6_OPC_CMP_AF_S:
25666                 case R6_OPC_CMP_UN_S:
25667                 case R6_OPC_CMP_EQ_S:
25668                 case R6_OPC_CMP_UEQ_S:
25669                 case R6_OPC_CMP_LT_S:
25670                 case R6_OPC_CMP_ULT_S:
25671                 case R6_OPC_CMP_LE_S:
25672                 case R6_OPC_CMP_ULE_S:
25673                 case R6_OPC_CMP_SAF_S:
25674                 case R6_OPC_CMP_SUN_S:
25675                 case R6_OPC_CMP_SEQ_S:
25676                 case R6_OPC_CMP_SEUQ_S:
25677                 case R6_OPC_CMP_SLT_S:
25678                 case R6_OPC_CMP_SULT_S:
25679                 case R6_OPC_CMP_SLE_S:
25680                 case R6_OPC_CMP_SULE_S:
25681                 case R6_OPC_CMP_OR_S:
25682                 case R6_OPC_CMP_UNE_S:
25683                 case R6_OPC_CMP_NE_S:
25684                 case R6_OPC_CMP_SOR_S:
25685                 case R6_OPC_CMP_SUNE_S:
25686                 case R6_OPC_CMP_SNE_S:
25687                     gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
25688                     break;
25689                 case R6_OPC_CMP_AF_D:
25690                 case R6_OPC_CMP_UN_D:
25691                 case R6_OPC_CMP_EQ_D:
25692                 case R6_OPC_CMP_UEQ_D:
25693                 case R6_OPC_CMP_LT_D:
25694                 case R6_OPC_CMP_ULT_D:
25695                 case R6_OPC_CMP_LE_D:
25696                 case R6_OPC_CMP_ULE_D:
25697                 case R6_OPC_CMP_SAF_D:
25698                 case R6_OPC_CMP_SUN_D:
25699                 case R6_OPC_CMP_SEQ_D:
25700                 case R6_OPC_CMP_SEUQ_D:
25701                 case R6_OPC_CMP_SLT_D:
25702                 case R6_OPC_CMP_SULT_D:
25703                 case R6_OPC_CMP_SLE_D:
25704                 case R6_OPC_CMP_SULE_D:
25705                 case R6_OPC_CMP_OR_D:
25706                 case R6_OPC_CMP_UNE_D:
25707                 case R6_OPC_CMP_NE_D:
25708                 case R6_OPC_CMP_SOR_D:
25709                 case R6_OPC_CMP_SUNE_D:
25710                 case R6_OPC_CMP_SNE_D:
25711                     gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
25712                     break;
25713                 default:
25714                     gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
25715                                rt, rd, sa, (imm >> 8) & 0x7);
25716
25717                     break;
25718                 }
25719             } else {
25720                 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
25721                            (imm >> 8) & 0x7);
25722             }
25723             break;
25724         }
25725         case OPC_BZ_V:
25726         case OPC_BNZ_V:
25727         case OPC_BZ_B:
25728         case OPC_BZ_H:
25729         case OPC_BZ_W:
25730         case OPC_BZ_D:
25731         case OPC_BNZ_B:
25732         case OPC_BNZ_H:
25733         case OPC_BNZ_W:
25734         case OPC_BNZ_D:
25735             check_insn(ctx, ASE_MSA);
25736             gen_msa_branch(env, ctx, op1);
25737             break;
25738         default:
25739             MIPS_INVAL("cp1");
25740             generate_exception_end(ctx, EXCP_RI);
25741             break;
25742         }
25743         break;
25744
25745     /* Compact branches [R6] and COP2 [non-R6] */
25746     case OPC_BC: /* OPC_LWC2 */
25747     case OPC_BALC: /* OPC_SWC2 */
25748         if (ctx->insn_flags & ISA_MIPS32R6) {
25749             /* OPC_BC, OPC_BALC */
25750             gen_compute_compact_branch(ctx, op, 0, 0,
25751                                        sextract32(ctx->opcode << 2, 0, 28));
25752         } else {
25753             /* OPC_LWC2, OPC_SWC2 */
25754             /* COP2: Not implemented. */
25755             generate_exception_err(ctx, EXCP_CpU, 2);
25756         }
25757         break;
25758     case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
25759     case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
25760         if (ctx->insn_flags & ISA_MIPS32R6) {
25761             if (rs != 0) {
25762                 /* OPC_BEQZC, OPC_BNEZC */
25763                 gen_compute_compact_branch(ctx, op, rs, 0,
25764                                            sextract32(ctx->opcode << 2, 0, 23));
25765             } else {
25766                 /* OPC_JIC, OPC_JIALC */
25767                 gen_compute_compact_branch(ctx, op, 0, rt, imm);
25768             }
25769         } else {
25770             /* OPC_LWC2, OPC_SWC2 */
25771             /* COP2: Not implemented. */
25772             generate_exception_err(ctx, EXCP_CpU, 2);
25773         }
25774         break;
25775     case OPC_CP2:
25776         check_insn(ctx, INSN_LOONGSON2F);
25777         /* Note that these instructions use different fields.  */
25778         gen_loongson_multimedia(ctx, sa, rd, rt);
25779         break;
25780
25781     case OPC_CP3:
25782         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25783         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
25784             check_cp1_enabled(ctx);
25785             op1 = MASK_CP3(ctx->opcode);
25786             switch (op1) {
25787             case OPC_LUXC1:
25788             case OPC_SUXC1:
25789                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
25790                 /* Fallthrough */
25791             case OPC_LWXC1:
25792             case OPC_LDXC1:
25793             case OPC_SWXC1:
25794             case OPC_SDXC1:
25795                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
25796                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
25797                 break;
25798             case OPC_PREFX:
25799                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
25800                 /* Treat as NOP. */
25801                 break;
25802             case OPC_ALNV_PS:
25803                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
25804                 /* Fallthrough */
25805             case OPC_MADD_S:
25806             case OPC_MADD_D:
25807             case OPC_MADD_PS:
25808             case OPC_MSUB_S:
25809             case OPC_MSUB_D:
25810             case OPC_MSUB_PS:
25811             case OPC_NMADD_S:
25812             case OPC_NMADD_D:
25813             case OPC_NMADD_PS:
25814             case OPC_NMSUB_S:
25815             case OPC_NMSUB_D:
25816             case OPC_NMSUB_PS:
25817                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
25818                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
25819                 break;
25820             default:
25821                 MIPS_INVAL("cp3");
25822                 generate_exception_end(ctx, EXCP_RI);
25823                 break;
25824             }
25825         } else {
25826             generate_exception_err(ctx, EXCP_CpU, 1);
25827         }
25828         break;
25829
25830 #if defined(TARGET_MIPS64)
25831     /* MIPS64 opcodes */
25832     case OPC_LDL:
25833     case OPC_LDR:
25834     case OPC_LLD:
25835         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25836         /* fall through */
25837     case OPC_LWU:
25838     case OPC_LD:
25839         check_insn(ctx, ISA_MIPS3);
25840         check_mips_64(ctx);
25841         gen_ld(ctx, op, rt, rs, imm);
25842         break;
25843     case OPC_SDL:
25844     case OPC_SDR:
25845         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25846         /* fall through */
25847     case OPC_SD:
25848         check_insn(ctx, ISA_MIPS3);
25849         check_mips_64(ctx);
25850         gen_st(ctx, op, rt, rs, imm);
25851         break;
25852     case OPC_SCD:
25853         check_insn_opc_removed(ctx, ISA_MIPS32R6);
25854         check_insn(ctx, ISA_MIPS3);
25855         check_mips_64(ctx);
25856         gen_st_cond(ctx, op, rt, rs, imm);
25857         break;
25858     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
25859         if (ctx->insn_flags & ISA_MIPS32R6) {
25860             /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
25861             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25862         } else {
25863             /* OPC_DADDI */
25864             check_insn(ctx, ISA_MIPS3);
25865             check_mips_64(ctx);
25866             gen_arith_imm(ctx, op, rt, rs, imm);
25867         }
25868         break;
25869     case OPC_DADDIU:
25870         check_insn(ctx, ISA_MIPS3);
25871         check_mips_64(ctx);
25872         gen_arith_imm(ctx, op, rt, rs, imm);
25873         break;
25874 #else
25875     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
25876         if (ctx->insn_flags & ISA_MIPS32R6) {
25877             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25878         } else {
25879             MIPS_INVAL("major opcode");
25880             generate_exception_end(ctx, EXCP_RI);
25881         }
25882         break;
25883 #endif
25884     case OPC_DAUI: /* OPC_JALX */
25885         if (ctx->insn_flags & ISA_MIPS32R6) {
25886 #if defined(TARGET_MIPS64)
25887             /* OPC_DAUI */
25888             check_mips_64(ctx);
25889             if (rs == 0) {
25890                 generate_exception(ctx, EXCP_RI);
25891             } else if (rt != 0) {
25892                 TCGv t0 = tcg_temp_new();
25893                 gen_load_gpr(t0, rs);
25894                 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
25895                 tcg_temp_free(t0);
25896             }
25897 #else
25898             generate_exception_end(ctx, EXCP_RI);
25899             MIPS_INVAL("major opcode");
25900 #endif
25901         } else {
25902             /* OPC_JALX */
25903             check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
25904             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
25905             gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
25906         }
25907         break;
25908     case OPC_MSA: /* OPC_MDMX */
25909         /* MDMX: Not implemented. */
25910         gen_msa(env, ctx);
25911         break;
25912     case OPC_PCREL:
25913         check_insn(ctx, ISA_MIPS32R6);
25914         gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
25915         break;
25916     default:            /* Invalid */
25917         MIPS_INVAL("major opcode");
25918         generate_exception_end(ctx, EXCP_RI);
25919         break;
25920     }
25921 }
25922
25923 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
25924 {
25925     DisasContext *ctx = container_of(dcbase, DisasContext, base);
25926     CPUMIPSState *env = cs->env_ptr;
25927
25928     ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
25929     ctx->saved_pc = -1;
25930     ctx->insn_flags = env->insn_flags;
25931     ctx->CP0_Config1 = env->CP0_Config1;
25932     ctx->CP0_Config2 = env->CP0_Config2;
25933     ctx->CP0_Config3 = env->CP0_Config3;
25934     ctx->CP0_Config5 = env->CP0_Config5;
25935     ctx->btarget = 0;
25936     ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
25937     ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
25938     ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
25939     ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
25940     ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
25941     ctx->PAMask = env->PAMask;
25942     ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
25943     ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
25944     ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
25945     ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
25946     ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
25947     /* Restore delay slot state from the tb context.  */
25948     ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
25949     ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
25950     ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
25951              (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
25952     ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
25953     ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
25954     ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
25955     ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
25956     restore_cpu_state(env, ctx);
25957 #ifdef CONFIG_USER_ONLY
25958         ctx->mem_idx = MIPS_HFLAG_UM;
25959 #else
25960         ctx->mem_idx = hflags_mmu_index(ctx->hflags);
25961 #endif
25962     ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
25963                                   MO_UNALN : MO_ALIGN;
25964
25965     LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
25966               ctx->hflags);
25967 }
25968
25969 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
25970 {
25971 }
25972
25973 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
25974 {
25975     DisasContext *ctx = container_of(dcbase, DisasContext, base);
25976
25977     tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
25978                        ctx->btarget);
25979 }
25980
25981 static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
25982                                      const CPUBreakpoint *bp)
25983 {
25984     DisasContext *ctx = container_of(dcbase, DisasContext, base);
25985
25986     save_cpu_state(ctx, 1);
25987     ctx->base.is_jmp = DISAS_NORETURN;
25988     gen_helper_raise_exception_debug(cpu_env);
25989     /* The address covered by the breakpoint must be included in
25990        [tb->pc, tb->pc + tb->size) in order to for it to be
25991        properly cleared -- thus we increment the PC here so that
25992        the logic setting tb->size below does the right thing.  */
25993     ctx->base.pc_next += 4;
25994     return true;
25995 }
25996
25997 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
25998 {
25999     CPUMIPSState *env = cs->env_ptr;
26000     DisasContext *ctx = container_of(dcbase, DisasContext, base);
26001     int insn_bytes;
26002     int is_slot;
26003
26004     is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
26005     if (ctx->insn_flags & ISA_NANOMIPS32) {
26006         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
26007         insn_bytes = decode_nanomips_opc(env, ctx);
26008     } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
26009         ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
26010         insn_bytes = 4;
26011         decode_opc(env, ctx);
26012     } else if (ctx->insn_flags & ASE_MICROMIPS) {
26013         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
26014         insn_bytes = decode_micromips_opc(env, ctx);
26015     } else if (ctx->insn_flags & ASE_MIPS16) {
26016         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
26017         insn_bytes = decode_mips16_opc(env, ctx);
26018     } else {
26019         generate_exception_end(ctx, EXCP_RI);
26020         g_assert(ctx->base.is_jmp == DISAS_NORETURN);
26021         return;
26022     }
26023
26024     if (ctx->hflags & MIPS_HFLAG_BMASK) {
26025         if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
26026                              MIPS_HFLAG_FBNSLOT))) {
26027             /* force to generate branch as there is neither delay nor
26028                forbidden slot */
26029             is_slot = 1;
26030         }
26031         if ((ctx->hflags & MIPS_HFLAG_M16) &&
26032             (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
26033             /* Force to generate branch as microMIPS R6 doesn't restrict
26034                branches in the forbidden slot. */
26035             is_slot = 1;
26036         }
26037     }
26038     if (is_slot) {
26039         gen_branch(ctx, insn_bytes);
26040     }
26041     ctx->base.pc_next += insn_bytes;
26042
26043     if (ctx->base.is_jmp != DISAS_NEXT) {
26044         return;
26045     }
26046     /* Execute a branch and its delay slot as a single instruction.
26047        This is what GDB expects and is consistent with what the
26048        hardware does (e.g. if a delay slot instruction faults, the
26049        reported PC is the PC of the branch).  */
26050     if (ctx->base.singlestep_enabled &&
26051         (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
26052         ctx->base.is_jmp = DISAS_TOO_MANY;
26053     }
26054     if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
26055         ctx->base.is_jmp = DISAS_TOO_MANY;
26056     }
26057 }
26058
26059 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
26060 {
26061     DisasContext *ctx = container_of(dcbase, DisasContext, base);
26062
26063     if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
26064         save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
26065         gen_helper_raise_exception_debug(cpu_env);
26066     } else {
26067         switch (ctx->base.is_jmp) {
26068         case DISAS_STOP:
26069             gen_save_pc(ctx->base.pc_next);
26070             tcg_gen_lookup_and_goto_ptr();
26071             break;
26072         case DISAS_NEXT:
26073         case DISAS_TOO_MANY:
26074             save_cpu_state(ctx, 0);
26075             gen_goto_tb(ctx, 0, ctx->base.pc_next);
26076             break;
26077         case DISAS_EXIT:
26078             tcg_gen_exit_tb(NULL, 0);
26079             break;
26080         case DISAS_NORETURN:
26081             break;
26082         default:
26083             g_assert_not_reached();
26084         }
26085     }
26086 }
26087
26088 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
26089 {
26090     qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
26091     log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
26092 }
26093
26094 static const TranslatorOps mips_tr_ops = {
26095     .init_disas_context = mips_tr_init_disas_context,
26096     .tb_start           = mips_tr_tb_start,
26097     .insn_start         = mips_tr_insn_start,
26098     .breakpoint_check   = mips_tr_breakpoint_check,
26099     .translate_insn     = mips_tr_translate_insn,
26100     .tb_stop            = mips_tr_tb_stop,
26101     .disas_log          = mips_tr_disas_log,
26102 };
26103
26104 void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
26105 {
26106     DisasContext ctx;
26107
26108     translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
26109 }
26110
26111 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
26112                            int flags)
26113 {
26114     int i;
26115     int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
26116
26117 #define printfpr(fp)                                                    \
26118     do {                                                                \
26119         if (is_fpu64)                                                   \
26120             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
26121                         " fd:%13g fs:%13g psu: %13g\n",                 \
26122                         (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
26123                         (double)(fp)->fd,                               \
26124                         (double)(fp)->fs[FP_ENDIAN_IDX],                \
26125                         (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
26126         else {                                                          \
26127             fpr_t tmp;                                                  \
26128             tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
26129             tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
26130             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
26131                         " fd:%13g fs:%13g psu:%13g\n",                  \
26132                         tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
26133                         (double)tmp.fd,                                 \
26134                         (double)tmp.fs[FP_ENDIAN_IDX],                  \
26135                         (double)tmp.fs[!FP_ENDIAN_IDX]);                \
26136         }                                                               \
26137     } while(0)
26138
26139
26140     fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
26141                 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
26142                 get_float_exception_flags(&env->active_fpu.fp_status));
26143     for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
26144         fpu_fprintf(f, "%3s: ", fregnames[i]);
26145         printfpr(&env->active_fpu.fpr[i]);
26146     }
26147
26148 #undef printfpr
26149 }
26150
26151 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
26152                          int flags)
26153 {
26154     MIPSCPU *cpu = MIPS_CPU(cs);
26155     CPUMIPSState *env = &cpu->env;
26156     int i;
26157
26158     cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
26159                 " LO=0x" TARGET_FMT_lx " ds %04x "
26160                 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
26161                 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
26162                 env->hflags, env->btarget, env->bcond);
26163     for (i = 0; i < 32; i++) {
26164         if ((i & 3) == 0)
26165             cpu_fprintf(f, "GPR%02d:", i);
26166         cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
26167         if ((i & 3) == 3)
26168             cpu_fprintf(f, "\n");
26169     }
26170
26171     cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
26172                 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
26173     cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
26174                 PRIx64 "\n",
26175                 env->CP0_Config0, env->CP0_Config1, env->lladdr);
26176     cpu_fprintf(f, "    Config2 0x%08x Config3 0x%08x\n",
26177                 env->CP0_Config2, env->CP0_Config3);
26178     cpu_fprintf(f, "    Config4 0x%08x Config5 0x%08x\n",
26179                 env->CP0_Config4, env->CP0_Config5);
26180     if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
26181         fpu_dump_state(env, f, cpu_fprintf, flags);
26182     }
26183 }
26184
26185 void mips_tcg_init(void)
26186 {
26187     int i;
26188
26189     cpu_gpr[0] = NULL;
26190     for (i = 1; i < 32; i++)
26191         cpu_gpr[i] = tcg_global_mem_new(cpu_env,
26192                                         offsetof(CPUMIPSState, active_tc.gpr[i]),
26193                                         regnames[i]);
26194
26195     for (i = 0; i < 32; i++) {
26196         int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
26197         msa_wr_d[i * 2] =
26198                 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
26199         /* The scalar floating-point unit (FPU) registers are mapped on
26200          * the MSA vector registers. */
26201         fpu_f64[i] = msa_wr_d[i * 2];
26202         off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
26203         msa_wr_d[i * 2 + 1] =
26204                 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
26205     }
26206
26207     cpu_PC = tcg_global_mem_new(cpu_env,
26208                                 offsetof(CPUMIPSState, active_tc.PC), "PC");
26209     for (i = 0; i < MIPS_DSP_ACC; i++) {
26210         cpu_HI[i] = tcg_global_mem_new(cpu_env,
26211                                        offsetof(CPUMIPSState, active_tc.HI[i]),
26212                                        regnames_HI[i]);
26213         cpu_LO[i] = tcg_global_mem_new(cpu_env,
26214                                        offsetof(CPUMIPSState, active_tc.LO[i]),
26215                                        regnames_LO[i]);
26216     }
26217     cpu_dspctrl = tcg_global_mem_new(cpu_env,
26218                                      offsetof(CPUMIPSState, active_tc.DSPControl),
26219                                      "DSPControl");
26220     bcond = tcg_global_mem_new(cpu_env,
26221                                offsetof(CPUMIPSState, bcond), "bcond");
26222     btarget = tcg_global_mem_new(cpu_env,
26223                                  offsetof(CPUMIPSState, btarget), "btarget");
26224     hflags = tcg_global_mem_new_i32(cpu_env,
26225                                     offsetof(CPUMIPSState, hflags), "hflags");
26226
26227     fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
26228                                       offsetof(CPUMIPSState, active_fpu.fcr0),
26229                                       "fcr0");
26230     fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
26231                                        offsetof(CPUMIPSState, active_fpu.fcr31),
26232                                        "fcr31");
26233 }
26234
26235 #include "translate_init.inc.c"
26236
26237 void cpu_mips_realize_env(CPUMIPSState *env)
26238 {
26239     env->exception_base = (int32_t)0xBFC00000;
26240
26241 #ifndef CONFIG_USER_ONLY
26242     mmu_init(env, env->cpu_model);
26243 #endif
26244     fpu_init(env, env->cpu_model);
26245     mvp_init(env, env->cpu_model);
26246 }
26247
26248 bool cpu_supports_cps_smp(const char *cpu_type)
26249 {
26250     const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
26251     return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
26252 }
26253
26254 bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
26255 {
26256     const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
26257     return (mcc->cpu_def->insn_flags & isa) != 0;
26258 }
26259
26260 void cpu_set_exception_base(int vp_index, target_ulong address)
26261 {
26262     MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
26263     vp->env.exception_base = address;
26264 }
26265
26266 void cpu_state_reset(CPUMIPSState *env)
26267 {
26268     MIPSCPU *cpu = mips_env_get_cpu(env);
26269     CPUState *cs = CPU(cpu);
26270
26271     /* Reset registers to their default values */
26272     env->CP0_PRid = env->cpu_model->CP0_PRid;
26273     env->CP0_Config0 = env->cpu_model->CP0_Config0;
26274 #ifdef TARGET_WORDS_BIGENDIAN
26275     env->CP0_Config0 |= (1 << CP0C0_BE);
26276 #endif
26277     env->CP0_Config1 = env->cpu_model->CP0_Config1;
26278     env->CP0_Config2 = env->cpu_model->CP0_Config2;
26279     env->CP0_Config3 = env->cpu_model->CP0_Config3;
26280     env->CP0_Config4 = env->cpu_model->CP0_Config4;
26281     env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
26282     env->CP0_Config5 = env->cpu_model->CP0_Config5;
26283     env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
26284     env->CP0_Config6 = env->cpu_model->CP0_Config6;
26285     env->CP0_Config7 = env->cpu_model->CP0_Config7;
26286     env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
26287                                  << env->cpu_model->CP0_LLAddr_shift;
26288     env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
26289     env->SYNCI_Step = env->cpu_model->SYNCI_Step;
26290     env->CCRes = env->cpu_model->CCRes;
26291     env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
26292     env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
26293     env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
26294     env->current_tc = 0;
26295     env->SEGBITS = env->cpu_model->SEGBITS;
26296     env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
26297 #if defined(TARGET_MIPS64)
26298     if (env->cpu_model->insn_flags & ISA_MIPS3) {
26299         env->SEGMask |= 3ULL << 62;
26300     }
26301 #endif
26302     env->PABITS = env->cpu_model->PABITS;
26303     env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
26304     env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
26305     env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
26306     env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
26307     env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
26308     env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
26309     env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
26310     env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
26311     env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
26312     env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
26313     env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
26314     env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
26315     env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
26316     env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
26317     env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
26318     env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
26319     env->msair = env->cpu_model->MSAIR;
26320     env->insn_flags = env->cpu_model->insn_flags;
26321
26322 #if defined(CONFIG_USER_ONLY)
26323     env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
26324 # ifdef TARGET_MIPS64
26325     /* Enable 64-bit register mode.  */
26326     env->CP0_Status |= (1 << CP0St_PX);
26327 # endif
26328 # ifdef TARGET_ABI_MIPSN64
26329     /* Enable 64-bit address mode.  */
26330     env->CP0_Status |= (1 << CP0St_UX);
26331 # endif
26332     /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
26333        hardware registers.  */
26334     env->CP0_HWREna |= 0x0000000F;
26335     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
26336         env->CP0_Status |= (1 << CP0St_CU1);
26337     }
26338     if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
26339         env->CP0_Status |= (1 << CP0St_MX);
26340     }
26341 # if defined(TARGET_MIPS64)
26342     /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
26343     if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
26344         (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
26345         env->CP0_Status |= (1 << CP0St_FR);
26346     }
26347 # endif
26348 #else
26349     if (env->hflags & MIPS_HFLAG_BMASK) {
26350         /* If the exception was raised from a delay slot,
26351            come back to the jump.  */
26352         env->CP0_ErrorEPC = (env->active_tc.PC
26353                              - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
26354     } else {
26355         env->CP0_ErrorEPC = env->active_tc.PC;
26356     }
26357     env->active_tc.PC = env->exception_base;
26358     env->CP0_Random = env->tlb->nb_tlb - 1;
26359     env->tlb->tlb_in_use = env->tlb->nb_tlb;
26360     env->CP0_Wired = 0;
26361     env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
26362     env->CP0_EBase = (cs->cpu_index & 0x3FF);
26363     if (mips_um_ksegs_enabled()) {
26364         env->CP0_EBase |= 0x40000000;
26365     } else {
26366         env->CP0_EBase |= (int32_t)0x80000000;
26367     }
26368     if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
26369         env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
26370     }
26371     env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
26372                                  0x3ff : 0xff;
26373     env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
26374     /* vectored interrupts not implemented, timer on int 7,
26375        no performance counters. */
26376     env->CP0_IntCtl = 0xe0000000;
26377     {
26378         int i;
26379
26380         for (i = 0; i < 7; i++) {
26381             env->CP0_WatchLo[i] = 0;
26382             env->CP0_WatchHi[i] = 0x80000000;
26383         }
26384         env->CP0_WatchLo[7] = 0;
26385         env->CP0_WatchHi[7] = 0;
26386     }
26387     /* Count register increments in debug mode, EJTAG version 1 */
26388     env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
26389
26390     cpu_mips_store_count(env, 1);
26391
26392     if (env->CP0_Config3 & (1 << CP0C3_MT)) {
26393         int i;
26394
26395         /* Only TC0 on VPE 0 starts as active.  */
26396         for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
26397             env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
26398             env->tcs[i].CP0_TCHalt = 1;
26399         }
26400         env->active_tc.CP0_TCHalt = 1;
26401         cs->halted = 1;
26402
26403         if (cs->cpu_index == 0) {
26404             /* VPE0 starts up enabled.  */
26405             env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
26406             env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
26407
26408             /* TC0 starts up unhalted.  */
26409             cs->halted = 0;
26410             env->active_tc.CP0_TCHalt = 0;
26411             env->tcs[0].CP0_TCHalt = 0;
26412             /* With thread 0 active.  */
26413             env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
26414             env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
26415         }
26416     }
26417
26418     /*
26419      * Configure default legacy segmentation control. We use this regardless of
26420      * whether segmentation control is presented to the guest.
26421      */
26422     /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
26423     env->CP0_SegCtl0 =   (CP0SC_AM_MK << CP0SC_AM);
26424     /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
26425     env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
26426     /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
26427     env->CP0_SegCtl1 =   (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
26428                          (2 << CP0SC_C);
26429     /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
26430     env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
26431                          (3 << CP0SC_C)) << 16;
26432     /* USeg (seg4 0x40000000..0x7FFFFFFF) */
26433     env->CP0_SegCtl2 =   (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
26434                          (1 << CP0SC_EU) | (2 << CP0SC_C);
26435     /* USeg (seg5 0x00000000..0x3FFFFFFF) */
26436     env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
26437                          (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
26438     /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
26439     env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
26440 #endif
26441     if ((env->insn_flags & ISA_MIPS32R6) &&
26442         (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
26443         /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
26444         env->CP0_Status |= (1 << CP0St_FR);
26445     }
26446
26447     if (env->insn_flags & ISA_MIPS32R6) {
26448         /* PTW  =  1 */
26449         env->CP0_PWSize = 0x40;
26450         /* GDI  = 12 */
26451         /* UDI  = 12 */
26452         /* MDI  = 12 */
26453         /* PRI  = 12 */
26454         /* PTEI =  2 */
26455         env->CP0_PWField = 0x0C30C302;
26456     } else {
26457         /* GDI  =  0 */
26458         /* UDI  =  0 */
26459         /* MDI  =  0 */
26460         /* PRI  =  0 */
26461         /* PTEI =  2 */
26462         env->CP0_PWField = 0x02;
26463     }
26464
26465     if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
26466         /*  microMIPS on reset when Config3.ISA is 3 */
26467         env->hflags |= MIPS_HFLAG_M16;
26468     }
26469
26470     /* MSA */
26471     if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
26472         msa_reset(env);
26473     }
26474
26475     compute_hflags(env);
26476     restore_fp_status(env);
26477     restore_pamask(env);
26478     cs->exception_index = EXCP_NONE;
26479
26480     if (semihosting_get_argc()) {
26481         /* UHI interface can be used to obtain argc and argv */
26482         env->active_tc.gpr[4] = -1;
26483     }
26484 }
26485
26486 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
26487                           target_ulong *data)
26488 {
26489     env->active_tc.PC = data[0];
26490     env->hflags &= ~MIPS_HFLAG_BMASK;
26491     env->hflags |= data[1];
26492     switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
26493     case MIPS_HFLAG_BR:
26494         break;
26495     case MIPS_HFLAG_BC:
26496     case MIPS_HFLAG_BL:
26497     case MIPS_HFLAG_B:
26498         env->btarget = data[2];
26499         break;
26500     }
26501 }
This page took 1.458871 seconds and 4 git commands to generate.