]> Git Repo - qemu.git/blob - target/mips/translate.c
Merge remote-tracking branch 'remotes/cminyard/tags/i2c-for-release-20190228' into...
[qemu.git] / target / mips / translate.c
1 /*
2  *  MIPS 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 (010.00 to 010.11) */
467     OPC_ALIGN_1   = (0x09 << 6) | OPC_BSHFL,
468     OPC_ALIGN_2   = (0x0A << 6) | OPC_BSHFL,
469     OPC_ALIGN_3   = (0x0B << 6) | OPC_BSHFL,
470     OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
471 };
472
473 /* DBSHFL opcodes */
474 #define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
475
476 enum {
477     OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
478     OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
479     OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
480     OPC_DALIGN_1   = (0x09 << 6) | OPC_DBSHFL,
481     OPC_DALIGN_2   = (0x0A << 6) | OPC_DBSHFL,
482     OPC_DALIGN_3   = (0x0B << 6) | OPC_DBSHFL,
483     OPC_DALIGN_4   = (0x0C << 6) | OPC_DBSHFL,
484     OPC_DALIGN_5   = (0x0D << 6) | OPC_DBSHFL,
485     OPC_DALIGN_6   = (0x0E << 6) | OPC_DBSHFL,
486     OPC_DALIGN_7   = (0x0F << 6) | OPC_DBSHFL,
487     OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
488 };
489
490 /* MIPS DSP REGIMM opcodes */
491 enum {
492     OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
493     OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
494 };
495
496 #define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
497 /* MIPS DSP Load */
498 enum {
499     OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
500     OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
501     OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
502     OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
503 };
504
505 #define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
506 enum {
507     /* MIPS DSP Arithmetic Sub-class */
508     OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
509     OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
510     OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
511     OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
512     OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
513     OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
514     OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
515     OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
516     OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
517     OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
518     OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
519     OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
520     OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
521     OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
522     OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
523     OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
524     OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
525     OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
526     /* MIPS DSP Multiply Sub-class insns */
527     OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
528     OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
529     OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
530     OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
531     OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
532     OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
533 };
534
535 #define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
536 #define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
537 enum {
538     /* MIPS DSP Arithmetic Sub-class */
539     OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
540     OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
541     OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
542     OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
543     OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
544     OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
545     OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
546     OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
547     OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
548     OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
549     OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
550     OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
551     /* MIPS DSP Multiply Sub-class insns */
552     OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
553     OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
554     OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
555     OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
556 };
557
558 #define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
559 enum {
560     /* MIPS DSP Arithmetic Sub-class */
561     OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
562     OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
563     OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
564     OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
565     OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
566     OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
567     OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
568     OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
569     OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
570     OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
571     OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
572     OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
573     OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
574     /* DSP Bit/Manipulation Sub-class */
575     OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
576     OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
577     OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
578     OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
579     OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
580 };
581
582 #define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
583 enum {
584     /* MIPS DSP Arithmetic Sub-class */
585     OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
586     OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
587     OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
588     OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
589     OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
590     OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
591     OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
592     /* DSP Compare-Pick Sub-class */
593     OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
594     OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
595     OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
596     OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
597     OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
598     OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
599     OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
600     OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
601     OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
602     OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
603     OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
604     OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
605     OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
606     OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
607     OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
608 };
609
610 #define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
611 enum {
612     /* MIPS DSP GPR-Based Shift Sub-class */
613     OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
614     OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
615     OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
616     OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
617     OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
618     OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
619     OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
620     OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
621     OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
622     OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
623     OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
624     OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
625     OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
626     OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
627     OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
628     OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
629     OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
630     OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
631     OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
632     OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
633     OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
634     OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
635 };
636
637 #define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
638 enum {
639     /* MIPS DSP Multiply Sub-class insns */
640     OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
641     OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
642     OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
643     OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
644     OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
645     OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
646     OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
647     OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
648     OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
649     OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
650     OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
651     OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
652     OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
653     OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
654     OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
655     OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
656     OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
657     OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
658     OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
659     OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
660     OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
661     OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
662 };
663
664 #define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
665 enum {
666     /* DSP Bit/Manipulation Sub-class */
667     OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
668 };
669
670 #define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
671 enum {
672     /* MIPS DSP Append Sub-class */
673     OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
674     OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
675     OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
676 };
677
678 #define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
679 enum {
680     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
681     OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
682     OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
683     OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
684     OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
685     OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
686     OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
687     OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
688     OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
689     OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
690     OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
691     OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
692     OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
693     OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
694     OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
695     OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
696     OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
697     OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
698 };
699
700 #define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
701 enum {
702     /* MIPS DSP Arithmetic Sub-class */
703     OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
704     OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
705     OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
706     OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
707     OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
708     OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
709     OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
710     OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
711     OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
712     OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
713     OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
714     OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
715     OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
716     OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
717     OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
718     OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
719     OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
720     /* DSP Bit/Manipulation Sub-class */
721     OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
722     OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
723     OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
724     OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
725     OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
726     OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
727 };
728
729 #define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
730 enum {
731     /* MIPS DSP Multiply Sub-class insns */
732     OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
733     OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
734     OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
735     OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
736     OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
737     /* MIPS DSP Arithmetic Sub-class */
738     OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
739     OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
740     OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
741     OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
742     OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
743     OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
744     OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
745     OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
746     OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
747     OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
748     OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
749     OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
750     OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
751     OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
752     OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
753     OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
754     OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
755     OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
756     OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
757     OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
758     OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
759 };
760
761 #define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
762 enum {
763     /* DSP Compare-Pick Sub-class */
764     OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
765     OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
766     OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
767     OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
768     OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
769     OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
770     OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
771     OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
772     OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
773     OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
774     OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
775     OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
776     OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
777     OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
778     OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
779     OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
780     OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
781     OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
782     OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
783     /* MIPS DSP Arithmetic Sub-class */
784     OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
785     OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
786     OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
787     OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
788     OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
789     OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
790     OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
791     OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
792 };
793
794 #define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
795 enum {
796     /* DSP Append Sub-class */
797     OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
798     OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
799     OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
800     OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
801 };
802
803 #define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
804 enum {
805     /* MIPS DSP Accumulator and DSPControl Access Sub-class */
806     OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
807     OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
808     OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
809     OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
810     OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
811     OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
812     OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
813     OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
814     OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
815     OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
816     OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
817     OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
818     OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
819     OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
820     OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
821     OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
822     OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
823     OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
824     OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
825     OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
826     OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
827 };
828
829 #define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
830 enum {
831     /* DSP Bit/Manipulation Sub-class */
832     OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
833 };
834
835 #define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
836 enum {
837     /* MIPS DSP Multiply Sub-class insns */
838     OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
839     OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
840     OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
841     OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
842     OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
843     OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
844     OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
845     OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
846     OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
847     OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
848     OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
849     OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
850     OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
851     OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
852     OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
853     OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
854     OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
855     OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
856     OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
857     OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
858     OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
859     OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
860     OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
861     OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
862     OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
863     OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
864 };
865
866 #define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
867 enum {
868     /* MIPS DSP GPR-Based Shift Sub-class */
869     OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
870     OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
871     OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
872     OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
873     OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
874     OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
875     OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
876     OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
877     OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
878     OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
879     OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
880     OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
881     OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
882     OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
883     OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
884     OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
885     OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
886     OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
887     OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
888     OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
889     OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
890     OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
891     OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
892     OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
893     OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
894     OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
895 };
896
897 /* Coprocessor 0 (rs field) */
898 #define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
899
900 enum {
901     OPC_MFC0     = (0x00 << 21) | OPC_CP0,
902     OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
903     OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
904     OPC_MTC0     = (0x04 << 21) | OPC_CP0,
905     OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
906     OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
907     OPC_MFTR     = (0x08 << 21) | OPC_CP0,
908     OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
909     OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
910     OPC_MTTR     = (0x0C << 21) | OPC_CP0,
911     OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
912     OPC_C0       = (0x10 << 21) | OPC_CP0,
913     OPC_C0_1     = (0x11 << 21) | OPC_CP0,
914     OPC_C0_2     = (0x12 << 21) | OPC_CP0,
915     OPC_C0_3     = (0x13 << 21) | OPC_CP0,
916     OPC_C0_4     = (0x14 << 21) | OPC_CP0,
917     OPC_C0_5     = (0x15 << 21) | OPC_CP0,
918     OPC_C0_6     = (0x16 << 21) | OPC_CP0,
919     OPC_C0_7     = (0x17 << 21) | OPC_CP0,
920     OPC_C0_8     = (0x18 << 21) | OPC_CP0,
921     OPC_C0_9     = (0x19 << 21) | OPC_CP0,
922     OPC_C0_A     = (0x1A << 21) | OPC_CP0,
923     OPC_C0_B     = (0x1B << 21) | OPC_CP0,
924     OPC_C0_C     = (0x1C << 21) | OPC_CP0,
925     OPC_C0_D     = (0x1D << 21) | OPC_CP0,
926     OPC_C0_E     = (0x1E << 21) | OPC_CP0,
927     OPC_C0_F     = (0x1F << 21) | OPC_CP0,
928 };
929
930 /* MFMC0 opcodes */
931 #define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
932
933 enum {
934     OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
935     OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
936     OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
937     OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
938     OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
939     OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
940     OPC_DVP      = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
941     OPC_EVP      = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
942 };
943
944 /* Coprocessor 0 (with rs == C0) */
945 #define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
946
947 enum {
948     OPC_TLBR     = 0x01 | OPC_C0,
949     OPC_TLBWI    = 0x02 | OPC_C0,
950     OPC_TLBINV   = 0x03 | OPC_C0,
951     OPC_TLBINVF  = 0x04 | OPC_C0,
952     OPC_TLBWR    = 0x06 | OPC_C0,
953     OPC_TLBP     = 0x08 | OPC_C0,
954     OPC_RFE      = 0x10 | OPC_C0,
955     OPC_ERET     = 0x18 | OPC_C0,
956     OPC_DERET    = 0x1F | OPC_C0,
957     OPC_WAIT     = 0x20 | OPC_C0,
958 };
959
960 /* Coprocessor 1 (rs field) */
961 #define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
962
963 /* Values for the fmt field in FP instructions */
964 enum {
965     /* 0 - 15 are reserved */
966     FMT_S = 16,          /* single fp */
967     FMT_D = 17,          /* double fp */
968     FMT_E = 18,          /* extended fp */
969     FMT_Q = 19,          /* quad fp */
970     FMT_W = 20,          /* 32-bit fixed */
971     FMT_L = 21,          /* 64-bit fixed */
972     FMT_PS = 22,         /* paired single fp */
973     /* 23 - 31 are reserved */
974 };
975
976 enum {
977     OPC_MFC1     = (0x00 << 21) | OPC_CP1,
978     OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
979     OPC_CFC1     = (0x02 << 21) | OPC_CP1,
980     OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
981     OPC_MTC1     = (0x04 << 21) | OPC_CP1,
982     OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
983     OPC_CTC1     = (0x06 << 21) | OPC_CP1,
984     OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
985     OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
986     OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
987     OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
988     OPC_BZ_V     = (0x0B << 21) | OPC_CP1,
989     OPC_BNZ_V    = (0x0F << 21) | OPC_CP1,
990     OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
991     OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
992     OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
993     OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
994     OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
995     OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
996     OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
997     OPC_BC1EQZ   = (0x09 << 21) | OPC_CP1,
998     OPC_BC1NEZ   = (0x0D << 21) | OPC_CP1,
999     OPC_BZ_B     = (0x18 << 21) | OPC_CP1,
1000     OPC_BZ_H     = (0x19 << 21) | OPC_CP1,
1001     OPC_BZ_W     = (0x1A << 21) | OPC_CP1,
1002     OPC_BZ_D     = (0x1B << 21) | OPC_CP1,
1003     OPC_BNZ_B    = (0x1C << 21) | OPC_CP1,
1004     OPC_BNZ_H    = (0x1D << 21) | OPC_CP1,
1005     OPC_BNZ_W    = (0x1E << 21) | OPC_CP1,
1006     OPC_BNZ_D    = (0x1F << 21) | OPC_CP1,
1007 };
1008
1009 #define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
1010 #define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
1011
1012 enum {
1013     OPC_BC1F     = (0x00 << 16) | OPC_BC1,
1014     OPC_BC1T     = (0x01 << 16) | OPC_BC1,
1015     OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
1016     OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
1017 };
1018
1019 enum {
1020     OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
1021     OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
1022 };
1023
1024 enum {
1025     OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
1026     OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
1027 };
1028
1029 #define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
1030
1031 enum {
1032     OPC_MFC2    = (0x00 << 21) | OPC_CP2,
1033     OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
1034     OPC_CFC2    = (0x02 << 21) | OPC_CP2,
1035     OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
1036     OPC_MTC2    = (0x04 << 21) | OPC_CP2,
1037     OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
1038     OPC_CTC2    = (0x06 << 21) | OPC_CP2,
1039     OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
1040     OPC_BC2     = (0x08 << 21) | OPC_CP2,
1041     OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
1042     OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
1043 };
1044
1045 #define MASK_LMI(op)  (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1046
1047 enum {
1048     OPC_PADDSH  = (24 << 21) | (0x00) | OPC_CP2,
1049     OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
1050     OPC_PADDH   = (26 << 21) | (0x00) | OPC_CP2,
1051     OPC_PADDW   = (27 << 21) | (0x00) | OPC_CP2,
1052     OPC_PADDSB  = (28 << 21) | (0x00) | OPC_CP2,
1053     OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
1054     OPC_PADDB   = (30 << 21) | (0x00) | OPC_CP2,
1055     OPC_PADDD   = (31 << 21) | (0x00) | OPC_CP2,
1056
1057     OPC_PSUBSH  = (24 << 21) | (0x01) | OPC_CP2,
1058     OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
1059     OPC_PSUBH   = (26 << 21) | (0x01) | OPC_CP2,
1060     OPC_PSUBW   = (27 << 21) | (0x01) | OPC_CP2,
1061     OPC_PSUBSB  = (28 << 21) | (0x01) | OPC_CP2,
1062     OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
1063     OPC_PSUBB   = (30 << 21) | (0x01) | OPC_CP2,
1064     OPC_PSUBD   = (31 << 21) | (0x01) | OPC_CP2,
1065
1066     OPC_PSHUFH   = (24 << 21) | (0x02) | OPC_CP2,
1067     OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
1068     OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
1069     OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
1070     OPC_XOR_CP2  = (28 << 21) | (0x02) | OPC_CP2,
1071     OPC_NOR_CP2  = (29 << 21) | (0x02) | OPC_CP2,
1072     OPC_AND_CP2  = (30 << 21) | (0x02) | OPC_CP2,
1073     OPC_PANDN    = (31 << 21) | (0x02) | OPC_CP2,
1074
1075     OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
1076     OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
1077     OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
1078     OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
1079     OPC_PINSRH_0  = (28 << 21) | (0x03) | OPC_CP2,
1080     OPC_PINSRH_1  = (29 << 21) | (0x03) | OPC_CP2,
1081     OPC_PINSRH_2  = (30 << 21) | (0x03) | OPC_CP2,
1082     OPC_PINSRH_3  = (31 << 21) | (0x03) | OPC_CP2,
1083
1084     OPC_PAVGH   = (24 << 21) | (0x08) | OPC_CP2,
1085     OPC_PAVGB   = (25 << 21) | (0x08) | OPC_CP2,
1086     OPC_PMAXSH  = (26 << 21) | (0x08) | OPC_CP2,
1087     OPC_PMINSH  = (27 << 21) | (0x08) | OPC_CP2,
1088     OPC_PMAXUB  = (28 << 21) | (0x08) | OPC_CP2,
1089     OPC_PMINUB  = (29 << 21) | (0x08) | OPC_CP2,
1090
1091     OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
1092     OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
1093     OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
1094     OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
1095     OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
1096     OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
1097
1098     OPC_PSLLW   = (24 << 21) | (0x0A) | OPC_CP2,
1099     OPC_PSLLH   = (25 << 21) | (0x0A) | OPC_CP2,
1100     OPC_PMULLH  = (26 << 21) | (0x0A) | OPC_CP2,
1101     OPC_PMULHH  = (27 << 21) | (0x0A) | OPC_CP2,
1102     OPC_PMULUW  = (28 << 21) | (0x0A) | OPC_CP2,
1103     OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
1104
1105     OPC_PSRLW     = (24 << 21) | (0x0B) | OPC_CP2,
1106     OPC_PSRLH     = (25 << 21) | (0x0B) | OPC_CP2,
1107     OPC_PSRAW     = (26 << 21) | (0x0B) | OPC_CP2,
1108     OPC_PSRAH     = (27 << 21) | (0x0B) | OPC_CP2,
1109     OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
1110     OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
1111
1112     OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
1113     OPC_OR_CP2   = (25 << 21) | (0x0C) | OPC_CP2,
1114     OPC_ADD_CP2  = (26 << 21) | (0x0C) | OPC_CP2,
1115     OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
1116     OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
1117     OPC_SEQ_CP2  = (29 << 21) | (0x0C) | OPC_CP2,
1118
1119     OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
1120     OPC_PASUBUB  = (25 << 21) | (0x0D) | OPC_CP2,
1121     OPC_SUB_CP2  = (26 << 21) | (0x0D) | OPC_CP2,
1122     OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
1123     OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
1124     OPC_SLT_CP2  = (29 << 21) | (0x0D) | OPC_CP2,
1125
1126     OPC_SLL_CP2  = (24 << 21) | (0x0E) | OPC_CP2,
1127     OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
1128     OPC_PEXTRH   = (26 << 21) | (0x0E) | OPC_CP2,
1129     OPC_PMADDHW  = (27 << 21) | (0x0E) | OPC_CP2,
1130     OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
1131     OPC_SLE_CP2  = (29 << 21) | (0x0E) | OPC_CP2,
1132
1133     OPC_SRL_CP2  = (24 << 21) | (0x0F) | OPC_CP2,
1134     OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
1135     OPC_SRA_CP2  = (26 << 21) | (0x0F) | OPC_CP2,
1136     OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
1137     OPC_BIADD    = (28 << 21) | (0x0F) | OPC_CP2,
1138     OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
1139 };
1140
1141
1142 #define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
1143
1144 enum {
1145     OPC_LWXC1   = 0x00 | OPC_CP3,
1146     OPC_LDXC1   = 0x01 | OPC_CP3,
1147     OPC_LUXC1   = 0x05 | OPC_CP3,
1148     OPC_SWXC1   = 0x08 | OPC_CP3,
1149     OPC_SDXC1   = 0x09 | OPC_CP3,
1150     OPC_SUXC1   = 0x0D | OPC_CP3,
1151     OPC_PREFX   = 0x0F | OPC_CP3,
1152     OPC_ALNV_PS = 0x1E | OPC_CP3,
1153     OPC_MADD_S  = 0x20 | OPC_CP3,
1154     OPC_MADD_D  = 0x21 | OPC_CP3,
1155     OPC_MADD_PS = 0x26 | OPC_CP3,
1156     OPC_MSUB_S  = 0x28 | OPC_CP3,
1157     OPC_MSUB_D  = 0x29 | OPC_CP3,
1158     OPC_MSUB_PS = 0x2E | OPC_CP3,
1159     OPC_NMADD_S = 0x30 | OPC_CP3,
1160     OPC_NMADD_D = 0x31 | OPC_CP3,
1161     OPC_NMADD_PS= 0x36 | OPC_CP3,
1162     OPC_NMSUB_S = 0x38 | OPC_CP3,
1163     OPC_NMSUB_D = 0x39 | OPC_CP3,
1164     OPC_NMSUB_PS= 0x3E | OPC_CP3,
1165 };
1166
1167 /* MSA Opcodes */
1168 #define MASK_MSA_MINOR(op)    (MASK_OP_MAJOR(op) | (op & 0x3F))
1169 enum {
1170     OPC_MSA_I8_00   = 0x00 | OPC_MSA,
1171     OPC_MSA_I8_01   = 0x01 | OPC_MSA,
1172     OPC_MSA_I8_02   = 0x02 | OPC_MSA,
1173     OPC_MSA_I5_06   = 0x06 | OPC_MSA,
1174     OPC_MSA_I5_07   = 0x07 | OPC_MSA,
1175     OPC_MSA_BIT_09  = 0x09 | OPC_MSA,
1176     OPC_MSA_BIT_0A  = 0x0A | OPC_MSA,
1177     OPC_MSA_3R_0D   = 0x0D | OPC_MSA,
1178     OPC_MSA_3R_0E   = 0x0E | OPC_MSA,
1179     OPC_MSA_3R_0F   = 0x0F | OPC_MSA,
1180     OPC_MSA_3R_10   = 0x10 | OPC_MSA,
1181     OPC_MSA_3R_11   = 0x11 | OPC_MSA,
1182     OPC_MSA_3R_12   = 0x12 | OPC_MSA,
1183     OPC_MSA_3R_13   = 0x13 | OPC_MSA,
1184     OPC_MSA_3R_14   = 0x14 | OPC_MSA,
1185     OPC_MSA_3R_15   = 0x15 | OPC_MSA,
1186     OPC_MSA_ELM     = 0x19 | OPC_MSA,
1187     OPC_MSA_3RF_1A  = 0x1A | OPC_MSA,
1188     OPC_MSA_3RF_1B  = 0x1B | OPC_MSA,
1189     OPC_MSA_3RF_1C  = 0x1C | OPC_MSA,
1190     OPC_MSA_VEC     = 0x1E | OPC_MSA,
1191
1192     /* MI10 instruction */
1193     OPC_LD_B    = (0x20) | OPC_MSA,
1194     OPC_LD_H    = (0x21) | OPC_MSA,
1195     OPC_LD_W    = (0x22) | OPC_MSA,
1196     OPC_LD_D    = (0x23) | OPC_MSA,
1197     OPC_ST_B    = (0x24) | OPC_MSA,
1198     OPC_ST_H    = (0x25) | OPC_MSA,
1199     OPC_ST_W    = (0x26) | OPC_MSA,
1200     OPC_ST_D    = (0x27) | OPC_MSA,
1201 };
1202
1203 enum {
1204     /* I5 instruction df(bits 22..21) = _b, _h, _w, _d */
1205     OPC_ADDVI_df    = (0x0 << 23) | OPC_MSA_I5_06,
1206     OPC_CEQI_df     = (0x0 << 23) | OPC_MSA_I5_07,
1207     OPC_SUBVI_df    = (0x1 << 23) | OPC_MSA_I5_06,
1208     OPC_MAXI_S_df   = (0x2 << 23) | OPC_MSA_I5_06,
1209     OPC_CLTI_S_df   = (0x2 << 23) | OPC_MSA_I5_07,
1210     OPC_MAXI_U_df   = (0x3 << 23) | OPC_MSA_I5_06,
1211     OPC_CLTI_U_df   = (0x3 << 23) | OPC_MSA_I5_07,
1212     OPC_MINI_S_df   = (0x4 << 23) | OPC_MSA_I5_06,
1213     OPC_CLEI_S_df   = (0x4 << 23) | OPC_MSA_I5_07,
1214     OPC_MINI_U_df   = (0x5 << 23) | OPC_MSA_I5_06,
1215     OPC_CLEI_U_df   = (0x5 << 23) | OPC_MSA_I5_07,
1216     OPC_LDI_df      = (0x6 << 23) | OPC_MSA_I5_07,
1217
1218     /* I8 instruction */
1219     OPC_ANDI_B  = (0x0 << 24) | OPC_MSA_I8_00,
1220     OPC_BMNZI_B = (0x0 << 24) | OPC_MSA_I8_01,
1221     OPC_SHF_B   = (0x0 << 24) | OPC_MSA_I8_02,
1222     OPC_ORI_B   = (0x1 << 24) | OPC_MSA_I8_00,
1223     OPC_BMZI_B  = (0x1 << 24) | OPC_MSA_I8_01,
1224     OPC_SHF_H   = (0x1 << 24) | OPC_MSA_I8_02,
1225     OPC_NORI_B  = (0x2 << 24) | OPC_MSA_I8_00,
1226     OPC_BSELI_B = (0x2 << 24) | OPC_MSA_I8_01,
1227     OPC_SHF_W   = (0x2 << 24) | OPC_MSA_I8_02,
1228     OPC_XORI_B  = (0x3 << 24) | OPC_MSA_I8_00,
1229
1230     /* VEC/2R/2RF instruction */
1231     OPC_AND_V   = (0x00 << 21) | OPC_MSA_VEC,
1232     OPC_OR_V    = (0x01 << 21) | OPC_MSA_VEC,
1233     OPC_NOR_V   = (0x02 << 21) | OPC_MSA_VEC,
1234     OPC_XOR_V   = (0x03 << 21) | OPC_MSA_VEC,
1235     OPC_BMNZ_V  = (0x04 << 21) | OPC_MSA_VEC,
1236     OPC_BMZ_V   = (0x05 << 21) | OPC_MSA_VEC,
1237     OPC_BSEL_V  = (0x06 << 21) | OPC_MSA_VEC,
1238
1239     OPC_MSA_2R      = (0x18 << 21) | OPC_MSA_VEC,
1240     OPC_MSA_2RF     = (0x19 << 21) | OPC_MSA_VEC,
1241
1242     /* 2R instruction df(bits 17..16) = _b, _h, _w, _d */
1243     OPC_FILL_df = (0x00 << 18) | OPC_MSA_2R,
1244     OPC_PCNT_df = (0x01 << 18) | OPC_MSA_2R,
1245     OPC_NLOC_df = (0x02 << 18) | OPC_MSA_2R,
1246     OPC_NLZC_df = (0x03 << 18) | OPC_MSA_2R,
1247
1248     /* 2RF instruction df(bit 16) = _w, _d */
1249     OPC_FCLASS_df   = (0x00 << 17) | OPC_MSA_2RF,
1250     OPC_FTRUNC_S_df = (0x01 << 17) | OPC_MSA_2RF,
1251     OPC_FTRUNC_U_df = (0x02 << 17) | OPC_MSA_2RF,
1252     OPC_FSQRT_df    = (0x03 << 17) | OPC_MSA_2RF,
1253     OPC_FRSQRT_df   = (0x04 << 17) | OPC_MSA_2RF,
1254     OPC_FRCP_df     = (0x05 << 17) | OPC_MSA_2RF,
1255     OPC_FRINT_df    = (0x06 << 17) | OPC_MSA_2RF,
1256     OPC_FLOG2_df    = (0x07 << 17) | OPC_MSA_2RF,
1257     OPC_FEXUPL_df   = (0x08 << 17) | OPC_MSA_2RF,
1258     OPC_FEXUPR_df   = (0x09 << 17) | OPC_MSA_2RF,
1259     OPC_FFQL_df     = (0x0A << 17) | OPC_MSA_2RF,
1260     OPC_FFQR_df     = (0x0B << 17) | OPC_MSA_2RF,
1261     OPC_FTINT_S_df  = (0x0C << 17) | OPC_MSA_2RF,
1262     OPC_FTINT_U_df  = (0x0D << 17) | OPC_MSA_2RF,
1263     OPC_FFINT_S_df  = (0x0E << 17) | OPC_MSA_2RF,
1264     OPC_FFINT_U_df  = (0x0F << 17) | OPC_MSA_2RF,
1265
1266     /* 3R instruction df(bits 22..21) = _b, _h, _w, d */
1267     OPC_SLL_df      = (0x0 << 23) | OPC_MSA_3R_0D,
1268     OPC_ADDV_df     = (0x0 << 23) | OPC_MSA_3R_0E,
1269     OPC_CEQ_df      = (0x0 << 23) | OPC_MSA_3R_0F,
1270     OPC_ADD_A_df    = (0x0 << 23) | OPC_MSA_3R_10,
1271     OPC_SUBS_S_df   = (0x0 << 23) | OPC_MSA_3R_11,
1272     OPC_MULV_df     = (0x0 << 23) | OPC_MSA_3R_12,
1273     OPC_DOTP_S_df   = (0x0 << 23) | OPC_MSA_3R_13,
1274     OPC_SLD_df      = (0x0 << 23) | OPC_MSA_3R_14,
1275     OPC_VSHF_df     = (0x0 << 23) | OPC_MSA_3R_15,
1276     OPC_SRA_df      = (0x1 << 23) | OPC_MSA_3R_0D,
1277     OPC_SUBV_df     = (0x1 << 23) | OPC_MSA_3R_0E,
1278     OPC_ADDS_A_df   = (0x1 << 23) | OPC_MSA_3R_10,
1279     OPC_SUBS_U_df   = (0x1 << 23) | OPC_MSA_3R_11,
1280     OPC_MADDV_df    = (0x1 << 23) | OPC_MSA_3R_12,
1281     OPC_DOTP_U_df   = (0x1 << 23) | OPC_MSA_3R_13,
1282     OPC_SPLAT_df    = (0x1 << 23) | OPC_MSA_3R_14,
1283     OPC_SRAR_df     = (0x1 << 23) | OPC_MSA_3R_15,
1284     OPC_SRL_df      = (0x2 << 23) | OPC_MSA_3R_0D,
1285     OPC_MAX_S_df    = (0x2 << 23) | OPC_MSA_3R_0E,
1286     OPC_CLT_S_df    = (0x2 << 23) | OPC_MSA_3R_0F,
1287     OPC_ADDS_S_df   = (0x2 << 23) | OPC_MSA_3R_10,
1288     OPC_SUBSUS_U_df = (0x2 << 23) | OPC_MSA_3R_11,
1289     OPC_MSUBV_df    = (0x2 << 23) | OPC_MSA_3R_12,
1290     OPC_DPADD_S_df  = (0x2 << 23) | OPC_MSA_3R_13,
1291     OPC_PCKEV_df    = (0x2 << 23) | OPC_MSA_3R_14,
1292     OPC_SRLR_df     = (0x2 << 23) | OPC_MSA_3R_15,
1293     OPC_BCLR_df     = (0x3 << 23) | OPC_MSA_3R_0D,
1294     OPC_MAX_U_df    = (0x3 << 23) | OPC_MSA_3R_0E,
1295     OPC_CLT_U_df    = (0x3 << 23) | OPC_MSA_3R_0F,
1296     OPC_ADDS_U_df   = (0x3 << 23) | OPC_MSA_3R_10,
1297     OPC_SUBSUU_S_df = (0x3 << 23) | OPC_MSA_3R_11,
1298     OPC_DPADD_U_df  = (0x3 << 23) | OPC_MSA_3R_13,
1299     OPC_PCKOD_df    = (0x3 << 23) | OPC_MSA_3R_14,
1300     OPC_BSET_df     = (0x4 << 23) | OPC_MSA_3R_0D,
1301     OPC_MIN_S_df    = (0x4 << 23) | OPC_MSA_3R_0E,
1302     OPC_CLE_S_df    = (0x4 << 23) | OPC_MSA_3R_0F,
1303     OPC_AVE_S_df    = (0x4 << 23) | OPC_MSA_3R_10,
1304     OPC_ASUB_S_df   = (0x4 << 23) | OPC_MSA_3R_11,
1305     OPC_DIV_S_df    = (0x4 << 23) | OPC_MSA_3R_12,
1306     OPC_DPSUB_S_df  = (0x4 << 23) | OPC_MSA_3R_13,
1307     OPC_ILVL_df     = (0x4 << 23) | OPC_MSA_3R_14,
1308     OPC_HADD_S_df   = (0x4 << 23) | OPC_MSA_3R_15,
1309     OPC_BNEG_df     = (0x5 << 23) | OPC_MSA_3R_0D,
1310     OPC_MIN_U_df    = (0x5 << 23) | OPC_MSA_3R_0E,
1311     OPC_CLE_U_df    = (0x5 << 23) | OPC_MSA_3R_0F,
1312     OPC_AVE_U_df    = (0x5 << 23) | OPC_MSA_3R_10,
1313     OPC_ASUB_U_df   = (0x5 << 23) | OPC_MSA_3R_11,
1314     OPC_DIV_U_df    = (0x5 << 23) | OPC_MSA_3R_12,
1315     OPC_DPSUB_U_df  = (0x5 << 23) | OPC_MSA_3R_13,
1316     OPC_ILVR_df     = (0x5 << 23) | OPC_MSA_3R_14,
1317     OPC_HADD_U_df   = (0x5 << 23) | OPC_MSA_3R_15,
1318     OPC_BINSL_df    = (0x6 << 23) | OPC_MSA_3R_0D,
1319     OPC_MAX_A_df    = (0x6 << 23) | OPC_MSA_3R_0E,
1320     OPC_AVER_S_df   = (0x6 << 23) | OPC_MSA_3R_10,
1321     OPC_MOD_S_df    = (0x6 << 23) | OPC_MSA_3R_12,
1322     OPC_ILVEV_df    = (0x6 << 23) | OPC_MSA_3R_14,
1323     OPC_HSUB_S_df   = (0x6 << 23) | OPC_MSA_3R_15,
1324     OPC_BINSR_df    = (0x7 << 23) | OPC_MSA_3R_0D,
1325     OPC_MIN_A_df    = (0x7 << 23) | OPC_MSA_3R_0E,
1326     OPC_AVER_U_df   = (0x7 << 23) | OPC_MSA_3R_10,
1327     OPC_MOD_U_df    = (0x7 << 23) | OPC_MSA_3R_12,
1328     OPC_ILVOD_df    = (0x7 << 23) | OPC_MSA_3R_14,
1329     OPC_HSUB_U_df   = (0x7 << 23) | OPC_MSA_3R_15,
1330
1331     /* ELM instructions df(bits 21..16) = _b, _h, _w, _d */
1332     OPC_SLDI_df     = (0x0 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1333     OPC_CTCMSA      = (0x0 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1334     OPC_SPLATI_df   = (0x1 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1335     OPC_CFCMSA      = (0x1 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1336     OPC_COPY_S_df   = (0x2 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1337     OPC_MOVE_V      = (0x2 << 22) | (0x3E << 16) | OPC_MSA_ELM,
1338     OPC_COPY_U_df   = (0x3 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1339     OPC_INSERT_df   = (0x4 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1340     OPC_INSVE_df    = (0x5 << 22) | (0x00 << 16) | OPC_MSA_ELM,
1341
1342     /* 3RF instruction _df(bit 21) = _w, _d */
1343     OPC_FCAF_df     = (0x0 << 22) | OPC_MSA_3RF_1A,
1344     OPC_FADD_df     = (0x0 << 22) | OPC_MSA_3RF_1B,
1345     OPC_FCUN_df     = (0x1 << 22) | OPC_MSA_3RF_1A,
1346     OPC_FSUB_df     = (0x1 << 22) | OPC_MSA_3RF_1B,
1347     OPC_FCOR_df     = (0x1 << 22) | OPC_MSA_3RF_1C,
1348     OPC_FCEQ_df     = (0x2 << 22) | OPC_MSA_3RF_1A,
1349     OPC_FMUL_df     = (0x2 << 22) | OPC_MSA_3RF_1B,
1350     OPC_FCUNE_df    = (0x2 << 22) | OPC_MSA_3RF_1C,
1351     OPC_FCUEQ_df    = (0x3 << 22) | OPC_MSA_3RF_1A,
1352     OPC_FDIV_df     = (0x3 << 22) | OPC_MSA_3RF_1B,
1353     OPC_FCNE_df     = (0x3 << 22) | OPC_MSA_3RF_1C,
1354     OPC_FCLT_df     = (0x4 << 22) | OPC_MSA_3RF_1A,
1355     OPC_FMADD_df    = (0x4 << 22) | OPC_MSA_3RF_1B,
1356     OPC_MUL_Q_df    = (0x4 << 22) | OPC_MSA_3RF_1C,
1357     OPC_FCULT_df    = (0x5 << 22) | OPC_MSA_3RF_1A,
1358     OPC_FMSUB_df    = (0x5 << 22) | OPC_MSA_3RF_1B,
1359     OPC_MADD_Q_df   = (0x5 << 22) | OPC_MSA_3RF_1C,
1360     OPC_FCLE_df     = (0x6 << 22) | OPC_MSA_3RF_1A,
1361     OPC_MSUB_Q_df   = (0x6 << 22) | OPC_MSA_3RF_1C,
1362     OPC_FCULE_df    = (0x7 << 22) | OPC_MSA_3RF_1A,
1363     OPC_FEXP2_df    = (0x7 << 22) | OPC_MSA_3RF_1B,
1364     OPC_FSAF_df     = (0x8 << 22) | OPC_MSA_3RF_1A,
1365     OPC_FEXDO_df    = (0x8 << 22) | OPC_MSA_3RF_1B,
1366     OPC_FSUN_df     = (0x9 << 22) | OPC_MSA_3RF_1A,
1367     OPC_FSOR_df     = (0x9 << 22) | OPC_MSA_3RF_1C,
1368     OPC_FSEQ_df     = (0xA << 22) | OPC_MSA_3RF_1A,
1369     OPC_FTQ_df      = (0xA << 22) | OPC_MSA_3RF_1B,
1370     OPC_FSUNE_df    = (0xA << 22) | OPC_MSA_3RF_1C,
1371     OPC_FSUEQ_df    = (0xB << 22) | OPC_MSA_3RF_1A,
1372     OPC_FSNE_df     = (0xB << 22) | OPC_MSA_3RF_1C,
1373     OPC_FSLT_df     = (0xC << 22) | OPC_MSA_3RF_1A,
1374     OPC_FMIN_df     = (0xC << 22) | OPC_MSA_3RF_1B,
1375     OPC_MULR_Q_df   = (0xC << 22) | OPC_MSA_3RF_1C,
1376     OPC_FSULT_df    = (0xD << 22) | OPC_MSA_3RF_1A,
1377     OPC_FMIN_A_df   = (0xD << 22) | OPC_MSA_3RF_1B,
1378     OPC_MADDR_Q_df  = (0xD << 22) | OPC_MSA_3RF_1C,
1379     OPC_FSLE_df     = (0xE << 22) | OPC_MSA_3RF_1A,
1380     OPC_FMAX_df     = (0xE << 22) | OPC_MSA_3RF_1B,
1381     OPC_MSUBR_Q_df  = (0xE << 22) | OPC_MSA_3RF_1C,
1382     OPC_FSULE_df    = (0xF << 22) | OPC_MSA_3RF_1A,
1383     OPC_FMAX_A_df   = (0xF << 22) | OPC_MSA_3RF_1B,
1384
1385     /* BIT instruction df(bits 22..16) = _B _H _W _D */
1386     OPC_SLLI_df     = (0x0 << 23) | OPC_MSA_BIT_09,
1387     OPC_SAT_S_df    = (0x0 << 23) | OPC_MSA_BIT_0A,
1388     OPC_SRAI_df     = (0x1 << 23) | OPC_MSA_BIT_09,
1389     OPC_SAT_U_df    = (0x1 << 23) | OPC_MSA_BIT_0A,
1390     OPC_SRLI_df     = (0x2 << 23) | OPC_MSA_BIT_09,
1391     OPC_SRARI_df    = (0x2 << 23) | OPC_MSA_BIT_0A,
1392     OPC_BCLRI_df    = (0x3 << 23) | OPC_MSA_BIT_09,
1393     OPC_SRLRI_df    = (0x3 << 23) | OPC_MSA_BIT_0A,
1394     OPC_BSETI_df    = (0x4 << 23) | OPC_MSA_BIT_09,
1395     OPC_BNEGI_df    = (0x5 << 23) | OPC_MSA_BIT_09,
1396     OPC_BINSLI_df   = (0x6 << 23) | OPC_MSA_BIT_09,
1397     OPC_BINSRI_df   = (0x7 << 23) | OPC_MSA_BIT_09,
1398 };
1399
1400
1401 /*
1402  *
1403  *       AN OVERVIEW OF MXU EXTENSION INSTRUCTION SET
1404  *       ============================================
1405  *
1406  *
1407  * MXU (full name: MIPS eXtension/enhanced Unit) is a SIMD extension of MIPS32
1408  * instructions set. It is designed to fit the needs of signal, graphical and
1409  * video processing applications. MXU instruction set is used in Xburst family
1410  * of microprocessors by Ingenic.
1411  *
1412  * MXU unit contains 17 registers called X0-X16. X0 is always zero, and X16 is
1413  * the control register.
1414  *
1415  *
1416  *     The notation used in MXU assembler mnemonics
1417  *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1418  *
1419  *  Register operands:
1420  *
1421  *   XRa, XRb, XRc, XRd - MXU registers
1422  *   Rb, Rc, Rd, Rs, Rt - general purpose MIPS registers
1423  *
1424  *  Non-register operands:
1425  *
1426  *   aptn1 - 1-bit accumulate add/subtract pattern
1427  *   aptn2 - 2-bit accumulate add/subtract pattern
1428  *   eptn2 - 2-bit execute add/subtract pattern
1429  *   optn2 - 2-bit operand pattern
1430  *   optn3 - 3-bit operand pattern
1431  *   sft4  - 4-bit shift amount
1432  *   strd2 - 2-bit stride amount
1433  *
1434  *  Prefixes:
1435  *
1436  *   Level of parallelism:                Operand size:
1437  *    S - single operation at a time       32 - word
1438  *    D - two operations in parallel       16 - half word
1439  *    Q - four operations in parallel       8 - byte
1440  *
1441  *  Operations:
1442  *
1443  *   ADD   - Add or subtract
1444  *   ADDC  - Add with carry-in
1445  *   ACC   - Accumulate
1446  *   ASUM  - Sum together then accumulate (add or subtract)
1447  *   ASUMC - Sum together then accumulate (add or subtract) with carry-in
1448  *   AVG   - Average between 2 operands
1449  *   ABD   - Absolute difference
1450  *   ALN   - Align data
1451  *   AND   - Logical bitwise 'and' operation
1452  *   CPS   - Copy sign
1453  *   EXTR  - Extract bits
1454  *   I2M   - Move from GPR register to MXU register
1455  *   LDD   - Load data from memory to XRF
1456  *   LDI   - Load data from memory to XRF (and increase the address base)
1457  *   LUI   - Load unsigned immediate
1458  *   MUL   - Multiply
1459  *   MULU  - Unsigned multiply
1460  *   MADD  - 64-bit operand add 32x32 product
1461  *   MSUB  - 64-bit operand subtract 32x32 product
1462  *   MAC   - Multiply and accumulate (add or subtract)
1463  *   MAD   - Multiply and add or subtract
1464  *   MAX   - Maximum between 2 operands
1465  *   MIN   - Minimum between 2 operands
1466  *   M2I   - Move from MXU register to GPR register
1467  *   MOVZ  - Move if zero
1468  *   MOVN  - Move if non-zero
1469  *   NOR   - Logical bitwise 'nor' operation
1470  *   OR    - Logical bitwise 'or' operation
1471  *   STD   - Store data from XRF to memory
1472  *   SDI   - Store data from XRF to memory (and increase the address base)
1473  *   SLT   - Set of less than comparison
1474  *   SAD   - Sum of absolute differences
1475  *   SLL   - Logical shift left
1476  *   SLR   - Logical shift right
1477  *   SAR   - Arithmetic shift right
1478  *   SAT   - Saturation
1479  *   SFL   - Shuffle
1480  *   SCOP  - Calculate x’s scope (-1, means x<0; 0, means x==0; 1, means x>0)
1481  *   XOR   - Logical bitwise 'exclusive or' operation
1482  *
1483  *  Suffixes:
1484  *
1485  *   E - Expand results
1486  *   F - Fixed point multiplication
1487  *   L - Low part result
1488  *   R - Doing rounding
1489  *   V - Variable instead of immediate
1490  *   W - Combine above L and V
1491  *
1492  *
1493  *     The list of MXU instructions grouped by functionality
1494  *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1495  *
1496  * Load/Store instructions           Multiplication instructions
1497  * -----------------------           ---------------------------
1498  *
1499  *  S32LDD XRa, Rb, s12               S32MADD XRa, XRd, Rs, Rt
1500  *  S32STD XRa, Rb, s12               S32MADDU XRa, XRd, Rs, Rt
1501  *  S32LDDV XRa, Rb, rc, strd2        S32MSUB XRa, XRd, Rs, Rt
1502  *  S32STDV XRa, Rb, rc, strd2        S32MSUBU XRa, XRd, Rs, Rt
1503  *  S32LDI XRa, Rb, s12               S32MUL XRa, XRd, Rs, Rt
1504  *  S32SDI XRa, Rb, s12               S32MULU XRa, XRd, Rs, Rt
1505  *  S32LDIV XRa, Rb, rc, strd2        D16MUL XRa, XRb, XRc, XRd, optn2
1506  *  S32SDIV XRa, Rb, rc, strd2        D16MULE XRa, XRb, XRc, optn2
1507  *  S32LDDR XRa, Rb, s12              D16MULF XRa, XRb, XRc, optn2
1508  *  S32STDR XRa, Rb, s12              D16MAC XRa, XRb, XRc, XRd, aptn2, optn2
1509  *  S32LDDVR XRa, Rb, rc, strd2       D16MACE XRa, XRb, XRc, XRd, aptn2, optn2
1510  *  S32STDVR XRa, Rb, rc, strd2       D16MACF XRa, XRb, XRc, XRd, aptn2, optn2
1511  *  S32LDIR XRa, Rb, s12              D16MADL XRa, XRb, XRc, XRd, aptn2, optn2
1512  *  S32SDIR XRa, Rb, s12              S16MAD XRa, XRb, XRc, XRd, aptn1, optn2
1513  *  S32LDIVR XRa, Rb, rc, strd2       Q8MUL XRa, XRb, XRc, XRd
1514  *  S32SDIVR XRa, Rb, rc, strd2       Q8MULSU XRa, XRb, XRc, XRd
1515  *  S16LDD XRa, Rb, s10, eptn2        Q8MAC XRa, XRb, XRc, XRd, aptn2
1516  *  S16STD XRa, Rb, s10, eptn2        Q8MACSU XRa, XRb, XRc, XRd, aptn2
1517  *  S16LDI XRa, Rb, s10, eptn2        Q8MADL XRa, XRb, XRc, XRd, aptn2
1518  *  S16SDI XRa, Rb, s10, eptn2
1519  *  S8LDD XRa, Rb, s8, eptn3
1520  *  S8STD XRa, Rb, s8, eptn3         Addition and subtraction instructions
1521  *  S8LDI XRa, Rb, s8, eptn3         -------------------------------------
1522  *  S8SDI XRa, Rb, s8, eptn3
1523  *  LXW Rd, Rs, Rt, strd2             D32ADD XRa, XRb, XRc, XRd, eptn2
1524  *  LXH Rd, Rs, Rt, strd2             D32ADDC XRa, XRb, XRc, XRd
1525  *  LXHU Rd, Rs, Rt, strd2            D32ACC XRa, XRb, XRc, XRd, eptn2
1526  *  LXB Rd, Rs, Rt, strd2             D32ACCM XRa, XRb, XRc, XRd, eptn2
1527  *  LXBU Rd, Rs, Rt, strd2            D32ASUM XRa, XRb, XRc, XRd, eptn2
1528  *                                    S32CPS XRa, XRb, XRc
1529  *                                    Q16ADD XRa, XRb, XRc, XRd, eptn2, optn2
1530  * Comparison instructions            Q16ACC XRa, XRb, XRc, XRd, eptn2
1531  * -----------------------            Q16ACCM XRa, XRb, XRc, XRd, eptn2
1532  *                                    D16ASUM XRa, XRb, XRc, XRd, eptn2
1533  *  S32MAX XRa, XRb, XRc              D16CPS XRa, XRb,
1534  *  S32MIN XRa, XRb, XRc              D16AVG XRa, XRb, XRc
1535  *  S32SLT XRa, XRb, XRc              D16AVGR XRa, XRb, XRc
1536  *  S32MOVZ XRa, XRb, XRc             Q8ADD XRa, XRb, XRc, eptn2
1537  *  S32MOVN XRa, XRb, XRc             Q8ADDE XRa, XRb, XRc, XRd, eptn2
1538  *  D16MAX XRa, XRb, XRc              Q8ACCE XRa, XRb, XRc, XRd, eptn2
1539  *  D16MIN XRa, XRb, XRc              Q8ABD XRa, XRb, XRc
1540  *  D16SLT XRa, XRb, XRc              Q8SAD XRa, XRb, XRc, XRd
1541  *  D16MOVZ XRa, XRb, XRc             Q8AVG XRa, XRb, XRc
1542  *  D16MOVN XRa, XRb, XRc             Q8AVGR XRa, XRb, XRc
1543  *  Q8MAX XRa, XRb, XRc               D8SUM XRa, XRb, XRc, XRd
1544  *  Q8MIN XRa, XRb, XRc               D8SUMC XRa, XRb, XRc, XRd
1545  *  Q8SLT XRa, XRb, XRc
1546  *  Q8SLTU XRa, XRb, XRc
1547  *  Q8MOVZ XRa, XRb, XRc             Shift instructions
1548  *  Q8MOVN XRa, XRb, XRc             ------------------
1549  *
1550  *                                    D32SLL XRa, XRb, XRc, XRd, sft4
1551  * Bitwise instructions               D32SLR XRa, XRb, XRc, XRd, sft4
1552  * --------------------               D32SAR XRa, XRb, XRc, XRd, sft4
1553  *                                    D32SARL XRa, XRb, XRc, sft4
1554  *  S32NOR XRa, XRb, XRc              D32SLLV XRa, XRb, Rb
1555  *  S32AND XRa, XRb, XRc              D32SLRV XRa, XRb, Rb
1556  *  S32XOR XRa, XRb, XRc              D32SARV XRa, XRb, Rb
1557  *  S32OR XRa, XRb, XRc               D32SARW XRa, XRb, XRc, Rb
1558  *                                    Q16SLL XRa, XRb, XRc, XRd, sft4
1559  *                                    Q16SLR XRa, XRb, XRc, XRd, sft4
1560  * Miscellaneous instructions         Q16SAR XRa, XRb, XRc, XRd, sft4
1561  * -------------------------          Q16SLLV XRa, XRb, Rb
1562  *                                    Q16SLRV XRa, XRb, Rb
1563  *  S32SFL XRa, XRb, XRc, XRd, optn2  Q16SARV XRa, XRb, Rb
1564  *  S32ALN XRa, XRb, XRc, Rb
1565  *  S32ALNI XRa, XRb, XRc, s3
1566  *  S32LUI XRa, s8, optn3            Move instructions
1567  *  S32EXTR XRa, XRb, Rb, bits5      -----------------
1568  *  S32EXTRV XRa, XRb, Rs, Rt
1569  *  Q16SCOP XRa, XRb, XRc, XRd        S32M2I XRa, Rb
1570  *  Q16SAT XRa, XRb, XRc              S32I2M XRa, Rb
1571  *
1572  *
1573  *     The opcode organization of MXU instructions
1574  *     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1575  *
1576  * The bits 31..26 of all MXU instructions are equal to 0x1C (also referred
1577  * as opcode SPECIAL2 in the base MIPS ISA). The organization and meaning of
1578  * other bits up to the instruction level is as follows:
1579  *
1580  *              bits
1581  *             05..00
1582  *
1583  *          â”Œâ”€ 000000 â”€ OPC_MXU_S32MADD
1584  *          â”œâ”€ 000001 â”€ OPC_MXU_S32MADDU
1585  *          â”œâ”€ 000010 â”€ <not assigned>   (non-MXU OPC_MUL)
1586  *          â”‚
1587  *          â”‚                               20..18
1588  *          â”œâ”€ 000011 â”€ OPC_MXU__POOL00 â”€â”¬â”€ 000 â”€ OPC_MXU_S32MAX
1589  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_S32MIN
1590  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_D16MAX
1591  *          â”‚                            â”œâ”€ 011 â”€ OPC_MXU_D16MIN
1592  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_Q8MAX
1593  *          â”‚                            â”œâ”€ 101 â”€ OPC_MXU_Q8MIN
1594  *          â”‚                            â”œâ”€ 110 â”€ OPC_MXU_Q8SLT
1595  *          â”‚                            â””─ 111 â”€ OPC_MXU_Q8SLTU
1596  *          â”œâ”€ 000100 â”€ OPC_MXU_S32MSUB
1597  *          â”œâ”€ 000101 â”€ OPC_MXU_S32MSUBU    20..18
1598  *          â”œâ”€ 000110 â”€ OPC_MXU__POOL01 â”€â”¬â”€ 000 â”€ OPC_MXU_S32SLT
1599  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_D16SLT
1600  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_D16AVG
1601  *          â”‚                            â”œâ”€ 011 â”€ OPC_MXU_D16AVGR
1602  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_Q8AVG
1603  *          â”‚                            â”œâ”€ 101 â”€ OPC_MXU_Q8AVGR
1604  *          â”‚                            â””─ 111 â”€ OPC_MXU_Q8ADD
1605  *          â”‚
1606  *          â”‚                               20..18
1607  *          â”œâ”€ 000111 â”€ OPC_MXU__POOL02 â”€â”¬â”€ 000 â”€ OPC_MXU_S32CPS
1608  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_D16CPS
1609  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_Q8ABD
1610  *          â”‚                            â””─ 110 â”€ OPC_MXU_Q16SAT
1611  *          â”œâ”€ 001000 â”€ OPC_MXU_D16MUL
1612  *          â”‚                               25..24
1613  *          â”œâ”€ 001001 â”€ OPC_MXU__POOL03 â”€â”¬â”€ 00 â”€ OPC_MXU_D16MULF
1614  *          â”‚                            â””─ 01 â”€ OPC_MXU_D16MULE
1615  *          â”œâ”€ 001010 â”€ OPC_MXU_D16MAC
1616  *          â”œâ”€ 001011 â”€ OPC_MXU_D16MACF
1617  *          â”œâ”€ 001100 â”€ OPC_MXU_D16MADL
1618  *          â”œâ”€ 001101 â”€ OPC_MXU_S16MAD
1619  *          â”œâ”€ 001110 â”€ OPC_MXU_Q16ADD
1620  *          â”œâ”€ 001111 â”€ OPC_MXU_D16MACE     23
1621  *          â”‚                            â”Œâ”€ 0 â”€ OPC_MXU_S32LDD
1622  *          â”œâ”€ 010000 â”€ OPC_MXU__POOL04 â”€â”´â”€ 1 â”€ OPC_MXU_S32LDDR
1623  *          â”‚
1624  *          â”‚                               23
1625  *          â”œâ”€ 010001 â”€ OPC_MXU__POOL05 â”€â”¬â”€ 0 â”€ OPC_MXU_S32STD
1626  *          â”‚                            â””─ 1 â”€ OPC_MXU_S32STDR
1627  *          â”‚
1628  *          â”‚                               13..10
1629  *          â”œâ”€ 010010 â”€ OPC_MXU__POOL06 â”€â”¬â”€ 0000 â”€ OPC_MXU_S32LDDV
1630  *          â”‚                            â””─ 0001 â”€ OPC_MXU_S32LDDVR
1631  *          â”‚
1632  *          â”‚                               13..10
1633  *          â”œâ”€ 010011 â”€ OPC_MXU__POOL07 â”€â”¬â”€ 0000 â”€ OPC_MXU_S32STDV
1634  *          â”‚                            â””─ 0001 â”€ OPC_MXU_S32STDVR
1635  *          â”‚
1636  *          â”‚                               23
1637  *          â”œâ”€ 010100 â”€ OPC_MXU__POOL08 â”€â”¬â”€ 0 â”€ OPC_MXU_S32LDI
1638  *          â”‚                            â””─ 1 â”€ OPC_MXU_S32LDIR
1639  *          â”‚
1640  *          â”‚                               23
1641  *          â”œâ”€ 010101 â”€ OPC_MXU__POOL09 â”€â”¬â”€ 0 â”€ OPC_MXU_S32SDI
1642  *          â”‚                            â””─ 1 â”€ OPC_MXU_S32SDIR
1643  *          â”‚
1644  *          â”‚                               13..10
1645  *          â”œâ”€ 010110 â”€ OPC_MXU__POOL10 â”€â”¬â”€ 0000 â”€ OPC_MXU_S32LDIV
1646  *          â”‚                            â””─ 0001 â”€ OPC_MXU_S32LDIVR
1647  *          â”‚
1648  *          â”‚                               13..10
1649  *          â”œâ”€ 010111 â”€ OPC_MXU__POOL11 â”€â”¬â”€ 0000 â”€ OPC_MXU_S32SDIV
1650  *          â”‚                            â””─ 0001 â”€ OPC_MXU_S32SDIVR
1651  *          â”œâ”€ 011000 â”€ OPC_MXU_D32ADD
1652  *          â”‚                               23..22
1653  *   MXU    â”œâ”€ 011001 â”€ OPC_MXU__POOL12 â”€â”¬â”€ 00 â”€ OPC_MXU_D32ACC
1654  * opcodes â”€â”¤                            â”œâ”€ 01 â”€ OPC_MXU_D32ACCM
1655  *          â”‚                            â””─ 10 â”€ OPC_MXU_D32ASUM
1656  *          â”œâ”€ 011010 â”€ <not assigned>
1657  *          â”‚                               23..22
1658  *          â”œâ”€ 011011 â”€ OPC_MXU__POOL13 â”€â”¬â”€ 00 â”€ OPC_MXU_Q16ACC
1659  *          â”‚                            â”œâ”€ 01 â”€ OPC_MXU_Q16ACCM
1660  *          â”‚                            â””─ 10 â”€ OPC_MXU_Q16ASUM
1661  *          â”‚
1662  *          â”‚                               23..22
1663  *          â”œâ”€ 011100 â”€ OPC_MXU__POOL14 â”€â”¬â”€ 00 â”€ OPC_MXU_Q8ADDE
1664  *          â”‚                            â”œâ”€ 01 â”€ OPC_MXU_D8SUM
1665  *          â”œâ”€ 011101 â”€ OPC_MXU_Q8ACCE   â””─ 10 â”€ OPC_MXU_D8SUMC
1666  *          â”œâ”€ 011110 â”€ <not assigned>
1667  *          â”œâ”€ 011111 â”€ <not assigned>
1668  *          â”œâ”€ 100000 â”€ <not assigned>   (overlaps with CLZ)
1669  *          â”œâ”€ 100001 â”€ <not assigned>   (overlaps with CLO)
1670  *          â”œâ”€ 100010 â”€ OPC_MXU_S8LDD
1671  *          â”œâ”€ 100011 â”€ OPC_MXU_S8STD       15..14
1672  *          â”œâ”€ 100100 â”€ OPC_MXU_S8LDI    â”Œâ”€ 00 â”€ OPC_MXU_S32MUL
1673  *          â”œâ”€ 100101 â”€ OPC_MXU_S8SDI    â”œâ”€ 00 â”€ OPC_MXU_S32MULU
1674  *          â”‚                            â”œâ”€ 00 â”€ OPC_MXU_S32EXTR
1675  *          â”œâ”€ 100110 â”€ OPC_MXU__POOL15 â”€â”´â”€ 00 â”€ OPC_MXU_S32EXTRV
1676  *          â”‚
1677  *          â”‚                               20..18
1678  *          â”œâ”€ 100111 â”€ OPC_MXU__POOL16 â”€â”¬â”€ 000 â”€ OPC_MXU_D32SARW
1679  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_S32ALN
1680  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_S32ALNI
1681  *          â”‚                            â”œâ”€ 011 â”€ OPC_MXU_S32LUI
1682  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_S32NOR
1683  *          â”‚                            â”œâ”€ 101 â”€ OPC_MXU_S32AND
1684  *          â”‚                            â”œâ”€ 110 â”€ OPC_MXU_S32OR
1685  *          â”‚                            â””─ 111 â”€ OPC_MXU_S32XOR
1686  *          â”‚
1687  *          â”‚                               7..5
1688  *          â”œâ”€ 101000 â”€ OPC_MXU__POOL17 â”€â”¬â”€ 000 â”€ OPC_MXU_LXB
1689  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_LXH
1690  *          â”œâ”€ 101001 â”€ <not assigned>   â”œâ”€ 011 â”€ OPC_MXU_LXW
1691  *          â”œâ”€ 101010 â”€ OPC_MXU_S16LDD   â”œâ”€ 100 â”€ OPC_MXU_LXBU
1692  *          â”œâ”€ 101011 â”€ OPC_MXU_S16STD   â””─ 101 â”€ OPC_MXU_LXHU
1693  *          â”œâ”€ 101100 â”€ OPC_MXU_S16LDI
1694  *          â”œâ”€ 101101 â”€ OPC_MXU_S16SDI
1695  *          â”œâ”€ 101110 â”€ OPC_MXU_S32M2I
1696  *          â”œâ”€ 101111 â”€ OPC_MXU_S32I2M
1697  *          â”œâ”€ 110000 â”€ OPC_MXU_D32SLL
1698  *          â”œâ”€ 110001 â”€ OPC_MXU_D32SLR      20..18
1699  *          â”œâ”€ 110010 â”€ OPC_MXU_D32SARL  â”Œâ”€ 000 â”€ OPC_MXU_D32SLLV
1700  *          â”œâ”€ 110011 â”€ OPC_MXU_D32SAR   â”œâ”€ 001 â”€ OPC_MXU_D32SLRV
1701  *          â”œâ”€ 110100 â”€ OPC_MXU_Q16SLL   â”œâ”€ 010 â”€ OPC_MXU_D32SARV
1702  *          â”œâ”€ 110101 â”€ OPC_MXU_Q16SLR   â”œâ”€ 011 â”€ OPC_MXU_Q16SLLV
1703  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_Q16SLRV
1704  *          â”œâ”€ 110110 â”€ OPC_MXU__POOL18 â”€â”´â”€ 101 â”€ OPC_MXU_Q16SARV
1705  *          â”‚
1706  *          â”œâ”€ 110111 â”€ OPC_MXU_Q16SAR
1707  *          â”‚                               23..22
1708  *          â”œâ”€ 111000 â”€ OPC_MXU__POOL19 â”€â”¬â”€ 00 â”€ OPC_MXU_Q8MUL
1709  *          â”‚                            â””─ 01 â”€ OPC_MXU_Q8MULSU
1710  *          â”‚
1711  *          â”‚                               20..18
1712  *          â”œâ”€ 111001 â”€ OPC_MXU__POOL20 â”€â”¬â”€ 000 â”€ OPC_MXU_Q8MOVZ
1713  *          â”‚                            â”œâ”€ 001 â”€ OPC_MXU_Q8MOVN
1714  *          â”‚                            â”œâ”€ 010 â”€ OPC_MXU_D16MOVZ
1715  *          â”‚                            â”œâ”€ 011 â”€ OPC_MXU_D16MOVN
1716  *          â”‚                            â”œâ”€ 100 â”€ OPC_MXU_S32MOVZ
1717  *          â”‚                            â””─ 101 â”€ OPC_MXU_S32MOVN
1718  *          â”‚
1719  *          â”‚                               23..22
1720  *          â”œâ”€ 111010 â”€ OPC_MXU__POOL21 â”€â”¬â”€ 00 â”€ OPC_MXU_Q8MAC
1721  *          â”‚                            â””─ 10 â”€ OPC_MXU_Q8MACSU
1722  *          â”œâ”€ 111011 â”€ OPC_MXU_Q16SCOP
1723  *          â”œâ”€ 111100 â”€ OPC_MXU_Q8MADL
1724  *          â”œâ”€ 111101 â”€ OPC_MXU_S32SFL
1725  *          â”œâ”€ 111110 â”€ OPC_MXU_Q8SAD
1726  *          â””─ 111111 â”€ <not assigned>   (overlaps with SDBBP)
1727  *
1728  *
1729  * Compiled after:
1730  *
1731  *   "XBurst® Instruction Set Architecture MIPS eXtension/enhanced Unit
1732  *   Programming Manual", Ingenic Semiconductor Co, Ltd., revision June 2, 2017
1733  */
1734
1735 enum {
1736     OPC_MXU_S32MADD  = 0x00,
1737     OPC_MXU_S32MADDU = 0x01,
1738     OPC__MXU_MUL     = 0x02,
1739     OPC_MXU__POOL00  = 0x03,
1740     OPC_MXU_S32MSUB  = 0x04,
1741     OPC_MXU_S32MSUBU = 0x05,
1742     OPC_MXU__POOL01  = 0x06,
1743     OPC_MXU__POOL02  = 0x07,
1744     OPC_MXU_D16MUL   = 0x08,
1745     OPC_MXU__POOL03  = 0x09,
1746     OPC_MXU_D16MAC   = 0x0A,
1747     OPC_MXU_D16MACF  = 0x0B,
1748     OPC_MXU_D16MADL  = 0x0C,
1749     OPC_MXU_S16MAD   = 0x0D,
1750     OPC_MXU_Q16ADD   = 0x0E,
1751     OPC_MXU_D16MACE  = 0x0F,
1752     OPC_MXU__POOL04  = 0x10,
1753     OPC_MXU__POOL05  = 0x11,
1754     OPC_MXU__POOL06  = 0x12,
1755     OPC_MXU__POOL07  = 0x13,
1756     OPC_MXU__POOL08  = 0x14,
1757     OPC_MXU__POOL09  = 0x15,
1758     OPC_MXU__POOL10  = 0x16,
1759     OPC_MXU__POOL11  = 0x17,
1760     OPC_MXU_D32ADD   = 0x18,
1761     OPC_MXU__POOL12  = 0x19,
1762     /* not assigned 0x1A */
1763     OPC_MXU__POOL13  = 0x1B,
1764     OPC_MXU__POOL14  = 0x1C,
1765     OPC_MXU_Q8ACCE   = 0x1D,
1766     /* not assigned 0x1E */
1767     /* not assigned 0x1F */
1768     /* not assigned 0x20 */
1769     /* not assigned 0x21 */
1770     OPC_MXU_S8LDD    = 0x22,
1771     OPC_MXU_S8STD    = 0x23,
1772     OPC_MXU_S8LDI    = 0x24,
1773     OPC_MXU_S8SDI    = 0x25,
1774     OPC_MXU__POOL15  = 0x26,
1775     OPC_MXU__POOL16  = 0x27,
1776     OPC_MXU__POOL17  = 0x28,
1777     /* not assigned 0x29 */
1778     OPC_MXU_S16LDD   = 0x2A,
1779     OPC_MXU_S16STD   = 0x2B,
1780     OPC_MXU_S16LDI   = 0x2C,
1781     OPC_MXU_S16SDI   = 0x2D,
1782     OPC_MXU_S32M2I   = 0x2E,
1783     OPC_MXU_S32I2M   = 0x2F,
1784     OPC_MXU_D32SLL   = 0x30,
1785     OPC_MXU_D32SLR   = 0x31,
1786     OPC_MXU_D32SARL  = 0x32,
1787     OPC_MXU_D32SAR   = 0x33,
1788     OPC_MXU_Q16SLL   = 0x34,
1789     OPC_MXU_Q16SLR   = 0x35,
1790     OPC_MXU__POOL18  = 0x36,
1791     OPC_MXU_Q16SAR   = 0x37,
1792     OPC_MXU__POOL19  = 0x38,
1793     OPC_MXU__POOL20  = 0x39,
1794     OPC_MXU__POOL21  = 0x3A,
1795     OPC_MXU_Q16SCOP  = 0x3B,
1796     OPC_MXU_Q8MADL   = 0x3C,
1797     OPC_MXU_S32SFL   = 0x3D,
1798     OPC_MXU_Q8SAD    = 0x3E,
1799     /* not assigned 0x3F */
1800 };
1801
1802
1803 /*
1804  * MXU pool 00
1805  */
1806 enum {
1807     OPC_MXU_S32MAX   = 0x00,
1808     OPC_MXU_S32MIN   = 0x01,
1809     OPC_MXU_D16MAX   = 0x02,
1810     OPC_MXU_D16MIN   = 0x03,
1811     OPC_MXU_Q8MAX    = 0x04,
1812     OPC_MXU_Q8MIN    = 0x05,
1813     OPC_MXU_Q8SLT    = 0x06,
1814     OPC_MXU_Q8SLTU   = 0x07,
1815 };
1816
1817 /*
1818  * MXU pool 01
1819  */
1820 enum {
1821     OPC_MXU_S32SLT   = 0x00,
1822     OPC_MXU_D16SLT   = 0x01,
1823     OPC_MXU_D16AVG   = 0x02,
1824     OPC_MXU_D16AVGR  = 0x03,
1825     OPC_MXU_Q8AVG    = 0x04,
1826     OPC_MXU_Q8AVGR   = 0x05,
1827     OPC_MXU_Q8ADD    = 0x07,
1828 };
1829
1830 /*
1831  * MXU pool 02
1832  */
1833 enum {
1834     OPC_MXU_S32CPS   = 0x00,
1835     OPC_MXU_D16CPS   = 0x02,
1836     OPC_MXU_Q8ABD    = 0x04,
1837     OPC_MXU_Q16SAT   = 0x06,
1838 };
1839
1840 /*
1841  * MXU pool 03
1842  */
1843 enum {
1844     OPC_MXU_D16MULF  = 0x00,
1845     OPC_MXU_D16MULE  = 0x01,
1846 };
1847
1848 /*
1849  * MXU pool 04
1850  */
1851 enum {
1852     OPC_MXU_S32LDD   = 0x00,
1853     OPC_MXU_S32LDDR  = 0x01,
1854 };
1855
1856 /*
1857  * MXU pool 05
1858  */
1859 enum {
1860     OPC_MXU_S32STD   = 0x00,
1861     OPC_MXU_S32STDR  = 0x01,
1862 };
1863
1864 /*
1865  * MXU pool 06
1866  */
1867 enum {
1868     OPC_MXU_S32LDDV  = 0x00,
1869     OPC_MXU_S32LDDVR = 0x01,
1870 };
1871
1872 /*
1873  * MXU pool 07
1874  */
1875 enum {
1876     OPC_MXU_S32STDV  = 0x00,
1877     OPC_MXU_S32STDVR = 0x01,
1878 };
1879
1880 /*
1881  * MXU pool 08
1882  */
1883 enum {
1884     OPC_MXU_S32LDI   = 0x00,
1885     OPC_MXU_S32LDIR  = 0x01,
1886 };
1887
1888 /*
1889  * MXU pool 09
1890  */
1891 enum {
1892     OPC_MXU_S32SDI   = 0x00,
1893     OPC_MXU_S32SDIR  = 0x01,
1894 };
1895
1896 /*
1897  * MXU pool 10
1898  */
1899 enum {
1900     OPC_MXU_S32LDIV  = 0x00,
1901     OPC_MXU_S32LDIVR = 0x01,
1902 };
1903
1904 /*
1905  * MXU pool 11
1906  */
1907 enum {
1908     OPC_MXU_S32SDIV  = 0x00,
1909     OPC_MXU_S32SDIVR = 0x01,
1910 };
1911
1912 /*
1913  * MXU pool 12
1914  */
1915 enum {
1916     OPC_MXU_D32ACC   = 0x00,
1917     OPC_MXU_D32ACCM  = 0x01,
1918     OPC_MXU_D32ASUM  = 0x02,
1919 };
1920
1921 /*
1922  * MXU pool 13
1923  */
1924 enum {
1925     OPC_MXU_Q16ACC   = 0x00,
1926     OPC_MXU_Q16ACCM  = 0x01,
1927     OPC_MXU_Q16ASUM  = 0x02,
1928 };
1929
1930 /*
1931  * MXU pool 14
1932  */
1933 enum {
1934     OPC_MXU_Q8ADDE   = 0x00,
1935     OPC_MXU_D8SUM    = 0x01,
1936     OPC_MXU_D8SUMC   = 0x02,
1937 };
1938
1939 /*
1940  * MXU pool 15
1941  */
1942 enum {
1943     OPC_MXU_S32MUL   = 0x00,
1944     OPC_MXU_S32MULU  = 0x01,
1945     OPC_MXU_S32EXTR  = 0x02,
1946     OPC_MXU_S32EXTRV = 0x03,
1947 };
1948
1949 /*
1950  * MXU pool 16
1951  */
1952 enum {
1953     OPC_MXU_D32SARW  = 0x00,
1954     OPC_MXU_S32ALN   = 0x01,
1955     OPC_MXU_S32ALNI  = 0x02,
1956     OPC_MXU_S32LUI   = 0x03,
1957     OPC_MXU_S32NOR   = 0x04,
1958     OPC_MXU_S32AND   = 0x05,
1959     OPC_MXU_S32OR    = 0x06,
1960     OPC_MXU_S32XOR   = 0x07,
1961 };
1962
1963 /*
1964  * MXU pool 17
1965  */
1966 enum {
1967     OPC_MXU_LXB      = 0x00,
1968     OPC_MXU_LXH      = 0x01,
1969     OPC_MXU_LXW      = 0x03,
1970     OPC_MXU_LXBU     = 0x04,
1971     OPC_MXU_LXHU     = 0x05,
1972 };
1973
1974 /*
1975  * MXU pool 18
1976  */
1977 enum {
1978     OPC_MXU_D32SLLV  = 0x00,
1979     OPC_MXU_D32SLRV  = 0x01,
1980     OPC_MXU_D32SARV  = 0x03,
1981     OPC_MXU_Q16SLLV  = 0x04,
1982     OPC_MXU_Q16SLRV  = 0x05,
1983     OPC_MXU_Q16SARV  = 0x07,
1984 };
1985
1986 /*
1987  * MXU pool 19
1988  */
1989 enum {
1990     OPC_MXU_Q8MUL    = 0x00,
1991     OPC_MXU_Q8MULSU  = 0x01,
1992 };
1993
1994 /*
1995  * MXU pool 20
1996  */
1997 enum {
1998     OPC_MXU_Q8MOVZ   = 0x00,
1999     OPC_MXU_Q8MOVN   = 0x01,
2000     OPC_MXU_D16MOVZ  = 0x02,
2001     OPC_MXU_D16MOVN  = 0x03,
2002     OPC_MXU_S32MOVZ  = 0x04,
2003     OPC_MXU_S32MOVN  = 0x05,
2004 };
2005
2006 /*
2007  * MXU pool 21
2008  */
2009 enum {
2010     OPC_MXU_Q8MAC    = 0x00,
2011     OPC_MXU_Q8MACSU  = 0x01,
2012 };
2013
2014 /*
2015  *     Overview of the TX79-specific instruction set
2016  *     =============================================
2017  *
2018  * The R5900 and the C790 have 128-bit wide GPRs, where the upper 64 bits
2019  * are only used by the specific quadword (128-bit) LQ/SQ load/store
2020  * instructions and certain multimedia instructions (MMIs). These MMIs
2021  * configure the 128-bit data path as two 64-bit, four 32-bit, eight 16-bit
2022  * or sixteen 8-bit paths.
2023  *
2024  * Reference:
2025  *
2026  * The Toshiba TX System RISC TX79 Core Architecture manual,
2027  * https://wiki.qemu.org/File:C790.pdf
2028  *
2029  *     Three-Operand Multiply and Multiply-Add (4 instructions)
2030  *     --------------------------------------------------------
2031  * MADD    [rd,] rs, rt      Multiply/Add
2032  * MADDU   [rd,] rs, rt      Multiply/Add Unsigned
2033  * MULT    [rd,] rs, rt      Multiply (3-operand)
2034  * MULTU   [rd,] rs, rt      Multiply Unsigned (3-operand)
2035  *
2036  *     Multiply Instructions for Pipeline 1 (10 instructions)
2037  *     ------------------------------------------------------
2038  * MULT1   [rd,] rs, rt      Multiply Pipeline 1
2039  * MULTU1  [rd,] rs, rt      Multiply Unsigned Pipeline 1
2040  * DIV1    rs, rt            Divide Pipeline 1
2041  * DIVU1   rs, rt            Divide Unsigned Pipeline 1
2042  * MADD1   [rd,] rs, rt      Multiply-Add Pipeline 1
2043  * MADDU1  [rd,] rs, rt      Multiply-Add Unsigned Pipeline 1
2044  * MFHI1   rd                Move From HI1 Register
2045  * MFLO1   rd                Move From LO1 Register
2046  * MTHI1   rs                Move To HI1 Register
2047  * MTLO1   rs                Move To LO1 Register
2048  *
2049  *     Arithmetic (19 instructions)
2050  *     ----------------------------
2051  * PADDB   rd, rs, rt        Parallel Add Byte
2052  * PSUBB   rd, rs, rt        Parallel Subtract Byte
2053  * PADDH   rd, rs, rt        Parallel Add Halfword
2054  * PSUBH   rd, rs, rt        Parallel Subtract Halfword
2055  * PADDW   rd, rs, rt        Parallel Add Word
2056  * PSUBW   rd, rs, rt        Parallel Subtract Word
2057  * PADSBH  rd, rs, rt        Parallel Add/Subtract Halfword
2058  * PADDSB  rd, rs, rt        Parallel Add with Signed Saturation Byte
2059  * PSUBSB  rd, rs, rt        Parallel Subtract with Signed Saturation Byte
2060  * PADDSH  rd, rs, rt        Parallel Add with Signed Saturation Halfword
2061  * PSUBSH  rd, rs, rt        Parallel Subtract with Signed Saturation Halfword
2062  * PADDSW  rd, rs, rt        Parallel Add with Signed Saturation Word
2063  * PSUBSW  rd, rs, rt        Parallel Subtract with Signed Saturation Word
2064  * PADDUB  rd, rs, rt        Parallel Add with Unsigned saturation Byte
2065  * PSUBUB  rd, rs, rt        Parallel Subtract with Unsigned saturation Byte
2066  * PADDUH  rd, rs, rt        Parallel Add with Unsigned saturation Halfword
2067  * PSUBUH  rd, rs, rt        Parallel Subtract with Unsigned saturation Halfword
2068  * PADDUW  rd, rs, rt        Parallel Add with Unsigned saturation Word
2069  * PSUBUW  rd, rs, rt        Parallel Subtract with Unsigned saturation Word
2070  *
2071  *     Min/Max (4 instructions)
2072  *     ------------------------
2073  * PMAXH   rd, rs, rt        Parallel Maximum Halfword
2074  * PMINH   rd, rs, rt        Parallel Minimum Halfword
2075  * PMAXW   rd, rs, rt        Parallel Maximum Word
2076  * PMINW   rd, rs, rt        Parallel Minimum Word
2077  *
2078  *     Absolute (2 instructions)
2079  *     -------------------------
2080  * PABSH   rd, rt            Parallel Absolute Halfword
2081  * PABSW   rd, rt            Parallel Absolute Word
2082  *
2083  *     Logical (4 instructions)
2084  *     ------------------------
2085  * PAND    rd, rs, rt        Parallel AND
2086  * POR     rd, rs, rt        Parallel OR
2087  * PXOR    rd, rs, rt        Parallel XOR
2088  * PNOR    rd, rs, rt        Parallel NOR
2089  *
2090  *     Shift (9 instructions)
2091  *     ----------------------
2092  * PSLLH   rd, rt, sa        Parallel Shift Left Logical Halfword
2093  * PSRLH   rd, rt, sa        Parallel Shift Right Logical Halfword
2094  * PSRAH   rd, rt, sa        Parallel Shift Right Arithmetic Halfword
2095  * PSLLW   rd, rt, sa        Parallel Shift Left Logical Word
2096  * PSRLW   rd, rt, sa        Parallel Shift Right Logical Word
2097  * PSRAW   rd, rt, sa        Parallel Shift Right Arithmetic Word
2098  * PSLLVW  rd, rt, rs        Parallel Shift Left Logical Variable Word
2099  * PSRLVW  rd, rt, rs        Parallel Shift Right Logical Variable Word
2100  * PSRAVW  rd, rt, rs        Parallel Shift Right Arithmetic Variable Word
2101  *
2102  *     Compare (6 instructions)
2103  *     ------------------------
2104  * PCGTB   rd, rs, rt        Parallel Compare for Greater Than Byte
2105  * PCEQB   rd, rs, rt        Parallel Compare for Equal Byte
2106  * PCGTH   rd, rs, rt        Parallel Compare for Greater Than Halfword
2107  * PCEQH   rd, rs, rt        Parallel Compare for Equal Halfword
2108  * PCGTW   rd, rs, rt        Parallel Compare for Greater Than Word
2109  * PCEQW   rd, rs, rt        Parallel Compare for Equal Word
2110  *
2111  *     LZC (1 instruction)
2112  *     -------------------
2113  * PLZCW   rd, rs            Parallel Leading Zero or One Count Word
2114  *
2115  *     Quadword Load and Store (2 instructions)
2116  *     ----------------------------------------
2117  * LQ      rt, offset(base)  Load Quadword
2118  * SQ      rt, offset(base)  Store Quadword
2119  *
2120  *     Multiply and Divide (19 instructions)
2121  *     -------------------------------------
2122  * PMULTW  rd, rs, rt        Parallel Multiply Word
2123  * PMULTUW rd, rs, rt        Parallel Multiply Unsigned Word
2124  * PDIVW   rs, rt            Parallel Divide Word
2125  * PDIVUW  rs, rt            Parallel Divide Unsigned Word
2126  * PMADDW  rd, rs, rt        Parallel Multiply-Add Word
2127  * PMADDUW rd, rs, rt        Parallel Multiply-Add Unsigned Word
2128  * PMSUBW  rd, rs, rt        Parallel Multiply-Subtract Word
2129  * PMULTH  rd, rs, rt        Parallel Multiply Halfword
2130  * PMADDH  rd, rs, rt        Parallel Multiply-Add Halfword
2131  * PMSUBH  rd, rs, rt        Parallel Multiply-Subtract Halfword
2132  * PHMADH  rd, rs, rt        Parallel Horizontal Multiply-Add Halfword
2133  * PHMSBH  rd, rs, rt        Parallel Horizontal Multiply-Subtract Halfword
2134  * PDIVBW  rs, rt            Parallel Divide Broadcast Word
2135  * PMFHI   rd                Parallel Move From HI Register
2136  * PMFLO   rd                Parallel Move From LO Register
2137  * PMTHI   rs                Parallel Move To HI Register
2138  * PMTLO   rs                Parallel Move To LO Register
2139  * PMFHL   rd                Parallel Move From HI/LO Register
2140  * PMTHL   rs                Parallel Move To HI/LO Register
2141  *
2142  *     Pack/Extend (11 instructions)
2143  *     -----------------------------
2144  * PPAC5   rd, rt            Parallel Pack to 5 bits
2145  * PPACB   rd, rs, rt        Parallel Pack to Byte
2146  * PPACH   rd, rs, rt        Parallel Pack to Halfword
2147  * PPACW   rd, rs, rt        Parallel Pack to Word
2148  * PEXT5   rd, rt            Parallel Extend Upper from 5 bits
2149  * PEXTUB  rd, rs, rt        Parallel Extend Upper from Byte
2150  * PEXTLB  rd, rs, rt        Parallel Extend Lower from Byte
2151  * PEXTUH  rd, rs, rt        Parallel Extend Upper from Halfword
2152  * PEXTLH  rd, rs, rt        Parallel Extend Lower from Halfword
2153  * PEXTUW  rd, rs, rt        Parallel Extend Upper from Word
2154  * PEXTLW  rd, rs, rt        Parallel Extend Lower from Word
2155  *
2156  *     Others (16 instructions)
2157  *     ------------------------
2158  * PCPYH   rd, rt            Parallel Copy Halfword
2159  * PCPYLD  rd, rs, rt        Parallel Copy Lower Doubleword
2160  * PCPYUD  rd, rs, rt        Parallel Copy Upper Doubleword
2161  * PREVH   rd, rt            Parallel Reverse Halfword
2162  * PINTH   rd, rs, rt        Parallel Interleave Halfword
2163  * PINTEH  rd, rs, rt        Parallel Interleave Even Halfword
2164  * PEXEH   rd, rt            Parallel Exchange Even Halfword
2165  * PEXCH   rd, rt            Parallel Exchange Center Halfword
2166  * PEXEW   rd, rt            Parallel Exchange Even Word
2167  * PEXCW   rd, rt            Parallel Exchange Center Word
2168  * QFSRV   rd, rs, rt        Quadword Funnel Shift Right Variable
2169  * MFSA    rd                Move from Shift Amount Register
2170  * MTSA    rs                Move to Shift Amount Register
2171  * MTSAB   rs, immediate     Move Byte Count to Shift Amount Register
2172  * MTSAH   rs, immediate     Move Halfword Count to Shift Amount Register
2173  * PROT3W  rd, rt            Parallel Rotate 3 Words
2174  *
2175  *     MMI (MultiMedia Instruction) encodings
2176  *     ======================================
2177  *
2178  * MMI instructions encoding table keys:
2179  *
2180  *     *   This code is reserved for future use. An attempt to execute it
2181  *         causes a Reserved Instruction exception.
2182  *     %   This code indicates an instruction class. The instruction word
2183  *         must be further decoded by examining additional tables that show
2184  *         the values for other instruction fields.
2185  *     #   This code is reserved for the unsupported instructions DMULT,
2186  *         DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
2187  *         to execute it causes a Reserved Instruction exception.
2188  *
2189  * MMI instructions encoded by opcode field (MMI, LQ, SQ):
2190  *
2191  *  31    26                                        0
2192  * +--------+----------------------------------------+
2193  * | opcode |                                        |
2194  * +--------+----------------------------------------+
2195  *
2196  *   opcode  bits 28..26
2197  *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
2198  *   31..29 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
2199  *   -------+-------+-------+-------+-------+-------+-------+-------+-------
2200  *    0 000 |SPECIAL| REGIMM|   J   |  JAL  |  BEQ  |  BNE  |  BLEZ |  BGTZ
2201  *    1 001 |  ADDI | ADDIU |  SLTI | SLTIU |  ANDI |  ORI  |  XORI |  LUI
2202  *    2 010 |  COP0 |  COP1 |   *   |   *   |  BEQL |  BNEL | BLEZL | BGTZL
2203  *    3 011 | DADDI | DADDIU|  LDL  |  LDR  |  MMI% |   *   |   LQ  |   SQ
2204  *    4 100 |   LB  |   LH  |  LWL  |   LW  |  LBU  |  LHU  |  LWR  |  LWU
2205  *    5 101 |   SB  |   SH  |  SWL  |   SW  |  SDL  |  SDR  |  SWR  | CACHE
2206  *    6 110 |   #   |  LWC1 |   #   |  PREF |   #   |  LDC1 |   #   |   LD
2207  *    7 111 |   #   |  SWC1 |   #   |   *   |   #   |  SDC1 |   #   |   SD
2208  */
2209
2210 enum {
2211     MMI_OPC_CLASS_MMI = 0x1C << 26,    /* Same as OPC_SPECIAL2 */
2212     MMI_OPC_LQ        = 0x1E << 26,    /* Same as OPC_MSA */
2213     MMI_OPC_SQ        = 0x1F << 26,    /* Same as OPC_SPECIAL3 */
2214 };
2215
2216 /*
2217  * MMI instructions with opcode field = MMI:
2218  *
2219  *  31    26                                 5      0
2220  * +--------+-------------------------------+--------+
2221  * |   MMI  |                               |function|
2222  * +--------+-------------------------------+--------+
2223  *
2224  * function  bits 2..0
2225  *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
2226  *     5..3 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
2227  *   -------+-------+-------+-------+-------+-------+-------+-------+-------
2228  *    0 000 |  MADD | MADDU |   *   |   *   | PLZCW |   *   |   *   |   *
2229  *    1 001 | MMI0% | MMI2% |   *   |   *   |   *   |   *   |   *   |   *
2230  *    2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 |   *   |   *   |   *   |   *
2231  *    3 011 | MULT1 | MULTU1|  DIV1 | DIVU1 |   *   |   *   |   *   |   *
2232  *    4 100 | MADD1 | MADDU1|   *   |   *   |   *   |   *   |   *   |   *
2233  *    5 101 | MMI1% | MMI3% |   *   |   *   |   *   |   *   |   *   |   *
2234  *    6 110 | PMFHL | PMTHL |   *   |   *   | PSLLH |   *   | PSRLH | PSRAH
2235  *    7 111 |   *   |   *   |   *   |   *   | PSLLW |   *   | PSRLW | PSRAW
2236  */
2237
2238 #define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
2239 enum {
2240     MMI_OPC_MADD       = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
2241     MMI_OPC_MADDU      = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
2242     MMI_OPC_PLZCW      = 0x04 | MMI_OPC_CLASS_MMI,
2243     MMI_OPC_CLASS_MMI0 = 0x08 | MMI_OPC_CLASS_MMI,
2244     MMI_OPC_CLASS_MMI2 = 0x09 | MMI_OPC_CLASS_MMI,
2245     MMI_OPC_MFHI1      = 0x10 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFHI */
2246     MMI_OPC_MTHI1      = 0x11 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTHI */
2247     MMI_OPC_MFLO1      = 0x12 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MFLO */
2248     MMI_OPC_MTLO1      = 0x13 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MTLO */
2249     MMI_OPC_MULT1      = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
2250     MMI_OPC_MULTU1     = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
2251     MMI_OPC_DIV1       = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV  */
2252     MMI_OPC_DIVU1      = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
2253     MMI_OPC_MADD1      = 0x20 | MMI_OPC_CLASS_MMI,
2254     MMI_OPC_MADDU1     = 0x21 | MMI_OPC_CLASS_MMI,
2255     MMI_OPC_CLASS_MMI1 = 0x28 | MMI_OPC_CLASS_MMI,
2256     MMI_OPC_CLASS_MMI3 = 0x29 | MMI_OPC_CLASS_MMI,
2257     MMI_OPC_PMFHL      = 0x30 | MMI_OPC_CLASS_MMI,
2258     MMI_OPC_PMTHL      = 0x31 | MMI_OPC_CLASS_MMI,
2259     MMI_OPC_PSLLH      = 0x34 | MMI_OPC_CLASS_MMI,
2260     MMI_OPC_PSRLH      = 0x36 | MMI_OPC_CLASS_MMI,
2261     MMI_OPC_PSRAH      = 0x37 | MMI_OPC_CLASS_MMI,
2262     MMI_OPC_PSLLW      = 0x3C | MMI_OPC_CLASS_MMI,
2263     MMI_OPC_PSRLW      = 0x3E | MMI_OPC_CLASS_MMI,
2264     MMI_OPC_PSRAW      = 0x3F | MMI_OPC_CLASS_MMI,
2265 };
2266
2267 /*
2268  * MMI instructions with opcode field = MMI and bits 5..0 = MMI0:
2269  *
2270  *  31    26                        10     6 5      0
2271  * +--------+----------------------+--------+--------+
2272  * |   MMI  |                      |function|  MMI0  |
2273  * +--------+----------------------+--------+--------+
2274  *
2275  * function  bits 7..6
2276  *     bits |   0   |   1   |   2   |   3
2277  *    10..8 |   00  |   01  |   10  |   11
2278  *   -------+-------+-------+-------+-------
2279  *    0 000 | PADDW | PSUBW | PCGTW | PMAXW
2280  *    1 001 | PADDH | PSUBH | PCGTH | PMAXH
2281  *    2 010 | PADDB | PSUBB | PCGTB |   *
2282  *    3 011 |   *   |   *   |   *   |   *
2283  *    4 100 | PADDSW| PSUBSW| PEXTLW| PPACW
2284  *    5 101 | PADDSH| PSUBSH| PEXTLH| PPACH
2285  *    6 110 | PADDSB| PSUBSB| PEXTLB| PPACB
2286  *    7 111 |   *   |   *   | PEXT5 | PPAC5
2287  */
2288
2289 #define MASK_MMI0(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2290 enum {
2291     MMI_OPC_0_PADDW  = (0x00 << 6) | MMI_OPC_CLASS_MMI0,
2292     MMI_OPC_0_PSUBW  = (0x01 << 6) | MMI_OPC_CLASS_MMI0,
2293     MMI_OPC_0_PCGTW  = (0x02 << 6) | MMI_OPC_CLASS_MMI0,
2294     MMI_OPC_0_PMAXW  = (0x03 << 6) | MMI_OPC_CLASS_MMI0,
2295     MMI_OPC_0_PADDH  = (0x04 << 6) | MMI_OPC_CLASS_MMI0,
2296     MMI_OPC_0_PSUBH  = (0x05 << 6) | MMI_OPC_CLASS_MMI0,
2297     MMI_OPC_0_PCGTH  = (0x06 << 6) | MMI_OPC_CLASS_MMI0,
2298     MMI_OPC_0_PMAXH  = (0x07 << 6) | MMI_OPC_CLASS_MMI0,
2299     MMI_OPC_0_PADDB  = (0x08 << 6) | MMI_OPC_CLASS_MMI0,
2300     MMI_OPC_0_PSUBB  = (0x09 << 6) | MMI_OPC_CLASS_MMI0,
2301     MMI_OPC_0_PCGTB  = (0x0A << 6) | MMI_OPC_CLASS_MMI0,
2302     MMI_OPC_0_PADDSW = (0x10 << 6) | MMI_OPC_CLASS_MMI0,
2303     MMI_OPC_0_PSUBSW = (0x11 << 6) | MMI_OPC_CLASS_MMI0,
2304     MMI_OPC_0_PEXTLW = (0x12 << 6) | MMI_OPC_CLASS_MMI0,
2305     MMI_OPC_0_PPACW  = (0x13 << 6) | MMI_OPC_CLASS_MMI0,
2306     MMI_OPC_0_PADDSH = (0x14 << 6) | MMI_OPC_CLASS_MMI0,
2307     MMI_OPC_0_PSUBSH = (0x15 << 6) | MMI_OPC_CLASS_MMI0,
2308     MMI_OPC_0_PEXTLH = (0x16 << 6) | MMI_OPC_CLASS_MMI0,
2309     MMI_OPC_0_PPACH  = (0x17 << 6) | MMI_OPC_CLASS_MMI0,
2310     MMI_OPC_0_PADDSB = (0x18 << 6) | MMI_OPC_CLASS_MMI0,
2311     MMI_OPC_0_PSUBSB = (0x19 << 6) | MMI_OPC_CLASS_MMI0,
2312     MMI_OPC_0_PEXTLB = (0x1A << 6) | MMI_OPC_CLASS_MMI0,
2313     MMI_OPC_0_PPACB  = (0x1B << 6) | MMI_OPC_CLASS_MMI0,
2314     MMI_OPC_0_PEXT5  = (0x1E << 6) | MMI_OPC_CLASS_MMI0,
2315     MMI_OPC_0_PPAC5  = (0x1F << 6) | MMI_OPC_CLASS_MMI0,
2316 };
2317
2318 /*
2319  * MMI instructions with opcode field = MMI and bits 5..0 = MMI1:
2320  *
2321  *  31    26                        10     6 5      0
2322  * +--------+----------------------+--------+--------+
2323  * |   MMI  |                      |function|  MMI1  |
2324  * +--------+----------------------+--------+--------+
2325  *
2326  * function  bits 7..6
2327  *     bits |   0   |   1   |   2   |   3
2328  *    10..8 |   00  |   01  |   10  |   11
2329  *   -------+-------+-------+-------+-------
2330  *    0 000 |   *   | PABSW | PCEQW | PMINW
2331  *    1 001 | PADSBH| PABSH | PCEQH | PMINH
2332  *    2 010 |   *   |   *   | PCEQB |   *
2333  *    3 011 |   *   |   *   |   *   |   *
2334  *    4 100 | PADDUW| PSUBUW| PEXTUW|   *
2335  *    5 101 | PADDUH| PSUBUH| PEXTUH|   *
2336  *    6 110 | PADDUB| PSUBUB| PEXTUB| QFSRV
2337  *    7 111 |   *   |   *   |   *   |   *
2338  */
2339
2340 #define MASK_MMI1(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2341 enum {
2342     MMI_OPC_1_PABSW  = (0x01 << 6) | MMI_OPC_CLASS_MMI1,
2343     MMI_OPC_1_PCEQW  = (0x02 << 6) | MMI_OPC_CLASS_MMI1,
2344     MMI_OPC_1_PMINW  = (0x03 << 6) | MMI_OPC_CLASS_MMI1,
2345     MMI_OPC_1_PADSBH = (0x04 << 6) | MMI_OPC_CLASS_MMI1,
2346     MMI_OPC_1_PABSH  = (0x05 << 6) | MMI_OPC_CLASS_MMI1,
2347     MMI_OPC_1_PCEQH  = (0x06 << 6) | MMI_OPC_CLASS_MMI1,
2348     MMI_OPC_1_PMINH  = (0x07 << 6) | MMI_OPC_CLASS_MMI1,
2349     MMI_OPC_1_PCEQB  = (0x0A << 6) | MMI_OPC_CLASS_MMI1,
2350     MMI_OPC_1_PADDUW = (0x10 << 6) | MMI_OPC_CLASS_MMI1,
2351     MMI_OPC_1_PSUBUW = (0x11 << 6) | MMI_OPC_CLASS_MMI1,
2352     MMI_OPC_1_PEXTUW = (0x12 << 6) | MMI_OPC_CLASS_MMI1,
2353     MMI_OPC_1_PADDUH = (0x14 << 6) | MMI_OPC_CLASS_MMI1,
2354     MMI_OPC_1_PSUBUH = (0x15 << 6) | MMI_OPC_CLASS_MMI1,
2355     MMI_OPC_1_PEXTUH = (0x16 << 6) | MMI_OPC_CLASS_MMI1,
2356     MMI_OPC_1_PADDUB = (0x18 << 6) | MMI_OPC_CLASS_MMI1,
2357     MMI_OPC_1_PSUBUB = (0x19 << 6) | MMI_OPC_CLASS_MMI1,
2358     MMI_OPC_1_PEXTUB = (0x1A << 6) | MMI_OPC_CLASS_MMI1,
2359     MMI_OPC_1_QFSRV  = (0x1B << 6) | MMI_OPC_CLASS_MMI1,
2360 };
2361
2362 /*
2363  * MMI instructions with opcode field = MMI and bits 5..0 = MMI2:
2364  *
2365  *  31    26                        10     6 5      0
2366  * +--------+----------------------+--------+--------+
2367  * |   MMI  |                      |function|  MMI2  |
2368  * +--------+----------------------+--------+--------+
2369  *
2370  * function  bits 7..6
2371  *     bits |   0   |   1   |   2   |   3
2372  *    10..8 |   00  |   01  |   10  |   11
2373  *   -------+-------+-------+-------+-------
2374  *    0 000 | PMADDW|   *   | PSLLVW| PSRLVW
2375  *    1 001 | PMSUBW|   *   |   *   |   *
2376  *    2 010 | PMFHI | PMFLO | PINTH |   *
2377  *    3 011 | PMULTW| PDIVW | PCPYLD|   *
2378  *    4 100 | PMADDH| PHMADH|  PAND |  PXOR
2379  *    5 101 | PMSUBH| PHMSBH|   *   |   *
2380  *    6 110 |   *   |   *   | PEXEH | PREVH
2381  *    7 111 | PMULTH| PDIVBW| PEXEW | PROT3W
2382  */
2383
2384 #define MASK_MMI2(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2385 enum {
2386     MMI_OPC_2_PMADDW = (0x00 << 6) | MMI_OPC_CLASS_MMI2,
2387     MMI_OPC_2_PSLLVW = (0x02 << 6) | MMI_OPC_CLASS_MMI2,
2388     MMI_OPC_2_PSRLVW = (0x03 << 6) | MMI_OPC_CLASS_MMI2,
2389     MMI_OPC_2_PMSUBW = (0x04 << 6) | MMI_OPC_CLASS_MMI2,
2390     MMI_OPC_2_PMFHI  = (0x08 << 6) | MMI_OPC_CLASS_MMI2,
2391     MMI_OPC_2_PMFLO  = (0x09 << 6) | MMI_OPC_CLASS_MMI2,
2392     MMI_OPC_2_PINTH  = (0x0A << 6) | MMI_OPC_CLASS_MMI2,
2393     MMI_OPC_2_PMULTW = (0x0C << 6) | MMI_OPC_CLASS_MMI2,
2394     MMI_OPC_2_PDIVW  = (0x0D << 6) | MMI_OPC_CLASS_MMI2,
2395     MMI_OPC_2_PCPYLD = (0x0E << 6) | MMI_OPC_CLASS_MMI2,
2396     MMI_OPC_2_PMADDH = (0x10 << 6) | MMI_OPC_CLASS_MMI2,
2397     MMI_OPC_2_PHMADH = (0x11 << 6) | MMI_OPC_CLASS_MMI2,
2398     MMI_OPC_2_PAND   = (0x12 << 6) | MMI_OPC_CLASS_MMI2,
2399     MMI_OPC_2_PXOR   = (0x13 << 6) | MMI_OPC_CLASS_MMI2,
2400     MMI_OPC_2_PMSUBH = (0x14 << 6) | MMI_OPC_CLASS_MMI2,
2401     MMI_OPC_2_PHMSBH = (0x15 << 6) | MMI_OPC_CLASS_MMI2,
2402     MMI_OPC_2_PEXEH  = (0x1A << 6) | MMI_OPC_CLASS_MMI2,
2403     MMI_OPC_2_PREVH  = (0x1B << 6) | MMI_OPC_CLASS_MMI2,
2404     MMI_OPC_2_PMULTH = (0x1C << 6) | MMI_OPC_CLASS_MMI2,
2405     MMI_OPC_2_PDIVBW = (0x1D << 6) | MMI_OPC_CLASS_MMI2,
2406     MMI_OPC_2_PEXEW  = (0x1E << 6) | MMI_OPC_CLASS_MMI2,
2407     MMI_OPC_2_PROT3W = (0x1F << 6) | MMI_OPC_CLASS_MMI2,
2408 };
2409
2410 /*
2411  * MMI instructions with opcode field = MMI and bits 5..0 = MMI3:
2412  *
2413  *  31    26                        10     6 5      0
2414  * +--------+----------------------+--------+--------+
2415  * |   MMI  |                      |function|  MMI3  |
2416  * +--------+----------------------+--------+--------+
2417  *
2418  * function  bits 7..6
2419  *     bits |   0   |   1   |   2   |   3
2420  *    10..8 |   00  |   01  |   10  |   11
2421  *   -------+-------+-------+-------+-------
2422  *    0 000 |PMADDUW|   *   |   *   | PSRAVW
2423  *    1 001 |   *   |   *   |   *   |   *
2424  *    2 010 | PMTHI | PMTLO | PINTEH|   *
2425  *    3 011 |PMULTUW| PDIVUW| PCPYUD|   *
2426  *    4 100 |   *   |   *   |  POR  |  PNOR
2427  *    5 101 |   *   |   *   |   *   |   *
2428  *    6 110 |   *   |   *   | PEXCH | PCPYH
2429  *    7 111 |   *   |   *   | PEXCW |   *
2430  */
2431
2432 #define MASK_MMI3(op) (MASK_OP_MAJOR(op) | ((op) & 0x7FF))
2433 enum {
2434     MMI_OPC_3_PMADDUW = (0x00 << 6) | MMI_OPC_CLASS_MMI3,
2435     MMI_OPC_3_PSRAVW  = (0x03 << 6) | MMI_OPC_CLASS_MMI3,
2436     MMI_OPC_3_PMTHI   = (0x08 << 6) | MMI_OPC_CLASS_MMI3,
2437     MMI_OPC_3_PMTLO   = (0x09 << 6) | MMI_OPC_CLASS_MMI3,
2438     MMI_OPC_3_PINTEH  = (0x0A << 6) | MMI_OPC_CLASS_MMI3,
2439     MMI_OPC_3_PMULTUW = (0x0C << 6) | MMI_OPC_CLASS_MMI3,
2440     MMI_OPC_3_PDIVUW  = (0x0D << 6) | MMI_OPC_CLASS_MMI3,
2441     MMI_OPC_3_PCPYUD  = (0x0E << 6) | MMI_OPC_CLASS_MMI3,
2442     MMI_OPC_3_POR     = (0x12 << 6) | MMI_OPC_CLASS_MMI3,
2443     MMI_OPC_3_PNOR    = (0x13 << 6) | MMI_OPC_CLASS_MMI3,
2444     MMI_OPC_3_PEXCH   = (0x1A << 6) | MMI_OPC_CLASS_MMI3,
2445     MMI_OPC_3_PCPYH   = (0x1B << 6) | MMI_OPC_CLASS_MMI3,
2446     MMI_OPC_3_PEXCW   = (0x1E << 6) | MMI_OPC_CLASS_MMI3,
2447 };
2448
2449 /* global register indices */
2450 static TCGv cpu_gpr[32], cpu_PC;
2451 static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
2452 static TCGv cpu_dspctrl, btarget, bcond;
2453 static TCGv cpu_lladdr, cpu_llval;
2454 static TCGv_i32 hflags;
2455 static TCGv_i32 fpu_fcr0, fpu_fcr31;
2456 static TCGv_i64 fpu_f64[32];
2457 static TCGv_i64 msa_wr_d[64];
2458
2459 #if defined(TARGET_MIPS64)
2460 /* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */
2461 static TCGv_i64 cpu_mmr[32];
2462 #endif
2463
2464 #if !defined(TARGET_MIPS64)
2465 /* MXU registers */
2466 static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
2467 static TCGv mxu_CR;
2468 #endif
2469
2470 #include "exec/gen-icount.h"
2471
2472 #define gen_helper_0e0i(name, arg) do {                           \
2473     TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
2474     gen_helper_##name(cpu_env, helper_tmp);                       \
2475     tcg_temp_free_i32(helper_tmp);                                \
2476     } while(0)
2477
2478 #define gen_helper_0e1i(name, arg1, arg2) do {                    \
2479     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
2480     gen_helper_##name(cpu_env, arg1, helper_tmp);                 \
2481     tcg_temp_free_i32(helper_tmp);                                \
2482     } while(0)
2483
2484 #define gen_helper_1e0i(name, ret, arg1) do {                     \
2485     TCGv_i32 helper_tmp = tcg_const_i32(arg1);                    \
2486     gen_helper_##name(ret, cpu_env, helper_tmp);                  \
2487     tcg_temp_free_i32(helper_tmp);                                \
2488     } while(0)
2489
2490 #define gen_helper_1e1i(name, ret, arg1, arg2) do {               \
2491     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
2492     gen_helper_##name(ret, cpu_env, arg1, helper_tmp);            \
2493     tcg_temp_free_i32(helper_tmp);                                \
2494     } while(0)
2495
2496 #define gen_helper_0e2i(name, arg1, arg2, arg3) do {              \
2497     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
2498     gen_helper_##name(cpu_env, arg1, arg2, helper_tmp);           \
2499     tcg_temp_free_i32(helper_tmp);                                \
2500     } while(0)
2501
2502 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do {         \
2503     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
2504     gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp);      \
2505     tcg_temp_free_i32(helper_tmp);                                \
2506     } while(0)
2507
2508 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do {        \
2509     TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
2510     gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp);     \
2511     tcg_temp_free_i32(helper_tmp);                                \
2512     } while(0)
2513
2514 typedef struct DisasContext {
2515     DisasContextBase base;
2516     target_ulong saved_pc;
2517     target_ulong page_start;
2518     uint32_t opcode;
2519     uint64_t insn_flags;
2520     int32_t CP0_Config1;
2521     int32_t CP0_Config2;
2522     int32_t CP0_Config3;
2523     int32_t CP0_Config5;
2524     /* Routine used to access memory */
2525     int mem_idx;
2526     TCGMemOp default_tcg_memop_mask;
2527     uint32_t hflags, saved_hflags;
2528     target_ulong btarget;
2529     bool ulri;
2530     int kscrexist;
2531     bool rxi;
2532     int ie;
2533     bool bi;
2534     bool bp;
2535     uint64_t PAMask;
2536     bool mvh;
2537     bool eva;
2538     bool sc;
2539     int CP0_LLAddr_shift;
2540     bool ps;
2541     bool vp;
2542     bool cmgcr;
2543     bool mrp;
2544     bool nan2008;
2545     bool abs2008;
2546     bool saar;
2547 } DisasContext;
2548
2549 #define DISAS_STOP       DISAS_TARGET_0
2550 #define DISAS_EXIT       DISAS_TARGET_1
2551
2552 static const char * const regnames[] = {
2553     "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2554     "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2555     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2556     "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2557 };
2558
2559 static const char * const regnames_HI[] = {
2560     "HI0", "HI1", "HI2", "HI3",
2561 };
2562
2563 static const char * const regnames_LO[] = {
2564     "LO0", "LO1", "LO2", "LO3",
2565 };
2566
2567 static const char * const fregnames[] = {
2568     "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
2569     "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
2570     "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2571     "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2572 };
2573
2574 static const char * const msaregnames[] = {
2575     "w0.d0",  "w0.d1",  "w1.d0",  "w1.d1",
2576     "w2.d0",  "w2.d1",  "w3.d0",  "w3.d1",
2577     "w4.d0",  "w4.d1",  "w5.d0",  "w5.d1",
2578     "w6.d0",  "w6.d1",  "w7.d0",  "w7.d1",
2579     "w8.d0",  "w8.d1",  "w9.d0",  "w9.d1",
2580     "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2581     "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2582     "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2583     "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2584     "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2585     "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2586     "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2587     "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2588     "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2589     "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2590     "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2591 };
2592
2593 #if !defined(TARGET_MIPS64)
2594 static const char * const mxuregnames[] = {
2595     "XR1",  "XR2",  "XR3",  "XR4",  "XR5",  "XR6",  "XR7",  "XR8",
2596     "XR9",  "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2597 };
2598 #endif
2599
2600 #define LOG_DISAS(...)                                                        \
2601     do {                                                                      \
2602         if (MIPS_DEBUG_DISAS) {                                               \
2603             qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
2604         }                                                                     \
2605     } while (0)
2606
2607 #define MIPS_INVAL(op)                                                        \
2608     do {                                                                      \
2609         if (MIPS_DEBUG_DISAS) {                                               \
2610             qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
2611                           TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2612                           ctx->base.pc_next, ctx->opcode, op,                 \
2613                           ctx->opcode >> 26, ctx->opcode & 0x3F,              \
2614                           ((ctx->opcode >> 16) & 0x1F));                      \
2615         }                                                                     \
2616     } while (0)
2617
2618 /* General purpose registers moves. */
2619 static inline void gen_load_gpr (TCGv t, int reg)
2620 {
2621     if (reg == 0)
2622         tcg_gen_movi_tl(t, 0);
2623     else
2624         tcg_gen_mov_tl(t, cpu_gpr[reg]);
2625 }
2626
2627 static inline void gen_store_gpr (TCGv t, int reg)
2628 {
2629     if (reg != 0)
2630         tcg_gen_mov_tl(cpu_gpr[reg], t);
2631 }
2632
2633 /* Moves to/from shadow registers. */
2634 static inline void gen_load_srsgpr (int from, int to)
2635 {
2636     TCGv t0 = tcg_temp_new();
2637
2638     if (from == 0)
2639         tcg_gen_movi_tl(t0, 0);
2640     else {
2641         TCGv_i32 t2 = tcg_temp_new_i32();
2642         TCGv_ptr addr = tcg_temp_new_ptr();
2643
2644         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2645         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2646         tcg_gen_andi_i32(t2, t2, 0xf);
2647         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2648         tcg_gen_ext_i32_ptr(addr, t2);
2649         tcg_gen_add_ptr(addr, cpu_env, addr);
2650
2651         tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2652         tcg_temp_free_ptr(addr);
2653         tcg_temp_free_i32(t2);
2654     }
2655     gen_store_gpr(t0, to);
2656     tcg_temp_free(t0);
2657 }
2658
2659 static inline void gen_store_srsgpr (int from, int to)
2660 {
2661     if (to != 0) {
2662         TCGv t0 = tcg_temp_new();
2663         TCGv_i32 t2 = tcg_temp_new_i32();
2664         TCGv_ptr addr = tcg_temp_new_ptr();
2665
2666         gen_load_gpr(t0, from);
2667         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2668         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2669         tcg_gen_andi_i32(t2, t2, 0xf);
2670         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2671         tcg_gen_ext_i32_ptr(addr, t2);
2672         tcg_gen_add_ptr(addr, cpu_env, addr);
2673
2674         tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2675         tcg_temp_free_ptr(addr);
2676         tcg_temp_free_i32(t2);
2677         tcg_temp_free(t0);
2678     }
2679 }
2680
2681 #if !defined(TARGET_MIPS64)
2682 /* MXU General purpose registers moves. */
2683 static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
2684 {
2685     if (reg == 0) {
2686         tcg_gen_movi_tl(t, 0);
2687     } else if (reg <= 15) {
2688         tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
2689     }
2690 }
2691
2692 static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
2693 {
2694     if (reg > 0 && reg <= 15) {
2695         tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
2696     }
2697 }
2698
2699 /* MXU control register moves. */
2700 static inline void gen_load_mxu_cr(TCGv t)
2701 {
2702     tcg_gen_mov_tl(t, mxu_CR);
2703 }
2704
2705 static inline void gen_store_mxu_cr(TCGv t)
2706 {
2707     /* TODO: Add handling of RW rules for MXU_CR. */
2708     tcg_gen_mov_tl(mxu_CR, t);
2709 }
2710 #endif
2711
2712
2713 /* Tests */
2714 static inline void gen_save_pc(target_ulong pc)
2715 {
2716     tcg_gen_movi_tl(cpu_PC, pc);
2717 }
2718
2719 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2720 {
2721     LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2722     if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2723         gen_save_pc(ctx->base.pc_next);
2724         ctx->saved_pc = ctx->base.pc_next;
2725     }
2726     if (ctx->hflags != ctx->saved_hflags) {
2727         tcg_gen_movi_i32(hflags, ctx->hflags);
2728         ctx->saved_hflags = ctx->hflags;
2729         switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2730         case MIPS_HFLAG_BR:
2731             break;
2732         case MIPS_HFLAG_BC:
2733         case MIPS_HFLAG_BL:
2734         case MIPS_HFLAG_B:
2735             tcg_gen_movi_tl(btarget, ctx->btarget);
2736             break;
2737         }
2738     }
2739 }
2740
2741 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2742 {
2743     ctx->saved_hflags = ctx->hflags;
2744     switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2745     case MIPS_HFLAG_BR:
2746         break;
2747     case MIPS_HFLAG_BC:
2748     case MIPS_HFLAG_BL:
2749     case MIPS_HFLAG_B:
2750         ctx->btarget = env->btarget;
2751         break;
2752     }
2753 }
2754
2755 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2756 {
2757     TCGv_i32 texcp = tcg_const_i32(excp);
2758     TCGv_i32 terr = tcg_const_i32(err);
2759     save_cpu_state(ctx, 1);
2760     gen_helper_raise_exception_err(cpu_env, texcp, terr);
2761     tcg_temp_free_i32(terr);
2762     tcg_temp_free_i32(texcp);
2763     ctx->base.is_jmp = DISAS_NORETURN;
2764 }
2765
2766 static inline void generate_exception(DisasContext *ctx, int excp)
2767 {
2768     gen_helper_0e0i(raise_exception, excp);
2769 }
2770
2771 static inline void generate_exception_end(DisasContext *ctx, int excp)
2772 {
2773     generate_exception_err(ctx, excp, 0);
2774 }
2775
2776 /* Floating point register moves. */
2777 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2778 {
2779     if (ctx->hflags & MIPS_HFLAG_FRE) {
2780         generate_exception(ctx, EXCP_RI);
2781     }
2782     tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2783 }
2784
2785 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2786 {
2787     TCGv_i64 t64;
2788     if (ctx->hflags & MIPS_HFLAG_FRE) {
2789         generate_exception(ctx, EXCP_RI);
2790     }
2791     t64 = tcg_temp_new_i64();
2792     tcg_gen_extu_i32_i64(t64, t);
2793     tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2794     tcg_temp_free_i64(t64);
2795 }
2796
2797 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2798 {
2799     if (ctx->hflags & MIPS_HFLAG_F64) {
2800         tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2801     } else {
2802         gen_load_fpr32(ctx, t, reg | 1);
2803     }
2804 }
2805
2806 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2807 {
2808     if (ctx->hflags & MIPS_HFLAG_F64) {
2809         TCGv_i64 t64 = tcg_temp_new_i64();
2810         tcg_gen_extu_i32_i64(t64, t);
2811         tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2812         tcg_temp_free_i64(t64);
2813     } else {
2814         gen_store_fpr32(ctx, t, reg | 1);
2815     }
2816 }
2817
2818 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2819 {
2820     if (ctx->hflags & MIPS_HFLAG_F64) {
2821         tcg_gen_mov_i64(t, fpu_f64[reg]);
2822     } else {
2823         tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2824     }
2825 }
2826
2827 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2828 {
2829     if (ctx->hflags & MIPS_HFLAG_F64) {
2830         tcg_gen_mov_i64(fpu_f64[reg], t);
2831     } else {
2832         TCGv_i64 t0;
2833         tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2834         t0 = tcg_temp_new_i64();
2835         tcg_gen_shri_i64(t0, t, 32);
2836         tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2837         tcg_temp_free_i64(t0);
2838     }
2839 }
2840
2841 static inline int get_fp_bit (int cc)
2842 {
2843     if (cc)
2844         return 24 + cc;
2845     else
2846         return 23;
2847 }
2848
2849 /* Addresses computation */
2850 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
2851 {
2852     tcg_gen_add_tl(ret, arg0, arg1);
2853
2854 #if defined(TARGET_MIPS64)
2855     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2856         tcg_gen_ext32s_i64(ret, ret);
2857     }
2858 #endif
2859 }
2860
2861 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2862                                     target_long ofs)
2863 {
2864     tcg_gen_addi_tl(ret, base, ofs);
2865
2866 #if defined(TARGET_MIPS64)
2867     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2868         tcg_gen_ext32s_i64(ret, ret);
2869     }
2870 #endif
2871 }
2872
2873 /* Addresses computation (translation time) */
2874 static target_long addr_add(DisasContext *ctx, target_long base,
2875                             target_long offset)
2876 {
2877     target_long sum = base + offset;
2878
2879 #if defined(TARGET_MIPS64)
2880     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2881         sum = (int32_t)sum;
2882     }
2883 #endif
2884     return sum;
2885 }
2886
2887 /* Sign-extract the low 32-bits to a target_long.  */
2888 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2889 {
2890 #if defined(TARGET_MIPS64)
2891     tcg_gen_ext32s_i64(ret, arg);
2892 #else
2893     tcg_gen_extrl_i64_i32(ret, arg);
2894 #endif
2895 }
2896
2897 /* Sign-extract the high 32-bits to a target_long.  */
2898 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2899 {
2900 #if defined(TARGET_MIPS64)
2901     tcg_gen_sari_i64(ret, arg, 32);
2902 #else
2903     tcg_gen_extrh_i64_i32(ret, arg);
2904 #endif
2905 }
2906
2907 static inline void check_cp0_enabled(DisasContext *ctx)
2908 {
2909     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
2910         generate_exception_err(ctx, EXCP_CpU, 0);
2911 }
2912
2913 static inline void check_cp1_enabled(DisasContext *ctx)
2914 {
2915     if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
2916         generate_exception_err(ctx, EXCP_CpU, 1);
2917 }
2918
2919 /* Verify that the processor is running with COP1X instructions enabled.
2920    This is associated with the nabla symbol in the MIPS32 and MIPS64
2921    opcode tables.  */
2922
2923 static inline void check_cop1x(DisasContext *ctx)
2924 {
2925     if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
2926         generate_exception_end(ctx, EXCP_RI);
2927 }
2928
2929 /* Verify that the processor is running with 64-bit floating-point
2930    operations enabled.  */
2931
2932 static inline void check_cp1_64bitmode(DisasContext *ctx)
2933 {
2934     if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
2935         generate_exception_end(ctx, EXCP_RI);
2936 }
2937
2938 /*
2939  * Verify if floating point register is valid; an operation is not defined
2940  * if bit 0 of any register specification is set and the FR bit in the
2941  * Status register equals zero, since the register numbers specify an
2942  * even-odd pair of adjacent coprocessor general registers. When the FR bit
2943  * in the Status register equals one, both even and odd register numbers
2944  * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2945  *
2946  * Multiple 64 bit wide registers can be checked by calling
2947  * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2948  */
2949 static inline void check_cp1_registers(DisasContext *ctx, int regs)
2950 {
2951     if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
2952         generate_exception_end(ctx, EXCP_RI);
2953 }
2954
2955 /* Verify that the processor is running with DSP instructions enabled.
2956    This is enabled by CP0 Status register MX(24) bit.
2957  */
2958
2959 static inline void check_dsp(DisasContext *ctx)
2960 {
2961     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2962         if (ctx->insn_flags & ASE_DSP) {
2963             generate_exception_end(ctx, EXCP_DSPDIS);
2964         } else {
2965             generate_exception_end(ctx, EXCP_RI);
2966         }
2967     }
2968 }
2969
2970 static inline void check_dsp_r2(DisasContext *ctx)
2971 {
2972     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2973         if (ctx->insn_flags & ASE_DSP) {
2974             generate_exception_end(ctx, EXCP_DSPDIS);
2975         } else {
2976             generate_exception_end(ctx, EXCP_RI);
2977         }
2978     }
2979 }
2980
2981 static inline void check_dsp_r3(DisasContext *ctx)
2982 {
2983     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
2984         if (ctx->insn_flags & ASE_DSP) {
2985             generate_exception_end(ctx, EXCP_DSPDIS);
2986         } else {
2987             generate_exception_end(ctx, EXCP_RI);
2988         }
2989     }
2990 }
2991
2992 /* This code generates a "reserved instruction" exception if the
2993    CPU does not support the instruction set corresponding to flags. */
2994 static inline void check_insn(DisasContext *ctx, uint64_t flags)
2995 {
2996     if (unlikely(!(ctx->insn_flags & flags))) {
2997         generate_exception_end(ctx, EXCP_RI);
2998     }
2999 }
3000
3001 /* This code generates a "reserved instruction" exception if the
3002    CPU has corresponding flag set which indicates that the instruction
3003    has been removed. */
3004 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
3005 {
3006     if (unlikely(ctx->insn_flags & flags)) {
3007         generate_exception_end(ctx, EXCP_RI);
3008     }
3009 }
3010
3011 /*
3012  * The Linux kernel traps certain reserved instruction exceptions to
3013  * emulate the corresponding instructions. QEMU is the kernel in user
3014  * mode, so those traps are emulated by accepting the instructions.
3015  *
3016  * A reserved instruction exception is generated for flagged CPUs if
3017  * QEMU runs in system mode.
3018  */
3019 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
3020 {
3021 #ifndef CONFIG_USER_ONLY
3022     check_insn_opc_removed(ctx, flags);
3023 #endif
3024 }
3025
3026 /* This code generates a "reserved instruction" exception if the
3027    CPU does not support 64-bit paired-single (PS) floating point data type */
3028 static inline void check_ps(DisasContext *ctx)
3029 {
3030     if (unlikely(!ctx->ps)) {
3031         generate_exception(ctx, EXCP_RI);
3032     }
3033     check_cp1_64bitmode(ctx);
3034 }
3035
3036 #ifdef TARGET_MIPS64
3037 /* This code generates a "reserved instruction" exception if 64-bit
3038    instructions are not enabled. */
3039 static inline void check_mips_64(DisasContext *ctx)
3040 {
3041     if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
3042         generate_exception_end(ctx, EXCP_RI);
3043 }
3044 #endif
3045
3046 #ifndef CONFIG_USER_ONLY
3047 static inline void check_mvh(DisasContext *ctx)
3048 {
3049     if (unlikely(!ctx->mvh)) {
3050         generate_exception(ctx, EXCP_RI);
3051     }
3052 }
3053 #endif
3054
3055 /*
3056  * This code generates a "reserved instruction" exception if the
3057  * Config5 XNP bit is set.
3058  */
3059 static inline void check_xnp(DisasContext *ctx)
3060 {
3061     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
3062         generate_exception_end(ctx, EXCP_RI);
3063     }
3064 }
3065
3066 #ifndef CONFIG_USER_ONLY
3067 /*
3068  * This code generates a "reserved instruction" exception if the
3069  * Config3 PW bit is NOT set.
3070  */
3071 static inline void check_pw(DisasContext *ctx)
3072 {
3073     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
3074         generate_exception_end(ctx, EXCP_RI);
3075     }
3076 }
3077 #endif
3078
3079 /*
3080  * This code generates a "reserved instruction" exception if the
3081  * Config3 MT bit is NOT set.
3082  */
3083 static inline void check_mt(DisasContext *ctx)
3084 {
3085     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3086         generate_exception_end(ctx, EXCP_RI);
3087     }
3088 }
3089
3090 #ifndef CONFIG_USER_ONLY
3091 /*
3092  * This code generates a "coprocessor unusable" exception if CP0 is not
3093  * available, and, if that is not the case, generates a "reserved instruction"
3094  * exception if the Config5 MT bit is NOT set. This is needed for availability
3095  * control of some of MT ASE instructions.
3096  */
3097 static inline void check_cp0_mt(DisasContext *ctx)
3098 {
3099     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
3100         generate_exception_err(ctx, EXCP_CpU, 0);
3101     } else {
3102         if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3103             generate_exception_err(ctx, EXCP_RI, 0);
3104         }
3105     }
3106 }
3107 #endif
3108
3109 /*
3110  * This code generates a "reserved instruction" exception if the
3111  * Config5 NMS bit is set.
3112  */
3113 static inline void check_nms(DisasContext *ctx)
3114 {
3115     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3116         generate_exception_end(ctx, EXCP_RI);
3117     }
3118 }
3119
3120 /*
3121  * This code generates a "reserved instruction" exception if the
3122  * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3123  * Config2 TL, and Config5 L2C are unset.
3124  */
3125 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
3126 {
3127     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
3128         !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
3129         !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
3130         !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
3131         !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
3132         !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))
3133     {
3134         generate_exception_end(ctx, EXCP_RI);
3135     }
3136 }
3137
3138 /*
3139  * This code generates a "reserved instruction" exception if the
3140  * Config5 EVA bit is NOT set.
3141  */
3142 static inline void check_eva(DisasContext *ctx)
3143 {
3144     if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3145         generate_exception_end(ctx, EXCP_RI);
3146     }
3147 }
3148
3149
3150 /* Define small wrappers for gen_load_fpr* so that we have a uniform
3151    calling interface for 32 and 64-bit FPRs.  No sense in changing
3152    all callers for gen_load_fpr32 when we need the CTX parameter for
3153    this one use.  */
3154 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3155 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3156 #define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
3157 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
3158                                                int ft, int fs, int cc)        \
3159 {                                                                             \
3160     TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
3161     TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
3162     switch (ifmt) {                                                           \
3163     case FMT_PS:                                                              \
3164         check_ps(ctx);                                                        \
3165         break;                                                                \
3166     case FMT_D:                                                               \
3167         if (abs) {                                                            \
3168             check_cop1x(ctx);                                                 \
3169         }                                                                     \
3170         check_cp1_registers(ctx, fs | ft);                                    \
3171         break;                                                                \
3172     case FMT_S:                                                               \
3173         if (abs) {                                                            \
3174             check_cop1x(ctx);                                                 \
3175         }                                                                     \
3176         break;                                                                \
3177     }                                                                         \
3178     gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
3179     gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
3180     switch (n) {                                                              \
3181     case  0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
3182     case  1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
3183     case  2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
3184     case  3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
3185     case  4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
3186     case  5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
3187     case  6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
3188     case  7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
3189     case  8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
3190     case  9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
3191     case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
3192     case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
3193     case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
3194     case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
3195     case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
3196     case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
3197     default: abort();                                                         \
3198     }                                                                         \
3199     tcg_temp_free_i##bits (fp0);                                              \
3200     tcg_temp_free_i##bits (fp1);                                              \
3201 }
3202
3203 FOP_CONDS(, 0, d, FMT_D, 64)
3204 FOP_CONDS(abs, 1, d, FMT_D, 64)
3205 FOP_CONDS(, 0, s, FMT_S, 32)
3206 FOP_CONDS(abs, 1, s, FMT_S, 32)
3207 FOP_CONDS(, 0, ps, FMT_PS, 64)
3208 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3209 #undef FOP_CONDS
3210
3211 #define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
3212 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n,        \
3213                                       int ft, int fs, int fd)           \
3214 {                                                                       \
3215     TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
3216     TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
3217     if (ifmt == FMT_D) {                                                \
3218         check_cp1_registers(ctx, fs | ft | fd);                         \
3219     }                                                                   \
3220     gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
3221     gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
3222     switch (n) {                                                        \
3223     case  0:                                                            \
3224         gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
3225         break;                                                          \
3226     case  1:                                                            \
3227         gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
3228         break;                                                          \
3229     case  2:                                                            \
3230         gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
3231         break;                                                          \
3232     case  3:                                                            \
3233         gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
3234         break;                                                          \
3235     case  4:                                                            \
3236         gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
3237         break;                                                          \
3238     case  5:                                                            \
3239         gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
3240         break;                                                          \
3241     case  6:                                                            \
3242         gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
3243         break;                                                          \
3244     case  7:                                                            \
3245         gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
3246         break;                                                          \
3247     case  8:                                                            \
3248         gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
3249         break;                                                          \
3250     case  9:                                                            \
3251         gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
3252         break;                                                          \
3253     case 10:                                                            \
3254         gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
3255         break;                                                          \
3256     case 11:                                                            \
3257         gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
3258         break;                                                          \
3259     case 12:                                                            \
3260         gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
3261         break;                                                          \
3262     case 13:                                                            \
3263         gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
3264         break;                                                          \
3265     case 14:                                                            \
3266         gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
3267         break;                                                          \
3268     case 15:                                                            \
3269         gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
3270         break;                                                          \
3271     case 17:                                                            \
3272         gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
3273         break;                                                          \
3274     case 18:                                                            \
3275         gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
3276         break;                                                          \
3277     case 19:                                                            \
3278         gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
3279         break;                                                          \
3280     case 25:                                                            \
3281         gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
3282         break;                                                          \
3283     case 26:                                                            \
3284         gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
3285         break;                                                          \
3286     case 27:                                                            \
3287         gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
3288         break;                                                          \
3289     default:                                                            \
3290         abort();                                                        \
3291     }                                                                   \
3292     STORE;                                                              \
3293     tcg_temp_free_i ## bits (fp0);                                      \
3294     tcg_temp_free_i ## bits (fp1);                                      \
3295 }
3296
3297 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
3298 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3299 #undef FOP_CONDNS
3300 #undef gen_ldcmp_fpr32
3301 #undef gen_ldcmp_fpr64
3302
3303 /* load/store instructions. */
3304 #ifdef CONFIG_USER_ONLY
3305 #define OP_LD_ATOMIC(insn,fname)                                           \
3306 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
3307                                 DisasContext *ctx)                         \
3308 {                                                                          \
3309     TCGv t0 = tcg_temp_new();                                              \
3310     tcg_gen_mov_tl(t0, arg1);                                              \
3311     tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
3312     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                \
3313     tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));                \
3314     tcg_temp_free(t0);                                                     \
3315 }
3316 #else
3317 #define OP_LD_ATOMIC(insn,fname)                                           \
3318 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
3319                                 DisasContext *ctx)                         \
3320 {                                                                          \
3321     gen_helper_1e1i(insn, ret, arg1, mem_idx);                             \
3322 }
3323 #endif
3324 OP_LD_ATOMIC(ll,ld32s);
3325 #if defined(TARGET_MIPS64)
3326 OP_LD_ATOMIC(lld,ld64);
3327 #endif
3328 #undef OP_LD_ATOMIC
3329
3330 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
3331                                   int base, int offset)
3332 {
3333     if (base == 0) {
3334         tcg_gen_movi_tl(addr, offset);
3335     } else if (offset == 0) {
3336         gen_load_gpr(addr, base);
3337     } else {
3338         tcg_gen_movi_tl(addr, offset);
3339         gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3340     }
3341 }
3342
3343 static target_ulong pc_relative_pc (DisasContext *ctx)
3344 {
3345     target_ulong pc = ctx->base.pc_next;
3346
3347     if (ctx->hflags & MIPS_HFLAG_BMASK) {
3348         int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3349
3350         pc -= branch_bytes;
3351     }
3352
3353     pc &= ~(target_ulong)3;
3354     return pc;
3355 }
3356
3357 /* Load */
3358 static void gen_ld(DisasContext *ctx, uint32_t opc,
3359                    int rt, int base, int offset)
3360 {
3361     TCGv t0, t1, t2;
3362     int mem_idx = ctx->mem_idx;
3363
3364     if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
3365         /* Loongson CPU uses a load to zero register for prefetch.
3366            We emulate it as a NOP. On other CPU we must perform the
3367            actual memory access. */
3368         return;
3369     }
3370
3371     t0 = tcg_temp_new();
3372     gen_base_offset_addr(ctx, t0, base, offset);
3373
3374     switch (opc) {
3375 #if defined(TARGET_MIPS64)
3376     case OPC_LWU:
3377         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
3378                            ctx->default_tcg_memop_mask);
3379         gen_store_gpr(t0, rt);
3380         break;
3381     case OPC_LD:
3382         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
3383                            ctx->default_tcg_memop_mask);
3384         gen_store_gpr(t0, rt);
3385         break;
3386     case OPC_LLD:
3387     case R6_OPC_LLD:
3388         op_ld_lld(t0, t0, mem_idx, ctx);
3389         gen_store_gpr(t0, rt);
3390         break;
3391     case OPC_LDL:
3392         t1 = tcg_temp_new();
3393         /* Do a byte access to possibly trigger a page
3394            fault with the unaligned address.  */
3395         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3396         tcg_gen_andi_tl(t1, t0, 7);
3397 #ifndef TARGET_WORDS_BIGENDIAN
3398         tcg_gen_xori_tl(t1, t1, 7);
3399 #endif
3400         tcg_gen_shli_tl(t1, t1, 3);
3401         tcg_gen_andi_tl(t0, t0, ~7);
3402         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3403         tcg_gen_shl_tl(t0, t0, t1);
3404         t2 = tcg_const_tl(-1);
3405         tcg_gen_shl_tl(t2, t2, t1);
3406         gen_load_gpr(t1, rt);
3407         tcg_gen_andc_tl(t1, t1, t2);
3408         tcg_temp_free(t2);
3409         tcg_gen_or_tl(t0, t0, t1);
3410         tcg_temp_free(t1);
3411         gen_store_gpr(t0, rt);
3412         break;
3413     case OPC_LDR:
3414         t1 = tcg_temp_new();
3415         /* Do a byte access to possibly trigger a page
3416            fault with the unaligned address.  */
3417         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3418         tcg_gen_andi_tl(t1, t0, 7);
3419 #ifdef TARGET_WORDS_BIGENDIAN
3420         tcg_gen_xori_tl(t1, t1, 7);
3421 #endif
3422         tcg_gen_shli_tl(t1, t1, 3);
3423         tcg_gen_andi_tl(t0, t0, ~7);
3424         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3425         tcg_gen_shr_tl(t0, t0, t1);
3426         tcg_gen_xori_tl(t1, t1, 63);
3427         t2 = tcg_const_tl(0xfffffffffffffffeull);
3428         tcg_gen_shl_tl(t2, t2, t1);
3429         gen_load_gpr(t1, rt);
3430         tcg_gen_and_tl(t1, t1, t2);
3431         tcg_temp_free(t2);
3432         tcg_gen_or_tl(t0, t0, t1);
3433         tcg_temp_free(t1);
3434         gen_store_gpr(t0, rt);
3435         break;
3436     case OPC_LDPC:
3437         t1 = tcg_const_tl(pc_relative_pc(ctx));
3438         gen_op_addr_add(ctx, t0, t0, t1);
3439         tcg_temp_free(t1);
3440         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3441         gen_store_gpr(t0, rt);
3442         break;
3443 #endif
3444     case OPC_LWPC:
3445         t1 = tcg_const_tl(pc_relative_pc(ctx));
3446         gen_op_addr_add(ctx, t0, t0, t1);
3447         tcg_temp_free(t1);
3448         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
3449         gen_store_gpr(t0, rt);
3450         break;
3451     case OPC_LWE:
3452         mem_idx = MIPS_HFLAG_UM;
3453         /* fall through */
3454     case OPC_LW:
3455         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
3456                            ctx->default_tcg_memop_mask);
3457         gen_store_gpr(t0, rt);
3458         break;
3459     case OPC_LHE:
3460         mem_idx = MIPS_HFLAG_UM;
3461         /* fall through */
3462     case OPC_LH:
3463         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
3464                            ctx->default_tcg_memop_mask);
3465         gen_store_gpr(t0, rt);
3466         break;
3467     case OPC_LHUE:
3468         mem_idx = MIPS_HFLAG_UM;
3469         /* fall through */
3470     case OPC_LHU:
3471         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
3472                            ctx->default_tcg_memop_mask);
3473         gen_store_gpr(t0, rt);
3474         break;
3475     case OPC_LBE:
3476         mem_idx = MIPS_HFLAG_UM;
3477         /* fall through */
3478     case OPC_LB:
3479         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
3480         gen_store_gpr(t0, rt);
3481         break;
3482     case OPC_LBUE:
3483         mem_idx = MIPS_HFLAG_UM;
3484         /* fall through */
3485     case OPC_LBU:
3486         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
3487         gen_store_gpr(t0, rt);
3488         break;
3489     case OPC_LWLE:
3490         mem_idx = MIPS_HFLAG_UM;
3491         /* fall through */
3492     case OPC_LWL:
3493         t1 = tcg_temp_new();
3494         /* Do a byte access to possibly trigger a page
3495            fault with the unaligned address.  */
3496         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3497         tcg_gen_andi_tl(t1, t0, 3);
3498 #ifndef TARGET_WORDS_BIGENDIAN
3499         tcg_gen_xori_tl(t1, t1, 3);
3500 #endif
3501         tcg_gen_shli_tl(t1, t1, 3);
3502         tcg_gen_andi_tl(t0, t0, ~3);
3503         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3504         tcg_gen_shl_tl(t0, t0, t1);
3505         t2 = tcg_const_tl(-1);
3506         tcg_gen_shl_tl(t2, t2, t1);
3507         gen_load_gpr(t1, rt);
3508         tcg_gen_andc_tl(t1, t1, t2);
3509         tcg_temp_free(t2);
3510         tcg_gen_or_tl(t0, t0, t1);
3511         tcg_temp_free(t1);
3512         tcg_gen_ext32s_tl(t0, t0);
3513         gen_store_gpr(t0, rt);
3514         break;
3515     case OPC_LWRE:
3516         mem_idx = MIPS_HFLAG_UM;
3517         /* fall through */
3518     case OPC_LWR:
3519         t1 = tcg_temp_new();
3520         /* Do a byte access to possibly trigger a page
3521            fault with the unaligned address.  */
3522         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3523         tcg_gen_andi_tl(t1, t0, 3);
3524 #ifdef TARGET_WORDS_BIGENDIAN
3525         tcg_gen_xori_tl(t1, t1, 3);
3526 #endif
3527         tcg_gen_shli_tl(t1, t1, 3);
3528         tcg_gen_andi_tl(t0, t0, ~3);
3529         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3530         tcg_gen_shr_tl(t0, t0, t1);
3531         tcg_gen_xori_tl(t1, t1, 31);
3532         t2 = tcg_const_tl(0xfffffffeull);
3533         tcg_gen_shl_tl(t2, t2, t1);
3534         gen_load_gpr(t1, rt);
3535         tcg_gen_and_tl(t1, t1, t2);
3536         tcg_temp_free(t2);
3537         tcg_gen_or_tl(t0, t0, t1);
3538         tcg_temp_free(t1);
3539         tcg_gen_ext32s_tl(t0, t0);
3540         gen_store_gpr(t0, rt);
3541         break;
3542     case OPC_LLE:
3543         mem_idx = MIPS_HFLAG_UM;
3544         /* fall through */
3545     case OPC_LL:
3546     case R6_OPC_LL:
3547         op_ld_ll(t0, t0, mem_idx, ctx);
3548         gen_store_gpr(t0, rt);
3549         break;
3550     }
3551     tcg_temp_free(t0);
3552 }
3553
3554 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3555                     uint32_t reg1, uint32_t reg2)
3556 {
3557     TCGv taddr = tcg_temp_new();
3558     TCGv_i64 tval = tcg_temp_new_i64();
3559     TCGv tmp1 = tcg_temp_new();
3560     TCGv tmp2 = tcg_temp_new();
3561
3562     gen_base_offset_addr(ctx, taddr, base, offset);
3563     tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3564 #ifdef TARGET_WORDS_BIGENDIAN
3565     tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3566 #else
3567     tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3568 #endif
3569     gen_store_gpr(tmp1, reg1);
3570     tcg_temp_free(tmp1);
3571     gen_store_gpr(tmp2, reg2);
3572     tcg_temp_free(tmp2);
3573     tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3574     tcg_temp_free_i64(tval);
3575     tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3576     tcg_temp_free(taddr);
3577 }
3578
3579 /* Store */
3580 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
3581                     int base, int offset)
3582 {
3583     TCGv t0 = tcg_temp_new();
3584     TCGv t1 = tcg_temp_new();
3585     int mem_idx = ctx->mem_idx;
3586
3587     gen_base_offset_addr(ctx, t0, base, offset);
3588     gen_load_gpr(t1, rt);
3589     switch (opc) {
3590 #if defined(TARGET_MIPS64)
3591     case OPC_SD:
3592         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3593                            ctx->default_tcg_memop_mask);
3594         break;
3595     case OPC_SDL:
3596         gen_helper_0e2i(sdl, t1, t0, mem_idx);
3597         break;
3598     case OPC_SDR:
3599         gen_helper_0e2i(sdr, t1, t0, mem_idx);
3600         break;
3601 #endif
3602     case OPC_SWE:
3603         mem_idx = MIPS_HFLAG_UM;
3604         /* fall through */
3605     case OPC_SW:
3606         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3607                            ctx->default_tcg_memop_mask);
3608         break;
3609     case OPC_SHE:
3610         mem_idx = MIPS_HFLAG_UM;
3611         /* fall through */
3612     case OPC_SH:
3613         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3614                            ctx->default_tcg_memop_mask);
3615         break;
3616     case OPC_SBE:
3617         mem_idx = MIPS_HFLAG_UM;
3618         /* fall through */
3619     case OPC_SB:
3620         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3621         break;
3622     case OPC_SWLE:
3623         mem_idx = MIPS_HFLAG_UM;
3624         /* fall through */
3625     case OPC_SWL:
3626         gen_helper_0e2i(swl, t1, t0, mem_idx);
3627         break;
3628     case OPC_SWRE:
3629         mem_idx = MIPS_HFLAG_UM;
3630         /* fall through */
3631     case OPC_SWR:
3632         gen_helper_0e2i(swr, t1, t0, mem_idx);
3633         break;
3634     }
3635     tcg_temp_free(t0);
3636     tcg_temp_free(t1);
3637 }
3638
3639
3640 /* Store conditional */
3641 static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
3642                         TCGMemOp tcg_mo, bool eva)
3643 {
3644     TCGv addr, t0, val;
3645     TCGLabel *l1 = gen_new_label();
3646     TCGLabel *done = gen_new_label();
3647
3648     t0 = tcg_temp_new();
3649     addr = tcg_temp_new();
3650     /* compare the address against that of the preceeding LL */
3651     gen_base_offset_addr(ctx, addr, base, offset);
3652     tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
3653     tcg_temp_free(addr);
3654     tcg_gen_movi_tl(t0, 0);
3655     gen_store_gpr(t0, rt);
3656     tcg_gen_br(done);
3657
3658     gen_set_label(l1);
3659     /* generate cmpxchg */
3660     val = tcg_temp_new();
3661     gen_load_gpr(val, rt);
3662     tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
3663                               eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
3664     tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
3665     gen_store_gpr(t0, rt);
3666     tcg_temp_free(val);
3667
3668     gen_set_label(done);
3669     tcg_temp_free(t0);
3670 }
3671
3672
3673 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3674                     uint32_t reg1, uint32_t reg2, bool eva)
3675 {
3676     TCGv taddr = tcg_temp_local_new();
3677     TCGv lladdr = tcg_temp_local_new();
3678     TCGv_i64 tval = tcg_temp_new_i64();
3679     TCGv_i64 llval = tcg_temp_new_i64();
3680     TCGv_i64 val = tcg_temp_new_i64();
3681     TCGv tmp1 = tcg_temp_new();
3682     TCGv tmp2 = tcg_temp_new();
3683     TCGLabel *lab_fail = gen_new_label();
3684     TCGLabel *lab_done = gen_new_label();
3685
3686     gen_base_offset_addr(ctx, taddr, base, offset);
3687
3688     tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3689     tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3690
3691     gen_load_gpr(tmp1, reg1);
3692     gen_load_gpr(tmp2, reg2);
3693
3694 #ifdef TARGET_WORDS_BIGENDIAN
3695     tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3696 #else
3697     tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3698 #endif
3699
3700     tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3701     tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3702                                eva ? MIPS_HFLAG_UM : ctx->mem_idx, MO_64);
3703     if (reg1 != 0) {
3704         tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3705     }
3706     tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3707
3708     gen_set_label(lab_fail);
3709
3710     if (reg1 != 0) {
3711         tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3712     }
3713     gen_set_label(lab_done);
3714     tcg_gen_movi_tl(lladdr, -1);
3715     tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3716 }
3717
3718 /* Load and store */
3719 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
3720                           TCGv t0)
3721 {
3722     /* Don't do NOP if destination is zero: we must perform the actual
3723        memory access. */
3724     switch (opc) {
3725     case OPC_LWC1:
3726         {
3727             TCGv_i32 fp0 = tcg_temp_new_i32();
3728             tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3729                                 ctx->default_tcg_memop_mask);
3730             gen_store_fpr32(ctx, fp0, ft);
3731             tcg_temp_free_i32(fp0);
3732         }
3733         break;
3734     case OPC_SWC1:
3735         {
3736             TCGv_i32 fp0 = tcg_temp_new_i32();
3737             gen_load_fpr32(ctx, fp0, ft);
3738             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3739                                 ctx->default_tcg_memop_mask);
3740             tcg_temp_free_i32(fp0);
3741         }
3742         break;
3743     case OPC_LDC1:
3744         {
3745             TCGv_i64 fp0 = tcg_temp_new_i64();
3746             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3747                                 ctx->default_tcg_memop_mask);
3748             gen_store_fpr64(ctx, fp0, ft);
3749             tcg_temp_free_i64(fp0);
3750         }
3751         break;
3752     case OPC_SDC1:
3753         {
3754             TCGv_i64 fp0 = tcg_temp_new_i64();
3755             gen_load_fpr64(ctx, fp0, ft);
3756             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3757                                 ctx->default_tcg_memop_mask);
3758             tcg_temp_free_i64(fp0);
3759         }
3760         break;
3761     default:
3762         MIPS_INVAL("flt_ldst");
3763         generate_exception_end(ctx, EXCP_RI);
3764         break;
3765     }
3766 }
3767
3768 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3769                           int rs, int16_t imm)
3770 {
3771     TCGv t0 = tcg_temp_new();
3772
3773     if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3774         check_cp1_enabled(ctx);
3775         switch (op) {
3776         case OPC_LDC1:
3777         case OPC_SDC1:
3778             check_insn(ctx, ISA_MIPS2);
3779             /* Fallthrough */
3780         default:
3781             gen_base_offset_addr(ctx, t0, rs, imm);
3782             gen_flt_ldst(ctx, op, rt, t0);
3783         }
3784     } else {
3785         generate_exception_err(ctx, EXCP_CpU, 1);
3786     }
3787     tcg_temp_free(t0);
3788 }
3789
3790 /* Arithmetic with immediate operand */
3791 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3792                           int rt, int rs, int imm)
3793 {
3794     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3795
3796     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3797         /* If no destination, treat it as a NOP.
3798            For addi, we must generate the overflow exception when needed. */
3799         return;
3800     }
3801     switch (opc) {
3802     case OPC_ADDI:
3803         {
3804             TCGv t0 = tcg_temp_local_new();
3805             TCGv t1 = tcg_temp_new();
3806             TCGv t2 = tcg_temp_new();
3807             TCGLabel *l1 = gen_new_label();
3808
3809             gen_load_gpr(t1, rs);
3810             tcg_gen_addi_tl(t0, t1, uimm);
3811             tcg_gen_ext32s_tl(t0, t0);
3812
3813             tcg_gen_xori_tl(t1, t1, ~uimm);
3814             tcg_gen_xori_tl(t2, t0, uimm);
3815             tcg_gen_and_tl(t1, t1, t2);
3816             tcg_temp_free(t2);
3817             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3818             tcg_temp_free(t1);
3819             /* operands of same sign, result different sign */
3820             generate_exception(ctx, EXCP_OVERFLOW);
3821             gen_set_label(l1);
3822             tcg_gen_ext32s_tl(t0, t0);
3823             gen_store_gpr(t0, rt);
3824             tcg_temp_free(t0);
3825         }
3826         break;
3827     case OPC_ADDIU:
3828         if (rs != 0) {
3829             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3830             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3831         } else {
3832             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3833         }
3834         break;
3835 #if defined(TARGET_MIPS64)
3836     case OPC_DADDI:
3837         {
3838             TCGv t0 = tcg_temp_local_new();
3839             TCGv t1 = tcg_temp_new();
3840             TCGv t2 = tcg_temp_new();
3841             TCGLabel *l1 = gen_new_label();
3842
3843             gen_load_gpr(t1, rs);
3844             tcg_gen_addi_tl(t0, t1, uimm);
3845
3846             tcg_gen_xori_tl(t1, t1, ~uimm);
3847             tcg_gen_xori_tl(t2, t0, uimm);
3848             tcg_gen_and_tl(t1, t1, t2);
3849             tcg_temp_free(t2);
3850             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3851             tcg_temp_free(t1);
3852             /* operands of same sign, result different sign */
3853             generate_exception(ctx, EXCP_OVERFLOW);
3854             gen_set_label(l1);
3855             gen_store_gpr(t0, rt);
3856             tcg_temp_free(t0);
3857         }
3858         break;
3859     case OPC_DADDIU:
3860         if (rs != 0) {
3861             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3862         } else {
3863             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3864         }
3865         break;
3866 #endif
3867     }
3868 }
3869
3870 /* Logic with immediate operand */
3871 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3872                           int rt, int rs, int16_t imm)
3873 {
3874     target_ulong uimm;
3875
3876     if (rt == 0) {
3877         /* If no destination, treat it as a NOP. */
3878         return;
3879     }
3880     uimm = (uint16_t)imm;
3881     switch (opc) {
3882     case OPC_ANDI:
3883         if (likely(rs != 0))
3884             tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3885         else
3886             tcg_gen_movi_tl(cpu_gpr[rt], 0);
3887         break;
3888     case OPC_ORI:
3889         if (rs != 0)
3890             tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3891         else
3892             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3893         break;
3894     case OPC_XORI:
3895         if (likely(rs != 0))
3896             tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3897         else
3898             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3899         break;
3900     case OPC_LUI:
3901         if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3902             /* OPC_AUI */
3903             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3904             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3905         } else {
3906             tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3907         }
3908         break;
3909
3910     default:
3911         break;
3912     }
3913 }
3914
3915 /* Set on less than with immediate operand */
3916 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3917                         int rt, int rs, int16_t imm)
3918 {
3919     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3920     TCGv t0;
3921
3922     if (rt == 0) {
3923         /* If no destination, treat it as a NOP. */
3924         return;
3925     }
3926     t0 = tcg_temp_new();
3927     gen_load_gpr(t0, rs);
3928     switch (opc) {
3929     case OPC_SLTI:
3930         tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
3931         break;
3932     case OPC_SLTIU:
3933         tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
3934         break;
3935     }
3936     tcg_temp_free(t0);
3937 }
3938
3939 /* Shifts with immediate operand */
3940 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
3941                           int rt, int rs, int16_t imm)
3942 {
3943     target_ulong uimm = ((uint16_t)imm) & 0x1f;
3944     TCGv t0;
3945
3946     if (rt == 0) {
3947         /* If no destination, treat it as a NOP. */
3948         return;
3949     }
3950
3951     t0 = tcg_temp_new();
3952     gen_load_gpr(t0, rs);
3953     switch (opc) {
3954     case OPC_SLL:
3955         tcg_gen_shli_tl(t0, t0, uimm);
3956         tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3957         break;
3958     case OPC_SRA:
3959         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3960         break;
3961     case OPC_SRL:
3962         if (uimm != 0) {
3963             tcg_gen_ext32u_tl(t0, t0);
3964             tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3965         } else {
3966             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3967         }
3968         break;
3969     case OPC_ROTR:
3970         if (uimm != 0) {
3971             TCGv_i32 t1 = tcg_temp_new_i32();
3972
3973             tcg_gen_trunc_tl_i32(t1, t0);
3974             tcg_gen_rotri_i32(t1, t1, uimm);
3975             tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
3976             tcg_temp_free_i32(t1);
3977         } else {
3978             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
3979         }
3980         break;
3981 #if defined(TARGET_MIPS64)
3982     case OPC_DSLL:
3983         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
3984         break;
3985     case OPC_DSRA:
3986         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
3987         break;
3988     case OPC_DSRL:
3989         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
3990         break;
3991     case OPC_DROTR:
3992         if (uimm != 0) {
3993             tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
3994         } else {
3995             tcg_gen_mov_tl(cpu_gpr[rt], t0);
3996         }
3997         break;
3998     case OPC_DSLL32:
3999         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
4000         break;
4001     case OPC_DSRA32:
4002         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
4003         break;
4004     case OPC_DSRL32:
4005         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
4006         break;
4007     case OPC_DROTR32:
4008         tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
4009         break;
4010 #endif
4011     }
4012     tcg_temp_free(t0);
4013 }
4014
4015 /* Arithmetic */
4016 static void gen_arith(DisasContext *ctx, uint32_t opc,
4017                       int rd, int rs, int rt)
4018 {
4019     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
4020        && opc != OPC_DADD && opc != OPC_DSUB) {
4021         /* If no destination, treat it as a NOP.
4022            For add & sub, we must generate the overflow exception when needed. */
4023         return;
4024     }
4025
4026     switch (opc) {
4027     case OPC_ADD:
4028         {
4029             TCGv t0 = tcg_temp_local_new();
4030             TCGv t1 = tcg_temp_new();
4031             TCGv t2 = tcg_temp_new();
4032             TCGLabel *l1 = gen_new_label();
4033
4034             gen_load_gpr(t1, rs);
4035             gen_load_gpr(t2, rt);
4036             tcg_gen_add_tl(t0, t1, t2);
4037             tcg_gen_ext32s_tl(t0, t0);
4038             tcg_gen_xor_tl(t1, t1, t2);
4039             tcg_gen_xor_tl(t2, t0, t2);
4040             tcg_gen_andc_tl(t1, t2, t1);
4041             tcg_temp_free(t2);
4042             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4043             tcg_temp_free(t1);
4044             /* operands of same sign, result different sign */
4045             generate_exception(ctx, EXCP_OVERFLOW);
4046             gen_set_label(l1);
4047             gen_store_gpr(t0, rd);
4048             tcg_temp_free(t0);
4049         }
4050         break;
4051     case OPC_ADDU:
4052         if (rs != 0 && rt != 0) {
4053             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4054             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4055         } else if (rs == 0 && rt != 0) {
4056             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4057         } else if (rs != 0 && rt == 0) {
4058             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4059         } else {
4060             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4061         }
4062         break;
4063     case OPC_SUB:
4064         {
4065             TCGv t0 = tcg_temp_local_new();
4066             TCGv t1 = tcg_temp_new();
4067             TCGv t2 = tcg_temp_new();
4068             TCGLabel *l1 = gen_new_label();
4069
4070             gen_load_gpr(t1, rs);
4071             gen_load_gpr(t2, rt);
4072             tcg_gen_sub_tl(t0, t1, t2);
4073             tcg_gen_ext32s_tl(t0, t0);
4074             tcg_gen_xor_tl(t2, t1, t2);
4075             tcg_gen_xor_tl(t1, t0, t1);
4076             tcg_gen_and_tl(t1, t1, t2);
4077             tcg_temp_free(t2);
4078             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4079             tcg_temp_free(t1);
4080             /* operands of different sign, first operand and result different sign */
4081             generate_exception(ctx, EXCP_OVERFLOW);
4082             gen_set_label(l1);
4083             gen_store_gpr(t0, rd);
4084             tcg_temp_free(t0);
4085         }
4086         break;
4087     case OPC_SUBU:
4088         if (rs != 0 && rt != 0) {
4089             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4090             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4091         } else if (rs == 0 && rt != 0) {
4092             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4093             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4094         } else if (rs != 0 && rt == 0) {
4095             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4096         } else {
4097             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4098         }
4099         break;
4100 #if defined(TARGET_MIPS64)
4101     case OPC_DADD:
4102         {
4103             TCGv t0 = tcg_temp_local_new();
4104             TCGv t1 = tcg_temp_new();
4105             TCGv t2 = tcg_temp_new();
4106             TCGLabel *l1 = gen_new_label();
4107
4108             gen_load_gpr(t1, rs);
4109             gen_load_gpr(t2, rt);
4110             tcg_gen_add_tl(t0, t1, t2);
4111             tcg_gen_xor_tl(t1, t1, t2);
4112             tcg_gen_xor_tl(t2, t0, t2);
4113             tcg_gen_andc_tl(t1, t2, t1);
4114             tcg_temp_free(t2);
4115             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4116             tcg_temp_free(t1);
4117             /* operands of same sign, result different sign */
4118             generate_exception(ctx, EXCP_OVERFLOW);
4119             gen_set_label(l1);
4120             gen_store_gpr(t0, rd);
4121             tcg_temp_free(t0);
4122         }
4123         break;
4124     case OPC_DADDU:
4125         if (rs != 0 && rt != 0) {
4126             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4127         } else if (rs == 0 && rt != 0) {
4128             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4129         } else if (rs != 0 && rt == 0) {
4130             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4131         } else {
4132             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4133         }
4134         break;
4135     case OPC_DSUB:
4136         {
4137             TCGv t0 = tcg_temp_local_new();
4138             TCGv t1 = tcg_temp_new();
4139             TCGv t2 = tcg_temp_new();
4140             TCGLabel *l1 = gen_new_label();
4141
4142             gen_load_gpr(t1, rs);
4143             gen_load_gpr(t2, rt);
4144             tcg_gen_sub_tl(t0, t1, t2);
4145             tcg_gen_xor_tl(t2, t1, t2);
4146             tcg_gen_xor_tl(t1, t0, t1);
4147             tcg_gen_and_tl(t1, t1, t2);
4148             tcg_temp_free(t2);
4149             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4150             tcg_temp_free(t1);
4151             /* operands of different sign, first operand and result different sign */
4152             generate_exception(ctx, EXCP_OVERFLOW);
4153             gen_set_label(l1);
4154             gen_store_gpr(t0, rd);
4155             tcg_temp_free(t0);
4156         }
4157         break;
4158     case OPC_DSUBU:
4159         if (rs != 0 && rt != 0) {
4160             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4161         } else if (rs == 0 && rt != 0) {
4162             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4163         } else if (rs != 0 && rt == 0) {
4164             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4165         } else {
4166             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4167         }
4168         break;
4169 #endif
4170     case OPC_MUL:
4171         if (likely(rs != 0 && rt != 0)) {
4172             tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4173             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4174         } else {
4175             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4176         }
4177         break;
4178     }
4179 }
4180
4181 /* Conditional move */
4182 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
4183                           int rd, int rs, int rt)
4184 {
4185     TCGv t0, t1, t2;
4186
4187     if (rd == 0) {
4188         /* If no destination, treat it as a NOP. */
4189         return;
4190     }
4191
4192     t0 = tcg_temp_new();
4193     gen_load_gpr(t0, rt);
4194     t1 = tcg_const_tl(0);
4195     t2 = tcg_temp_new();
4196     gen_load_gpr(t2, rs);
4197     switch (opc) {
4198     case OPC_MOVN:
4199         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4200         break;
4201     case OPC_MOVZ:
4202         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4203         break;
4204     case OPC_SELNEZ:
4205         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
4206         break;
4207     case OPC_SELEQZ:
4208         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
4209         break;
4210     }
4211     tcg_temp_free(t2);
4212     tcg_temp_free(t1);
4213     tcg_temp_free(t0);
4214 }
4215
4216 /* Logic */
4217 static void gen_logic(DisasContext *ctx, uint32_t opc,
4218                       int rd, int rs, int rt)
4219 {
4220     if (rd == 0) {
4221         /* If no destination, treat it as a NOP. */
4222         return;
4223     }
4224
4225     switch (opc) {
4226     case OPC_AND:
4227         if (likely(rs != 0 && rt != 0)) {
4228             tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4229         } else {
4230             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4231         }
4232         break;
4233     case OPC_NOR:
4234         if (rs != 0 && rt != 0) {
4235             tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4236         } else if (rs == 0 && rt != 0) {
4237             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4238         } else if (rs != 0 && rt == 0) {
4239             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4240         } else {
4241             tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4242         }
4243         break;
4244     case OPC_OR:
4245         if (likely(rs != 0 && rt != 0)) {
4246             tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4247         } else if (rs == 0 && rt != 0) {
4248             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4249         } else if (rs != 0 && rt == 0) {
4250             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4251         } else {
4252             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4253         }
4254         break;
4255     case OPC_XOR:
4256         if (likely(rs != 0 && rt != 0)) {
4257             tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4258         } else if (rs == 0 && rt != 0) {
4259             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4260         } else if (rs != 0 && rt == 0) {
4261             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4262         } else {
4263             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4264         }
4265         break;
4266     }
4267 }
4268
4269 /* Set on lower than */
4270 static void gen_slt(DisasContext *ctx, uint32_t opc,
4271                     int rd, int rs, int rt)
4272 {
4273     TCGv t0, t1;
4274
4275     if (rd == 0) {
4276         /* If no destination, treat it as a NOP. */
4277         return;
4278     }
4279
4280     t0 = tcg_temp_new();
4281     t1 = tcg_temp_new();
4282     gen_load_gpr(t0, rs);
4283     gen_load_gpr(t1, rt);
4284     switch (opc) {
4285     case OPC_SLT:
4286         tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
4287         break;
4288     case OPC_SLTU:
4289         tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
4290         break;
4291     }
4292     tcg_temp_free(t0);
4293     tcg_temp_free(t1);
4294 }
4295
4296 /* Shifts */
4297 static void gen_shift(DisasContext *ctx, uint32_t opc,
4298                       int rd, int rs, int rt)
4299 {
4300     TCGv t0, t1;
4301
4302     if (rd == 0) {
4303         /* If no destination, treat it as a NOP.
4304            For add & sub, we must generate the overflow exception when needed. */
4305         return;
4306     }
4307
4308     t0 = tcg_temp_new();
4309     t1 = tcg_temp_new();
4310     gen_load_gpr(t0, rs);
4311     gen_load_gpr(t1, rt);
4312     switch (opc) {
4313     case OPC_SLLV:
4314         tcg_gen_andi_tl(t0, t0, 0x1f);
4315         tcg_gen_shl_tl(t0, t1, t0);
4316         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4317         break;
4318     case OPC_SRAV:
4319         tcg_gen_andi_tl(t0, t0, 0x1f);
4320         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4321         break;
4322     case OPC_SRLV:
4323         tcg_gen_ext32u_tl(t1, t1);
4324         tcg_gen_andi_tl(t0, t0, 0x1f);
4325         tcg_gen_shr_tl(t0, t1, t0);
4326         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4327         break;
4328     case OPC_ROTRV:
4329         {
4330             TCGv_i32 t2 = tcg_temp_new_i32();
4331             TCGv_i32 t3 = tcg_temp_new_i32();
4332
4333             tcg_gen_trunc_tl_i32(t2, t0);
4334             tcg_gen_trunc_tl_i32(t3, t1);
4335             tcg_gen_andi_i32(t2, t2, 0x1f);
4336             tcg_gen_rotr_i32(t2, t3, t2);
4337             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4338             tcg_temp_free_i32(t2);
4339             tcg_temp_free_i32(t3);
4340         }
4341         break;
4342 #if defined(TARGET_MIPS64)
4343     case OPC_DSLLV:
4344         tcg_gen_andi_tl(t0, t0, 0x3f);
4345         tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
4346         break;
4347     case OPC_DSRAV:
4348         tcg_gen_andi_tl(t0, t0, 0x3f);
4349         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4350         break;
4351     case OPC_DSRLV:
4352         tcg_gen_andi_tl(t0, t0, 0x3f);
4353         tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
4354         break;
4355     case OPC_DROTRV:
4356         tcg_gen_andi_tl(t0, t0, 0x3f);
4357         tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
4358         break;
4359 #endif
4360     }
4361     tcg_temp_free(t0);
4362     tcg_temp_free(t1);
4363 }
4364
4365 #if defined(TARGET_MIPS64)
4366 /* Copy GPR to and from TX79 HI1/LO1 register. */
4367 static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
4368 {
4369     if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
4370         /* Treat as NOP. */
4371         return;
4372     }
4373
4374     switch (opc) {
4375     case MMI_OPC_MFHI1:
4376         tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
4377         break;
4378     case MMI_OPC_MFLO1:
4379         tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
4380         break;
4381     case MMI_OPC_MTHI1:
4382         if (reg != 0) {
4383             tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
4384         } else {
4385             tcg_gen_movi_tl(cpu_HI[1], 0);
4386         }
4387         break;
4388     case MMI_OPC_MTLO1:
4389         if (reg != 0) {
4390             tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
4391         } else {
4392             tcg_gen_movi_tl(cpu_LO[1], 0);
4393         }
4394         break;
4395     default:
4396         MIPS_INVAL("mfthilo1 TX79");
4397         generate_exception_end(ctx, EXCP_RI);
4398         break;
4399     }
4400 }
4401 #endif
4402
4403 /* Arithmetic on HI/LO registers */
4404 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
4405 {
4406     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
4407         /* Treat as NOP. */
4408         return;
4409     }
4410
4411     if (acc != 0) {
4412         check_dsp(ctx);
4413     }
4414
4415     switch (opc) {
4416     case OPC_MFHI:
4417 #if defined(TARGET_MIPS64)
4418         if (acc != 0) {
4419             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4420         } else
4421 #endif
4422         {
4423             tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4424         }
4425         break;
4426     case OPC_MFLO:
4427 #if defined(TARGET_MIPS64)
4428         if (acc != 0) {
4429             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4430         } else
4431 #endif
4432         {
4433             tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4434         }
4435         break;
4436     case OPC_MTHI:
4437         if (reg != 0) {
4438 #if defined(TARGET_MIPS64)
4439             if (acc != 0) {
4440                 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4441             } else
4442 #endif
4443             {
4444                 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4445             }
4446         } else {
4447             tcg_gen_movi_tl(cpu_HI[acc], 0);
4448         }
4449         break;
4450     case OPC_MTLO:
4451         if (reg != 0) {
4452 #if defined(TARGET_MIPS64)
4453             if (acc != 0) {
4454                 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4455             } else
4456 #endif
4457             {
4458                 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4459             }
4460         } else {
4461             tcg_gen_movi_tl(cpu_LO[acc], 0);
4462         }
4463         break;
4464     }
4465 }
4466
4467 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4468                              TCGMemOp memop)
4469 {
4470     TCGv t0 = tcg_const_tl(addr);
4471     tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4472     gen_store_gpr(t0, reg);
4473     tcg_temp_free(t0);
4474 }
4475
4476 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4477                              int rs)
4478 {
4479     target_long offset;
4480     target_long addr;
4481
4482     switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
4483     case OPC_ADDIUPC:
4484         if (rs != 0) {
4485             offset = sextract32(ctx->opcode << 2, 0, 21);
4486             addr = addr_add(ctx, pc, offset);
4487             tcg_gen_movi_tl(cpu_gpr[rs], addr);
4488         }
4489         break;
4490     case R6_OPC_LWPC:
4491         offset = sextract32(ctx->opcode << 2, 0, 21);
4492         addr = addr_add(ctx, pc, offset);
4493         gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4494         break;
4495 #if defined(TARGET_MIPS64)
4496     case OPC_LWUPC:
4497         check_mips_64(ctx);
4498         offset = sextract32(ctx->opcode << 2, 0, 21);
4499         addr = addr_add(ctx, pc, offset);
4500         gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4501         break;
4502 #endif
4503     default:
4504         switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
4505         case OPC_AUIPC:
4506             if (rs != 0) {
4507                 offset = sextract32(ctx->opcode, 0, 16) << 16;
4508                 addr = addr_add(ctx, pc, offset);
4509                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4510             }
4511             break;
4512         case OPC_ALUIPC:
4513             if (rs != 0) {
4514                 offset = sextract32(ctx->opcode, 0, 16) << 16;
4515                 addr = ~0xFFFF & addr_add(ctx, pc, offset);
4516                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4517             }
4518             break;
4519 #if defined(TARGET_MIPS64)
4520         case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4521         case R6_OPC_LDPC + (1 << 16):
4522         case R6_OPC_LDPC + (2 << 16):
4523         case R6_OPC_LDPC + (3 << 16):
4524             check_mips_64(ctx);
4525             offset = sextract32(ctx->opcode << 3, 0, 21);
4526             addr = addr_add(ctx, (pc & ~0x7), offset);
4527             gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4528             break;
4529 #endif
4530         default:
4531             MIPS_INVAL("OPC_PCREL");
4532             generate_exception_end(ctx, EXCP_RI);
4533             break;
4534         }
4535         break;
4536     }
4537 }
4538
4539 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4540 {
4541     TCGv t0, t1;
4542
4543     if (rd == 0) {
4544         /* Treat as NOP. */
4545         return;
4546     }
4547
4548     t0 = tcg_temp_new();
4549     t1 = tcg_temp_new();
4550
4551     gen_load_gpr(t0, rs);
4552     gen_load_gpr(t1, rt);
4553
4554     switch (opc) {
4555     case R6_OPC_DIV:
4556         {
4557             TCGv t2 = tcg_temp_new();
4558             TCGv t3 = tcg_temp_new();
4559             tcg_gen_ext32s_tl(t0, t0);
4560             tcg_gen_ext32s_tl(t1, t1);
4561             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4562             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4563             tcg_gen_and_tl(t2, t2, t3);
4564             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4565             tcg_gen_or_tl(t2, t2, t3);
4566             tcg_gen_movi_tl(t3, 0);
4567             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4568             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4569             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4570             tcg_temp_free(t3);
4571             tcg_temp_free(t2);
4572         }
4573         break;
4574     case R6_OPC_MOD:
4575         {
4576             TCGv t2 = tcg_temp_new();
4577             TCGv t3 = tcg_temp_new();
4578             tcg_gen_ext32s_tl(t0, t0);
4579             tcg_gen_ext32s_tl(t1, t1);
4580             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4581             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4582             tcg_gen_and_tl(t2, t2, t3);
4583             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4584             tcg_gen_or_tl(t2, t2, t3);
4585             tcg_gen_movi_tl(t3, 0);
4586             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4587             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4588             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4589             tcg_temp_free(t3);
4590             tcg_temp_free(t2);
4591         }
4592         break;
4593     case R6_OPC_DIVU:
4594         {
4595             TCGv t2 = tcg_const_tl(0);
4596             TCGv t3 = tcg_const_tl(1);
4597             tcg_gen_ext32u_tl(t0, t0);
4598             tcg_gen_ext32u_tl(t1, t1);
4599             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4600             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4601             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4602             tcg_temp_free(t3);
4603             tcg_temp_free(t2);
4604         }
4605         break;
4606     case R6_OPC_MODU:
4607         {
4608             TCGv t2 = tcg_const_tl(0);
4609             TCGv t3 = tcg_const_tl(1);
4610             tcg_gen_ext32u_tl(t0, t0);
4611             tcg_gen_ext32u_tl(t1, t1);
4612             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4613             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4614             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4615             tcg_temp_free(t3);
4616             tcg_temp_free(t2);
4617         }
4618         break;
4619     case R6_OPC_MUL:
4620         {
4621             TCGv_i32 t2 = tcg_temp_new_i32();
4622             TCGv_i32 t3 = tcg_temp_new_i32();
4623             tcg_gen_trunc_tl_i32(t2, t0);
4624             tcg_gen_trunc_tl_i32(t3, t1);
4625             tcg_gen_mul_i32(t2, t2, t3);
4626             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4627             tcg_temp_free_i32(t2);
4628             tcg_temp_free_i32(t3);
4629         }
4630         break;
4631     case R6_OPC_MUH:
4632         {
4633             TCGv_i32 t2 = tcg_temp_new_i32();
4634             TCGv_i32 t3 = tcg_temp_new_i32();
4635             tcg_gen_trunc_tl_i32(t2, t0);
4636             tcg_gen_trunc_tl_i32(t3, t1);
4637             tcg_gen_muls2_i32(t2, t3, t2, t3);
4638             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4639             tcg_temp_free_i32(t2);
4640             tcg_temp_free_i32(t3);
4641         }
4642         break;
4643     case R6_OPC_MULU:
4644         {
4645             TCGv_i32 t2 = tcg_temp_new_i32();
4646             TCGv_i32 t3 = tcg_temp_new_i32();
4647             tcg_gen_trunc_tl_i32(t2, t0);
4648             tcg_gen_trunc_tl_i32(t3, t1);
4649             tcg_gen_mul_i32(t2, t2, t3);
4650             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4651             tcg_temp_free_i32(t2);
4652             tcg_temp_free_i32(t3);
4653         }
4654         break;
4655     case R6_OPC_MUHU:
4656         {
4657             TCGv_i32 t2 = tcg_temp_new_i32();
4658             TCGv_i32 t3 = tcg_temp_new_i32();
4659             tcg_gen_trunc_tl_i32(t2, t0);
4660             tcg_gen_trunc_tl_i32(t3, t1);
4661             tcg_gen_mulu2_i32(t2, t3, t2, t3);
4662             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4663             tcg_temp_free_i32(t2);
4664             tcg_temp_free_i32(t3);
4665         }
4666         break;
4667 #if defined(TARGET_MIPS64)
4668     case R6_OPC_DDIV:
4669         {
4670             TCGv t2 = tcg_temp_new();
4671             TCGv t3 = tcg_temp_new();
4672             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4673             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4674             tcg_gen_and_tl(t2, t2, t3);
4675             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4676             tcg_gen_or_tl(t2, t2, t3);
4677             tcg_gen_movi_tl(t3, 0);
4678             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4679             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4680             tcg_temp_free(t3);
4681             tcg_temp_free(t2);
4682         }
4683         break;
4684     case R6_OPC_DMOD:
4685         {
4686             TCGv t2 = tcg_temp_new();
4687             TCGv t3 = tcg_temp_new();
4688             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4689             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4690             tcg_gen_and_tl(t2, t2, t3);
4691             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4692             tcg_gen_or_tl(t2, t2, t3);
4693             tcg_gen_movi_tl(t3, 0);
4694             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4695             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4696             tcg_temp_free(t3);
4697             tcg_temp_free(t2);
4698         }
4699         break;
4700     case R6_OPC_DDIVU:
4701         {
4702             TCGv t2 = tcg_const_tl(0);
4703             TCGv t3 = tcg_const_tl(1);
4704             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4705             tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4706             tcg_temp_free(t3);
4707             tcg_temp_free(t2);
4708         }
4709         break;
4710     case R6_OPC_DMODU:
4711         {
4712             TCGv t2 = tcg_const_tl(0);
4713             TCGv t3 = tcg_const_tl(1);
4714             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4715             tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4716             tcg_temp_free(t3);
4717             tcg_temp_free(t2);
4718         }
4719         break;
4720     case R6_OPC_DMUL:
4721         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4722         break;
4723     case R6_OPC_DMUH:
4724         {
4725             TCGv t2 = tcg_temp_new();
4726             tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4727             tcg_temp_free(t2);
4728         }
4729         break;
4730     case R6_OPC_DMULU:
4731         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4732         break;
4733     case R6_OPC_DMUHU:
4734         {
4735             TCGv t2 = tcg_temp_new();
4736             tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4737             tcg_temp_free(t2);
4738         }
4739         break;
4740 #endif
4741     default:
4742         MIPS_INVAL("r6 mul/div");
4743         generate_exception_end(ctx, EXCP_RI);
4744         goto out;
4745     }
4746  out:
4747     tcg_temp_free(t0);
4748     tcg_temp_free(t1);
4749 }
4750
4751 #if defined(TARGET_MIPS64)
4752 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
4753 {
4754     TCGv t0, t1;
4755
4756     t0 = tcg_temp_new();
4757     t1 = tcg_temp_new();
4758
4759     gen_load_gpr(t0, rs);
4760     gen_load_gpr(t1, rt);
4761
4762     switch (opc) {
4763     case MMI_OPC_DIV1:
4764         {
4765             TCGv t2 = tcg_temp_new();
4766             TCGv t3 = tcg_temp_new();
4767             tcg_gen_ext32s_tl(t0, t0);
4768             tcg_gen_ext32s_tl(t1, t1);
4769             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4770             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4771             tcg_gen_and_tl(t2, t2, t3);
4772             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4773             tcg_gen_or_tl(t2, t2, t3);
4774             tcg_gen_movi_tl(t3, 0);
4775             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4776             tcg_gen_div_tl(cpu_LO[1], t0, t1);
4777             tcg_gen_rem_tl(cpu_HI[1], t0, t1);
4778             tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4779             tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4780             tcg_temp_free(t3);
4781             tcg_temp_free(t2);
4782         }
4783         break;
4784     case MMI_OPC_DIVU1:
4785         {
4786             TCGv t2 = tcg_const_tl(0);
4787             TCGv t3 = tcg_const_tl(1);
4788             tcg_gen_ext32u_tl(t0, t0);
4789             tcg_gen_ext32u_tl(t1, t1);
4790             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4791             tcg_gen_divu_tl(cpu_LO[1], t0, t1);
4792             tcg_gen_remu_tl(cpu_HI[1], t0, t1);
4793             tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4794             tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4795             tcg_temp_free(t3);
4796             tcg_temp_free(t2);
4797         }
4798         break;
4799     default:
4800         MIPS_INVAL("div1 TX79");
4801         generate_exception_end(ctx, EXCP_RI);
4802         goto out;
4803     }
4804  out:
4805     tcg_temp_free(t0);
4806     tcg_temp_free(t1);
4807 }
4808 #endif
4809
4810 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4811                        int acc, int rs, int rt)
4812 {
4813     TCGv t0, t1;
4814
4815     t0 = tcg_temp_new();
4816     t1 = tcg_temp_new();
4817
4818     gen_load_gpr(t0, rs);
4819     gen_load_gpr(t1, rt);
4820
4821     if (acc != 0) {
4822         check_dsp(ctx);
4823     }
4824
4825     switch (opc) {
4826     case OPC_DIV:
4827         {
4828             TCGv t2 = tcg_temp_new();
4829             TCGv t3 = tcg_temp_new();
4830             tcg_gen_ext32s_tl(t0, t0);
4831             tcg_gen_ext32s_tl(t1, t1);
4832             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4833             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4834             tcg_gen_and_tl(t2, t2, t3);
4835             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4836             tcg_gen_or_tl(t2, t2, t3);
4837             tcg_gen_movi_tl(t3, 0);
4838             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4839             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4840             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4841             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4842             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4843             tcg_temp_free(t3);
4844             tcg_temp_free(t2);
4845         }
4846         break;
4847     case OPC_DIVU:
4848         {
4849             TCGv t2 = tcg_const_tl(0);
4850             TCGv t3 = tcg_const_tl(1);
4851             tcg_gen_ext32u_tl(t0, t0);
4852             tcg_gen_ext32u_tl(t1, t1);
4853             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4854             tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4855             tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4856             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4857             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4858             tcg_temp_free(t3);
4859             tcg_temp_free(t2);
4860         }
4861         break;
4862     case OPC_MULT:
4863         {
4864             TCGv_i32 t2 = tcg_temp_new_i32();
4865             TCGv_i32 t3 = tcg_temp_new_i32();
4866             tcg_gen_trunc_tl_i32(t2, t0);
4867             tcg_gen_trunc_tl_i32(t3, t1);
4868             tcg_gen_muls2_i32(t2, t3, t2, t3);
4869             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4870             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4871             tcg_temp_free_i32(t2);
4872             tcg_temp_free_i32(t3);
4873         }
4874         break;
4875     case OPC_MULTU:
4876         {
4877             TCGv_i32 t2 = tcg_temp_new_i32();
4878             TCGv_i32 t3 = tcg_temp_new_i32();
4879             tcg_gen_trunc_tl_i32(t2, t0);
4880             tcg_gen_trunc_tl_i32(t3, t1);
4881             tcg_gen_mulu2_i32(t2, t3, t2, t3);
4882             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4883             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4884             tcg_temp_free_i32(t2);
4885             tcg_temp_free_i32(t3);
4886         }
4887         break;
4888 #if defined(TARGET_MIPS64)
4889     case OPC_DDIV:
4890         {
4891             TCGv t2 = tcg_temp_new();
4892             TCGv t3 = tcg_temp_new();
4893             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4894             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4895             tcg_gen_and_tl(t2, t2, t3);
4896             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4897             tcg_gen_or_tl(t2, t2, t3);
4898             tcg_gen_movi_tl(t3, 0);
4899             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4900             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4901             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4902             tcg_temp_free(t3);
4903             tcg_temp_free(t2);
4904         }
4905         break;
4906     case OPC_DDIVU:
4907         {
4908             TCGv t2 = tcg_const_tl(0);
4909             TCGv t3 = tcg_const_tl(1);
4910             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4911             tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4912             tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4913             tcg_temp_free(t3);
4914             tcg_temp_free(t2);
4915         }
4916         break;
4917     case OPC_DMULT:
4918         tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4919         break;
4920     case OPC_DMULTU:
4921         tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4922         break;
4923 #endif
4924     case OPC_MADD:
4925         {
4926             TCGv_i64 t2 = tcg_temp_new_i64();
4927             TCGv_i64 t3 = tcg_temp_new_i64();
4928
4929             tcg_gen_ext_tl_i64(t2, t0);
4930             tcg_gen_ext_tl_i64(t3, t1);
4931             tcg_gen_mul_i64(t2, t2, t3);
4932             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4933             tcg_gen_add_i64(t2, t2, t3);
4934             tcg_temp_free_i64(t3);
4935             gen_move_low32(cpu_LO[acc], t2);
4936             gen_move_high32(cpu_HI[acc], t2);
4937             tcg_temp_free_i64(t2);
4938         }
4939         break;
4940     case OPC_MADDU:
4941         {
4942             TCGv_i64 t2 = tcg_temp_new_i64();
4943             TCGv_i64 t3 = tcg_temp_new_i64();
4944
4945             tcg_gen_ext32u_tl(t0, t0);
4946             tcg_gen_ext32u_tl(t1, t1);
4947             tcg_gen_extu_tl_i64(t2, t0);
4948             tcg_gen_extu_tl_i64(t3, t1);
4949             tcg_gen_mul_i64(t2, t2, t3);
4950             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4951             tcg_gen_add_i64(t2, t2, t3);
4952             tcg_temp_free_i64(t3);
4953             gen_move_low32(cpu_LO[acc], t2);
4954             gen_move_high32(cpu_HI[acc], t2);
4955             tcg_temp_free_i64(t2);
4956         }
4957         break;
4958     case OPC_MSUB:
4959         {
4960             TCGv_i64 t2 = tcg_temp_new_i64();
4961             TCGv_i64 t3 = tcg_temp_new_i64();
4962
4963             tcg_gen_ext_tl_i64(t2, t0);
4964             tcg_gen_ext_tl_i64(t3, t1);
4965             tcg_gen_mul_i64(t2, t2, t3);
4966             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4967             tcg_gen_sub_i64(t2, t3, t2);
4968             tcg_temp_free_i64(t3);
4969             gen_move_low32(cpu_LO[acc], t2);
4970             gen_move_high32(cpu_HI[acc], t2);
4971             tcg_temp_free_i64(t2);
4972         }
4973         break;
4974     case OPC_MSUBU:
4975         {
4976             TCGv_i64 t2 = tcg_temp_new_i64();
4977             TCGv_i64 t3 = tcg_temp_new_i64();
4978
4979             tcg_gen_ext32u_tl(t0, t0);
4980             tcg_gen_ext32u_tl(t1, t1);
4981             tcg_gen_extu_tl_i64(t2, t0);
4982             tcg_gen_extu_tl_i64(t3, t1);
4983             tcg_gen_mul_i64(t2, t2, t3);
4984             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4985             tcg_gen_sub_i64(t2, t3, t2);
4986             tcg_temp_free_i64(t3);
4987             gen_move_low32(cpu_LO[acc], t2);
4988             gen_move_high32(cpu_HI[acc], t2);
4989             tcg_temp_free_i64(t2);
4990         }
4991         break;
4992     default:
4993         MIPS_INVAL("mul/div");
4994         generate_exception_end(ctx, EXCP_RI);
4995         goto out;
4996     }
4997  out:
4998     tcg_temp_free(t0);
4999     tcg_temp_free(t1);
5000 }
5001
5002 /*
5003  * These MULT[U] and MADD[U] instructions implemented in for example
5004  * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
5005  * architectures are special three-operand variants with the syntax
5006  *
5007  *     MULT[U][1] rd, rs, rt
5008  *
5009  * such that
5010  *
5011  *     (rd, LO, HI) <- rs * rt
5012  *
5013  * and
5014  *
5015  *     MADD[U][1] rd, rs, rt
5016  *
5017  * such that
5018  *
5019  *     (rd, LO, HI) <- (LO, HI) + rs * rt
5020  *
5021  * where the low-order 32-bits of the result is placed into both the
5022  * GPR rd and the special register LO. The high-order 32-bits of the
5023  * result is placed into the special register HI.
5024  *
5025  * If the GPR rd is omitted in assembly language, it is taken to be 0,
5026  * which is the zero register that always reads as 0.
5027  */
5028 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
5029                          int rd, int rs, int rt)
5030 {
5031     TCGv t0 = tcg_temp_new();
5032     TCGv t1 = tcg_temp_new();
5033     int acc = 0;
5034
5035     gen_load_gpr(t0, rs);
5036     gen_load_gpr(t1, rt);
5037
5038     switch (opc) {
5039     case MMI_OPC_MULT1:
5040         acc = 1;
5041         /* Fall through */
5042     case OPC_MULT:
5043         {
5044             TCGv_i32 t2 = tcg_temp_new_i32();
5045             TCGv_i32 t3 = tcg_temp_new_i32();
5046             tcg_gen_trunc_tl_i32(t2, t0);
5047             tcg_gen_trunc_tl_i32(t3, t1);
5048             tcg_gen_muls2_i32(t2, t3, t2, t3);
5049             if (rd) {
5050                 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5051             }
5052             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5053             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5054             tcg_temp_free_i32(t2);
5055             tcg_temp_free_i32(t3);
5056         }
5057         break;
5058     case MMI_OPC_MULTU1:
5059         acc = 1;
5060         /* Fall through */
5061     case OPC_MULTU:
5062         {
5063             TCGv_i32 t2 = tcg_temp_new_i32();
5064             TCGv_i32 t3 = tcg_temp_new_i32();
5065             tcg_gen_trunc_tl_i32(t2, t0);
5066             tcg_gen_trunc_tl_i32(t3, t1);
5067             tcg_gen_mulu2_i32(t2, t3, t2, t3);
5068             if (rd) {
5069                 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5070             }
5071             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5072             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5073             tcg_temp_free_i32(t2);
5074             tcg_temp_free_i32(t3);
5075         }
5076         break;
5077     case MMI_OPC_MADD1:
5078         acc = 1;
5079         /* Fall through */
5080     case MMI_OPC_MADD:
5081         {
5082             TCGv_i64 t2 = tcg_temp_new_i64();
5083             TCGv_i64 t3 = tcg_temp_new_i64();
5084
5085             tcg_gen_ext_tl_i64(t2, t0);
5086             tcg_gen_ext_tl_i64(t3, t1);
5087             tcg_gen_mul_i64(t2, t2, t3);
5088             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5089             tcg_gen_add_i64(t2, t2, t3);
5090             tcg_temp_free_i64(t3);
5091             gen_move_low32(cpu_LO[acc], t2);
5092             gen_move_high32(cpu_HI[acc], t2);
5093             if (rd) {
5094                 gen_move_low32(cpu_gpr[rd], t2);
5095             }
5096             tcg_temp_free_i64(t2);
5097         }
5098         break;
5099     case MMI_OPC_MADDU1:
5100         acc = 1;
5101         /* Fall through */
5102     case MMI_OPC_MADDU:
5103         {
5104             TCGv_i64 t2 = tcg_temp_new_i64();
5105             TCGv_i64 t3 = tcg_temp_new_i64();
5106
5107             tcg_gen_ext32u_tl(t0, t0);
5108             tcg_gen_ext32u_tl(t1, t1);
5109             tcg_gen_extu_tl_i64(t2, t0);
5110             tcg_gen_extu_tl_i64(t3, t1);
5111             tcg_gen_mul_i64(t2, t2, t3);
5112             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5113             tcg_gen_add_i64(t2, t2, t3);
5114             tcg_temp_free_i64(t3);
5115             gen_move_low32(cpu_LO[acc], t2);
5116             gen_move_high32(cpu_HI[acc], t2);
5117             if (rd) {
5118                 gen_move_low32(cpu_gpr[rd], t2);
5119             }
5120             tcg_temp_free_i64(t2);
5121         }
5122         break;
5123     default:
5124         MIPS_INVAL("mul/madd TXx9");
5125         generate_exception_end(ctx, EXCP_RI);
5126         goto out;
5127     }
5128
5129  out:
5130     tcg_temp_free(t0);
5131     tcg_temp_free(t1);
5132 }
5133
5134 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
5135                             int rd, int rs, int rt)
5136 {
5137     TCGv t0 = tcg_temp_new();
5138     TCGv t1 = tcg_temp_new();
5139
5140     gen_load_gpr(t0, rs);
5141     gen_load_gpr(t1, rt);
5142
5143     switch (opc) {
5144     case OPC_VR54XX_MULS:
5145         gen_helper_muls(t0, cpu_env, t0, t1);
5146         break;
5147     case OPC_VR54XX_MULSU:
5148         gen_helper_mulsu(t0, cpu_env, t0, t1);
5149         break;
5150     case OPC_VR54XX_MACC:
5151         gen_helper_macc(t0, cpu_env, t0, t1);
5152         break;
5153     case OPC_VR54XX_MACCU:
5154         gen_helper_maccu(t0, cpu_env, t0, t1);
5155         break;
5156     case OPC_VR54XX_MSAC:
5157         gen_helper_msac(t0, cpu_env, t0, t1);
5158         break;
5159     case OPC_VR54XX_MSACU:
5160         gen_helper_msacu(t0, cpu_env, t0, t1);
5161         break;
5162     case OPC_VR54XX_MULHI:
5163         gen_helper_mulhi(t0, cpu_env, t0, t1);
5164         break;
5165     case OPC_VR54XX_MULHIU:
5166         gen_helper_mulhiu(t0, cpu_env, t0, t1);
5167         break;
5168     case OPC_VR54XX_MULSHI:
5169         gen_helper_mulshi(t0, cpu_env, t0, t1);
5170         break;
5171     case OPC_VR54XX_MULSHIU:
5172         gen_helper_mulshiu(t0, cpu_env, t0, t1);
5173         break;
5174     case OPC_VR54XX_MACCHI:
5175         gen_helper_macchi(t0, cpu_env, t0, t1);
5176         break;
5177     case OPC_VR54XX_MACCHIU:
5178         gen_helper_macchiu(t0, cpu_env, t0, t1);
5179         break;
5180     case OPC_VR54XX_MSACHI:
5181         gen_helper_msachi(t0, cpu_env, t0, t1);
5182         break;
5183     case OPC_VR54XX_MSACHIU:
5184         gen_helper_msachiu(t0, cpu_env, t0, t1);
5185         break;
5186     default:
5187         MIPS_INVAL("mul vr54xx");
5188         generate_exception_end(ctx, EXCP_RI);
5189         goto out;
5190     }
5191     gen_store_gpr(t0, rd);
5192
5193  out:
5194     tcg_temp_free(t0);
5195     tcg_temp_free(t1);
5196 }
5197
5198 static void gen_cl (DisasContext *ctx, uint32_t opc,
5199                     int rd, int rs)
5200 {
5201     TCGv t0;
5202
5203     if (rd == 0) {
5204         /* Treat as NOP. */
5205         return;
5206     }
5207     t0 = cpu_gpr[rd];
5208     gen_load_gpr(t0, rs);
5209
5210     switch (opc) {
5211     case OPC_CLO:
5212     case R6_OPC_CLO:
5213 #if defined(TARGET_MIPS64)
5214     case OPC_DCLO:
5215     case R6_OPC_DCLO:
5216 #endif
5217         tcg_gen_not_tl(t0, t0);
5218         break;
5219     }
5220
5221     switch (opc) {
5222     case OPC_CLO:
5223     case R6_OPC_CLO:
5224     case OPC_CLZ:
5225     case R6_OPC_CLZ:
5226         tcg_gen_ext32u_tl(t0, t0);
5227         tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
5228         tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
5229         break;
5230 #if defined(TARGET_MIPS64)
5231     case OPC_DCLO:
5232     case R6_OPC_DCLO:
5233     case OPC_DCLZ:
5234     case R6_OPC_DCLZ:
5235         tcg_gen_clzi_i64(t0, t0, 64);
5236         break;
5237 #endif
5238     }
5239 }
5240
5241 /* Godson integer instructions */
5242 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
5243                                  int rd, int rs, int rt)
5244 {
5245     TCGv t0, t1;
5246
5247     if (rd == 0) {
5248         /* Treat as NOP. */
5249         return;
5250     }
5251
5252     switch (opc) {
5253     case OPC_MULT_G_2E:
5254     case OPC_MULT_G_2F:
5255     case OPC_MULTU_G_2E:
5256     case OPC_MULTU_G_2F:
5257 #if defined(TARGET_MIPS64)
5258     case OPC_DMULT_G_2E:
5259     case OPC_DMULT_G_2F:
5260     case OPC_DMULTU_G_2E:
5261     case OPC_DMULTU_G_2F:
5262 #endif
5263         t0 = tcg_temp_new();
5264         t1 = tcg_temp_new();
5265         break;
5266     default:
5267         t0 = tcg_temp_local_new();
5268         t1 = tcg_temp_local_new();
5269         break;
5270     }
5271
5272     gen_load_gpr(t0, rs);
5273     gen_load_gpr(t1, rt);
5274
5275     switch (opc) {
5276     case OPC_MULT_G_2E:
5277     case OPC_MULT_G_2F:
5278         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5279         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5280         break;
5281     case OPC_MULTU_G_2E:
5282     case OPC_MULTU_G_2F:
5283         tcg_gen_ext32u_tl(t0, t0);
5284         tcg_gen_ext32u_tl(t1, t1);
5285         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5286         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5287         break;
5288     case OPC_DIV_G_2E:
5289     case OPC_DIV_G_2F:
5290         {
5291             TCGLabel *l1 = gen_new_label();
5292             TCGLabel *l2 = gen_new_label();
5293             TCGLabel *l3 = gen_new_label();
5294             tcg_gen_ext32s_tl(t0, t0);
5295             tcg_gen_ext32s_tl(t1, t1);
5296             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5297             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5298             tcg_gen_br(l3);
5299             gen_set_label(l1);
5300             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5301             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5302             tcg_gen_mov_tl(cpu_gpr[rd], t0);
5303             tcg_gen_br(l3);
5304             gen_set_label(l2);
5305             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5306             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5307             gen_set_label(l3);
5308         }
5309         break;
5310     case OPC_DIVU_G_2E:
5311     case OPC_DIVU_G_2F:
5312         {
5313             TCGLabel *l1 = gen_new_label();
5314             TCGLabel *l2 = gen_new_label();
5315             tcg_gen_ext32u_tl(t0, t0);
5316             tcg_gen_ext32u_tl(t1, t1);
5317             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5318             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5319             tcg_gen_br(l2);
5320             gen_set_label(l1);
5321             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5322             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5323             gen_set_label(l2);
5324         }
5325         break;
5326     case OPC_MOD_G_2E:
5327     case OPC_MOD_G_2F:
5328         {
5329             TCGLabel *l1 = gen_new_label();
5330             TCGLabel *l2 = gen_new_label();
5331             TCGLabel *l3 = gen_new_label();
5332             tcg_gen_ext32u_tl(t0, t0);
5333             tcg_gen_ext32u_tl(t1, t1);
5334             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5335             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5336             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5337             gen_set_label(l1);
5338             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5339             tcg_gen_br(l3);
5340             gen_set_label(l2);
5341             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5342             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5343             gen_set_label(l3);
5344         }
5345         break;
5346     case OPC_MODU_G_2E:
5347     case OPC_MODU_G_2F:
5348         {
5349             TCGLabel *l1 = gen_new_label();
5350             TCGLabel *l2 = gen_new_label();
5351             tcg_gen_ext32u_tl(t0, t0);
5352             tcg_gen_ext32u_tl(t1, t1);
5353             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5354             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5355             tcg_gen_br(l2);
5356             gen_set_label(l1);
5357             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5358             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5359             gen_set_label(l2);
5360         }
5361         break;
5362 #if defined(TARGET_MIPS64)
5363     case OPC_DMULT_G_2E:
5364     case OPC_DMULT_G_2F:
5365         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5366         break;
5367     case OPC_DMULTU_G_2E:
5368     case OPC_DMULTU_G_2F:
5369         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5370         break;
5371     case OPC_DDIV_G_2E:
5372     case OPC_DDIV_G_2F:
5373         {
5374             TCGLabel *l1 = gen_new_label();
5375             TCGLabel *l2 = gen_new_label();
5376             TCGLabel *l3 = gen_new_label();
5377             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5378             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5379             tcg_gen_br(l3);
5380             gen_set_label(l1);
5381             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5382             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5383             tcg_gen_mov_tl(cpu_gpr[rd], t0);
5384             tcg_gen_br(l3);
5385             gen_set_label(l2);
5386             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5387             gen_set_label(l3);
5388         }
5389         break;
5390     case OPC_DDIVU_G_2E:
5391     case OPC_DDIVU_G_2F:
5392         {
5393             TCGLabel *l1 = gen_new_label();
5394             TCGLabel *l2 = gen_new_label();
5395             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5396             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5397             tcg_gen_br(l2);
5398             gen_set_label(l1);
5399             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5400             gen_set_label(l2);
5401         }
5402         break;
5403     case OPC_DMOD_G_2E:
5404     case OPC_DMOD_G_2F:
5405         {
5406             TCGLabel *l1 = gen_new_label();
5407             TCGLabel *l2 = gen_new_label();
5408             TCGLabel *l3 = gen_new_label();
5409             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5410             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5411             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5412             gen_set_label(l1);
5413             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5414             tcg_gen_br(l3);
5415             gen_set_label(l2);
5416             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5417             gen_set_label(l3);
5418         }
5419         break;
5420     case OPC_DMODU_G_2E:
5421     case OPC_DMODU_G_2F:
5422         {
5423             TCGLabel *l1 = gen_new_label();
5424             TCGLabel *l2 = gen_new_label();
5425             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5426             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5427             tcg_gen_br(l2);
5428             gen_set_label(l1);
5429             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5430             gen_set_label(l2);
5431         }
5432         break;
5433 #endif
5434     }
5435
5436     tcg_temp_free(t0);
5437     tcg_temp_free(t1);
5438 }
5439
5440 /* Loongson multimedia instructions */
5441 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5442 {
5443     uint32_t opc, shift_max;
5444     TCGv_i64 t0, t1;
5445
5446     opc = MASK_LMI(ctx->opcode);
5447     switch (opc) {
5448     case OPC_ADD_CP2:
5449     case OPC_SUB_CP2:
5450     case OPC_DADD_CP2:
5451     case OPC_DSUB_CP2:
5452         t0 = tcg_temp_local_new_i64();
5453         t1 = tcg_temp_local_new_i64();
5454         break;
5455     default:
5456         t0 = tcg_temp_new_i64();
5457         t1 = tcg_temp_new_i64();
5458         break;
5459     }
5460
5461     check_cp1_enabled(ctx);
5462     gen_load_fpr64(ctx, t0, rs);
5463     gen_load_fpr64(ctx, t1, rt);
5464
5465 #define LMI_HELPER(UP, LO) \
5466     case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
5467 #define LMI_HELPER_1(UP, LO) \
5468     case OPC_##UP: gen_helper_##LO(t0, t0); break
5469 #define LMI_DIRECT(UP, LO, OP) \
5470     case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
5471
5472     switch (opc) {
5473     LMI_HELPER(PADDSH, paddsh);
5474     LMI_HELPER(PADDUSH, paddush);
5475     LMI_HELPER(PADDH, paddh);
5476     LMI_HELPER(PADDW, paddw);
5477     LMI_HELPER(PADDSB, paddsb);
5478     LMI_HELPER(PADDUSB, paddusb);
5479     LMI_HELPER(PADDB, paddb);
5480
5481     LMI_HELPER(PSUBSH, psubsh);
5482     LMI_HELPER(PSUBUSH, psubush);
5483     LMI_HELPER(PSUBH, psubh);
5484     LMI_HELPER(PSUBW, psubw);
5485     LMI_HELPER(PSUBSB, psubsb);
5486     LMI_HELPER(PSUBUSB, psubusb);
5487     LMI_HELPER(PSUBB, psubb);
5488
5489     LMI_HELPER(PSHUFH, pshufh);
5490     LMI_HELPER(PACKSSWH, packsswh);
5491     LMI_HELPER(PACKSSHB, packsshb);
5492     LMI_HELPER(PACKUSHB, packushb);
5493
5494     LMI_HELPER(PUNPCKLHW, punpcklhw);
5495     LMI_HELPER(PUNPCKHHW, punpckhhw);
5496     LMI_HELPER(PUNPCKLBH, punpcklbh);
5497     LMI_HELPER(PUNPCKHBH, punpckhbh);
5498     LMI_HELPER(PUNPCKLWD, punpcklwd);
5499     LMI_HELPER(PUNPCKHWD, punpckhwd);
5500
5501     LMI_HELPER(PAVGH, pavgh);
5502     LMI_HELPER(PAVGB, pavgb);
5503     LMI_HELPER(PMAXSH, pmaxsh);
5504     LMI_HELPER(PMINSH, pminsh);
5505     LMI_HELPER(PMAXUB, pmaxub);
5506     LMI_HELPER(PMINUB, pminub);
5507
5508     LMI_HELPER(PCMPEQW, pcmpeqw);
5509     LMI_HELPER(PCMPGTW, pcmpgtw);
5510     LMI_HELPER(PCMPEQH, pcmpeqh);
5511     LMI_HELPER(PCMPGTH, pcmpgth);
5512     LMI_HELPER(PCMPEQB, pcmpeqb);
5513     LMI_HELPER(PCMPGTB, pcmpgtb);
5514
5515     LMI_HELPER(PSLLW, psllw);
5516     LMI_HELPER(PSLLH, psllh);
5517     LMI_HELPER(PSRLW, psrlw);
5518     LMI_HELPER(PSRLH, psrlh);
5519     LMI_HELPER(PSRAW, psraw);
5520     LMI_HELPER(PSRAH, psrah);
5521
5522     LMI_HELPER(PMULLH, pmullh);
5523     LMI_HELPER(PMULHH, pmulhh);
5524     LMI_HELPER(PMULHUH, pmulhuh);
5525     LMI_HELPER(PMADDHW, pmaddhw);
5526
5527     LMI_HELPER(PASUBUB, pasubub);
5528     LMI_HELPER_1(BIADD, biadd);
5529     LMI_HELPER_1(PMOVMSKB, pmovmskb);
5530
5531     LMI_DIRECT(PADDD, paddd, add);
5532     LMI_DIRECT(PSUBD, psubd, sub);
5533     LMI_DIRECT(XOR_CP2, xor, xor);
5534     LMI_DIRECT(NOR_CP2, nor, nor);
5535     LMI_DIRECT(AND_CP2, and, and);
5536     LMI_DIRECT(OR_CP2, or, or);
5537
5538     case OPC_PANDN:
5539         tcg_gen_andc_i64(t0, t1, t0);
5540         break;
5541
5542     case OPC_PINSRH_0:
5543         tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
5544         break;
5545     case OPC_PINSRH_1:
5546         tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
5547         break;
5548     case OPC_PINSRH_2:
5549         tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
5550         break;
5551     case OPC_PINSRH_3:
5552         tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
5553         break;
5554
5555     case OPC_PEXTRH:
5556         tcg_gen_andi_i64(t1, t1, 3);
5557         tcg_gen_shli_i64(t1, t1, 4);
5558         tcg_gen_shr_i64(t0, t0, t1);
5559         tcg_gen_ext16u_i64(t0, t0);
5560         break;
5561
5562     case OPC_ADDU_CP2:
5563         tcg_gen_add_i64(t0, t0, t1);
5564         tcg_gen_ext32s_i64(t0, t0);
5565         break;
5566     case OPC_SUBU_CP2:
5567         tcg_gen_sub_i64(t0, t0, t1);
5568         tcg_gen_ext32s_i64(t0, t0);
5569         break;
5570
5571     case OPC_SLL_CP2:
5572         shift_max = 32;
5573         goto do_shift;
5574     case OPC_SRL_CP2:
5575         shift_max = 32;
5576         goto do_shift;
5577     case OPC_SRA_CP2:
5578         shift_max = 32;
5579         goto do_shift;
5580     case OPC_DSLL_CP2:
5581         shift_max = 64;
5582         goto do_shift;
5583     case OPC_DSRL_CP2:
5584         shift_max = 64;
5585         goto do_shift;
5586     case OPC_DSRA_CP2:
5587         shift_max = 64;
5588         goto do_shift;
5589     do_shift:
5590         /* Make sure shift count isn't TCG undefined behaviour.  */
5591         tcg_gen_andi_i64(t1, t1, shift_max - 1);
5592
5593         switch (opc) {
5594         case OPC_SLL_CP2:
5595         case OPC_DSLL_CP2:
5596             tcg_gen_shl_i64(t0, t0, t1);
5597             break;
5598         case OPC_SRA_CP2:
5599         case OPC_DSRA_CP2:
5600             /* Since SRA is UndefinedResult without sign-extended inputs,
5601                we can treat SRA and DSRA the same.  */
5602             tcg_gen_sar_i64(t0, t0, t1);
5603             break;
5604         case OPC_SRL_CP2:
5605             /* We want to shift in zeros for SRL; zero-extend first.  */
5606             tcg_gen_ext32u_i64(t0, t0);
5607             /* FALLTHRU */
5608         case OPC_DSRL_CP2:
5609             tcg_gen_shr_i64(t0, t0, t1);
5610             break;
5611         }
5612
5613         if (shift_max == 32) {
5614             tcg_gen_ext32s_i64(t0, t0);
5615         }
5616
5617         /* Shifts larger than MAX produce zero.  */
5618         tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5619         tcg_gen_neg_i64(t1, t1);
5620         tcg_gen_and_i64(t0, t0, t1);
5621         break;
5622
5623     case OPC_ADD_CP2:
5624     case OPC_DADD_CP2:
5625         {
5626             TCGv_i64 t2 = tcg_temp_new_i64();
5627             TCGLabel *lab = gen_new_label();
5628
5629             tcg_gen_mov_i64(t2, t0);
5630             tcg_gen_add_i64(t0, t1, t2);
5631             if (opc == OPC_ADD_CP2) {
5632                 tcg_gen_ext32s_i64(t0, t0);
5633             }
5634             tcg_gen_xor_i64(t1, t1, t2);
5635             tcg_gen_xor_i64(t2, t2, t0);
5636             tcg_gen_andc_i64(t1, t2, t1);
5637             tcg_temp_free_i64(t2);
5638             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5639             generate_exception(ctx, EXCP_OVERFLOW);
5640             gen_set_label(lab);
5641             break;
5642         }
5643
5644     case OPC_SUB_CP2:
5645     case OPC_DSUB_CP2:
5646         {
5647             TCGv_i64 t2 = tcg_temp_new_i64();
5648             TCGLabel *lab = gen_new_label();
5649
5650             tcg_gen_mov_i64(t2, t0);
5651             tcg_gen_sub_i64(t0, t1, t2);
5652             if (opc == OPC_SUB_CP2) {
5653                 tcg_gen_ext32s_i64(t0, t0);
5654             }
5655             tcg_gen_xor_i64(t1, t1, t2);
5656             tcg_gen_xor_i64(t2, t2, t0);
5657             tcg_gen_and_i64(t1, t1, t2);
5658             tcg_temp_free_i64(t2);
5659             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5660             generate_exception(ctx, EXCP_OVERFLOW);
5661             gen_set_label(lab);
5662             break;
5663         }
5664
5665     case OPC_PMULUW:
5666         tcg_gen_ext32u_i64(t0, t0);
5667         tcg_gen_ext32u_i64(t1, t1);
5668         tcg_gen_mul_i64(t0, t0, t1);
5669         break;
5670
5671     case OPC_SEQU_CP2:
5672     case OPC_SEQ_CP2:
5673     case OPC_SLTU_CP2:
5674     case OPC_SLT_CP2:
5675     case OPC_SLEU_CP2:
5676     case OPC_SLE_CP2:
5677         /* ??? Document is unclear: Set FCC[CC].  Does that mean the
5678            FD field is the CC field?  */
5679     default:
5680         MIPS_INVAL("loongson_cp2");
5681         generate_exception_end(ctx, EXCP_RI);
5682         return;
5683     }
5684
5685 #undef LMI_HELPER
5686 #undef LMI_DIRECT
5687
5688     gen_store_fpr64(ctx, t0, rd);
5689
5690     tcg_temp_free_i64(t0);
5691     tcg_temp_free_i64(t1);
5692 }
5693
5694 /* Traps */
5695 static void gen_trap (DisasContext *ctx, uint32_t opc,
5696                       int rs, int rt, int16_t imm)
5697 {
5698     int cond;
5699     TCGv t0 = tcg_temp_new();
5700     TCGv t1 = tcg_temp_new();
5701
5702     cond = 0;
5703     /* Load needed operands */
5704     switch (opc) {
5705     case OPC_TEQ:
5706     case OPC_TGE:
5707     case OPC_TGEU:
5708     case OPC_TLT:
5709     case OPC_TLTU:
5710     case OPC_TNE:
5711         /* Compare two registers */
5712         if (rs != rt) {
5713             gen_load_gpr(t0, rs);
5714             gen_load_gpr(t1, rt);
5715             cond = 1;
5716         }
5717         break;
5718     case OPC_TEQI:
5719     case OPC_TGEI:
5720     case OPC_TGEIU:
5721     case OPC_TLTI:
5722     case OPC_TLTIU:
5723     case OPC_TNEI:
5724         /* Compare register to immediate */
5725         if (rs != 0 || imm != 0) {
5726             gen_load_gpr(t0, rs);
5727             tcg_gen_movi_tl(t1, (int32_t)imm);
5728             cond = 1;
5729         }
5730         break;
5731     }
5732     if (cond == 0) {
5733         switch (opc) {
5734         case OPC_TEQ:   /* rs == rs */
5735         case OPC_TEQI:  /* r0 == 0  */
5736         case OPC_TGE:   /* rs >= rs */
5737         case OPC_TGEI:  /* r0 >= 0  */
5738         case OPC_TGEU:  /* rs >= rs unsigned */
5739         case OPC_TGEIU: /* r0 >= 0  unsigned */
5740             /* Always trap */
5741             generate_exception_end(ctx, EXCP_TRAP);
5742             break;
5743         case OPC_TLT:   /* rs < rs           */
5744         case OPC_TLTI:  /* r0 < 0            */
5745         case OPC_TLTU:  /* rs < rs unsigned  */
5746         case OPC_TLTIU: /* r0 < 0  unsigned  */
5747         case OPC_TNE:   /* rs != rs          */
5748         case OPC_TNEI:  /* r0 != 0           */
5749             /* Never trap: treat as NOP. */
5750             break;
5751         }
5752     } else {
5753         TCGLabel *l1 = gen_new_label();
5754
5755         switch (opc) {
5756         case OPC_TEQ:
5757         case OPC_TEQI:
5758             tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
5759             break;
5760         case OPC_TGE:
5761         case OPC_TGEI:
5762             tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
5763             break;
5764         case OPC_TGEU:
5765         case OPC_TGEIU:
5766             tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
5767             break;
5768         case OPC_TLT:
5769         case OPC_TLTI:
5770             tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5771             break;
5772         case OPC_TLTU:
5773         case OPC_TLTIU:
5774             tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5775             break;
5776         case OPC_TNE:
5777         case OPC_TNEI:
5778             tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
5779             break;
5780         }
5781         generate_exception(ctx, EXCP_TRAP);
5782         gen_set_label(l1);
5783     }
5784     tcg_temp_free(t0);
5785     tcg_temp_free(t1);
5786 }
5787
5788 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5789 {
5790     if (unlikely(ctx->base.singlestep_enabled)) {
5791         return false;
5792     }
5793
5794 #ifndef CONFIG_USER_ONLY
5795     return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
5796 #else
5797     return true;
5798 #endif
5799 }
5800
5801 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
5802 {
5803     if (use_goto_tb(ctx, dest)) {
5804         tcg_gen_goto_tb(n);
5805         gen_save_pc(dest);
5806         tcg_gen_exit_tb(ctx->base.tb, n);
5807     } else {
5808         gen_save_pc(dest);
5809         if (ctx->base.singlestep_enabled) {
5810             save_cpu_state(ctx, 0);
5811             gen_helper_raise_exception_debug(cpu_env);
5812         }
5813         tcg_gen_lookup_and_goto_ptr();
5814     }
5815 }
5816
5817 /* Branches (before delay slot) */
5818 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
5819                                 int insn_bytes,
5820                                 int rs, int rt, int32_t offset,
5821                                 int delayslot_size)
5822 {
5823     target_ulong btgt = -1;
5824     int blink = 0;
5825     int bcond_compute = 0;
5826     TCGv t0 = tcg_temp_new();
5827     TCGv t1 = tcg_temp_new();
5828
5829     if (ctx->hflags & MIPS_HFLAG_BMASK) {
5830 #ifdef MIPS_DEBUG_DISAS
5831         LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5832                   TARGET_FMT_lx "\n", ctx->base.pc_next);
5833 #endif
5834         generate_exception_end(ctx, EXCP_RI);
5835         goto out;
5836     }
5837
5838     /* Load needed operands */
5839     switch (opc) {
5840     case OPC_BEQ:
5841     case OPC_BEQL:
5842     case OPC_BNE:
5843     case OPC_BNEL:
5844         /* Compare two registers */
5845         if (rs != rt) {
5846             gen_load_gpr(t0, rs);
5847             gen_load_gpr(t1, rt);
5848             bcond_compute = 1;
5849         }
5850         btgt = ctx->base.pc_next + insn_bytes + offset;
5851         break;
5852     case OPC_BGEZ:
5853     case OPC_BGEZAL:
5854     case OPC_BGEZALL:
5855     case OPC_BGEZL:
5856     case OPC_BGTZ:
5857     case OPC_BGTZL:
5858     case OPC_BLEZ:
5859     case OPC_BLEZL:
5860     case OPC_BLTZ:
5861     case OPC_BLTZAL:
5862     case OPC_BLTZALL:
5863     case OPC_BLTZL:
5864         /* Compare to zero */
5865         if (rs != 0) {
5866             gen_load_gpr(t0, rs);
5867             bcond_compute = 1;
5868         }
5869         btgt = ctx->base.pc_next + insn_bytes + offset;
5870         break;
5871     case OPC_BPOSGE32:
5872 #if defined(TARGET_MIPS64)
5873     case OPC_BPOSGE64:
5874         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5875 #else
5876         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5877 #endif
5878         bcond_compute = 1;
5879         btgt = ctx->base.pc_next + insn_bytes + offset;
5880         break;
5881     case OPC_J:
5882     case OPC_JAL:
5883     case OPC_JALX:
5884         /* Jump to immediate */
5885         btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5886             (uint32_t)offset;
5887         break;
5888     case OPC_JR:
5889     case OPC_JALR:
5890         /* Jump to register */
5891         if (offset != 0 && offset != 16) {
5892             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5893                others are reserved. */
5894             MIPS_INVAL("jump hint");
5895             generate_exception_end(ctx, EXCP_RI);
5896             goto out;
5897         }
5898         gen_load_gpr(btarget, rs);
5899         break;
5900     default:
5901         MIPS_INVAL("branch/jump");
5902         generate_exception_end(ctx, EXCP_RI);
5903         goto out;
5904     }
5905     if (bcond_compute == 0) {
5906         /* No condition to be computed */
5907         switch (opc) {
5908         case OPC_BEQ:     /* rx == rx        */
5909         case OPC_BEQL:    /* rx == rx likely */
5910         case OPC_BGEZ:    /* 0 >= 0          */
5911         case OPC_BGEZL:   /* 0 >= 0 likely   */
5912         case OPC_BLEZ:    /* 0 <= 0          */
5913         case OPC_BLEZL:   /* 0 <= 0 likely   */
5914             /* Always take */
5915             ctx->hflags |= MIPS_HFLAG_B;
5916             break;
5917         case OPC_BGEZAL:  /* 0 >= 0          */
5918         case OPC_BGEZALL: /* 0 >= 0 likely   */
5919             /* Always take and link */
5920             blink = 31;
5921             ctx->hflags |= MIPS_HFLAG_B;
5922             break;
5923         case OPC_BNE:     /* rx != rx        */
5924         case OPC_BGTZ:    /* 0 > 0           */
5925         case OPC_BLTZ:    /* 0 < 0           */
5926             /* Treat as NOP. */
5927             goto out;
5928         case OPC_BLTZAL:  /* 0 < 0           */
5929             /* Handle as an unconditional branch to get correct delay
5930                slot checking.  */
5931             blink = 31;
5932             btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
5933             ctx->hflags |= MIPS_HFLAG_B;
5934             break;
5935         case OPC_BLTZALL: /* 0 < 0 likely */
5936             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5937             /* Skip the instruction in the delay slot */
5938             ctx->base.pc_next += 4;
5939             goto out;
5940         case OPC_BNEL:    /* rx != rx likely */
5941         case OPC_BGTZL:   /* 0 > 0 likely */
5942         case OPC_BLTZL:   /* 0 < 0 likely */
5943             /* Skip the instruction in the delay slot */
5944             ctx->base.pc_next += 4;
5945             goto out;
5946         case OPC_J:
5947             ctx->hflags |= MIPS_HFLAG_B;
5948             break;
5949         case OPC_JALX:
5950             ctx->hflags |= MIPS_HFLAG_BX;
5951             /* Fallthrough */
5952         case OPC_JAL:
5953             blink = 31;
5954             ctx->hflags |= MIPS_HFLAG_B;
5955             break;
5956         case OPC_JR:
5957             ctx->hflags |= MIPS_HFLAG_BR;
5958             break;
5959         case OPC_JALR:
5960             blink = rt;
5961             ctx->hflags |= MIPS_HFLAG_BR;
5962             break;
5963         default:
5964             MIPS_INVAL("branch/jump");
5965             generate_exception_end(ctx, EXCP_RI);
5966             goto out;
5967         }
5968     } else {
5969         switch (opc) {
5970         case OPC_BEQ:
5971             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5972             goto not_likely;
5973         case OPC_BEQL:
5974             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5975             goto likely;
5976         case OPC_BNE:
5977             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5978             goto not_likely;
5979         case OPC_BNEL:
5980             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5981             goto likely;
5982         case OPC_BGEZ:
5983             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5984             goto not_likely;
5985         case OPC_BGEZL:
5986             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5987             goto likely;
5988         case OPC_BGEZAL:
5989             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5990             blink = 31;
5991             goto not_likely;
5992         case OPC_BGEZALL:
5993             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5994             blink = 31;
5995             goto likely;
5996         case OPC_BGTZ:
5997             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5998             goto not_likely;
5999         case OPC_BGTZL:
6000             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6001             goto likely;
6002         case OPC_BLEZ:
6003             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6004             goto not_likely;
6005         case OPC_BLEZL:
6006             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6007             goto likely;
6008         case OPC_BLTZ:
6009             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6010             goto not_likely;
6011         case OPC_BLTZL:
6012             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6013             goto likely;
6014         case OPC_BPOSGE32:
6015             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6016             goto not_likely;
6017 #if defined(TARGET_MIPS64)
6018         case OPC_BPOSGE64:
6019             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
6020             goto not_likely;
6021 #endif
6022         case OPC_BLTZAL:
6023             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6024             blink = 31;
6025         not_likely:
6026             ctx->hflags |= MIPS_HFLAG_BC;
6027             break;
6028         case OPC_BLTZALL:
6029             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6030             blink = 31;
6031         likely:
6032             ctx->hflags |= MIPS_HFLAG_BL;
6033             break;
6034         default:
6035             MIPS_INVAL("conditional branch/jump");
6036             generate_exception_end(ctx, EXCP_RI);
6037             goto out;
6038         }
6039     }
6040
6041     ctx->btarget = btgt;
6042
6043     switch (delayslot_size) {
6044     case 2:
6045         ctx->hflags |= MIPS_HFLAG_BDS16;
6046         break;
6047     case 4:
6048         ctx->hflags |= MIPS_HFLAG_BDS32;
6049         break;
6050     }
6051
6052     if (blink > 0) {
6053         int post_delay = insn_bytes + delayslot_size;
6054         int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
6055
6056         tcg_gen_movi_tl(cpu_gpr[blink],
6057                         ctx->base.pc_next + post_delay + lowbit);
6058     }
6059
6060  out:
6061     if (insn_bytes == 2)
6062         ctx->hflags |= MIPS_HFLAG_B16;
6063     tcg_temp_free(t0);
6064     tcg_temp_free(t1);
6065 }
6066
6067
6068 /* nanoMIPS Branches */
6069 static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
6070                                 int insn_bytes,
6071                                 int rs, int rt, int32_t offset)
6072 {
6073     target_ulong btgt = -1;
6074     int bcond_compute = 0;
6075     TCGv t0 = tcg_temp_new();
6076     TCGv t1 = tcg_temp_new();
6077
6078     /* Load needed operands */
6079     switch (opc) {
6080     case OPC_BEQ:
6081     case OPC_BNE:
6082         /* Compare two registers */
6083         if (rs != rt) {
6084             gen_load_gpr(t0, rs);
6085             gen_load_gpr(t1, rt);
6086             bcond_compute = 1;
6087         }
6088         btgt = ctx->base.pc_next + insn_bytes + offset;
6089         break;
6090     case OPC_BGEZAL:
6091         /* Compare to zero */
6092         if (rs != 0) {
6093             gen_load_gpr(t0, rs);
6094             bcond_compute = 1;
6095         }
6096         btgt = ctx->base.pc_next + insn_bytes + offset;
6097         break;
6098     case OPC_BPOSGE32:
6099         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6100         bcond_compute = 1;
6101         btgt = ctx->base.pc_next + insn_bytes + offset;
6102         break;
6103     case OPC_JR:
6104     case OPC_JALR:
6105         /* Jump to register */
6106         if (offset != 0 && offset != 16) {
6107             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6108                others are reserved. */
6109             MIPS_INVAL("jump hint");
6110             generate_exception_end(ctx, EXCP_RI);
6111             goto out;
6112         }
6113         gen_load_gpr(btarget, rs);
6114         break;
6115     default:
6116         MIPS_INVAL("branch/jump");
6117         generate_exception_end(ctx, EXCP_RI);
6118         goto out;
6119     }
6120     if (bcond_compute == 0) {
6121         /* No condition to be computed */
6122         switch (opc) {
6123         case OPC_BEQ:     /* rx == rx        */
6124             /* Always take */
6125             ctx->hflags |= MIPS_HFLAG_B;
6126             break;
6127         case OPC_BGEZAL:  /* 0 >= 0          */
6128             /* Always take and link */
6129             tcg_gen_movi_tl(cpu_gpr[31],
6130                             ctx->base.pc_next + insn_bytes);
6131             ctx->hflags |= MIPS_HFLAG_B;
6132             break;
6133         case OPC_BNE:     /* rx != rx        */
6134             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6135             /* Skip the instruction in the delay slot */
6136             ctx->base.pc_next += 4;
6137             goto out;
6138         case OPC_JR:
6139             ctx->hflags |= MIPS_HFLAG_BR;
6140             break;
6141         case OPC_JALR:
6142             if (rt > 0) {
6143                 tcg_gen_movi_tl(cpu_gpr[rt],
6144                                 ctx->base.pc_next + insn_bytes);
6145             }
6146             ctx->hflags |= MIPS_HFLAG_BR;
6147             break;
6148         default:
6149             MIPS_INVAL("branch/jump");
6150             generate_exception_end(ctx, EXCP_RI);
6151             goto out;
6152         }
6153     } else {
6154         switch (opc) {
6155         case OPC_BEQ:
6156             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6157             goto not_likely;
6158         case OPC_BNE:
6159             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6160             goto not_likely;
6161         case OPC_BGEZAL:
6162             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6163             tcg_gen_movi_tl(cpu_gpr[31],
6164                             ctx->base.pc_next + insn_bytes);
6165             goto not_likely;
6166         case OPC_BPOSGE32:
6167             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6168         not_likely:
6169             ctx->hflags |= MIPS_HFLAG_BC;
6170             break;
6171         default:
6172             MIPS_INVAL("conditional branch/jump");
6173             generate_exception_end(ctx, EXCP_RI);
6174             goto out;
6175         }
6176     }
6177
6178     ctx->btarget = btgt;
6179
6180  out:
6181     if (insn_bytes == 2) {
6182         ctx->hflags |= MIPS_HFLAG_B16;
6183     }
6184     tcg_temp_free(t0);
6185     tcg_temp_free(t1);
6186 }
6187
6188
6189 /* special3 bitfield operations */
6190 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
6191                         int rs, int lsb, int msb)
6192 {
6193     TCGv t0 = tcg_temp_new();
6194     TCGv t1 = tcg_temp_new();
6195
6196     gen_load_gpr(t1, rs);
6197     switch (opc) {
6198     case OPC_EXT:
6199         if (lsb + msb > 31) {
6200             goto fail;
6201         }
6202         if (msb != 31) {
6203             tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6204         } else {
6205             /* The two checks together imply that lsb == 0,
6206                so this is a simple sign-extension.  */
6207             tcg_gen_ext32s_tl(t0, t1);
6208         }
6209         break;
6210 #if defined(TARGET_MIPS64)
6211     case OPC_DEXTU:
6212         lsb += 32;
6213         goto do_dext;
6214     case OPC_DEXTM:
6215         msb += 32;
6216         goto do_dext;
6217     case OPC_DEXT:
6218     do_dext:
6219         if (lsb + msb > 63) {
6220             goto fail;
6221         }
6222         tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6223         break;
6224 #endif
6225     case OPC_INS:
6226         if (lsb > msb) {
6227             goto fail;
6228         }
6229         gen_load_gpr(t0, rt);
6230         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6231         tcg_gen_ext32s_tl(t0, t0);
6232         break;
6233 #if defined(TARGET_MIPS64)
6234     case OPC_DINSU:
6235         lsb += 32;
6236         /* FALLTHRU */
6237     case OPC_DINSM:
6238         msb += 32;
6239         /* FALLTHRU */
6240     case OPC_DINS:
6241         if (lsb > msb) {
6242             goto fail;
6243         }
6244         gen_load_gpr(t0, rt);
6245         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6246         break;
6247 #endif
6248     default:
6249 fail:
6250         MIPS_INVAL("bitops");
6251         generate_exception_end(ctx, EXCP_RI);
6252         tcg_temp_free(t0);
6253         tcg_temp_free(t1);
6254         return;
6255     }
6256     gen_store_gpr(t0, rt);
6257     tcg_temp_free(t0);
6258     tcg_temp_free(t1);
6259 }
6260
6261 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
6262 {
6263     TCGv t0;
6264
6265     if (rd == 0) {
6266         /* If no destination, treat it as a NOP. */
6267         return;
6268     }
6269
6270     t0 = tcg_temp_new();
6271     gen_load_gpr(t0, rt);
6272     switch (op2) {
6273     case OPC_WSBH:
6274         {
6275             TCGv t1 = tcg_temp_new();
6276             TCGv t2 = tcg_const_tl(0x00FF00FF);
6277
6278             tcg_gen_shri_tl(t1, t0, 8);
6279             tcg_gen_and_tl(t1, t1, t2);
6280             tcg_gen_and_tl(t0, t0, t2);
6281             tcg_gen_shli_tl(t0, t0, 8);
6282             tcg_gen_or_tl(t0, t0, t1);
6283             tcg_temp_free(t2);
6284             tcg_temp_free(t1);
6285             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6286         }
6287         break;
6288     case OPC_SEB:
6289         tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
6290         break;
6291     case OPC_SEH:
6292         tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
6293         break;
6294 #if defined(TARGET_MIPS64)
6295     case OPC_DSBH:
6296         {
6297             TCGv t1 = tcg_temp_new();
6298             TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
6299
6300             tcg_gen_shri_tl(t1, t0, 8);
6301             tcg_gen_and_tl(t1, t1, t2);
6302             tcg_gen_and_tl(t0, t0, t2);
6303             tcg_gen_shli_tl(t0, t0, 8);
6304             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6305             tcg_temp_free(t2);
6306             tcg_temp_free(t1);
6307         }
6308         break;
6309     case OPC_DSHD:
6310         {
6311             TCGv t1 = tcg_temp_new();
6312             TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
6313
6314             tcg_gen_shri_tl(t1, t0, 16);
6315             tcg_gen_and_tl(t1, t1, t2);
6316             tcg_gen_and_tl(t0, t0, t2);
6317             tcg_gen_shli_tl(t0, t0, 16);
6318             tcg_gen_or_tl(t0, t0, t1);
6319             tcg_gen_shri_tl(t1, t0, 32);
6320             tcg_gen_shli_tl(t0, t0, 32);
6321             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6322             tcg_temp_free(t2);
6323             tcg_temp_free(t1);
6324         }
6325         break;
6326 #endif
6327     default:
6328         MIPS_INVAL("bsfhl");
6329         generate_exception_end(ctx, EXCP_RI);
6330         tcg_temp_free(t0);
6331         return;
6332     }
6333     tcg_temp_free(t0);
6334 }
6335
6336 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
6337                     int imm2)
6338 {
6339     TCGv t0;
6340     TCGv t1;
6341     if (rd == 0) {
6342         /* Treat as NOP. */
6343         return;
6344     }
6345     t0 = tcg_temp_new();
6346     t1 = tcg_temp_new();
6347     gen_load_gpr(t0, rs);
6348     gen_load_gpr(t1, rt);
6349     tcg_gen_shli_tl(t0, t0, imm2 + 1);
6350     tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
6351     if (opc == OPC_LSA) {
6352         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
6353     }
6354
6355     tcg_temp_free(t1);
6356     tcg_temp_free(t0);
6357
6358     return;
6359 }
6360
6361 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6362                            int rt, int bits)
6363 {
6364     TCGv t0;
6365     if (rd == 0) {
6366         /* Treat as NOP. */
6367         return;
6368     }
6369     t0 = tcg_temp_new();
6370     if (bits == 0 || bits == wordsz) {
6371         if (bits == 0) {
6372             gen_load_gpr(t0, rt);
6373         } else {
6374             gen_load_gpr(t0, rs);
6375         }
6376         switch (wordsz) {
6377         case 32:
6378             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6379             break;
6380 #if defined(TARGET_MIPS64)
6381         case 64:
6382             tcg_gen_mov_tl(cpu_gpr[rd], t0);
6383             break;
6384 #endif
6385         }
6386     } else {
6387         TCGv t1 = tcg_temp_new();
6388         gen_load_gpr(t0, rt);
6389         gen_load_gpr(t1, rs);
6390         switch (wordsz) {
6391         case 32:
6392             {
6393                 TCGv_i64 t2 = tcg_temp_new_i64();
6394                 tcg_gen_concat_tl_i64(t2, t1, t0);
6395                 tcg_gen_shri_i64(t2, t2, 32 - bits);
6396                 gen_move_low32(cpu_gpr[rd], t2);
6397                 tcg_temp_free_i64(t2);
6398             }
6399             break;
6400 #if defined(TARGET_MIPS64)
6401         case 64:
6402             tcg_gen_shli_tl(t0, t0, bits);
6403             tcg_gen_shri_tl(t1, t1, 64 - bits);
6404             tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6405             break;
6406 #endif
6407         }
6408         tcg_temp_free(t1);
6409     }
6410
6411     tcg_temp_free(t0);
6412 }
6413
6414 static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6415                       int bp)
6416 {
6417     gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6418 }
6419
6420 static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6421                     int shift)
6422 {
6423     gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6424 }
6425
6426 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6427 {
6428     TCGv t0;
6429     if (rd == 0) {
6430         /* Treat as NOP. */
6431         return;
6432     }
6433     t0 = tcg_temp_new();
6434     gen_load_gpr(t0, rt);
6435     switch (opc) {
6436     case OPC_BITSWAP:
6437         gen_helper_bitswap(cpu_gpr[rd], t0);
6438         break;
6439 #if defined(TARGET_MIPS64)
6440     case OPC_DBITSWAP:
6441         gen_helper_dbitswap(cpu_gpr[rd], t0);
6442         break;
6443 #endif
6444     }
6445     tcg_temp_free(t0);
6446 }
6447
6448 #ifndef CONFIG_USER_ONLY
6449 /* CP0 (MMU and control) */
6450 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6451 {
6452     TCGv_i64 t0 = tcg_temp_new_i64();
6453     TCGv_i64 t1 = tcg_temp_new_i64();
6454
6455     tcg_gen_ext_tl_i64(t0, arg);
6456     tcg_gen_ld_i64(t1, cpu_env, off);
6457 #if defined(TARGET_MIPS64)
6458     tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6459 #else
6460     tcg_gen_concat32_i64(t1, t1, t0);
6461 #endif
6462     tcg_gen_st_i64(t1, cpu_env, off);
6463     tcg_temp_free_i64(t1);
6464     tcg_temp_free_i64(t0);
6465 }
6466
6467 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6468 {
6469     TCGv_i64 t0 = tcg_temp_new_i64();
6470     TCGv_i64 t1 = tcg_temp_new_i64();
6471
6472     tcg_gen_ext_tl_i64(t0, arg);
6473     tcg_gen_ld_i64(t1, cpu_env, off);
6474     tcg_gen_concat32_i64(t1, t1, t0);
6475     tcg_gen_st_i64(t1, cpu_env, off);
6476     tcg_temp_free_i64(t1);
6477     tcg_temp_free_i64(t0);
6478 }
6479
6480 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6481 {
6482     TCGv_i64 t0 = tcg_temp_new_i64();
6483
6484     tcg_gen_ld_i64(t0, cpu_env, off);
6485 #if defined(TARGET_MIPS64)
6486     tcg_gen_shri_i64(t0, t0, 30);
6487 #else
6488     tcg_gen_shri_i64(t0, t0, 32);
6489 #endif
6490     gen_move_low32(arg, t0);
6491     tcg_temp_free_i64(t0);
6492 }
6493
6494 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6495 {
6496     TCGv_i64 t0 = tcg_temp_new_i64();
6497
6498     tcg_gen_ld_i64(t0, cpu_env, off);
6499     tcg_gen_shri_i64(t0, t0, 32 + shift);
6500     gen_move_low32(arg, t0);
6501     tcg_temp_free_i64(t0);
6502 }
6503
6504 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
6505 {
6506     TCGv_i32 t0 = tcg_temp_new_i32();
6507
6508     tcg_gen_ld_i32(t0, cpu_env, off);
6509     tcg_gen_ext_i32_tl(arg, t0);
6510     tcg_temp_free_i32(t0);
6511 }
6512
6513 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
6514 {
6515     tcg_gen_ld_tl(arg, cpu_env, off);
6516     tcg_gen_ext32s_tl(arg, arg);
6517 }
6518
6519 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
6520 {
6521     TCGv_i32 t0 = tcg_temp_new_i32();
6522
6523     tcg_gen_trunc_tl_i32(t0, arg);
6524     tcg_gen_st_i32(t0, cpu_env, off);
6525     tcg_temp_free_i32(t0);
6526 }
6527
6528 #define CP0_CHECK(c)                            \
6529     do {                                        \
6530         if (!(c)) {                             \
6531             goto cp0_unimplemented;             \
6532         }                                       \
6533     } while (0)
6534
6535 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6536 {
6537     const char *register_name = "invalid";
6538
6539     switch (reg) {
6540     case CP0_REGISTER_02:
6541         switch (sel) {
6542         case 0:
6543             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6544             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6545             register_name = "EntryLo0";
6546             break;
6547         default:
6548             goto cp0_unimplemented;
6549         }
6550         break;
6551     case CP0_REGISTER_03:
6552         switch (sel) {
6553         case 0:
6554             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6555             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6556             register_name = "EntryLo1";
6557             break;
6558         default:
6559             goto cp0_unimplemented;
6560         }
6561         break;
6562     case CP0_REGISTER_09:
6563         switch (sel) {
6564         case 7:
6565             CP0_CHECK(ctx->saar);
6566             gen_helper_mfhc0_saar(arg, cpu_env);
6567             register_name = "SAAR";
6568             break;
6569         default:
6570             goto cp0_unimplemented;
6571         }
6572         break;
6573     case CP0_REGISTER_17:
6574         switch (sel) {
6575         case 0:
6576             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
6577                              ctx->CP0_LLAddr_shift);
6578             register_name = "LLAddr";
6579             break;
6580         case 1:
6581             CP0_CHECK(ctx->mrp);
6582             gen_helper_mfhc0_maar(arg, cpu_env);
6583             register_name = "MAAR";
6584             break;
6585         default:
6586             goto cp0_unimplemented;
6587         }
6588         break;
6589     case CP0_REGISTER_28:
6590         switch (sel) {
6591         case 0:
6592         case 2:
6593         case 4:
6594         case 6:
6595             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6596             register_name = "TagLo";
6597             break;
6598         default:
6599             goto cp0_unimplemented;
6600         }
6601         break;
6602     default:
6603         goto cp0_unimplemented;
6604     }
6605     trace_mips_translate_c0("mfhc0", register_name, reg, sel);
6606     return;
6607
6608 cp0_unimplemented:
6609     qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
6610                   register_name, reg, sel);
6611     tcg_gen_movi_tl(arg, 0);
6612 }
6613
6614 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6615 {
6616     const char *register_name = "invalid";
6617     uint64_t mask = ctx->PAMask >> 36;
6618
6619     switch (reg) {
6620     case CP0_REGISTER_02:
6621         switch (sel) {
6622         case 0:
6623             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6624             tcg_gen_andi_tl(arg, arg, mask);
6625             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6626             register_name = "EntryLo0";
6627             break;
6628         default:
6629             goto cp0_unimplemented;
6630         }
6631         break;
6632     case CP0_REGISTER_03:
6633         switch (sel) {
6634         case 0:
6635             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6636             tcg_gen_andi_tl(arg, arg, mask);
6637             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6638             register_name = "EntryLo1";
6639             break;
6640         default:
6641             goto cp0_unimplemented;
6642         }
6643         break;
6644     case CP0_REGISTER_09:
6645         switch (sel) {
6646         case 7:
6647             CP0_CHECK(ctx->saar);
6648             gen_helper_mthc0_saar(cpu_env, arg);
6649             register_name = "SAAR";
6650             break;
6651         default:
6652             goto cp0_unimplemented;
6653         }
6654     case CP0_REGISTER_17:
6655         switch (sel) {
6656         case 0:
6657             /* LLAddr is read-only (the only exception is bit 0 if LLB is
6658                supported); the CP0_LLAddr_rw_bitmask does not seem to be
6659                relevant for modern MIPS cores supporting MTHC0, therefore
6660                treating MTHC0 to LLAddr as NOP. */
6661             register_name = "LLAddr";
6662             break;
6663         case 1:
6664             CP0_CHECK(ctx->mrp);
6665             gen_helper_mthc0_maar(cpu_env, arg);
6666             register_name = "MAAR";
6667             break;
6668         default:
6669             goto cp0_unimplemented;
6670         }
6671         break;
6672     case CP0_REGISTER_28:
6673         switch (sel) {
6674         case 0:
6675         case 2:
6676         case 4:
6677         case 6:
6678             tcg_gen_andi_tl(arg, arg, mask);
6679             gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6680             register_name = "TagLo";
6681             break;
6682         default:
6683             goto cp0_unimplemented;
6684         }
6685         break;
6686     default:
6687         goto cp0_unimplemented;
6688     }
6689     trace_mips_translate_c0("mthc0", register_name, reg, sel);
6690
6691 cp0_unimplemented:
6692     qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
6693                   register_name, reg, sel);
6694 }
6695
6696 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6697 {
6698     if (ctx->insn_flags & ISA_MIPS32R6) {
6699         tcg_gen_movi_tl(arg, 0);
6700     } else {
6701         tcg_gen_movi_tl(arg, ~0);
6702     }
6703 }
6704
6705 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6706 {
6707     const char *register_name = "invalid";
6708
6709     if (sel != 0)
6710         check_insn(ctx, ISA_MIPS32);
6711
6712     switch (reg) {
6713     case CP0_REGISTER_00:
6714         switch (sel) {
6715         case 0:
6716             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6717             register_name = "Index";
6718             break;
6719         case 1:
6720             CP0_CHECK(ctx->insn_flags & ASE_MT);
6721             gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6722             register_name = "MVPControl";
6723             break;
6724         case 2:
6725             CP0_CHECK(ctx->insn_flags & ASE_MT);
6726             gen_helper_mfc0_mvpconf0(arg, cpu_env);
6727             register_name = "MVPConf0";
6728             break;
6729         case 3:
6730             CP0_CHECK(ctx->insn_flags & ASE_MT);
6731             gen_helper_mfc0_mvpconf1(arg, cpu_env);
6732             register_name = "MVPConf1";
6733             break;
6734         case 4:
6735             CP0_CHECK(ctx->vp);
6736             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6737             register_name = "VPControl";
6738             break;
6739         default:
6740             goto cp0_unimplemented;
6741         }
6742         break;
6743     case CP0_REGISTER_01:
6744         switch (sel) {
6745         case 0:
6746             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6747             gen_helper_mfc0_random(arg, cpu_env);
6748             register_name = "Random";
6749             break;
6750         case 1:
6751             CP0_CHECK(ctx->insn_flags & ASE_MT);
6752             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6753             register_name = "VPEControl";
6754             break;
6755         case 2:
6756             CP0_CHECK(ctx->insn_flags & ASE_MT);
6757             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6758             register_name = "VPEConf0";
6759             break;
6760         case 3:
6761             CP0_CHECK(ctx->insn_flags & ASE_MT);
6762             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6763             register_name = "VPEConf1";
6764             break;
6765         case 4:
6766             CP0_CHECK(ctx->insn_flags & ASE_MT);
6767             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
6768             register_name = "YQMask";
6769             break;
6770         case 5:
6771             CP0_CHECK(ctx->insn_flags & ASE_MT);
6772             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
6773             register_name = "VPESchedule";
6774             break;
6775         case 6:
6776             CP0_CHECK(ctx->insn_flags & ASE_MT);
6777             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6778             register_name = "VPEScheFBack";
6779             break;
6780         case 7:
6781             CP0_CHECK(ctx->insn_flags & ASE_MT);
6782             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6783             register_name = "VPEOpt";
6784             break;
6785         default:
6786             goto cp0_unimplemented;
6787         }
6788         break;
6789     case CP0_REGISTER_02:
6790         switch (sel) {
6791         case 0:
6792             {
6793                 TCGv_i64 tmp = tcg_temp_new_i64();
6794                 tcg_gen_ld_i64(tmp, cpu_env,
6795                                offsetof(CPUMIPSState, CP0_EntryLo0));
6796 #if defined(TARGET_MIPS64)
6797                 if (ctx->rxi) {
6798                     /* Move RI/XI fields to bits 31:30 */
6799                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6800                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6801                 }
6802 #endif
6803                 gen_move_low32(arg, tmp);
6804                 tcg_temp_free_i64(tmp);
6805             }
6806             register_name = "EntryLo0";
6807             break;
6808         case 1:
6809             CP0_CHECK(ctx->insn_flags & ASE_MT);
6810             gen_helper_mfc0_tcstatus(arg, cpu_env);
6811             register_name = "TCStatus";
6812             break;
6813         case 2:
6814             CP0_CHECK(ctx->insn_flags & ASE_MT);
6815             gen_helper_mfc0_tcbind(arg, cpu_env);
6816             register_name = "TCBind";
6817             break;
6818         case 3:
6819             CP0_CHECK(ctx->insn_flags & ASE_MT);
6820             gen_helper_mfc0_tcrestart(arg, cpu_env);
6821             register_name = "TCRestart";
6822             break;
6823         case 4:
6824             CP0_CHECK(ctx->insn_flags & ASE_MT);
6825             gen_helper_mfc0_tchalt(arg, cpu_env);
6826             register_name = "TCHalt";
6827             break;
6828         case 5:
6829             CP0_CHECK(ctx->insn_flags & ASE_MT);
6830             gen_helper_mfc0_tccontext(arg, cpu_env);
6831             register_name = "TCContext";
6832             break;
6833         case 6:
6834             CP0_CHECK(ctx->insn_flags & ASE_MT);
6835             gen_helper_mfc0_tcschedule(arg, cpu_env);
6836             register_name = "TCSchedule";
6837             break;
6838         case 7:
6839             CP0_CHECK(ctx->insn_flags & ASE_MT);
6840             gen_helper_mfc0_tcschefback(arg, cpu_env);
6841             register_name = "TCScheFBack";
6842             break;
6843         default:
6844             goto cp0_unimplemented;
6845         }
6846         break;
6847     case CP0_REGISTER_03:
6848         switch (sel) {
6849         case 0:
6850             {
6851                 TCGv_i64 tmp = tcg_temp_new_i64();
6852                 tcg_gen_ld_i64(tmp, cpu_env,
6853                                offsetof(CPUMIPSState, CP0_EntryLo1));
6854 #if defined(TARGET_MIPS64)
6855                 if (ctx->rxi) {
6856                     /* Move RI/XI fields to bits 31:30 */
6857                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6858                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6859                 }
6860 #endif
6861                 gen_move_low32(arg, tmp);
6862                 tcg_temp_free_i64(tmp);
6863             }
6864             register_name = "EntryLo1";
6865             break;
6866         case 1:
6867             CP0_CHECK(ctx->vp);
6868             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6869             register_name = "GlobalNumber";
6870             break;
6871         default:
6872             goto cp0_unimplemented;
6873         }
6874         break;
6875     case CP0_REGISTER_04:
6876         switch (sel) {
6877         case 0:
6878             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6879             tcg_gen_ext32s_tl(arg, arg);
6880             register_name = "Context";
6881             break;
6882         case 1:
6883 //            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
6884             register_name = "ContextConfig";
6885             goto cp0_unimplemented;
6886         case 2:
6887             CP0_CHECK(ctx->ulri);
6888             tcg_gen_ld_tl(arg, cpu_env,
6889                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6890             tcg_gen_ext32s_tl(arg, arg);
6891             register_name = "UserLocal";
6892             break;
6893         default:
6894             goto cp0_unimplemented;
6895         }
6896         break;
6897     case CP0_REGISTER_05:
6898         switch (sel) {
6899         case 0:
6900             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6901             register_name = "PageMask";
6902             break;
6903         case 1:
6904             check_insn(ctx, ISA_MIPS32R2);
6905             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6906             register_name = "PageGrain";
6907             break;
6908         case 2:
6909             CP0_CHECK(ctx->sc);
6910             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6911             tcg_gen_ext32s_tl(arg, arg);
6912             register_name = "SegCtl0";
6913             break;
6914         case 3:
6915             CP0_CHECK(ctx->sc);
6916             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6917             tcg_gen_ext32s_tl(arg, arg);
6918             register_name = "SegCtl1";
6919             break;
6920         case 4:
6921             CP0_CHECK(ctx->sc);
6922             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6923             tcg_gen_ext32s_tl(arg, arg);
6924             register_name = "SegCtl2";
6925             break;
6926         case 5:
6927             check_pw(ctx);
6928             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6929             register_name = "PWBase";
6930             break;
6931         case 6:
6932             check_pw(ctx);
6933             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
6934             register_name = "PWField";
6935             break;
6936         case 7:
6937             check_pw(ctx);
6938             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
6939             register_name = "PWSize";
6940             break;
6941         default:
6942             goto cp0_unimplemented;
6943         }
6944         break;
6945     case CP0_REGISTER_06:
6946         switch (sel) {
6947         case 0:
6948             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6949             register_name = "Wired";
6950             break;
6951         case 1:
6952             check_insn(ctx, ISA_MIPS32R2);
6953             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6954             register_name = "SRSConf0";
6955             break;
6956         case 2:
6957             check_insn(ctx, ISA_MIPS32R2);
6958             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6959             register_name = "SRSConf1";
6960             break;
6961         case 3:
6962             check_insn(ctx, ISA_MIPS32R2);
6963             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6964             register_name = "SRSConf2";
6965             break;
6966         case 4:
6967             check_insn(ctx, ISA_MIPS32R2);
6968             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6969             register_name = "SRSConf3";
6970             break;
6971         case 5:
6972             check_insn(ctx, ISA_MIPS32R2);
6973             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6974             register_name = "SRSConf4";
6975             break;
6976         case 6:
6977             check_pw(ctx);
6978             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6979             register_name = "PWCtl";
6980             break;
6981         default:
6982             goto cp0_unimplemented;
6983         }
6984         break;
6985     case CP0_REGISTER_07:
6986         switch (sel) {
6987         case 0:
6988             check_insn(ctx, ISA_MIPS32R2);
6989             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6990             register_name = "HWREna";
6991             break;
6992         default:
6993             goto cp0_unimplemented;
6994         }
6995         break;
6996     case CP0_REGISTER_08:
6997         switch (sel) {
6998         case 0:
6999             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7000             tcg_gen_ext32s_tl(arg, arg);
7001             register_name = "BadVAddr";
7002             break;
7003         case 1:
7004             CP0_CHECK(ctx->bi);
7005             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7006             register_name = "BadInstr";
7007             break;
7008         case 2:
7009             CP0_CHECK(ctx->bp);
7010             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7011             register_name = "BadInstrP";
7012             break;
7013         case 3:
7014             CP0_CHECK(ctx->bi);
7015             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7016             tcg_gen_andi_tl(arg, arg, ~0xffff);
7017             register_name = "BadInstrX";
7018             break;
7019        default:
7020             goto cp0_unimplemented;
7021         }
7022         break;
7023     case CP0_REGISTER_09:
7024         switch (sel) {
7025         case 0:
7026             /* Mark as an IO operation because we read the time.  */
7027             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7028                 gen_io_start();
7029             }
7030             gen_helper_mfc0_count(arg, cpu_env);
7031             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7032                 gen_io_end();
7033             }
7034             /* Break the TB to be able to take timer interrupts immediately
7035                after reading count. DISAS_STOP isn't sufficient, we need to
7036                ensure we break completely out of translated code.  */
7037             gen_save_pc(ctx->base.pc_next + 4);
7038             ctx->base.is_jmp = DISAS_EXIT;
7039             register_name = "Count";
7040             break;
7041         case 6:
7042             CP0_CHECK(ctx->saar);
7043             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7044             register_name = "SAARI";
7045             break;
7046         case 7:
7047             CP0_CHECK(ctx->saar);
7048             gen_helper_mfc0_saar(arg, cpu_env);
7049             register_name = "SAAR";
7050             break;
7051         default:
7052             goto cp0_unimplemented;
7053         }
7054         break;
7055     case CP0_REGISTER_10:
7056         switch (sel) {
7057         case 0:
7058             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7059             tcg_gen_ext32s_tl(arg, arg);
7060             register_name = "EntryHi";
7061             break;
7062         default:
7063             goto cp0_unimplemented;
7064         }
7065         break;
7066     case CP0_REGISTER_11:
7067         switch (sel) {
7068         case 0:
7069             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7070             register_name = "Compare";
7071             break;
7072         /* 6,7 are implementation dependent */
7073         default:
7074             goto cp0_unimplemented;
7075         }
7076         break;
7077     case CP0_REGISTER_12:
7078         switch (sel) {
7079         case 0:
7080             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7081             register_name = "Status";
7082             break;
7083         case 1:
7084             check_insn(ctx, ISA_MIPS32R2);
7085             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7086             register_name = "IntCtl";
7087             break;
7088         case 2:
7089             check_insn(ctx, ISA_MIPS32R2);
7090             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7091             register_name = "SRSCtl";
7092             break;
7093         case 3:
7094             check_insn(ctx, ISA_MIPS32R2);
7095             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7096             register_name = "SRSMap";
7097             break;
7098         default:
7099             goto cp0_unimplemented;
7100        }
7101         break;
7102     case CP0_REGISTER_13:
7103         switch (sel) {
7104         case 0:
7105             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7106             register_name = "Cause";
7107             break;
7108         default:
7109             goto cp0_unimplemented;
7110        }
7111         break;
7112     case CP0_REGISTER_14:
7113         switch (sel) {
7114         case 0:
7115             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7116             tcg_gen_ext32s_tl(arg, arg);
7117             register_name = "EPC";
7118             break;
7119         default:
7120             goto cp0_unimplemented;
7121         }
7122         break;
7123     case CP0_REGISTER_15:
7124         switch (sel) {
7125         case 0:
7126             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7127             register_name = "PRid";
7128             break;
7129         case 1:
7130             check_insn(ctx, ISA_MIPS32R2);
7131             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7132             tcg_gen_ext32s_tl(arg, arg);
7133             register_name = "EBase";
7134             break;
7135         case 3:
7136             check_insn(ctx, ISA_MIPS32R2);
7137             CP0_CHECK(ctx->cmgcr);
7138             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7139             tcg_gen_ext32s_tl(arg, arg);
7140             register_name = "CMGCRBase";
7141             break;
7142         default:
7143             goto cp0_unimplemented;
7144        }
7145         break;
7146     case CP0_REGISTER_16:
7147         switch (sel) {
7148         case 0:
7149             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7150             register_name = "Config";
7151             break;
7152         case 1:
7153             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7154             register_name = "Config1";
7155             break;
7156         case 2:
7157             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7158             register_name = "Config2";
7159             break;
7160         case 3:
7161             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7162             register_name = "Config3";
7163             break;
7164         case 4:
7165             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7166             register_name = "Config4";
7167             break;
7168         case 5:
7169             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7170             register_name = "Config5";
7171             break;
7172         /* 6,7 are implementation dependent */
7173         case 6:
7174             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7175             register_name = "Config6";
7176             break;
7177         case 7:
7178             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7179             register_name = "Config7";
7180             break;
7181         default:
7182             goto cp0_unimplemented;
7183         }
7184         break;
7185     case CP0_REGISTER_17:
7186         switch (sel) {
7187         case 0:
7188             gen_helper_mfc0_lladdr(arg, cpu_env);
7189             register_name = "LLAddr";
7190             break;
7191         case 1:
7192             CP0_CHECK(ctx->mrp);
7193             gen_helper_mfc0_maar(arg, cpu_env);
7194             register_name = "MAAR";
7195             break;
7196         case 2:
7197             CP0_CHECK(ctx->mrp);
7198             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7199             register_name = "MAARI";
7200             break;
7201         default:
7202             goto cp0_unimplemented;
7203         }
7204         break;
7205     case CP0_REGISTER_18:
7206         switch (sel) {
7207         case 0:
7208         case 1:
7209         case 2:
7210         case 3:
7211         case 4:
7212         case 5:
7213         case 6:
7214         case 7:
7215             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7216             gen_helper_1e0i(mfc0_watchlo, arg, sel);
7217             register_name = "WatchLo";
7218             break;
7219         default:
7220             goto cp0_unimplemented;
7221         }
7222         break;
7223     case CP0_REGISTER_19:
7224         switch (sel) {
7225         case 0:
7226         case 1:
7227         case 2:
7228         case 3:
7229         case 4:
7230         case 5:
7231         case 6:
7232         case 7:
7233             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7234             gen_helper_1e0i(mfc0_watchhi, arg, sel);
7235             register_name = "WatchHi";
7236             break;
7237         default:
7238             goto cp0_unimplemented;
7239         }
7240         break;
7241     case CP0_REGISTER_20:
7242         switch (sel) {
7243         case 0:
7244 #if defined(TARGET_MIPS64)
7245             check_insn(ctx, ISA_MIPS3);
7246             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7247             tcg_gen_ext32s_tl(arg, arg);
7248             register_name = "XContext";
7249             break;
7250 #endif
7251         default:
7252             goto cp0_unimplemented;
7253         }
7254         break;
7255     case CP0_REGISTER_21:
7256        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7257         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7258         switch (sel) {
7259         case 0:
7260             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7261             register_name = "Framemask";
7262             break;
7263         default:
7264             goto cp0_unimplemented;
7265         }
7266         break;
7267     case CP0_REGISTER_22:
7268         tcg_gen_movi_tl(arg, 0); /* unimplemented */
7269         register_name = "'Diagnostic"; /* implementation dependent */
7270         break;
7271     case CP0_REGISTER_23:
7272         switch (sel) {
7273         case 0:
7274             gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7275             register_name = "Debug";
7276             break;
7277         case 1:
7278 //            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
7279             register_name = "TraceControl";
7280             goto cp0_unimplemented;
7281         case 2:
7282 //            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
7283             register_name = "TraceControl2";
7284             goto cp0_unimplemented;
7285         case 3:
7286 //            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
7287             register_name = "UserTraceData";
7288             goto cp0_unimplemented;
7289         case 4:
7290 //            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
7291             register_name = "TraceBPC";
7292             goto cp0_unimplemented;
7293         default:
7294             goto cp0_unimplemented;
7295         }
7296         break;
7297     case CP0_REGISTER_24:
7298         switch (sel) {
7299         case 0:
7300             /* EJTAG support */
7301             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7302             tcg_gen_ext32s_tl(arg, arg);
7303             register_name = "DEPC";
7304             break;
7305         default:
7306             goto cp0_unimplemented;
7307         }
7308         break;
7309     case CP0_REGISTER_25:
7310         switch (sel) {
7311         case 0:
7312             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7313             register_name = "Performance0";
7314             break;
7315         case 1:
7316 //            gen_helper_mfc0_performance1(arg);
7317             register_name = "Performance1";
7318             goto cp0_unimplemented;
7319         case 2:
7320 //            gen_helper_mfc0_performance2(arg);
7321             register_name = "Performance2";
7322             goto cp0_unimplemented;
7323         case 3:
7324 //            gen_helper_mfc0_performance3(arg);
7325             register_name = "Performance3";
7326             goto cp0_unimplemented;
7327         case 4:
7328 //            gen_helper_mfc0_performance4(arg);
7329             register_name = "Performance4";
7330             goto cp0_unimplemented;
7331         case 5:
7332 //            gen_helper_mfc0_performance5(arg);
7333             register_name = "Performance5";
7334             goto cp0_unimplemented;
7335         case 6:
7336 //            gen_helper_mfc0_performance6(arg);
7337             register_name = "Performance6";
7338             goto cp0_unimplemented;
7339         case 7:
7340 //            gen_helper_mfc0_performance7(arg);
7341             register_name = "Performance7";
7342             goto cp0_unimplemented;
7343         default:
7344             goto cp0_unimplemented;
7345         }
7346         break;
7347     case CP0_REGISTER_26:
7348         switch (sel) {
7349         case 0:
7350             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7351             register_name = "ErrCtl";
7352             break;
7353         default:
7354             goto cp0_unimplemented;
7355         }
7356         break;
7357     case CP0_REGISTER_27:
7358         switch (sel) {
7359         case 0:
7360         case 1:
7361         case 2:
7362         case 3:
7363             tcg_gen_movi_tl(arg, 0); /* unimplemented */
7364             register_name = "CacheErr";
7365             break;
7366         default:
7367             goto cp0_unimplemented;
7368         }
7369         break;
7370     case CP0_REGISTER_28:
7371         switch (sel) {
7372         case 0:
7373         case 2:
7374         case 4:
7375         case 6:
7376             {
7377                 TCGv_i64 tmp = tcg_temp_new_i64();
7378                 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
7379                 gen_move_low32(arg, tmp);
7380                 tcg_temp_free_i64(tmp);
7381             }
7382             register_name = "TagLo";
7383             break;
7384         case 1:
7385         case 3:
7386         case 5:
7387         case 7:
7388             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7389             register_name = "DataLo";
7390             break;
7391         default:
7392             goto cp0_unimplemented;
7393         }
7394         break;
7395     case CP0_REGISTER_29:
7396         switch (sel) {
7397         case 0:
7398         case 2:
7399         case 4:
7400         case 6:
7401             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7402             register_name = "TagHi";
7403             break;
7404         case 1:
7405         case 3:
7406         case 5:
7407         case 7:
7408             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7409             register_name = "DataHi";
7410             break;
7411         default:
7412             goto cp0_unimplemented;
7413         }
7414         break;
7415     case CP0_REGISTER_30:
7416         switch (sel) {
7417         case 0:
7418             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7419             tcg_gen_ext32s_tl(arg, arg);
7420             register_name = "ErrorEPC";
7421             break;
7422         default:
7423             goto cp0_unimplemented;
7424         }
7425         break;
7426     case CP0_REGISTER_31:
7427         switch (sel) {
7428         case 0:
7429             /* EJTAG support */
7430             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7431             register_name = "DESAVE";
7432             break;
7433         case 2:
7434         case 3:
7435         case 4:
7436         case 5:
7437         case 6:
7438         case 7:
7439             CP0_CHECK(ctx->kscrexist & (1 << sel));
7440             tcg_gen_ld_tl(arg, cpu_env,
7441                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7442             tcg_gen_ext32s_tl(arg, arg);
7443             register_name = "KScratch";
7444             break;
7445         default:
7446             goto cp0_unimplemented;
7447         }
7448         break;
7449     default:
7450        goto cp0_unimplemented;
7451     }
7452     trace_mips_translate_c0("mfc0", register_name, reg, sel);
7453     return;
7454
7455 cp0_unimplemented:
7456     qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
7457                   register_name, reg, sel);
7458     gen_mfc0_unimplemented(ctx, arg);
7459 }
7460
7461 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7462 {
7463     const char *register_name = "invalid";
7464
7465     if (sel != 0)
7466         check_insn(ctx, ISA_MIPS32);
7467
7468     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7469         gen_io_start();
7470     }
7471
7472     switch (reg) {
7473     case CP0_REGISTER_00:
7474         switch (sel) {
7475         case 0:
7476             gen_helper_mtc0_index(cpu_env, arg);
7477             register_name = "Index";
7478             break;
7479         case 1:
7480             CP0_CHECK(ctx->insn_flags & ASE_MT);
7481             gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7482             register_name = "MVPControl";
7483             break;
7484         case 2:
7485             CP0_CHECK(ctx->insn_flags & ASE_MT);
7486             /* ignored */
7487             register_name = "MVPConf0";
7488             break;
7489         case 3:
7490             CP0_CHECK(ctx->insn_flags & ASE_MT);
7491             /* ignored */
7492             register_name = "MVPConf1";
7493             break;
7494         case 4:
7495             CP0_CHECK(ctx->vp);
7496             /* ignored */
7497             register_name = "VPControl";
7498             break;
7499         default:
7500             goto cp0_unimplemented;
7501         }
7502         break;
7503     case CP0_REGISTER_01:
7504         switch (sel) {
7505         case 0:
7506             /* ignored */
7507             register_name = "Random";
7508             break;
7509         case 1:
7510             CP0_CHECK(ctx->insn_flags & ASE_MT);
7511             gen_helper_mtc0_vpecontrol(cpu_env, arg);
7512             register_name = "VPEControl";
7513             break;
7514         case 2:
7515             CP0_CHECK(ctx->insn_flags & ASE_MT);
7516             gen_helper_mtc0_vpeconf0(cpu_env, arg);
7517             register_name = "VPEConf0";
7518             break;
7519         case 3:
7520             CP0_CHECK(ctx->insn_flags & ASE_MT);
7521             gen_helper_mtc0_vpeconf1(cpu_env, arg);
7522             register_name = "VPEConf1";
7523             break;
7524         case 4:
7525             CP0_CHECK(ctx->insn_flags & ASE_MT);
7526             gen_helper_mtc0_yqmask(cpu_env, arg);
7527             register_name = "YQMask";
7528             break;
7529         case 5:
7530             CP0_CHECK(ctx->insn_flags & ASE_MT);
7531             tcg_gen_st_tl(arg, cpu_env,
7532                           offsetof(CPUMIPSState, CP0_VPESchedule));
7533             register_name = "VPESchedule";
7534             break;
7535         case 6:
7536             CP0_CHECK(ctx->insn_flags & ASE_MT);
7537             tcg_gen_st_tl(arg, cpu_env,
7538                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
7539             register_name = "VPEScheFBack";
7540             break;
7541         case 7:
7542             CP0_CHECK(ctx->insn_flags & ASE_MT);
7543             gen_helper_mtc0_vpeopt(cpu_env, arg);
7544             register_name = "VPEOpt";
7545             break;
7546         default:
7547             goto cp0_unimplemented;
7548         }
7549         break;
7550     case CP0_REGISTER_02:
7551         switch (sel) {
7552         case 0:
7553             gen_helper_mtc0_entrylo0(cpu_env, arg);
7554             register_name = "EntryLo0";
7555             break;
7556         case 1:
7557             CP0_CHECK(ctx->insn_flags & ASE_MT);
7558             gen_helper_mtc0_tcstatus(cpu_env, arg);
7559             register_name = "TCStatus";
7560             break;
7561         case 2:
7562             CP0_CHECK(ctx->insn_flags & ASE_MT);
7563             gen_helper_mtc0_tcbind(cpu_env, arg);
7564             register_name = "TCBind";
7565             break;
7566         case 3:
7567             CP0_CHECK(ctx->insn_flags & ASE_MT);
7568             gen_helper_mtc0_tcrestart(cpu_env, arg);
7569             register_name = "TCRestart";
7570             break;
7571         case 4:
7572             CP0_CHECK(ctx->insn_flags & ASE_MT);
7573             gen_helper_mtc0_tchalt(cpu_env, arg);
7574             register_name = "TCHalt";
7575             break;
7576         case 5:
7577             CP0_CHECK(ctx->insn_flags & ASE_MT);
7578             gen_helper_mtc0_tccontext(cpu_env, arg);
7579             register_name = "TCContext";
7580             break;
7581         case 6:
7582             CP0_CHECK(ctx->insn_flags & ASE_MT);
7583             gen_helper_mtc0_tcschedule(cpu_env, arg);
7584             register_name = "TCSchedule";
7585             break;
7586         case 7:
7587             CP0_CHECK(ctx->insn_flags & ASE_MT);
7588             gen_helper_mtc0_tcschefback(cpu_env, arg);
7589             register_name = "TCScheFBack";
7590             break;
7591         default:
7592             goto cp0_unimplemented;
7593         }
7594         break;
7595     case CP0_REGISTER_03:
7596         switch (sel) {
7597         case 0:
7598             gen_helper_mtc0_entrylo1(cpu_env, arg);
7599             register_name = "EntryLo1";
7600             break;
7601         case 1:
7602             CP0_CHECK(ctx->vp);
7603             /* ignored */
7604             register_name = "GlobalNumber";
7605             break;
7606         default:
7607             goto cp0_unimplemented;
7608         }
7609         break;
7610     case CP0_REGISTER_04:
7611         switch (sel) {
7612         case 0:
7613             gen_helper_mtc0_context(cpu_env, arg);
7614             register_name = "Context";
7615             break;
7616         case 1:
7617 //            gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7618             register_name = "ContextConfig";
7619             goto cp0_unimplemented;
7620         case 2:
7621             CP0_CHECK(ctx->ulri);
7622             tcg_gen_st_tl(arg, cpu_env,
7623                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7624             register_name = "UserLocal";
7625             break;
7626         default:
7627             goto cp0_unimplemented;
7628         }
7629         break;
7630     case CP0_REGISTER_05:
7631         switch (sel) {
7632         case 0:
7633             gen_helper_mtc0_pagemask(cpu_env, arg);
7634             register_name = "PageMask";
7635             break;
7636         case 1:
7637             check_insn(ctx, ISA_MIPS32R2);
7638             gen_helper_mtc0_pagegrain(cpu_env, arg);
7639             register_name = "PageGrain";
7640             ctx->base.is_jmp = DISAS_STOP;
7641             break;
7642         case 2:
7643             CP0_CHECK(ctx->sc);
7644             gen_helper_mtc0_segctl0(cpu_env, arg);
7645             register_name = "SegCtl0";
7646             break;
7647         case 3:
7648             CP0_CHECK(ctx->sc);
7649             gen_helper_mtc0_segctl1(cpu_env, arg);
7650             register_name = "SegCtl1";
7651             break;
7652         case 4:
7653             CP0_CHECK(ctx->sc);
7654             gen_helper_mtc0_segctl2(cpu_env, arg);
7655             register_name = "SegCtl2";
7656             break;
7657         case 5:
7658             check_pw(ctx);
7659             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7660             register_name = "PWBase";
7661             break;
7662         case 6:
7663             check_pw(ctx);
7664             gen_helper_mtc0_pwfield(cpu_env, arg);
7665             register_name = "PWField";
7666             break;
7667         case 7:
7668             check_pw(ctx);
7669             gen_helper_mtc0_pwsize(cpu_env, arg);
7670             register_name = "PWSize";
7671             break;
7672         default:
7673             goto cp0_unimplemented;
7674         }
7675         break;
7676     case CP0_REGISTER_06:
7677         switch (sel) {
7678         case 0:
7679             gen_helper_mtc0_wired(cpu_env, arg);
7680             register_name = "Wired";
7681             break;
7682         case 1:
7683             check_insn(ctx, ISA_MIPS32R2);
7684             gen_helper_mtc0_srsconf0(cpu_env, arg);
7685             register_name = "SRSConf0";
7686             break;
7687         case 2:
7688             check_insn(ctx, ISA_MIPS32R2);
7689             gen_helper_mtc0_srsconf1(cpu_env, arg);
7690             register_name = "SRSConf1";
7691             break;
7692         case 3:
7693             check_insn(ctx, ISA_MIPS32R2);
7694             gen_helper_mtc0_srsconf2(cpu_env, arg);
7695             register_name = "SRSConf2";
7696             break;
7697         case 4:
7698             check_insn(ctx, ISA_MIPS32R2);
7699             gen_helper_mtc0_srsconf3(cpu_env, arg);
7700             register_name = "SRSConf3";
7701             break;
7702         case 5:
7703             check_insn(ctx, ISA_MIPS32R2);
7704             gen_helper_mtc0_srsconf4(cpu_env, arg);
7705             register_name = "SRSConf4";
7706             break;
7707         case 6:
7708             check_pw(ctx);
7709             gen_helper_mtc0_pwctl(cpu_env, arg);
7710             register_name = "PWCtl";
7711             break;
7712         default:
7713             goto cp0_unimplemented;
7714         }
7715         break;
7716     case CP0_REGISTER_07:
7717         switch (sel) {
7718         case 0:
7719             check_insn(ctx, ISA_MIPS32R2);
7720             gen_helper_mtc0_hwrena(cpu_env, arg);
7721             ctx->base.is_jmp = DISAS_STOP;
7722             register_name = "HWREna";
7723             break;
7724         default:
7725             goto cp0_unimplemented;
7726         }
7727         break;
7728     case CP0_REGISTER_08:
7729         switch (sel) {
7730         case 0:
7731             /* ignored */
7732             register_name = "BadVAddr";
7733             break;
7734         case 1:
7735             /* ignored */
7736             register_name = "BadInstr";
7737             break;
7738         case 2:
7739             /* ignored */
7740             register_name = "BadInstrP";
7741             break;
7742         case 3:
7743             /* ignored */
7744             register_name = "BadInstrX";
7745             break;
7746         default:
7747             goto cp0_unimplemented;
7748         }
7749         break;
7750     case CP0_REGISTER_09:
7751         switch (sel) {
7752         case 0:
7753             gen_helper_mtc0_count(cpu_env, arg);
7754             register_name = "Count";
7755             break;
7756         case 6:
7757             CP0_CHECK(ctx->saar);
7758             gen_helper_mtc0_saari(cpu_env, arg);
7759             register_name = "SAARI";
7760             break;
7761         case 7:
7762             CP0_CHECK(ctx->saar);
7763             gen_helper_mtc0_saar(cpu_env, arg);
7764             register_name = "SAAR";
7765             break;
7766         default:
7767             goto cp0_unimplemented;
7768         }
7769         break;
7770     case CP0_REGISTER_10:
7771         switch (sel) {
7772         case 0:
7773             gen_helper_mtc0_entryhi(cpu_env, arg);
7774             register_name = "EntryHi";
7775             break;
7776         default:
7777             goto cp0_unimplemented;
7778         }
7779         break;
7780     case CP0_REGISTER_11:
7781         switch (sel) {
7782         case 0:
7783             gen_helper_mtc0_compare(cpu_env, arg);
7784             register_name = "Compare";
7785             break;
7786         /* 6,7 are implementation dependent */
7787         default:
7788             goto cp0_unimplemented;
7789         }
7790         break;
7791     case CP0_REGISTER_12:
7792         switch (sel) {
7793         case 0:
7794             save_cpu_state(ctx, 1);
7795             gen_helper_mtc0_status(cpu_env, arg);
7796             /* DISAS_STOP isn't good enough here, hflags may have changed. */
7797             gen_save_pc(ctx->base.pc_next + 4);
7798             ctx->base.is_jmp = DISAS_EXIT;
7799             register_name = "Status";
7800             break;
7801         case 1:
7802             check_insn(ctx, ISA_MIPS32R2);
7803             gen_helper_mtc0_intctl(cpu_env, arg);
7804             /* Stop translation as we may have switched the execution mode */
7805             ctx->base.is_jmp = DISAS_STOP;
7806             register_name = "IntCtl";
7807             break;
7808         case 2:
7809             check_insn(ctx, ISA_MIPS32R2);
7810             gen_helper_mtc0_srsctl(cpu_env, arg);
7811             /* Stop translation as we may have switched the execution mode */
7812             ctx->base.is_jmp = DISAS_STOP;
7813             register_name = "SRSCtl";
7814             break;
7815         case 3:
7816             check_insn(ctx, ISA_MIPS32R2);
7817             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7818             /* Stop translation as we may have switched the execution mode */
7819             ctx->base.is_jmp = DISAS_STOP;
7820             register_name = "SRSMap";
7821             break;
7822         default:
7823             goto cp0_unimplemented;
7824         }
7825         break;
7826     case CP0_REGISTER_13:
7827         switch (sel) {
7828         case 0:
7829             save_cpu_state(ctx, 1);
7830             gen_helper_mtc0_cause(cpu_env, arg);
7831             /* Stop translation as we may have triggered an interrupt.
7832              * DISAS_STOP isn't sufficient, we need to ensure we break out of
7833              * translated code to check for pending interrupts.  */
7834             gen_save_pc(ctx->base.pc_next + 4);
7835             ctx->base.is_jmp = DISAS_EXIT;
7836             register_name = "Cause";
7837             break;
7838         default:
7839             goto cp0_unimplemented;
7840         }
7841         break;
7842     case CP0_REGISTER_14:
7843         switch (sel) {
7844         case 0:
7845             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7846             register_name = "EPC";
7847             break;
7848         default:
7849             goto cp0_unimplemented;
7850         }
7851         break;
7852     case CP0_REGISTER_15:
7853         switch (sel) {
7854         case 0:
7855             /* ignored */
7856             register_name = "PRid";
7857             break;
7858         case 1:
7859             check_insn(ctx, ISA_MIPS32R2);
7860             gen_helper_mtc0_ebase(cpu_env, arg);
7861             register_name = "EBase";
7862             break;
7863         default:
7864             goto cp0_unimplemented;
7865         }
7866         break;
7867     case CP0_REGISTER_16:
7868         switch (sel) {
7869         case 0:
7870             gen_helper_mtc0_config0(cpu_env, arg);
7871             register_name = "Config";
7872             /* Stop translation as we may have switched the execution mode */
7873             ctx->base.is_jmp = DISAS_STOP;
7874             break;
7875         case 1:
7876             /* ignored, read only */
7877             register_name = "Config1";
7878             break;
7879         case 2:
7880             gen_helper_mtc0_config2(cpu_env, arg);
7881             register_name = "Config2";
7882             /* Stop translation as we may have switched the execution mode */
7883             ctx->base.is_jmp = DISAS_STOP;
7884             break;
7885         case 3:
7886             gen_helper_mtc0_config3(cpu_env, arg);
7887             register_name = "Config3";
7888             /* Stop translation as we may have switched the execution mode */
7889             ctx->base.is_jmp = DISAS_STOP;
7890             break;
7891         case 4:
7892             gen_helper_mtc0_config4(cpu_env, arg);
7893             register_name = "Config4";
7894             ctx->base.is_jmp = DISAS_STOP;
7895             break;
7896         case 5:
7897             gen_helper_mtc0_config5(cpu_env, arg);
7898             register_name = "Config5";
7899             /* Stop translation as we may have switched the execution mode */
7900             ctx->base.is_jmp = DISAS_STOP;
7901             break;
7902         /* 6,7 are implementation dependent */
7903         case 6:
7904             /* ignored */
7905             register_name = "Config6";
7906             break;
7907         case 7:
7908             /* ignored */
7909             register_name = "Config7";
7910             break;
7911         default:
7912             register_name = "Invalid config selector";
7913             goto cp0_unimplemented;
7914         }
7915         break;
7916     case CP0_REGISTER_17:
7917         switch (sel) {
7918         case 0:
7919             gen_helper_mtc0_lladdr(cpu_env, arg);
7920             register_name = "LLAddr";
7921             break;
7922         case 1:
7923             CP0_CHECK(ctx->mrp);
7924             gen_helper_mtc0_maar(cpu_env, arg);
7925             register_name = "MAAR";
7926             break;
7927         case 2:
7928             CP0_CHECK(ctx->mrp);
7929             gen_helper_mtc0_maari(cpu_env, arg);
7930             register_name = "MAARI";
7931             break;
7932         default:
7933             goto cp0_unimplemented;
7934         }
7935         break;
7936     case CP0_REGISTER_18:
7937         switch (sel) {
7938         case 0:
7939         case 1:
7940         case 2:
7941         case 3:
7942         case 4:
7943         case 5:
7944         case 6:
7945         case 7:
7946             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7947             gen_helper_0e1i(mtc0_watchlo, arg, sel);
7948             register_name = "WatchLo";
7949             break;
7950         default:
7951             goto cp0_unimplemented;
7952         }
7953         break;
7954     case CP0_REGISTER_19:
7955         switch (sel) {
7956         case 0:
7957         case 1:
7958         case 2:
7959         case 3:
7960         case 4:
7961         case 5:
7962         case 6:
7963         case 7:
7964             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7965             gen_helper_0e1i(mtc0_watchhi, arg, sel);
7966             register_name = "WatchHi";
7967             break;
7968         default:
7969             goto cp0_unimplemented;
7970         }
7971         break;
7972     case CP0_REGISTER_20:
7973         switch (sel) {
7974         case 0:
7975 #if defined(TARGET_MIPS64)
7976             check_insn(ctx, ISA_MIPS3);
7977             gen_helper_mtc0_xcontext(cpu_env, arg);
7978             register_name = "XContext";
7979             break;
7980 #endif
7981         default:
7982             goto cp0_unimplemented;
7983         }
7984         break;
7985     case CP0_REGISTER_21:
7986        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7987         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7988         switch (sel) {
7989         case 0:
7990             gen_helper_mtc0_framemask(cpu_env, arg);
7991             register_name = "Framemask";
7992             break;
7993         default:
7994             goto cp0_unimplemented;
7995         }
7996         break;
7997     case CP0_REGISTER_22:
7998         /* ignored */
7999         register_name = "Diagnostic"; /* implementation dependent */
8000         break;
8001     case CP0_REGISTER_23:
8002         switch (sel) {
8003         case 0:
8004             gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8005             /* DISAS_STOP isn't good enough here, hflags may have changed. */
8006             gen_save_pc(ctx->base.pc_next + 4);
8007             ctx->base.is_jmp = DISAS_EXIT;
8008             register_name = "Debug";
8009             break;
8010         case 1:
8011 //            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8012             register_name = "TraceControl";
8013             /* Stop translation as we may have switched the execution mode */
8014             ctx->base.is_jmp = DISAS_STOP;
8015             goto cp0_unimplemented;
8016         case 2:
8017 //            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8018             register_name = "TraceControl2";
8019             /* Stop translation as we may have switched the execution mode */
8020             ctx->base.is_jmp = DISAS_STOP;
8021             goto cp0_unimplemented;
8022         case 3:
8023             /* Stop translation as we may have switched the execution mode */
8024             ctx->base.is_jmp = DISAS_STOP;
8025 //            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8026             register_name = "UserTraceData";
8027             /* Stop translation as we may have switched the execution mode */
8028             ctx->base.is_jmp = DISAS_STOP;
8029             goto cp0_unimplemented;
8030         case 4:
8031 //            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8032             /* Stop translation as we may have switched the execution mode */
8033             ctx->base.is_jmp = DISAS_STOP;
8034             register_name = "TraceBPC";
8035             goto cp0_unimplemented;
8036         default:
8037             goto cp0_unimplemented;
8038         }
8039         break;
8040     case CP0_REGISTER_24:
8041         switch (sel) {
8042         case 0:
8043             /* EJTAG support */
8044             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8045             register_name = "DEPC";
8046             break;
8047         default:
8048             goto cp0_unimplemented;
8049         }
8050         break;
8051     case CP0_REGISTER_25:
8052         switch (sel) {
8053         case 0:
8054             gen_helper_mtc0_performance0(cpu_env, arg);
8055             register_name = "Performance0";
8056             break;
8057         case 1:
8058 //            gen_helper_mtc0_performance1(arg);
8059             register_name = "Performance1";
8060             goto cp0_unimplemented;
8061         case 2:
8062 //            gen_helper_mtc0_performance2(arg);
8063             register_name = "Performance2";
8064             goto cp0_unimplemented;
8065         case 3:
8066 //            gen_helper_mtc0_performance3(arg);
8067             register_name = "Performance3";
8068             goto cp0_unimplemented;
8069         case 4:
8070 //            gen_helper_mtc0_performance4(arg);
8071             register_name = "Performance4";
8072             goto cp0_unimplemented;
8073         case 5:
8074 //            gen_helper_mtc0_performance5(arg);
8075             register_name = "Performance5";
8076             goto cp0_unimplemented;
8077         case 6:
8078 //            gen_helper_mtc0_performance6(arg);
8079             register_name = "Performance6";
8080             goto cp0_unimplemented;
8081         case 7:
8082 //            gen_helper_mtc0_performance7(arg);
8083             register_name = "Performance7";
8084             goto cp0_unimplemented;
8085         default:
8086             goto cp0_unimplemented;
8087         }
8088        break;
8089     case CP0_REGISTER_26:
8090         switch (sel) {
8091         case 0:
8092             gen_helper_mtc0_errctl(cpu_env, arg);
8093             ctx->base.is_jmp = DISAS_STOP;
8094             register_name = "ErrCtl";
8095             break;
8096         default:
8097             goto cp0_unimplemented;
8098         }
8099         break;
8100     case CP0_REGISTER_27:
8101         switch (sel) {
8102         case 0:
8103         case 1:
8104         case 2:
8105         case 3:
8106             /* ignored */
8107             register_name = "CacheErr";
8108             break;
8109         default:
8110             goto cp0_unimplemented;
8111         }
8112        break;
8113     case CP0_REGISTER_28:
8114         switch (sel) {
8115         case 0:
8116         case 2:
8117         case 4:
8118         case 6:
8119             gen_helper_mtc0_taglo(cpu_env, arg);
8120             register_name = "TagLo";
8121             break;
8122         case 1:
8123         case 3:
8124         case 5:
8125         case 7:
8126             gen_helper_mtc0_datalo(cpu_env, arg);
8127             register_name = "DataLo";
8128             break;
8129         default:
8130             goto cp0_unimplemented;
8131         }
8132         break;
8133     case CP0_REGISTER_29:
8134         switch (sel) {
8135         case 0:
8136         case 2:
8137         case 4:
8138         case 6:
8139             gen_helper_mtc0_taghi(cpu_env, arg);
8140             register_name = "TagHi";
8141             break;
8142         case 1:
8143         case 3:
8144         case 5:
8145         case 7:
8146             gen_helper_mtc0_datahi(cpu_env, arg);
8147             register_name = "DataHi";
8148             break;
8149         default:
8150             register_name = "invalid sel";
8151             goto cp0_unimplemented;
8152         }
8153        break;
8154     case CP0_REGISTER_30:
8155         switch (sel) {
8156         case 0:
8157             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8158             register_name = "ErrorEPC";
8159             break;
8160         default:
8161             goto cp0_unimplemented;
8162         }
8163         break;
8164     case CP0_REGISTER_31:
8165         switch (sel) {
8166         case 0:
8167             /* EJTAG support */
8168             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8169             register_name = "DESAVE";
8170             break;
8171         case 2:
8172         case 3:
8173         case 4:
8174         case 5:
8175         case 6:
8176         case 7:
8177             CP0_CHECK(ctx->kscrexist & (1 << sel));
8178             tcg_gen_st_tl(arg, cpu_env,
8179                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8180             register_name = "KScratch";
8181             break;
8182         default:
8183             goto cp0_unimplemented;
8184         }
8185         break;
8186     default:
8187        goto cp0_unimplemented;
8188     }
8189     trace_mips_translate_c0("mtc0", register_name, reg, sel);
8190
8191     /* For simplicity assume that all writes can cause interrupts.  */
8192     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8193         gen_io_end();
8194         /* DISAS_STOP isn't sufficient, we need to ensure we break out of
8195          * translated code to check for pending interrupts.  */
8196         gen_save_pc(ctx->base.pc_next + 4);
8197         ctx->base.is_jmp = DISAS_EXIT;
8198     }
8199     return;
8200
8201 cp0_unimplemented:
8202     qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
8203                   register_name, reg, sel);
8204 }
8205
8206 #if defined(TARGET_MIPS64)
8207 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8208 {
8209     const char *register_name = "invalid";
8210
8211     if (sel != 0)
8212         check_insn(ctx, ISA_MIPS64);
8213
8214     switch (reg) {
8215     case CP0_REGISTER_00:
8216         switch (sel) {
8217         case 0:
8218             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
8219             register_name = "Index";
8220             break;
8221         case 1:
8222             CP0_CHECK(ctx->insn_flags & ASE_MT);
8223             gen_helper_mfc0_mvpcontrol(arg, cpu_env);
8224             register_name = "MVPControl";
8225             break;
8226         case 2:
8227             CP0_CHECK(ctx->insn_flags & ASE_MT);
8228             gen_helper_mfc0_mvpconf0(arg, cpu_env);
8229             register_name = "MVPConf0";
8230             break;
8231         case 3:
8232             CP0_CHECK(ctx->insn_flags & ASE_MT);
8233             gen_helper_mfc0_mvpconf1(arg, cpu_env);
8234             register_name = "MVPConf1";
8235             break;
8236         case 4:
8237             CP0_CHECK(ctx->vp);
8238             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
8239             register_name = "VPControl";
8240             break;
8241         default:
8242             goto cp0_unimplemented;
8243         }
8244         break;
8245     case CP0_REGISTER_01:
8246         switch (sel) {
8247         case 0:
8248             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8249             gen_helper_mfc0_random(arg, cpu_env);
8250             register_name = "Random";
8251             break;
8252         case 1:
8253             CP0_CHECK(ctx->insn_flags & ASE_MT);
8254             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
8255             register_name = "VPEControl";
8256             break;
8257         case 2:
8258             CP0_CHECK(ctx->insn_flags & ASE_MT);
8259             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
8260             register_name = "VPEConf0";
8261             break;
8262         case 3:
8263             CP0_CHECK(ctx->insn_flags & ASE_MT);
8264             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
8265             register_name = "VPEConf1";
8266             break;
8267         case 4:
8268             CP0_CHECK(ctx->insn_flags & ASE_MT);
8269             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
8270             register_name = "YQMask";
8271             break;
8272         case 5:
8273             CP0_CHECK(ctx->insn_flags & ASE_MT);
8274             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8275             register_name = "VPESchedule";
8276             break;
8277         case 6:
8278             CP0_CHECK(ctx->insn_flags & ASE_MT);
8279             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8280             register_name = "VPEScheFBack";
8281             break;
8282         case 7:
8283             CP0_CHECK(ctx->insn_flags & ASE_MT);
8284             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
8285             register_name = "VPEOpt";
8286             break;
8287         default:
8288             goto cp0_unimplemented;
8289         }
8290         break;
8291     case CP0_REGISTER_02:
8292         switch (sel) {
8293         case 0:
8294             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
8295             register_name = "EntryLo0";
8296             break;
8297         case 1:
8298             CP0_CHECK(ctx->insn_flags & ASE_MT);
8299             gen_helper_mfc0_tcstatus(arg, cpu_env);
8300             register_name = "TCStatus";
8301             break;
8302         case 2:
8303             CP0_CHECK(ctx->insn_flags & ASE_MT);
8304             gen_helper_mfc0_tcbind(arg, cpu_env);
8305             register_name = "TCBind";
8306             break;
8307         case 3:
8308             CP0_CHECK(ctx->insn_flags & ASE_MT);
8309             gen_helper_dmfc0_tcrestart(arg, cpu_env);
8310             register_name = "TCRestart";
8311             break;
8312         case 4:
8313             CP0_CHECK(ctx->insn_flags & ASE_MT);
8314             gen_helper_dmfc0_tchalt(arg, cpu_env);
8315             register_name = "TCHalt";
8316             break;
8317         case 5:
8318             CP0_CHECK(ctx->insn_flags & ASE_MT);
8319             gen_helper_dmfc0_tccontext(arg, cpu_env);
8320             register_name = "TCContext";
8321             break;
8322         case 6:
8323             CP0_CHECK(ctx->insn_flags & ASE_MT);
8324             gen_helper_dmfc0_tcschedule(arg, cpu_env);
8325             register_name = "TCSchedule";
8326             break;
8327         case 7:
8328             CP0_CHECK(ctx->insn_flags & ASE_MT);
8329             gen_helper_dmfc0_tcschefback(arg, cpu_env);
8330             register_name = "TCScheFBack";
8331             break;
8332         default:
8333             goto cp0_unimplemented;
8334         }
8335         break;
8336     case CP0_REGISTER_03:
8337         switch (sel) {
8338         case 0:
8339             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
8340             register_name = "EntryLo1";
8341             break;
8342         case 1:
8343             CP0_CHECK(ctx->vp);
8344             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
8345             register_name = "GlobalNumber";
8346             break;
8347         default:
8348             goto cp0_unimplemented;
8349         }
8350         break;
8351     case CP0_REGISTER_04:
8352         switch (sel) {
8353         case 0:
8354             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
8355             register_name = "Context";
8356             break;
8357         case 1:
8358 //            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
8359             register_name = "ContextConfig";
8360             goto cp0_unimplemented;
8361         case 2:
8362             CP0_CHECK(ctx->ulri);
8363             tcg_gen_ld_tl(arg, cpu_env,
8364                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8365             register_name = "UserLocal";
8366             break;
8367         default:
8368             goto cp0_unimplemented;
8369         }
8370         break;
8371     case CP0_REGISTER_05:
8372         switch (sel) {
8373         case 0:
8374             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
8375             register_name = "PageMask";
8376             break;
8377         case 1:
8378             check_insn(ctx, ISA_MIPS32R2);
8379             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
8380             register_name = "PageGrain";
8381             break;
8382         case 2:
8383             CP0_CHECK(ctx->sc);
8384             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
8385             register_name = "SegCtl0";
8386             break;
8387         case 3:
8388             CP0_CHECK(ctx->sc);
8389             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
8390             register_name = "SegCtl1";
8391             break;
8392         case 4:
8393             CP0_CHECK(ctx->sc);
8394             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
8395             register_name = "SegCtl2";
8396             break;
8397         case 5:
8398             check_pw(ctx);
8399             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8400             register_name = "PWBase";
8401             break;
8402         case 6:
8403             check_pw(ctx);
8404             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
8405             register_name = "PWField";
8406             break;
8407         case 7:
8408             check_pw(ctx);
8409             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8410             register_name = "PWSize";
8411             break;
8412         default:
8413             goto cp0_unimplemented;
8414         }
8415         break;
8416     case CP0_REGISTER_06:
8417         switch (sel) {
8418         case 0:
8419             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
8420             register_name = "Wired";
8421             break;
8422         case 1:
8423             check_insn(ctx, ISA_MIPS32R2);
8424             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
8425             register_name = "SRSConf0";
8426             break;
8427         case 2:
8428             check_insn(ctx, ISA_MIPS32R2);
8429             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
8430             register_name = "SRSConf1";
8431             break;
8432         case 3:
8433             check_insn(ctx, ISA_MIPS32R2);
8434             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
8435             register_name = "SRSConf2";
8436             break;
8437         case 4:
8438             check_insn(ctx, ISA_MIPS32R2);
8439             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
8440             register_name = "SRSConf3";
8441             break;
8442         case 5:
8443             check_insn(ctx, ISA_MIPS32R2);
8444             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
8445             register_name = "SRSConf4";
8446             break;
8447         case 6:
8448             check_pw(ctx);
8449             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8450             register_name = "PWCtl";
8451             break;
8452         default:
8453             goto cp0_unimplemented;
8454         }
8455         break;
8456     case CP0_REGISTER_07:
8457         switch (sel) {
8458         case 0:
8459             check_insn(ctx, ISA_MIPS32R2);
8460             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
8461             register_name = "HWREna";
8462             break;
8463         default:
8464             goto cp0_unimplemented;
8465         }
8466         break;
8467     case CP0_REGISTER_08:
8468         switch (sel) {
8469         case 0:
8470             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
8471             register_name = "BadVAddr";
8472             break;
8473         case 1:
8474             CP0_CHECK(ctx->bi);
8475             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8476             register_name = "BadInstr";
8477             break;
8478         case 2:
8479             CP0_CHECK(ctx->bp);
8480             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8481             register_name = "BadInstrP";
8482             break;
8483         case 3:
8484             CP0_CHECK(ctx->bi);
8485             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8486             tcg_gen_andi_tl(arg, arg, ~0xffff);
8487             register_name = "BadInstrX";
8488             break;
8489         default:
8490             goto cp0_unimplemented;
8491         }
8492         break;
8493     case CP0_REGISTER_09:
8494         switch (sel) {
8495         case 0:
8496             /* Mark as an IO operation because we read the time.  */
8497             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8498                 gen_io_start();
8499             }
8500             gen_helper_mfc0_count(arg, cpu_env);
8501             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8502                 gen_io_end();
8503             }
8504             /* Break the TB to be able to take timer interrupts immediately
8505                after reading count. DISAS_STOP isn't sufficient, we need to
8506                ensure we break completely out of translated code.  */
8507             gen_save_pc(ctx->base.pc_next + 4);
8508             ctx->base.is_jmp = DISAS_EXIT;
8509             register_name = "Count";
8510             break;
8511         case 6:
8512             CP0_CHECK(ctx->saar);
8513             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
8514             register_name = "SAARI";
8515             break;
8516         case 7:
8517             CP0_CHECK(ctx->saar);
8518             gen_helper_dmfc0_saar(arg, cpu_env);
8519             register_name = "SAAR";
8520             break;
8521         default:
8522             goto cp0_unimplemented;
8523         }
8524         break;
8525     case CP0_REGISTER_10:
8526         switch (sel) {
8527         case 0:
8528             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
8529             register_name = "EntryHi";
8530             break;
8531         default:
8532             goto cp0_unimplemented;
8533         }
8534         break;
8535     case CP0_REGISTER_11:
8536         switch (sel) {
8537         case 0:
8538             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
8539             register_name = "Compare";
8540             break;
8541         /* 6,7 are implementation dependent */
8542         default:
8543             goto cp0_unimplemented;
8544         }
8545         break;
8546     case CP0_REGISTER_12:
8547         switch (sel) {
8548         case 0:
8549             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
8550             register_name = "Status";
8551             break;
8552         case 1:
8553             check_insn(ctx, ISA_MIPS32R2);
8554             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
8555             register_name = "IntCtl";
8556             break;
8557         case 2:
8558             check_insn(ctx, ISA_MIPS32R2);
8559             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
8560             register_name = "SRSCtl";
8561             break;
8562         case 3:
8563             check_insn(ctx, ISA_MIPS32R2);
8564             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8565             register_name = "SRSMap";
8566             break;
8567         default:
8568             goto cp0_unimplemented;
8569         }
8570         break;
8571     case CP0_REGISTER_13:
8572         switch (sel) {
8573         case 0:
8574             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
8575             register_name = "Cause";
8576             break;
8577         default:
8578             goto cp0_unimplemented;
8579         }
8580         break;
8581     case CP0_REGISTER_14:
8582         switch (sel) {
8583         case 0:
8584             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8585             register_name = "EPC";
8586             break;
8587         default:
8588             goto cp0_unimplemented;
8589         }
8590         break;
8591     case CP0_REGISTER_15:
8592         switch (sel) {
8593         case 0:
8594             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
8595             register_name = "PRid";
8596             break;
8597         case 1:
8598             check_insn(ctx, ISA_MIPS32R2);
8599             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
8600             register_name = "EBase";
8601             break;
8602         case 3:
8603             check_insn(ctx, ISA_MIPS32R2);
8604             CP0_CHECK(ctx->cmgcr);
8605             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8606             register_name = "CMGCRBase";
8607             break;
8608         default:
8609             goto cp0_unimplemented;
8610         }
8611         break;
8612     case CP0_REGISTER_16:
8613         switch (sel) {
8614         case 0:
8615             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
8616             register_name = "Config";
8617             break;
8618         case 1:
8619             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
8620             register_name = "Config1";
8621             break;
8622         case 2:
8623             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
8624             register_name = "Config2";
8625             break;
8626         case 3:
8627             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
8628             register_name = "Config3";
8629             break;
8630         case 4:
8631             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8632             register_name = "Config4";
8633             break;
8634         case 5:
8635             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8636             register_name = "Config5";
8637             break;
8638        /* 6,7 are implementation dependent */
8639         case 6:
8640             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
8641             register_name = "Config6";
8642             break;
8643         case 7:
8644             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
8645             register_name = "Config7";
8646             break;
8647         default:
8648             goto cp0_unimplemented;
8649         }
8650         break;
8651     case CP0_REGISTER_17:
8652         switch (sel) {
8653         case 0:
8654             gen_helper_dmfc0_lladdr(arg, cpu_env);
8655             register_name = "LLAddr";
8656             break;
8657         case 1:
8658             CP0_CHECK(ctx->mrp);
8659             gen_helper_dmfc0_maar(arg, cpu_env);
8660             register_name = "MAAR";
8661             break;
8662         case 2:
8663             CP0_CHECK(ctx->mrp);
8664             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8665             register_name = "MAARI";
8666             break;
8667         default:
8668             goto cp0_unimplemented;
8669         }
8670         break;
8671     case CP0_REGISTER_18:
8672         switch (sel) {
8673         case 0:
8674         case 1:
8675         case 2:
8676         case 3:
8677         case 4:
8678         case 5:
8679         case 6:
8680         case 7:
8681             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8682             gen_helper_1e0i(dmfc0_watchlo, arg, sel);
8683             register_name = "WatchLo";
8684             break;
8685         default:
8686             goto cp0_unimplemented;
8687         }
8688         break;
8689     case CP0_REGISTER_19:
8690         switch (sel) {
8691         case 0:
8692         case 1:
8693         case 2:
8694         case 3:
8695         case 4:
8696         case 5:
8697         case 6:
8698         case 7:
8699             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8700             gen_helper_1e0i(mfc0_watchhi, arg, sel);
8701             register_name = "WatchHi";
8702             break;
8703         default:
8704             goto cp0_unimplemented;
8705         }
8706         break;
8707     case CP0_REGISTER_20:
8708         switch (sel) {
8709         case 0:
8710             check_insn(ctx, ISA_MIPS3);
8711             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
8712             register_name = "XContext";
8713             break;
8714         default:
8715             goto cp0_unimplemented;
8716         }
8717         break;
8718     case CP0_REGISTER_21:
8719        /* Officially reserved, but sel 0 is used for R1x000 framemask */
8720         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8721         switch (sel) {
8722         case 0:
8723             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
8724             register_name = "Framemask";
8725             break;
8726         default:
8727             goto cp0_unimplemented;
8728         }
8729         break;
8730     case CP0_REGISTER_22:
8731         tcg_gen_movi_tl(arg, 0); /* unimplemented */
8732         register_name = "'Diagnostic"; /* implementation dependent */
8733         break;
8734     case CP0_REGISTER_23:
8735         switch (sel) {
8736         case 0:
8737             gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
8738             register_name = "Debug";
8739             break;
8740         case 1:
8741 //            gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
8742             register_name = "TraceControl";
8743             goto cp0_unimplemented;
8744         case 2:
8745 //            gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
8746             register_name = "TraceControl2";
8747             goto cp0_unimplemented;
8748         case 3:
8749 //            gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
8750             register_name = "UserTraceData";
8751             goto cp0_unimplemented;
8752         case 4:
8753 //            gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
8754             register_name = "TraceBPC";
8755             goto cp0_unimplemented;
8756         default:
8757             goto cp0_unimplemented;
8758         }
8759         break;
8760     case CP0_REGISTER_24:
8761         switch (sel) {
8762         case 0:
8763             /* EJTAG support */
8764             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8765             register_name = "DEPC";
8766             break;
8767         default:
8768             goto cp0_unimplemented;
8769         }
8770         break;
8771     case CP0_REGISTER_25:
8772         switch (sel) {
8773         case 0:
8774             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
8775             register_name = "Performance0";
8776             break;
8777         case 1:
8778 //            gen_helper_dmfc0_performance1(arg);
8779             register_name = "Performance1";
8780             goto cp0_unimplemented;
8781         case 2:
8782 //            gen_helper_dmfc0_performance2(arg);
8783             register_name = "Performance2";
8784             goto cp0_unimplemented;
8785         case 3:
8786 //            gen_helper_dmfc0_performance3(arg);
8787             register_name = "Performance3";
8788             goto cp0_unimplemented;
8789         case 4:
8790 //            gen_helper_dmfc0_performance4(arg);
8791             register_name = "Performance4";
8792             goto cp0_unimplemented;
8793         case 5:
8794 //            gen_helper_dmfc0_performance5(arg);
8795             register_name = "Performance5";
8796             goto cp0_unimplemented;
8797         case 6:
8798 //            gen_helper_dmfc0_performance6(arg);
8799             register_name = "Performance6";
8800             goto cp0_unimplemented;
8801         case 7:
8802 //            gen_helper_dmfc0_performance7(arg);
8803             register_name = "Performance7";
8804             goto cp0_unimplemented;
8805         default:
8806             goto cp0_unimplemented;
8807         }
8808         break;
8809     case CP0_REGISTER_26:
8810         switch (sel) {
8811         case 0:
8812             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8813             register_name = "ErrCtl";
8814             break;
8815         default:
8816             goto cp0_unimplemented;
8817         }
8818         break;
8819     case CP0_REGISTER_27:
8820         switch (sel) {
8821         /* ignored */
8822         case 0:
8823         case 1:
8824         case 2:
8825         case 3:
8826             tcg_gen_movi_tl(arg, 0); /* unimplemented */
8827             register_name = "CacheErr";
8828             break;
8829         default:
8830             goto cp0_unimplemented;
8831         }
8832         break;
8833     case CP0_REGISTER_28:
8834         switch (sel) {
8835         case 0:
8836         case 2:
8837         case 4:
8838         case 6:
8839             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
8840             register_name = "TagLo";
8841             break;
8842         case 1:
8843         case 3:
8844         case 5:
8845         case 7:
8846             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
8847             register_name = "DataLo";
8848             break;
8849         default:
8850             goto cp0_unimplemented;
8851         }
8852         break;
8853     case CP0_REGISTER_29:
8854         switch (sel) {
8855         case 0:
8856         case 2:
8857         case 4:
8858         case 6:
8859             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
8860             register_name = "TagHi";
8861             break;
8862         case 1:
8863         case 3:
8864         case 5:
8865         case 7:
8866             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
8867             register_name = "DataHi";
8868             break;
8869         default:
8870             goto cp0_unimplemented;
8871         }
8872         break;
8873     case CP0_REGISTER_30:
8874         switch (sel) {
8875         case 0:
8876             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8877             register_name = "ErrorEPC";
8878             break;
8879         default:
8880             goto cp0_unimplemented;
8881         }
8882         break;
8883     case CP0_REGISTER_31:
8884         switch (sel) {
8885         case 0:
8886             /* EJTAG support */
8887             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8888             register_name = "DESAVE";
8889             break;
8890         case 2:
8891         case 3:
8892         case 4:
8893         case 5:
8894         case 6:
8895         case 7:
8896             CP0_CHECK(ctx->kscrexist & (1 << sel));
8897             tcg_gen_ld_tl(arg, cpu_env,
8898                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8899             register_name = "KScratch";
8900             break;
8901         default:
8902             goto cp0_unimplemented;
8903         }
8904         break;
8905     default:
8906         goto cp0_unimplemented;
8907     }
8908     trace_mips_translate_c0("dmfc0", register_name, reg, sel);
8909     return;
8910
8911 cp0_unimplemented:
8912     qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
8913                   register_name, reg, sel);
8914     gen_mfc0_unimplemented(ctx, arg);
8915 }
8916
8917 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8918 {
8919     const char *register_name = "invalid";
8920
8921     if (sel != 0)
8922         check_insn(ctx, ISA_MIPS64);
8923
8924     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8925         gen_io_start();
8926     }
8927
8928     switch (reg) {
8929     case CP0_REGISTER_00:
8930         switch (sel) {
8931         case 0:
8932             gen_helper_mtc0_index(cpu_env, arg);
8933             register_name = "Index";
8934             break;
8935         case 1:
8936             CP0_CHECK(ctx->insn_flags & ASE_MT);
8937             gen_helper_mtc0_mvpcontrol(cpu_env, arg);
8938             register_name = "MVPControl";
8939             break;
8940         case 2:
8941             CP0_CHECK(ctx->insn_flags & ASE_MT);
8942             /* ignored */
8943             register_name = "MVPConf0";
8944             break;
8945         case 3:
8946             CP0_CHECK(ctx->insn_flags & ASE_MT);
8947             /* ignored */
8948             register_name = "MVPConf1";
8949             break;
8950         case 4:
8951             CP0_CHECK(ctx->vp);
8952             /* ignored */
8953             register_name = "VPControl";
8954             break;
8955         default:
8956             goto cp0_unimplemented;
8957         }
8958         break;
8959     case CP0_REGISTER_01:
8960         switch (sel) {
8961         case 0:
8962             /* ignored */
8963             register_name = "Random";
8964             break;
8965         case 1:
8966             CP0_CHECK(ctx->insn_flags & ASE_MT);
8967             gen_helper_mtc0_vpecontrol(cpu_env, arg);
8968             register_name = "VPEControl";
8969             break;
8970         case 2:
8971             CP0_CHECK(ctx->insn_flags & ASE_MT);
8972             gen_helper_mtc0_vpeconf0(cpu_env, arg);
8973             register_name = "VPEConf0";
8974             break;
8975         case 3:
8976             CP0_CHECK(ctx->insn_flags & ASE_MT);
8977             gen_helper_mtc0_vpeconf1(cpu_env, arg);
8978             register_name = "VPEConf1";
8979             break;
8980         case 4:
8981             CP0_CHECK(ctx->insn_flags & ASE_MT);
8982             gen_helper_mtc0_yqmask(cpu_env, arg);
8983             register_name = "YQMask";
8984             break;
8985         case 5:
8986             CP0_CHECK(ctx->insn_flags & ASE_MT);
8987             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8988             register_name = "VPESchedule";
8989             break;
8990         case 6:
8991             CP0_CHECK(ctx->insn_flags & ASE_MT);
8992             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8993             register_name = "VPEScheFBack";
8994             break;
8995         case 7:
8996             CP0_CHECK(ctx->insn_flags & ASE_MT);
8997             gen_helper_mtc0_vpeopt(cpu_env, arg);
8998             register_name = "VPEOpt";
8999             break;
9000         default:
9001             goto cp0_unimplemented;
9002         }
9003         break;
9004     case CP0_REGISTER_02:
9005         switch (sel) {
9006         case 0:
9007             gen_helper_dmtc0_entrylo0(cpu_env, arg);
9008             register_name = "EntryLo0";
9009             break;
9010         case 1:
9011             CP0_CHECK(ctx->insn_flags & ASE_MT);
9012             gen_helper_mtc0_tcstatus(cpu_env, arg);
9013             register_name = "TCStatus";
9014             break;
9015         case 2:
9016             CP0_CHECK(ctx->insn_flags & ASE_MT);
9017             gen_helper_mtc0_tcbind(cpu_env, arg);
9018             register_name = "TCBind";
9019             break;
9020         case 3:
9021             CP0_CHECK(ctx->insn_flags & ASE_MT);
9022             gen_helper_mtc0_tcrestart(cpu_env, arg);
9023             register_name = "TCRestart";
9024             break;
9025         case 4:
9026             CP0_CHECK(ctx->insn_flags & ASE_MT);
9027             gen_helper_mtc0_tchalt(cpu_env, arg);
9028             register_name = "TCHalt";
9029             break;
9030         case 5:
9031             CP0_CHECK(ctx->insn_flags & ASE_MT);
9032             gen_helper_mtc0_tccontext(cpu_env, arg);
9033             register_name = "TCContext";
9034             break;
9035         case 6:
9036             CP0_CHECK(ctx->insn_flags & ASE_MT);
9037             gen_helper_mtc0_tcschedule(cpu_env, arg);
9038             register_name = "TCSchedule";
9039             break;
9040         case 7:
9041             CP0_CHECK(ctx->insn_flags & ASE_MT);
9042             gen_helper_mtc0_tcschefback(cpu_env, arg);
9043             register_name = "TCScheFBack";
9044             break;
9045         default:
9046             goto cp0_unimplemented;
9047         }
9048         break;
9049     case CP0_REGISTER_03:
9050         switch (sel) {
9051         case 0:
9052             gen_helper_dmtc0_entrylo1(cpu_env, arg);
9053             register_name = "EntryLo1";
9054             break;
9055         case 1:
9056             CP0_CHECK(ctx->vp);
9057             /* ignored */
9058             register_name = "GlobalNumber";
9059             break;
9060         default:
9061             goto cp0_unimplemented;
9062         }
9063         break;
9064     case CP0_REGISTER_04:
9065         switch (sel) {
9066         case 0:
9067             gen_helper_mtc0_context(cpu_env, arg);
9068             register_name = "Context";
9069             break;
9070         case 1:
9071 //           gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
9072             register_name = "ContextConfig";
9073             goto cp0_unimplemented;
9074         case 2:
9075             CP0_CHECK(ctx->ulri);
9076             tcg_gen_st_tl(arg, cpu_env,
9077                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
9078             register_name = "UserLocal";
9079             break;
9080         default:
9081             goto cp0_unimplemented;
9082         }
9083         break;
9084     case CP0_REGISTER_05:
9085         switch (sel) {
9086         case 0:
9087             gen_helper_mtc0_pagemask(cpu_env, arg);
9088             register_name = "PageMask";
9089             break;
9090         case 1:
9091             check_insn(ctx, ISA_MIPS32R2);
9092             gen_helper_mtc0_pagegrain(cpu_env, arg);
9093             register_name = "PageGrain";
9094             break;
9095         case 2:
9096             CP0_CHECK(ctx->sc);
9097             gen_helper_mtc0_segctl0(cpu_env, arg);
9098             register_name = "SegCtl0";
9099             break;
9100         case 3:
9101             CP0_CHECK(ctx->sc);
9102             gen_helper_mtc0_segctl1(cpu_env, arg);
9103             register_name = "SegCtl1";
9104             break;
9105         case 4:
9106             CP0_CHECK(ctx->sc);
9107             gen_helper_mtc0_segctl2(cpu_env, arg);
9108             register_name = "SegCtl2";
9109             break;
9110         case 5:
9111             check_pw(ctx);
9112             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
9113             register_name = "PWBase";
9114             break;
9115         case 6:
9116             check_pw(ctx);
9117             gen_helper_mtc0_pwfield(cpu_env, arg);
9118             register_name = "PWField";
9119             break;
9120         case 7:
9121             check_pw(ctx);
9122             gen_helper_mtc0_pwsize(cpu_env, arg);
9123             register_name = "PWSize";
9124             break;
9125         default:
9126             goto cp0_unimplemented;
9127         }
9128         break;
9129     case CP0_REGISTER_06:
9130         switch (sel) {
9131         case 0:
9132             gen_helper_mtc0_wired(cpu_env, arg);
9133             register_name = "Wired";
9134             break;
9135         case 1:
9136             check_insn(ctx, ISA_MIPS32R2);
9137             gen_helper_mtc0_srsconf0(cpu_env, arg);
9138             register_name = "SRSConf0";
9139             break;
9140         case 2:
9141             check_insn(ctx, ISA_MIPS32R2);
9142             gen_helper_mtc0_srsconf1(cpu_env, arg);
9143             register_name = "SRSConf1";
9144             break;
9145         case 3:
9146             check_insn(ctx, ISA_MIPS32R2);
9147             gen_helper_mtc0_srsconf2(cpu_env, arg);
9148             register_name = "SRSConf2";
9149             break;
9150         case 4:
9151             check_insn(ctx, ISA_MIPS32R2);
9152             gen_helper_mtc0_srsconf3(cpu_env, arg);
9153             register_name = "SRSConf3";
9154             break;
9155         case 5:
9156             check_insn(ctx, ISA_MIPS32R2);
9157             gen_helper_mtc0_srsconf4(cpu_env, arg);
9158             register_name = "SRSConf4";
9159             break;
9160         case 6:
9161             check_pw(ctx);
9162             gen_helper_mtc0_pwctl(cpu_env, arg);
9163             register_name = "PWCtl";
9164             break;
9165         default:
9166             goto cp0_unimplemented;
9167         }
9168         break;
9169     case CP0_REGISTER_07:
9170         switch (sel) {
9171         case 0:
9172             check_insn(ctx, ISA_MIPS32R2);
9173             gen_helper_mtc0_hwrena(cpu_env, arg);
9174             ctx->base.is_jmp = DISAS_STOP;
9175             register_name = "HWREna";
9176             break;
9177         default:
9178             goto cp0_unimplemented;
9179         }
9180         break;
9181     case CP0_REGISTER_08:
9182         switch (sel) {
9183         case 0:
9184             /* ignored */
9185             register_name = "BadVAddr";
9186             break;
9187         case 1:
9188             /* ignored */
9189             register_name = "BadInstr";
9190             break;
9191         case 2:
9192             /* ignored */
9193             register_name = "BadInstrP";
9194             break;
9195         case 3:
9196             /* ignored */
9197             register_name = "BadInstrX";
9198             break;
9199         default:
9200             goto cp0_unimplemented;
9201         }
9202         break;
9203     case CP0_REGISTER_09:
9204         switch (sel) {
9205         case 0:
9206             gen_helper_mtc0_count(cpu_env, arg);
9207             register_name = "Count";
9208             break;
9209         case 6:
9210             CP0_CHECK(ctx->saar);
9211             gen_helper_mtc0_saari(cpu_env, arg);
9212             register_name = "SAARI";
9213             break;
9214         case 7:
9215             CP0_CHECK(ctx->saar);
9216             gen_helper_mtc0_saar(cpu_env, arg);
9217             register_name = "SAAR";
9218             break;
9219         default:
9220             goto cp0_unimplemented;
9221         }
9222         /* Stop translation as we may have switched the execution mode */
9223         ctx->base.is_jmp = DISAS_STOP;
9224         break;
9225     case CP0_REGISTER_10:
9226         switch (sel) {
9227         case 0:
9228             gen_helper_mtc0_entryhi(cpu_env, arg);
9229             register_name = "EntryHi";
9230             break;
9231         default:
9232             goto cp0_unimplemented;
9233         }
9234         break;
9235     case CP0_REGISTER_11:
9236         switch (sel) {
9237         case 0:
9238             gen_helper_mtc0_compare(cpu_env, arg);
9239             register_name = "Compare";
9240             break;
9241         /* 6,7 are implementation dependent */
9242         default:
9243             goto cp0_unimplemented;
9244         }
9245         /* Stop translation as we may have switched the execution mode */
9246         ctx->base.is_jmp = DISAS_STOP;
9247         break;
9248     case CP0_REGISTER_12:
9249         switch (sel) {
9250         case 0:
9251             save_cpu_state(ctx, 1);
9252             gen_helper_mtc0_status(cpu_env, arg);
9253             /* DISAS_STOP isn't good enough here, hflags may have changed. */
9254             gen_save_pc(ctx->base.pc_next + 4);
9255             ctx->base.is_jmp = DISAS_EXIT;
9256             register_name = "Status";
9257             break;
9258         case 1:
9259             check_insn(ctx, ISA_MIPS32R2);
9260             gen_helper_mtc0_intctl(cpu_env, arg);
9261             /* Stop translation as we may have switched the execution mode */
9262             ctx->base.is_jmp = DISAS_STOP;
9263             register_name = "IntCtl";
9264             break;
9265         case 2:
9266             check_insn(ctx, ISA_MIPS32R2);
9267             gen_helper_mtc0_srsctl(cpu_env, arg);
9268             /* Stop translation as we may have switched the execution mode */
9269             ctx->base.is_jmp = DISAS_STOP;
9270             register_name = "SRSCtl";
9271             break;
9272         case 3:
9273             check_insn(ctx, ISA_MIPS32R2);
9274             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
9275             /* Stop translation as we may have switched the execution mode */
9276             ctx->base.is_jmp = DISAS_STOP;
9277             register_name = "SRSMap";
9278             break;
9279         default:
9280             goto cp0_unimplemented;
9281         }
9282         break;
9283     case CP0_REGISTER_13:
9284         switch (sel) {
9285         case 0:
9286             save_cpu_state(ctx, 1);
9287             gen_helper_mtc0_cause(cpu_env, arg);
9288             /* Stop translation as we may have triggered an interrupt.
9289              * DISAS_STOP isn't sufficient, we need to ensure we break out of
9290              * translated code to check for pending interrupts.  */
9291             gen_save_pc(ctx->base.pc_next + 4);
9292             ctx->base.is_jmp = DISAS_EXIT;
9293             register_name = "Cause";
9294             break;
9295         default:
9296             goto cp0_unimplemented;
9297         }
9298         break;
9299     case CP0_REGISTER_14:
9300         switch (sel) {
9301         case 0:
9302             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
9303             register_name = "EPC";
9304             break;
9305         default:
9306             goto cp0_unimplemented;
9307         }
9308         break;
9309     case CP0_REGISTER_15:
9310         switch (sel) {
9311         case 0:
9312             /* ignored */
9313             register_name = "PRid";
9314             break;
9315         case 1:
9316             check_insn(ctx, ISA_MIPS32R2);
9317             gen_helper_mtc0_ebase(cpu_env, arg);
9318             register_name = "EBase";
9319             break;
9320         default:
9321             goto cp0_unimplemented;
9322         }
9323         break;
9324     case CP0_REGISTER_16:
9325         switch (sel) {
9326         case 0:
9327             gen_helper_mtc0_config0(cpu_env, arg);
9328             register_name = "Config";
9329             /* Stop translation as we may have switched the execution mode */
9330             ctx->base.is_jmp = DISAS_STOP;
9331             break;
9332         case 1:
9333             /* ignored, read only */
9334             register_name = "Config1";
9335             break;
9336         case 2:
9337             gen_helper_mtc0_config2(cpu_env, arg);
9338             register_name = "Config2";
9339             /* Stop translation as we may have switched the execution mode */
9340             ctx->base.is_jmp = DISAS_STOP;
9341             break;
9342         case 3:
9343             gen_helper_mtc0_config3(cpu_env, arg);
9344             register_name = "Config3";
9345             /* Stop translation as we may have switched the execution mode */
9346             ctx->base.is_jmp = DISAS_STOP;
9347             break;
9348         case 4:
9349             /* currently ignored */
9350             register_name = "Config4";
9351             break;
9352         case 5:
9353             gen_helper_mtc0_config5(cpu_env, arg);
9354             register_name = "Config5";
9355             /* Stop translation as we may have switched the execution mode */
9356             ctx->base.is_jmp = DISAS_STOP;
9357             break;
9358         /* 6,7 are implementation dependent */
9359         default:
9360             register_name = "Invalid config selector";
9361             goto cp0_unimplemented;
9362         }
9363         break;
9364     case CP0_REGISTER_17:
9365         switch (sel) {
9366         case 0:
9367             gen_helper_mtc0_lladdr(cpu_env, arg);
9368             register_name = "LLAddr";
9369             break;
9370         case 1:
9371             CP0_CHECK(ctx->mrp);
9372             gen_helper_mtc0_maar(cpu_env, arg);
9373             register_name = "MAAR";
9374             break;
9375         case 2:
9376             CP0_CHECK(ctx->mrp);
9377             gen_helper_mtc0_maari(cpu_env, arg);
9378             register_name = "MAARI";
9379             break;
9380         default:
9381             goto cp0_unimplemented;
9382         }
9383         break;
9384     case CP0_REGISTER_18:
9385         switch (sel) {
9386         case 0:
9387         case 1:
9388         case 2:
9389         case 3:
9390         case 4:
9391         case 5:
9392         case 6:
9393         case 7:
9394             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9395             gen_helper_0e1i(mtc0_watchlo, arg, sel);
9396             register_name = "WatchLo";
9397             break;
9398         default:
9399             goto cp0_unimplemented;
9400         }
9401         break;
9402     case CP0_REGISTER_19:
9403         switch (sel) {
9404         case 0:
9405         case 1:
9406         case 2:
9407         case 3:
9408         case 4:
9409         case 5:
9410         case 6:
9411         case 7:
9412             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9413             gen_helper_0e1i(mtc0_watchhi, arg, sel);
9414             register_name = "WatchHi";
9415             break;
9416         default:
9417             goto cp0_unimplemented;
9418         }
9419         break;
9420     case CP0_REGISTER_20:
9421         switch (sel) {
9422         case 0:
9423             check_insn(ctx, ISA_MIPS3);
9424             gen_helper_mtc0_xcontext(cpu_env, arg);
9425             register_name = "XContext";
9426             break;
9427         default:
9428             goto cp0_unimplemented;
9429         }
9430         break;
9431     case CP0_REGISTER_21:
9432        /* Officially reserved, but sel 0 is used for R1x000 framemask */
9433         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9434         switch (sel) {
9435         case 0:
9436             gen_helper_mtc0_framemask(cpu_env, arg);
9437             register_name = "Framemask";
9438             break;
9439         default:
9440             goto cp0_unimplemented;
9441         }
9442         break;
9443     case CP0_REGISTER_22:
9444         /* ignored */
9445         register_name = "Diagnostic"; /* implementation dependent */
9446         break;
9447     case CP0_REGISTER_23:
9448         switch (sel) {
9449         case 0:
9450             gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
9451             /* DISAS_STOP isn't good enough here, hflags may have changed. */
9452             gen_save_pc(ctx->base.pc_next + 4);
9453             ctx->base.is_jmp = DISAS_EXIT;
9454             register_name = "Debug";
9455             break;
9456         case 1:
9457 //            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
9458             /* Stop translation as we may have switched the execution mode */
9459             ctx->base.is_jmp = DISAS_STOP;
9460             register_name = "TraceControl";
9461             goto cp0_unimplemented;
9462         case 2:
9463 //            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
9464             /* Stop translation as we may have switched the execution mode */
9465             ctx->base.is_jmp = DISAS_STOP;
9466             register_name = "TraceControl2";
9467             goto cp0_unimplemented;
9468         case 3:
9469 //            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
9470             /* Stop translation as we may have switched the execution mode */
9471             ctx->base.is_jmp = DISAS_STOP;
9472             register_name = "UserTraceData";
9473             goto cp0_unimplemented;
9474         case 4:
9475 //            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
9476             /* Stop translation as we may have switched the execution mode */
9477             ctx->base.is_jmp = DISAS_STOP;
9478             register_name = "TraceBPC";
9479             goto cp0_unimplemented;
9480         default:
9481             goto cp0_unimplemented;
9482         }
9483         break;
9484     case CP0_REGISTER_24:
9485         switch (sel) {
9486         case 0:
9487             /* EJTAG support */
9488             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
9489             register_name = "DEPC";
9490             break;
9491         default:
9492             goto cp0_unimplemented;
9493         }
9494         break;
9495     case CP0_REGISTER_25:
9496         switch (sel) {
9497         case 0:
9498             gen_helper_mtc0_performance0(cpu_env, arg);
9499             register_name = "Performance0";
9500             break;
9501         case 1:
9502 //            gen_helper_mtc0_performance1(cpu_env, arg);
9503             register_name = "Performance1";
9504             goto cp0_unimplemented;
9505         case 2:
9506 //            gen_helper_mtc0_performance2(cpu_env, arg);
9507             register_name = "Performance2";
9508             goto cp0_unimplemented;
9509         case 3:
9510 //            gen_helper_mtc0_performance3(cpu_env, arg);
9511             register_name = "Performance3";
9512             goto cp0_unimplemented;
9513         case 4:
9514 //            gen_helper_mtc0_performance4(cpu_env, arg);
9515             register_name = "Performance4";
9516             goto cp0_unimplemented;
9517         case 5:
9518 //            gen_helper_mtc0_performance5(cpu_env, arg);
9519             register_name = "Performance5";
9520             goto cp0_unimplemented;
9521         case 6:
9522 //            gen_helper_mtc0_performance6(cpu_env, arg);
9523             register_name = "Performance6";
9524             goto cp0_unimplemented;
9525         case 7:
9526 //            gen_helper_mtc0_performance7(cpu_env, arg);
9527             register_name = "Performance7";
9528             goto cp0_unimplemented;
9529         default:
9530             goto cp0_unimplemented;
9531         }
9532         break;
9533     case CP0_REGISTER_26:
9534         switch (sel) {
9535         case 0:
9536             gen_helper_mtc0_errctl(cpu_env, arg);
9537             ctx->base.is_jmp = DISAS_STOP;
9538             register_name = "ErrCtl";
9539             break;
9540         default:
9541             goto cp0_unimplemented;
9542         }
9543         break;
9544     case CP0_REGISTER_27:
9545         switch (sel) {
9546         case 0:
9547         case 1:
9548         case 2:
9549         case 3:
9550             /* ignored */
9551             register_name = "CacheErr";
9552             break;
9553         default:
9554             goto cp0_unimplemented;
9555         }
9556         break;
9557     case CP0_REGISTER_28:
9558         switch (sel) {
9559         case 0:
9560         case 2:
9561         case 4:
9562         case 6:
9563             gen_helper_mtc0_taglo(cpu_env, arg);
9564             register_name = "TagLo";
9565             break;
9566         case 1:
9567         case 3:
9568         case 5:
9569         case 7:
9570             gen_helper_mtc0_datalo(cpu_env, arg);
9571             register_name = "DataLo";
9572             break;
9573         default:
9574             goto cp0_unimplemented;
9575         }
9576         break;
9577     case CP0_REGISTER_29:
9578         switch (sel) {
9579         case 0:
9580         case 2:
9581         case 4:
9582         case 6:
9583             gen_helper_mtc0_taghi(cpu_env, arg);
9584             register_name = "TagHi";
9585             break;
9586         case 1:
9587         case 3:
9588         case 5:
9589         case 7:
9590             gen_helper_mtc0_datahi(cpu_env, arg);
9591             register_name = "DataHi";
9592             break;
9593         default:
9594             register_name = "invalid sel";
9595             goto cp0_unimplemented;
9596         }
9597         break;
9598     case CP0_REGISTER_30:
9599         switch (sel) {
9600         case 0:
9601             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
9602             register_name = "ErrorEPC";
9603             break;
9604         default:
9605             goto cp0_unimplemented;
9606         }
9607         break;
9608     case CP0_REGISTER_31:
9609         switch (sel) {
9610         case 0:
9611             /* EJTAG support */
9612             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
9613             register_name = "DESAVE";
9614             break;
9615         case 2:
9616         case 3:
9617         case 4:
9618         case 5:
9619         case 6:
9620         case 7:
9621             CP0_CHECK(ctx->kscrexist & (1 << sel));
9622             tcg_gen_st_tl(arg, cpu_env,
9623                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9624             register_name = "KScratch";
9625             break;
9626         default:
9627             goto cp0_unimplemented;
9628         }
9629         break;
9630     default:
9631         goto cp0_unimplemented;
9632     }
9633     trace_mips_translate_c0("dmtc0", register_name, reg, sel);
9634
9635     /* For simplicity assume that all writes can cause interrupts.  */
9636     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9637         gen_io_end();
9638         /* DISAS_STOP isn't sufficient, we need to ensure we break out of
9639          * translated code to check for pending interrupts.  */
9640         gen_save_pc(ctx->base.pc_next + 4);
9641         ctx->base.is_jmp = DISAS_EXIT;
9642     }
9643     return;
9644
9645 cp0_unimplemented:
9646     qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
9647                   register_name, reg, sel);
9648 }
9649 #endif /* TARGET_MIPS64 */
9650
9651 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
9652                      int u, int sel, int h)
9653 {
9654     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9655     TCGv t0 = tcg_temp_local_new();
9656
9657     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9658         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9659          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9660         tcg_gen_movi_tl(t0, -1);
9661     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9662              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9663         tcg_gen_movi_tl(t0, -1);
9664     else if (u == 0) {
9665         switch (rt) {
9666         case 1:
9667             switch (sel) {
9668             case 1:
9669                 gen_helper_mftc0_vpecontrol(t0, cpu_env);
9670                 break;
9671             case 2:
9672                 gen_helper_mftc0_vpeconf0(t0, cpu_env);
9673                 break;
9674             default:
9675                 goto die;
9676                 break;
9677             }
9678             break;
9679         case 2:
9680             switch (sel) {
9681             case 1:
9682                 gen_helper_mftc0_tcstatus(t0, cpu_env);
9683                 break;
9684             case 2:
9685                 gen_helper_mftc0_tcbind(t0, cpu_env);
9686                 break;
9687             case 3:
9688                 gen_helper_mftc0_tcrestart(t0, cpu_env);
9689                 break;
9690             case 4:
9691                 gen_helper_mftc0_tchalt(t0, cpu_env);
9692                 break;
9693             case 5:
9694                 gen_helper_mftc0_tccontext(t0, cpu_env);
9695                 break;
9696             case 6:
9697                 gen_helper_mftc0_tcschedule(t0, cpu_env);
9698                 break;
9699             case 7:
9700                 gen_helper_mftc0_tcschefback(t0, cpu_env);
9701                 break;
9702             default:
9703                 gen_mfc0(ctx, t0, rt, sel);
9704                 break;
9705             }
9706             break;
9707         case 10:
9708             switch (sel) {
9709             case 0:
9710                 gen_helper_mftc0_entryhi(t0, cpu_env);
9711                 break;
9712             default:
9713                 gen_mfc0(ctx, t0, rt, sel);
9714                 break;
9715             }
9716         case 12:
9717             switch (sel) {
9718             case 0:
9719                 gen_helper_mftc0_status(t0, cpu_env);
9720                 break;
9721             default:
9722                 gen_mfc0(ctx, t0, rt, sel);
9723                 break;
9724             }
9725         case 13:
9726             switch (sel) {
9727             case 0:
9728                 gen_helper_mftc0_cause(t0, cpu_env);
9729                 break;
9730             default:
9731                 goto die;
9732                 break;
9733             }
9734             break;
9735         case 14:
9736             switch (sel) {
9737             case 0:
9738                 gen_helper_mftc0_epc(t0, cpu_env);
9739                 break;
9740             default:
9741                 goto die;
9742                 break;
9743             }
9744             break;
9745         case 15:
9746             switch (sel) {
9747             case 1:
9748                 gen_helper_mftc0_ebase(t0, cpu_env);
9749                 break;
9750             default:
9751                 goto die;
9752                 break;
9753             }
9754             break;
9755         case 16:
9756             switch (sel) {
9757             case 0:
9758             case 1:
9759             case 2:
9760             case 3:
9761             case 4:
9762             case 5:
9763             case 6:
9764             case 7:
9765                 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
9766                 break;
9767             default:
9768                 goto die;
9769                 break;
9770             }
9771             break;
9772         case 23:
9773             switch (sel) {
9774             case 0:
9775                 gen_helper_mftc0_debug(t0, cpu_env);
9776                 break;
9777             default:
9778                 gen_mfc0(ctx, t0, rt, sel);
9779                 break;
9780             }
9781             break;
9782         default:
9783             gen_mfc0(ctx, t0, rt, sel);
9784         }
9785     } else switch (sel) {
9786     /* GPR registers. */
9787     case 0:
9788         gen_helper_1e0i(mftgpr, t0, rt);
9789         break;
9790     /* Auxiliary CPU registers */
9791     case 1:
9792         switch (rt) {
9793         case 0:
9794             gen_helper_1e0i(mftlo, t0, 0);
9795             break;
9796         case 1:
9797             gen_helper_1e0i(mfthi, t0, 0);
9798             break;
9799         case 2:
9800             gen_helper_1e0i(mftacx, t0, 0);
9801             break;
9802         case 4:
9803             gen_helper_1e0i(mftlo, t0, 1);
9804             break;
9805         case 5:
9806             gen_helper_1e0i(mfthi, t0, 1);
9807             break;
9808         case 6:
9809             gen_helper_1e0i(mftacx, t0, 1);
9810             break;
9811         case 8:
9812             gen_helper_1e0i(mftlo, t0, 2);
9813             break;
9814         case 9:
9815             gen_helper_1e0i(mfthi, t0, 2);
9816             break;
9817         case 10:
9818             gen_helper_1e0i(mftacx, t0, 2);
9819             break;
9820         case 12:
9821             gen_helper_1e0i(mftlo, t0, 3);
9822             break;
9823         case 13:
9824             gen_helper_1e0i(mfthi, t0, 3);
9825             break;
9826         case 14:
9827             gen_helper_1e0i(mftacx, t0, 3);
9828             break;
9829         case 16:
9830             gen_helper_mftdsp(t0, cpu_env);
9831             break;
9832         default:
9833             goto die;
9834         }
9835         break;
9836     /* Floating point (COP1). */
9837     case 2:
9838         /* XXX: For now we support only a single FPU context. */
9839         if (h == 0) {
9840             TCGv_i32 fp0 = tcg_temp_new_i32();
9841
9842             gen_load_fpr32(ctx, fp0, rt);
9843             tcg_gen_ext_i32_tl(t0, fp0);
9844             tcg_temp_free_i32(fp0);
9845         } else {
9846             TCGv_i32 fp0 = tcg_temp_new_i32();
9847
9848             gen_load_fpr32h(ctx, fp0, rt);
9849             tcg_gen_ext_i32_tl(t0, fp0);
9850             tcg_temp_free_i32(fp0);
9851         }
9852         break;
9853     case 3:
9854         /* XXX: For now we support only a single FPU context. */
9855         gen_helper_1e0i(cfc1, t0, rt);
9856         break;
9857     /* COP2: Not implemented. */
9858     case 4:
9859     case 5:
9860         /* fall through */
9861     default:
9862         goto die;
9863     }
9864     trace_mips_translate_tr("mftr", rt, u, sel, h);
9865     gen_store_gpr(t0, rd);
9866     tcg_temp_free(t0);
9867     return;
9868
9869 die:
9870     tcg_temp_free(t0);
9871     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9872     generate_exception_end(ctx, EXCP_RI);
9873 }
9874
9875 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
9876                      int u, int sel, int h)
9877 {
9878     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9879     TCGv t0 = tcg_temp_local_new();
9880
9881     gen_load_gpr(t0, rt);
9882     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9883         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9884          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9885         /* NOP */ ;
9886     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9887              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9888         /* NOP */ ;
9889     else if (u == 0) {
9890         switch (rd) {
9891         case 1:
9892             switch (sel) {
9893             case 1:
9894                 gen_helper_mttc0_vpecontrol(cpu_env, t0);
9895                 break;
9896             case 2:
9897                 gen_helper_mttc0_vpeconf0(cpu_env, t0);
9898                 break;
9899             default:
9900                 goto die;
9901                 break;
9902             }
9903             break;
9904         case 2:
9905             switch (sel) {
9906             case 1:
9907                 gen_helper_mttc0_tcstatus(cpu_env, t0);
9908                 break;
9909             case 2:
9910                 gen_helper_mttc0_tcbind(cpu_env, t0);
9911                 break;
9912             case 3:
9913                 gen_helper_mttc0_tcrestart(cpu_env, t0);
9914                 break;
9915             case 4:
9916                 gen_helper_mttc0_tchalt(cpu_env, t0);
9917                 break;
9918             case 5:
9919                 gen_helper_mttc0_tccontext(cpu_env, t0);
9920                 break;
9921             case 6:
9922                 gen_helper_mttc0_tcschedule(cpu_env, t0);
9923                 break;
9924             case 7:
9925                 gen_helper_mttc0_tcschefback(cpu_env, t0);
9926                 break;
9927             default:
9928                 gen_mtc0(ctx, t0, rd, sel);
9929                 break;
9930             }
9931             break;
9932         case 10:
9933             switch (sel) {
9934             case 0:
9935                 gen_helper_mttc0_entryhi(cpu_env, t0);
9936                 break;
9937             default:
9938                 gen_mtc0(ctx, t0, rd, sel);
9939                 break;
9940             }
9941         case 12:
9942             switch (sel) {
9943             case 0:
9944                 gen_helper_mttc0_status(cpu_env, t0);
9945                 break;
9946             default:
9947                 gen_mtc0(ctx, t0, rd, sel);
9948                 break;
9949             }
9950         case 13:
9951             switch (sel) {
9952             case 0:
9953                 gen_helper_mttc0_cause(cpu_env, t0);
9954                 break;
9955             default:
9956                 goto die;
9957                 break;
9958             }
9959             break;
9960         case 15:
9961             switch (sel) {
9962             case 1:
9963                 gen_helper_mttc0_ebase(cpu_env, t0);
9964                 break;
9965             default:
9966                 goto die;
9967                 break;
9968             }
9969             break;
9970         case 23:
9971             switch (sel) {
9972             case 0:
9973                 gen_helper_mttc0_debug(cpu_env, t0);
9974                 break;
9975             default:
9976                 gen_mtc0(ctx, t0, rd, sel);
9977                 break;
9978             }
9979             break;
9980         default:
9981             gen_mtc0(ctx, t0, rd, sel);
9982         }
9983     } else switch (sel) {
9984     /* GPR registers. */
9985     case 0:
9986         gen_helper_0e1i(mttgpr, t0, rd);
9987         break;
9988     /* Auxiliary CPU registers */
9989     case 1:
9990         switch (rd) {
9991         case 0:
9992             gen_helper_0e1i(mttlo, t0, 0);
9993             break;
9994         case 1:
9995             gen_helper_0e1i(mtthi, t0, 0);
9996             break;
9997         case 2:
9998             gen_helper_0e1i(mttacx, t0, 0);
9999             break;
10000         case 4:
10001             gen_helper_0e1i(mttlo, t0, 1);
10002             break;
10003         case 5:
10004             gen_helper_0e1i(mtthi, t0, 1);
10005             break;
10006         case 6:
10007             gen_helper_0e1i(mttacx, t0, 1);
10008             break;
10009         case 8:
10010             gen_helper_0e1i(mttlo, t0, 2);
10011             break;
10012         case 9:
10013             gen_helper_0e1i(mtthi, t0, 2);
10014             break;
10015         case 10:
10016             gen_helper_0e1i(mttacx, t0, 2);
10017             break;
10018         case 12:
10019             gen_helper_0e1i(mttlo, t0, 3);
10020             break;
10021         case 13:
10022             gen_helper_0e1i(mtthi, t0, 3);
10023             break;
10024         case 14:
10025             gen_helper_0e1i(mttacx, t0, 3);
10026             break;
10027         case 16:
10028             gen_helper_mttdsp(cpu_env, t0);
10029             break;
10030         default:
10031             goto die;
10032         }
10033         break;
10034     /* Floating point (COP1). */
10035     case 2:
10036         /* XXX: For now we support only a single FPU context. */
10037         if (h == 0) {
10038             TCGv_i32 fp0 = tcg_temp_new_i32();
10039
10040             tcg_gen_trunc_tl_i32(fp0, t0);
10041             gen_store_fpr32(ctx, fp0, rd);
10042             tcg_temp_free_i32(fp0);
10043         } else {
10044             TCGv_i32 fp0 = tcg_temp_new_i32();
10045
10046             tcg_gen_trunc_tl_i32(fp0, t0);
10047             gen_store_fpr32h(ctx, fp0, rd);
10048             tcg_temp_free_i32(fp0);
10049         }
10050         break;
10051     case 3:
10052         /* XXX: For now we support only a single FPU context. */
10053         {
10054             TCGv_i32 fs_tmp = tcg_const_i32(rd);
10055
10056             gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10057             tcg_temp_free_i32(fs_tmp);
10058         }
10059         /* Stop translation as we may have changed hflags */
10060         ctx->base.is_jmp = DISAS_STOP;
10061         break;
10062     /* COP2: Not implemented. */
10063     case 4:
10064     case 5:
10065         /* fall through */
10066     default:
10067         goto die;
10068     }
10069     trace_mips_translate_tr("mttr", rd, u, sel, h);
10070     tcg_temp_free(t0);
10071     return;
10072
10073 die:
10074     tcg_temp_free(t0);
10075     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
10076     generate_exception_end(ctx, EXCP_RI);
10077 }
10078
10079 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
10080 {
10081     const char *opn = "ldst";
10082
10083     check_cp0_enabled(ctx);
10084     switch (opc) {
10085     case OPC_MFC0:
10086         if (rt == 0) {
10087             /* Treat as NOP. */
10088             return;
10089         }
10090         gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10091         opn = "mfc0";
10092         break;
10093     case OPC_MTC0:
10094         {
10095             TCGv t0 = tcg_temp_new();
10096
10097             gen_load_gpr(t0, rt);
10098             gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
10099             tcg_temp_free(t0);
10100         }
10101         opn = "mtc0";
10102         break;
10103 #if defined(TARGET_MIPS64)
10104     case OPC_DMFC0:
10105         check_insn(ctx, ISA_MIPS3);
10106         if (rt == 0) {
10107             /* Treat as NOP. */
10108             return;
10109         }
10110         gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10111         opn = "dmfc0";
10112         break;
10113     case OPC_DMTC0:
10114         check_insn(ctx, ISA_MIPS3);
10115         {
10116             TCGv t0 = tcg_temp_new();
10117
10118             gen_load_gpr(t0, rt);
10119             gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
10120             tcg_temp_free(t0);
10121         }
10122         opn = "dmtc0";
10123         break;
10124 #endif
10125     case OPC_MFHC0:
10126         check_mvh(ctx);
10127         if (rt == 0) {
10128             /* Treat as NOP. */
10129             return;
10130         }
10131         gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10132         opn = "mfhc0";
10133         break;
10134     case OPC_MTHC0:
10135         check_mvh(ctx);
10136         {
10137             TCGv t0 = tcg_temp_new();
10138             gen_load_gpr(t0, rt);
10139             gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
10140             tcg_temp_free(t0);
10141         }
10142         opn = "mthc0";
10143         break;
10144     case OPC_MFTR:
10145         check_cp0_enabled(ctx);
10146         if (rd == 0) {
10147             /* Treat as NOP. */
10148             return;
10149         }
10150         gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
10151                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10152         opn = "mftr";
10153         break;
10154     case OPC_MTTR:
10155         check_cp0_enabled(ctx);
10156         gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
10157                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10158         opn = "mttr";
10159         break;
10160     case OPC_TLBWI:
10161         opn = "tlbwi";
10162         if (!env->tlb->helper_tlbwi)
10163             goto die;
10164         gen_helper_tlbwi(cpu_env);
10165         break;
10166     case OPC_TLBINV:
10167         opn = "tlbinv";
10168         if (ctx->ie >= 2) {
10169             if (!env->tlb->helper_tlbinv) {
10170                 goto die;
10171             }
10172             gen_helper_tlbinv(cpu_env);
10173         } /* treat as nop if TLBINV not supported */
10174         break;
10175     case OPC_TLBINVF:
10176         opn = "tlbinvf";
10177         if (ctx->ie >= 2) {
10178             if (!env->tlb->helper_tlbinvf) {
10179                 goto die;
10180             }
10181             gen_helper_tlbinvf(cpu_env);
10182         } /* treat as nop if TLBINV not supported */
10183         break;
10184     case OPC_TLBWR:
10185         opn = "tlbwr";
10186         if (!env->tlb->helper_tlbwr)
10187             goto die;
10188         gen_helper_tlbwr(cpu_env);
10189         break;
10190     case OPC_TLBP:
10191         opn = "tlbp";
10192         if (!env->tlb->helper_tlbp)
10193             goto die;
10194         gen_helper_tlbp(cpu_env);
10195         break;
10196     case OPC_TLBR:
10197         opn = "tlbr";
10198         if (!env->tlb->helper_tlbr)
10199             goto die;
10200         gen_helper_tlbr(cpu_env);
10201         break;
10202     case OPC_ERET: /* OPC_ERETNC */
10203         if ((ctx->insn_flags & ISA_MIPS32R6) &&
10204             (ctx->hflags & MIPS_HFLAG_BMASK)) {
10205             goto die;
10206         } else {
10207             int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
10208             if (ctx->opcode & (1 << bit_shift)) {
10209                 /* OPC_ERETNC */
10210                 opn = "eretnc";
10211                 check_insn(ctx, ISA_MIPS32R5);
10212                 gen_helper_eretnc(cpu_env);
10213             } else {
10214                 /* OPC_ERET */
10215                 opn = "eret";
10216                 check_insn(ctx, ISA_MIPS2);
10217                 gen_helper_eret(cpu_env);
10218             }
10219             ctx->base.is_jmp = DISAS_EXIT;
10220         }
10221         break;
10222     case OPC_DERET:
10223         opn = "deret";
10224         check_insn(ctx, ISA_MIPS32);
10225         if ((ctx->insn_flags & ISA_MIPS32R6) &&
10226             (ctx->hflags & MIPS_HFLAG_BMASK)) {
10227             goto die;
10228         }
10229         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10230             MIPS_INVAL(opn);
10231             generate_exception_end(ctx, EXCP_RI);
10232         } else {
10233             gen_helper_deret(cpu_env);
10234             ctx->base.is_jmp = DISAS_EXIT;
10235         }
10236         break;
10237     case OPC_WAIT:
10238         opn = "wait";
10239         check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
10240         if ((ctx->insn_flags & ISA_MIPS32R6) &&
10241             (ctx->hflags & MIPS_HFLAG_BMASK)) {
10242             goto die;
10243         }
10244         /* If we get an exception, we want to restart at next instruction */
10245         ctx->base.pc_next += 4;
10246         save_cpu_state(ctx, 1);
10247         ctx->base.pc_next -= 4;
10248         gen_helper_wait(cpu_env);
10249         ctx->base.is_jmp = DISAS_NORETURN;
10250         break;
10251     default:
10252  die:
10253         MIPS_INVAL(opn);
10254         generate_exception_end(ctx, EXCP_RI);
10255         return;
10256     }
10257     (void)opn; /* avoid a compiler warning */
10258 }
10259 #endif /* !CONFIG_USER_ONLY */
10260
10261 /* CP1 Branches (before delay slot) */
10262 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
10263                                 int32_t cc, int32_t offset)
10264 {
10265     target_ulong btarget;
10266     TCGv_i32 t0 = tcg_temp_new_i32();
10267
10268     if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10269         generate_exception_end(ctx, EXCP_RI);
10270         goto out;
10271     }
10272
10273     if (cc != 0)
10274         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
10275
10276     btarget = ctx->base.pc_next + 4 + offset;
10277
10278     switch (op) {
10279     case OPC_BC1F:
10280         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10281         tcg_gen_not_i32(t0, t0);
10282         tcg_gen_andi_i32(t0, t0, 1);
10283         tcg_gen_extu_i32_tl(bcond, t0);
10284         goto not_likely;
10285     case OPC_BC1FL:
10286         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10287         tcg_gen_not_i32(t0, t0);
10288         tcg_gen_andi_i32(t0, t0, 1);
10289         tcg_gen_extu_i32_tl(bcond, t0);
10290         goto likely;
10291     case OPC_BC1T:
10292         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10293         tcg_gen_andi_i32(t0, t0, 1);
10294         tcg_gen_extu_i32_tl(bcond, t0);
10295         goto not_likely;
10296     case OPC_BC1TL:
10297         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10298         tcg_gen_andi_i32(t0, t0, 1);
10299         tcg_gen_extu_i32_tl(bcond, t0);
10300     likely:
10301         ctx->hflags |= MIPS_HFLAG_BL;
10302         break;
10303     case OPC_BC1FANY2:
10304         {
10305             TCGv_i32 t1 = tcg_temp_new_i32();
10306             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10307             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10308             tcg_gen_nand_i32(t0, t0, t1);
10309             tcg_temp_free_i32(t1);
10310             tcg_gen_andi_i32(t0, t0, 1);
10311             tcg_gen_extu_i32_tl(bcond, t0);
10312         }
10313         goto not_likely;
10314     case OPC_BC1TANY2:
10315         {
10316             TCGv_i32 t1 = tcg_temp_new_i32();
10317             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10318             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10319             tcg_gen_or_i32(t0, t0, t1);
10320             tcg_temp_free_i32(t1);
10321             tcg_gen_andi_i32(t0, t0, 1);
10322             tcg_gen_extu_i32_tl(bcond, t0);
10323         }
10324         goto not_likely;
10325     case OPC_BC1FANY4:
10326         {
10327             TCGv_i32 t1 = tcg_temp_new_i32();
10328             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10329             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10330             tcg_gen_and_i32(t0, t0, t1);
10331             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10332             tcg_gen_and_i32(t0, t0, t1);
10333             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10334             tcg_gen_nand_i32(t0, t0, t1);
10335             tcg_temp_free_i32(t1);
10336             tcg_gen_andi_i32(t0, t0, 1);
10337             tcg_gen_extu_i32_tl(bcond, t0);
10338         }
10339         goto not_likely;
10340     case OPC_BC1TANY4:
10341         {
10342             TCGv_i32 t1 = tcg_temp_new_i32();
10343             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10344             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10345             tcg_gen_or_i32(t0, t0, t1);
10346             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10347             tcg_gen_or_i32(t0, t0, t1);
10348             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10349             tcg_gen_or_i32(t0, t0, t1);
10350             tcg_temp_free_i32(t1);
10351             tcg_gen_andi_i32(t0, t0, 1);
10352             tcg_gen_extu_i32_tl(bcond, t0);
10353         }
10354     not_likely:
10355         ctx->hflags |= MIPS_HFLAG_BC;
10356         break;
10357     default:
10358         MIPS_INVAL("cp1 cond branch");
10359         generate_exception_end(ctx, EXCP_RI);
10360         goto out;
10361     }
10362     ctx->btarget = btarget;
10363     ctx->hflags |= MIPS_HFLAG_BDS32;
10364  out:
10365     tcg_temp_free_i32(t0);
10366 }
10367
10368 /* R6 CP1 Branches */
10369 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
10370                                    int32_t ft, int32_t offset,
10371                                    int delayslot_size)
10372 {
10373     target_ulong btarget;
10374     TCGv_i64 t0 = tcg_temp_new_i64();
10375
10376     if (ctx->hflags & MIPS_HFLAG_BMASK) {
10377 #ifdef MIPS_DEBUG_DISAS
10378         LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10379                   "\n", ctx->base.pc_next);
10380 #endif
10381         generate_exception_end(ctx, EXCP_RI);
10382         goto out;
10383     }
10384
10385     gen_load_fpr64(ctx, t0, ft);
10386     tcg_gen_andi_i64(t0, t0, 1);
10387
10388     btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
10389
10390     switch (op) {
10391     case OPC_BC1EQZ:
10392         tcg_gen_xori_i64(t0, t0, 1);
10393         ctx->hflags |= MIPS_HFLAG_BC;
10394         break;
10395     case OPC_BC1NEZ:
10396         /* t0 already set */
10397         ctx->hflags |= MIPS_HFLAG_BC;
10398         break;
10399     default:
10400         MIPS_INVAL("cp1 cond branch");
10401         generate_exception_end(ctx, EXCP_RI);
10402         goto out;
10403     }
10404
10405     tcg_gen_trunc_i64_tl(bcond, t0);
10406
10407     ctx->btarget = btarget;
10408
10409     switch (delayslot_size) {
10410     case 2:
10411         ctx->hflags |= MIPS_HFLAG_BDS16;
10412         break;
10413     case 4:
10414         ctx->hflags |= MIPS_HFLAG_BDS32;
10415         break;
10416     }
10417
10418 out:
10419     tcg_temp_free_i64(t0);
10420 }
10421
10422 /* Coprocessor 1 (FPU) */
10423
10424 #define FOP(func, fmt) (((fmt) << 21) | (func))
10425
10426 enum fopcode {
10427     OPC_ADD_S = FOP(0, FMT_S),
10428     OPC_SUB_S = FOP(1, FMT_S),
10429     OPC_MUL_S = FOP(2, FMT_S),
10430     OPC_DIV_S = FOP(3, FMT_S),
10431     OPC_SQRT_S = FOP(4, FMT_S),
10432     OPC_ABS_S = FOP(5, FMT_S),
10433     OPC_MOV_S = FOP(6, FMT_S),
10434     OPC_NEG_S = FOP(7, FMT_S),
10435     OPC_ROUND_L_S = FOP(8, FMT_S),
10436     OPC_TRUNC_L_S = FOP(9, FMT_S),
10437     OPC_CEIL_L_S = FOP(10, FMT_S),
10438     OPC_FLOOR_L_S = FOP(11, FMT_S),
10439     OPC_ROUND_W_S = FOP(12, FMT_S),
10440     OPC_TRUNC_W_S = FOP(13, FMT_S),
10441     OPC_CEIL_W_S = FOP(14, FMT_S),
10442     OPC_FLOOR_W_S = FOP(15, FMT_S),
10443     OPC_SEL_S = FOP(16, FMT_S),
10444     OPC_MOVCF_S = FOP(17, FMT_S),
10445     OPC_MOVZ_S = FOP(18, FMT_S),
10446     OPC_MOVN_S = FOP(19, FMT_S),
10447     OPC_SELEQZ_S = FOP(20, FMT_S),
10448     OPC_RECIP_S = FOP(21, FMT_S),
10449     OPC_RSQRT_S = FOP(22, FMT_S),
10450     OPC_SELNEZ_S = FOP(23, FMT_S),
10451     OPC_MADDF_S = FOP(24, FMT_S),
10452     OPC_MSUBF_S = FOP(25, FMT_S),
10453     OPC_RINT_S = FOP(26, FMT_S),
10454     OPC_CLASS_S = FOP(27, FMT_S),
10455     OPC_MIN_S = FOP(28, FMT_S),
10456     OPC_RECIP2_S = FOP(28, FMT_S),
10457     OPC_MINA_S = FOP(29, FMT_S),
10458     OPC_RECIP1_S = FOP(29, FMT_S),
10459     OPC_MAX_S = FOP(30, FMT_S),
10460     OPC_RSQRT1_S = FOP(30, FMT_S),
10461     OPC_MAXA_S = FOP(31, FMT_S),
10462     OPC_RSQRT2_S = FOP(31, FMT_S),
10463     OPC_CVT_D_S = FOP(33, FMT_S),
10464     OPC_CVT_W_S = FOP(36, FMT_S),
10465     OPC_CVT_L_S = FOP(37, FMT_S),
10466     OPC_CVT_PS_S = FOP(38, FMT_S),
10467     OPC_CMP_F_S = FOP (48, FMT_S),
10468     OPC_CMP_UN_S = FOP (49, FMT_S),
10469     OPC_CMP_EQ_S = FOP (50, FMT_S),
10470     OPC_CMP_UEQ_S = FOP (51, FMT_S),
10471     OPC_CMP_OLT_S = FOP (52, FMT_S),
10472     OPC_CMP_ULT_S = FOP (53, FMT_S),
10473     OPC_CMP_OLE_S = FOP (54, FMT_S),
10474     OPC_CMP_ULE_S = FOP (55, FMT_S),
10475     OPC_CMP_SF_S = FOP (56, FMT_S),
10476     OPC_CMP_NGLE_S = FOP (57, FMT_S),
10477     OPC_CMP_SEQ_S = FOP (58, FMT_S),
10478     OPC_CMP_NGL_S = FOP (59, FMT_S),
10479     OPC_CMP_LT_S = FOP (60, FMT_S),
10480     OPC_CMP_NGE_S = FOP (61, FMT_S),
10481     OPC_CMP_LE_S = FOP (62, FMT_S),
10482     OPC_CMP_NGT_S = FOP (63, FMT_S),
10483
10484     OPC_ADD_D = FOP(0, FMT_D),
10485     OPC_SUB_D = FOP(1, FMT_D),
10486     OPC_MUL_D = FOP(2, FMT_D),
10487     OPC_DIV_D = FOP(3, FMT_D),
10488     OPC_SQRT_D = FOP(4, FMT_D),
10489     OPC_ABS_D = FOP(5, FMT_D),
10490     OPC_MOV_D = FOP(6, FMT_D),
10491     OPC_NEG_D = FOP(7, FMT_D),
10492     OPC_ROUND_L_D = FOP(8, FMT_D),
10493     OPC_TRUNC_L_D = FOP(9, FMT_D),
10494     OPC_CEIL_L_D = FOP(10, FMT_D),
10495     OPC_FLOOR_L_D = FOP(11, FMT_D),
10496     OPC_ROUND_W_D = FOP(12, FMT_D),
10497     OPC_TRUNC_W_D = FOP(13, FMT_D),
10498     OPC_CEIL_W_D = FOP(14, FMT_D),
10499     OPC_FLOOR_W_D = FOP(15, FMT_D),
10500     OPC_SEL_D = FOP(16, FMT_D),
10501     OPC_MOVCF_D = FOP(17, FMT_D),
10502     OPC_MOVZ_D = FOP(18, FMT_D),
10503     OPC_MOVN_D = FOP(19, FMT_D),
10504     OPC_SELEQZ_D = FOP(20, FMT_D),
10505     OPC_RECIP_D = FOP(21, FMT_D),
10506     OPC_RSQRT_D = FOP(22, FMT_D),
10507     OPC_SELNEZ_D = FOP(23, FMT_D),
10508     OPC_MADDF_D = FOP(24, FMT_D),
10509     OPC_MSUBF_D = FOP(25, FMT_D),
10510     OPC_RINT_D = FOP(26, FMT_D),
10511     OPC_CLASS_D = FOP(27, FMT_D),
10512     OPC_MIN_D = FOP(28, FMT_D),
10513     OPC_RECIP2_D = FOP(28, FMT_D),
10514     OPC_MINA_D = FOP(29, FMT_D),
10515     OPC_RECIP1_D = FOP(29, FMT_D),
10516     OPC_MAX_D = FOP(30, FMT_D),
10517     OPC_RSQRT1_D = FOP(30, FMT_D),
10518     OPC_MAXA_D = FOP(31, FMT_D),
10519     OPC_RSQRT2_D = FOP(31, FMT_D),
10520     OPC_CVT_S_D = FOP(32, FMT_D),
10521     OPC_CVT_W_D = FOP(36, FMT_D),
10522     OPC_CVT_L_D = FOP(37, FMT_D),
10523     OPC_CMP_F_D = FOP (48, FMT_D),
10524     OPC_CMP_UN_D = FOP (49, FMT_D),
10525     OPC_CMP_EQ_D = FOP (50, FMT_D),
10526     OPC_CMP_UEQ_D = FOP (51, FMT_D),
10527     OPC_CMP_OLT_D = FOP (52, FMT_D),
10528     OPC_CMP_ULT_D = FOP (53, FMT_D),
10529     OPC_CMP_OLE_D = FOP (54, FMT_D),
10530     OPC_CMP_ULE_D = FOP (55, FMT_D),
10531     OPC_CMP_SF_D = FOP (56, FMT_D),
10532     OPC_CMP_NGLE_D = FOP (57, FMT_D),
10533     OPC_CMP_SEQ_D = FOP (58, FMT_D),
10534     OPC_CMP_NGL_D = FOP (59, FMT_D),
10535     OPC_CMP_LT_D = FOP (60, FMT_D),
10536     OPC_CMP_NGE_D = FOP (61, FMT_D),
10537     OPC_CMP_LE_D = FOP (62, FMT_D),
10538     OPC_CMP_NGT_D = FOP (63, FMT_D),
10539
10540     OPC_CVT_S_W = FOP(32, FMT_W),
10541     OPC_CVT_D_W = FOP(33, FMT_W),
10542     OPC_CVT_S_L = FOP(32, FMT_L),
10543     OPC_CVT_D_L = FOP(33, FMT_L),
10544     OPC_CVT_PS_PW = FOP(38, FMT_W),
10545
10546     OPC_ADD_PS = FOP(0, FMT_PS),
10547     OPC_SUB_PS = FOP(1, FMT_PS),
10548     OPC_MUL_PS = FOP(2, FMT_PS),
10549     OPC_DIV_PS = FOP(3, FMT_PS),
10550     OPC_ABS_PS = FOP(5, FMT_PS),
10551     OPC_MOV_PS = FOP(6, FMT_PS),
10552     OPC_NEG_PS = FOP(7, FMT_PS),
10553     OPC_MOVCF_PS = FOP(17, FMT_PS),
10554     OPC_MOVZ_PS = FOP(18, FMT_PS),
10555     OPC_MOVN_PS = FOP(19, FMT_PS),
10556     OPC_ADDR_PS = FOP(24, FMT_PS),
10557     OPC_MULR_PS = FOP(26, FMT_PS),
10558     OPC_RECIP2_PS = FOP(28, FMT_PS),
10559     OPC_RECIP1_PS = FOP(29, FMT_PS),
10560     OPC_RSQRT1_PS = FOP(30, FMT_PS),
10561     OPC_RSQRT2_PS = FOP(31, FMT_PS),
10562
10563     OPC_CVT_S_PU = FOP(32, FMT_PS),
10564     OPC_CVT_PW_PS = FOP(36, FMT_PS),
10565     OPC_CVT_S_PL = FOP(40, FMT_PS),
10566     OPC_PLL_PS = FOP(44, FMT_PS),
10567     OPC_PLU_PS = FOP(45, FMT_PS),
10568     OPC_PUL_PS = FOP(46, FMT_PS),
10569     OPC_PUU_PS = FOP(47, FMT_PS),
10570     OPC_CMP_F_PS = FOP (48, FMT_PS),
10571     OPC_CMP_UN_PS = FOP (49, FMT_PS),
10572     OPC_CMP_EQ_PS = FOP (50, FMT_PS),
10573     OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
10574     OPC_CMP_OLT_PS = FOP (52, FMT_PS),
10575     OPC_CMP_ULT_PS = FOP (53, FMT_PS),
10576     OPC_CMP_OLE_PS = FOP (54, FMT_PS),
10577     OPC_CMP_ULE_PS = FOP (55, FMT_PS),
10578     OPC_CMP_SF_PS = FOP (56, FMT_PS),
10579     OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
10580     OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
10581     OPC_CMP_NGL_PS = FOP (59, FMT_PS),
10582     OPC_CMP_LT_PS = FOP (60, FMT_PS),
10583     OPC_CMP_NGE_PS = FOP (61, FMT_PS),
10584     OPC_CMP_LE_PS = FOP (62, FMT_PS),
10585     OPC_CMP_NGT_PS = FOP (63, FMT_PS),
10586 };
10587
10588 enum r6_f_cmp_op {
10589     R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
10590     R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
10591     R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
10592     R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
10593     R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
10594     R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
10595     R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
10596     R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
10597     R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
10598     R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
10599     R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
10600     R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10601     R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
10602     R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10603     R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
10604     R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10605     R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
10606     R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
10607     R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
10608     R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
10609     R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10610     R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
10611
10612     R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
10613     R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
10614     R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
10615     R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
10616     R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
10617     R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
10618     R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
10619     R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
10620     R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
10621     R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
10622     R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
10623     R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10624     R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
10625     R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10626     R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
10627     R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10628     R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
10629     R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
10630     R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
10631     R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
10632     R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10633     R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
10634 };
10635 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
10636 {
10637     TCGv t0 = tcg_temp_new();
10638
10639     switch (opc) {
10640     case OPC_MFC1:
10641         {
10642             TCGv_i32 fp0 = tcg_temp_new_i32();
10643
10644             gen_load_fpr32(ctx, fp0, fs);
10645             tcg_gen_ext_i32_tl(t0, fp0);
10646             tcg_temp_free_i32(fp0);
10647         }
10648         gen_store_gpr(t0, rt);
10649         break;
10650     case OPC_MTC1:
10651         gen_load_gpr(t0, rt);
10652         {
10653             TCGv_i32 fp0 = tcg_temp_new_i32();
10654
10655             tcg_gen_trunc_tl_i32(fp0, t0);
10656             gen_store_fpr32(ctx, fp0, fs);
10657             tcg_temp_free_i32(fp0);
10658         }
10659         break;
10660     case OPC_CFC1:
10661         gen_helper_1e0i(cfc1, t0, fs);
10662         gen_store_gpr(t0, rt);
10663         break;
10664     case OPC_CTC1:
10665         gen_load_gpr(t0, rt);
10666         save_cpu_state(ctx, 0);
10667         {
10668             TCGv_i32 fs_tmp = tcg_const_i32(fs);
10669
10670             gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10671             tcg_temp_free_i32(fs_tmp);
10672         }
10673         /* Stop translation as we may have changed hflags */
10674         ctx->base.is_jmp = DISAS_STOP;
10675         break;
10676 #if defined(TARGET_MIPS64)
10677     case OPC_DMFC1:
10678         gen_load_fpr64(ctx, t0, fs);
10679         gen_store_gpr(t0, rt);
10680         break;
10681     case OPC_DMTC1:
10682         gen_load_gpr(t0, rt);
10683         gen_store_fpr64(ctx, t0, fs);
10684         break;
10685 #endif
10686     case OPC_MFHC1:
10687         {
10688             TCGv_i32 fp0 = tcg_temp_new_i32();
10689
10690             gen_load_fpr32h(ctx, fp0, fs);
10691             tcg_gen_ext_i32_tl(t0, fp0);
10692             tcg_temp_free_i32(fp0);
10693         }
10694         gen_store_gpr(t0, rt);
10695         break;
10696     case OPC_MTHC1:
10697         gen_load_gpr(t0, rt);
10698         {
10699             TCGv_i32 fp0 = tcg_temp_new_i32();
10700
10701             tcg_gen_trunc_tl_i32(fp0, t0);
10702             gen_store_fpr32h(ctx, fp0, fs);
10703             tcg_temp_free_i32(fp0);
10704         }
10705         break;
10706     default:
10707         MIPS_INVAL("cp1 move");
10708         generate_exception_end(ctx, EXCP_RI);
10709         goto out;
10710     }
10711
10712  out:
10713     tcg_temp_free(t0);
10714 }
10715
10716 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
10717 {
10718     TCGLabel *l1;
10719     TCGCond cond;
10720     TCGv_i32 t0;
10721
10722     if (rd == 0) {
10723         /* Treat as NOP. */
10724         return;
10725     }
10726
10727     if (tf)
10728         cond = TCG_COND_EQ;
10729     else
10730         cond = TCG_COND_NE;
10731
10732     l1 = gen_new_label();
10733     t0 = tcg_temp_new_i32();
10734     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10735     tcg_gen_brcondi_i32(cond, t0, 0, l1);
10736     tcg_temp_free_i32(t0);
10737     if (rs == 0) {
10738         tcg_gen_movi_tl(cpu_gpr[rd], 0);
10739     } else {
10740         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
10741     }
10742     gen_set_label(l1);
10743 }
10744
10745 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
10746                                int tf)
10747 {
10748     int cond;
10749     TCGv_i32 t0 = tcg_temp_new_i32();
10750     TCGLabel *l1 = gen_new_label();
10751
10752     if (tf)
10753         cond = TCG_COND_EQ;
10754     else
10755         cond = TCG_COND_NE;
10756
10757     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10758     tcg_gen_brcondi_i32(cond, t0, 0, l1);
10759     gen_load_fpr32(ctx, t0, fs);
10760     gen_store_fpr32(ctx, t0, fd);
10761     gen_set_label(l1);
10762     tcg_temp_free_i32(t0);
10763 }
10764
10765 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
10766 {
10767     int cond;
10768     TCGv_i32 t0 = tcg_temp_new_i32();
10769     TCGv_i64 fp0;
10770     TCGLabel *l1 = gen_new_label();
10771
10772     if (tf)
10773         cond = TCG_COND_EQ;
10774     else
10775         cond = TCG_COND_NE;
10776
10777     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10778     tcg_gen_brcondi_i32(cond, t0, 0, l1);
10779     tcg_temp_free_i32(t0);
10780     fp0 = tcg_temp_new_i64();
10781     gen_load_fpr64(ctx, fp0, fs);
10782     gen_store_fpr64(ctx, fp0, fd);
10783     tcg_temp_free_i64(fp0);
10784     gen_set_label(l1);
10785 }
10786
10787 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
10788                                 int cc, int tf)
10789 {
10790     int cond;
10791     TCGv_i32 t0 = tcg_temp_new_i32();
10792     TCGLabel *l1 = gen_new_label();
10793     TCGLabel *l2 = gen_new_label();
10794
10795     if (tf)
10796         cond = TCG_COND_EQ;
10797     else
10798         cond = TCG_COND_NE;
10799
10800     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10801     tcg_gen_brcondi_i32(cond, t0, 0, l1);
10802     gen_load_fpr32(ctx, t0, fs);
10803     gen_store_fpr32(ctx, t0, fd);
10804     gen_set_label(l1);
10805
10806     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
10807     tcg_gen_brcondi_i32(cond, t0, 0, l2);
10808     gen_load_fpr32h(ctx, t0, fs);
10809     gen_store_fpr32h(ctx, t0, fd);
10810     tcg_temp_free_i32(t0);
10811     gen_set_label(l2);
10812 }
10813
10814 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10815                       int fs)
10816 {
10817     TCGv_i32 t1 = tcg_const_i32(0);
10818     TCGv_i32 fp0 = tcg_temp_new_i32();
10819     TCGv_i32 fp1 = tcg_temp_new_i32();
10820     TCGv_i32 fp2 = tcg_temp_new_i32();
10821     gen_load_fpr32(ctx, fp0, fd);
10822     gen_load_fpr32(ctx, fp1, ft);
10823     gen_load_fpr32(ctx, fp2, fs);
10824
10825     switch (op1) {
10826     case OPC_SEL_S:
10827         tcg_gen_andi_i32(fp0, fp0, 1);
10828         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10829         break;
10830     case OPC_SELEQZ_S:
10831         tcg_gen_andi_i32(fp1, fp1, 1);
10832         tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10833         break;
10834     case OPC_SELNEZ_S:
10835         tcg_gen_andi_i32(fp1, fp1, 1);
10836         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10837         break;
10838     default:
10839         MIPS_INVAL("gen_sel_s");
10840         generate_exception_end(ctx, EXCP_RI);
10841         break;
10842     }
10843
10844     gen_store_fpr32(ctx, fp0, fd);
10845     tcg_temp_free_i32(fp2);
10846     tcg_temp_free_i32(fp1);
10847     tcg_temp_free_i32(fp0);
10848     tcg_temp_free_i32(t1);
10849 }
10850
10851 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10852                       int fs)
10853 {
10854     TCGv_i64 t1 = tcg_const_i64(0);
10855     TCGv_i64 fp0 = tcg_temp_new_i64();
10856     TCGv_i64 fp1 = tcg_temp_new_i64();
10857     TCGv_i64 fp2 = tcg_temp_new_i64();
10858     gen_load_fpr64(ctx, fp0, fd);
10859     gen_load_fpr64(ctx, fp1, ft);
10860     gen_load_fpr64(ctx, fp2, fs);
10861
10862     switch (op1) {
10863     case OPC_SEL_D:
10864         tcg_gen_andi_i64(fp0, fp0, 1);
10865         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10866         break;
10867     case OPC_SELEQZ_D:
10868         tcg_gen_andi_i64(fp1, fp1, 1);
10869         tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10870         break;
10871     case OPC_SELNEZ_D:
10872         tcg_gen_andi_i64(fp1, fp1, 1);
10873         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10874         break;
10875     default:
10876         MIPS_INVAL("gen_sel_d");
10877         generate_exception_end(ctx, EXCP_RI);
10878         break;
10879     }
10880
10881     gen_store_fpr64(ctx, fp0, fd);
10882     tcg_temp_free_i64(fp2);
10883     tcg_temp_free_i64(fp1);
10884     tcg_temp_free_i64(fp0);
10885     tcg_temp_free_i64(t1);
10886 }
10887
10888 static void gen_farith (DisasContext *ctx, enum fopcode op1,
10889                         int ft, int fs, int fd, int cc)
10890 {
10891     uint32_t func = ctx->opcode & 0x3f;
10892     switch (op1) {
10893     case OPC_ADD_S:
10894         {
10895             TCGv_i32 fp0 = tcg_temp_new_i32();
10896             TCGv_i32 fp1 = tcg_temp_new_i32();
10897
10898             gen_load_fpr32(ctx, fp0, fs);
10899             gen_load_fpr32(ctx, fp1, ft);
10900             gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
10901             tcg_temp_free_i32(fp1);
10902             gen_store_fpr32(ctx, fp0, fd);
10903             tcg_temp_free_i32(fp0);
10904         }
10905         break;
10906     case OPC_SUB_S:
10907         {
10908             TCGv_i32 fp0 = tcg_temp_new_i32();
10909             TCGv_i32 fp1 = tcg_temp_new_i32();
10910
10911             gen_load_fpr32(ctx, fp0, fs);
10912             gen_load_fpr32(ctx, fp1, ft);
10913             gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
10914             tcg_temp_free_i32(fp1);
10915             gen_store_fpr32(ctx, fp0, fd);
10916             tcg_temp_free_i32(fp0);
10917         }
10918         break;
10919     case OPC_MUL_S:
10920         {
10921             TCGv_i32 fp0 = tcg_temp_new_i32();
10922             TCGv_i32 fp1 = tcg_temp_new_i32();
10923
10924             gen_load_fpr32(ctx, fp0, fs);
10925             gen_load_fpr32(ctx, fp1, ft);
10926             gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
10927             tcg_temp_free_i32(fp1);
10928             gen_store_fpr32(ctx, fp0, fd);
10929             tcg_temp_free_i32(fp0);
10930         }
10931         break;
10932     case OPC_DIV_S:
10933         {
10934             TCGv_i32 fp0 = tcg_temp_new_i32();
10935             TCGv_i32 fp1 = tcg_temp_new_i32();
10936
10937             gen_load_fpr32(ctx, fp0, fs);
10938             gen_load_fpr32(ctx, fp1, ft);
10939             gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
10940             tcg_temp_free_i32(fp1);
10941             gen_store_fpr32(ctx, fp0, fd);
10942             tcg_temp_free_i32(fp0);
10943         }
10944         break;
10945     case OPC_SQRT_S:
10946         {
10947             TCGv_i32 fp0 = tcg_temp_new_i32();
10948
10949             gen_load_fpr32(ctx, fp0, fs);
10950             gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
10951             gen_store_fpr32(ctx, fp0, fd);
10952             tcg_temp_free_i32(fp0);
10953         }
10954         break;
10955     case OPC_ABS_S:
10956         {
10957             TCGv_i32 fp0 = tcg_temp_new_i32();
10958
10959             gen_load_fpr32(ctx, fp0, fs);
10960             if (ctx->abs2008) {
10961                 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10962             } else {
10963                 gen_helper_float_abs_s(fp0, fp0);
10964             }
10965             gen_store_fpr32(ctx, fp0, fd);
10966             tcg_temp_free_i32(fp0);
10967         }
10968         break;
10969     case OPC_MOV_S:
10970         {
10971             TCGv_i32 fp0 = tcg_temp_new_i32();
10972
10973             gen_load_fpr32(ctx, fp0, fs);
10974             gen_store_fpr32(ctx, fp0, fd);
10975             tcg_temp_free_i32(fp0);
10976         }
10977         break;
10978     case OPC_NEG_S:
10979         {
10980             TCGv_i32 fp0 = tcg_temp_new_i32();
10981
10982             gen_load_fpr32(ctx, fp0, fs);
10983             if (ctx->abs2008) {
10984                 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10985             } else {
10986                 gen_helper_float_chs_s(fp0, fp0);
10987             }
10988             gen_store_fpr32(ctx, fp0, fd);
10989             tcg_temp_free_i32(fp0);
10990         }
10991         break;
10992     case OPC_ROUND_L_S:
10993         check_cp1_64bitmode(ctx);
10994         {
10995             TCGv_i32 fp32 = tcg_temp_new_i32();
10996             TCGv_i64 fp64 = tcg_temp_new_i64();
10997
10998             gen_load_fpr32(ctx, fp32, fs);
10999             if (ctx->nan2008) {
11000                 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
11001             } else {
11002                 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
11003             }
11004             tcg_temp_free_i32(fp32);
11005             gen_store_fpr64(ctx, fp64, fd);
11006             tcg_temp_free_i64(fp64);
11007         }
11008         break;
11009     case OPC_TRUNC_L_S:
11010         check_cp1_64bitmode(ctx);
11011         {
11012             TCGv_i32 fp32 = tcg_temp_new_i32();
11013             TCGv_i64 fp64 = tcg_temp_new_i64();
11014
11015             gen_load_fpr32(ctx, fp32, fs);
11016             if (ctx->nan2008) {
11017                 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
11018             } else {
11019                 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
11020             }
11021             tcg_temp_free_i32(fp32);
11022             gen_store_fpr64(ctx, fp64, fd);
11023             tcg_temp_free_i64(fp64);
11024         }
11025         break;
11026     case OPC_CEIL_L_S:
11027         check_cp1_64bitmode(ctx);
11028         {
11029             TCGv_i32 fp32 = tcg_temp_new_i32();
11030             TCGv_i64 fp64 = tcg_temp_new_i64();
11031
11032             gen_load_fpr32(ctx, fp32, fs);
11033             if (ctx->nan2008) {
11034                 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
11035             } else {
11036                 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
11037             }
11038             tcg_temp_free_i32(fp32);
11039             gen_store_fpr64(ctx, fp64, fd);
11040             tcg_temp_free_i64(fp64);
11041         }
11042         break;
11043     case OPC_FLOOR_L_S:
11044         check_cp1_64bitmode(ctx);
11045         {
11046             TCGv_i32 fp32 = tcg_temp_new_i32();
11047             TCGv_i64 fp64 = tcg_temp_new_i64();
11048
11049             gen_load_fpr32(ctx, fp32, fs);
11050             if (ctx->nan2008) {
11051                 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
11052             } else {
11053                 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
11054             }
11055             tcg_temp_free_i32(fp32);
11056             gen_store_fpr64(ctx, fp64, fd);
11057             tcg_temp_free_i64(fp64);
11058         }
11059         break;
11060     case OPC_ROUND_W_S:
11061         {
11062             TCGv_i32 fp0 = tcg_temp_new_i32();
11063
11064             gen_load_fpr32(ctx, fp0, fs);
11065             if (ctx->nan2008) {
11066                 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
11067             } else {
11068                 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
11069             }
11070             gen_store_fpr32(ctx, fp0, fd);
11071             tcg_temp_free_i32(fp0);
11072         }
11073         break;
11074     case OPC_TRUNC_W_S:
11075         {
11076             TCGv_i32 fp0 = tcg_temp_new_i32();
11077
11078             gen_load_fpr32(ctx, fp0, fs);
11079             if (ctx->nan2008) {
11080                 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
11081             } else {
11082                 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
11083             }
11084             gen_store_fpr32(ctx, fp0, fd);
11085             tcg_temp_free_i32(fp0);
11086         }
11087         break;
11088     case OPC_CEIL_W_S:
11089         {
11090             TCGv_i32 fp0 = tcg_temp_new_i32();
11091
11092             gen_load_fpr32(ctx, fp0, fs);
11093             if (ctx->nan2008) {
11094                 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
11095             } else {
11096                 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
11097             }
11098             gen_store_fpr32(ctx, fp0, fd);
11099             tcg_temp_free_i32(fp0);
11100         }
11101         break;
11102     case OPC_FLOOR_W_S:
11103         {
11104             TCGv_i32 fp0 = tcg_temp_new_i32();
11105
11106             gen_load_fpr32(ctx, fp0, fs);
11107             if (ctx->nan2008) {
11108                 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
11109             } else {
11110                 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
11111             }
11112             gen_store_fpr32(ctx, fp0, fd);
11113             tcg_temp_free_i32(fp0);
11114         }
11115         break;
11116     case OPC_SEL_S:
11117         check_insn(ctx, ISA_MIPS32R6);
11118         gen_sel_s(ctx, op1, fd, ft, fs);
11119         break;
11120     case OPC_SELEQZ_S:
11121         check_insn(ctx, ISA_MIPS32R6);
11122         gen_sel_s(ctx, op1, fd, ft, fs);
11123         break;
11124     case OPC_SELNEZ_S:
11125         check_insn(ctx, ISA_MIPS32R6);
11126         gen_sel_s(ctx, op1, fd, ft, fs);
11127         break;
11128     case OPC_MOVCF_S:
11129         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11130         gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11131         break;
11132     case OPC_MOVZ_S:
11133         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11134         {
11135             TCGLabel *l1 = gen_new_label();
11136             TCGv_i32 fp0;
11137
11138             if (ft != 0) {
11139                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11140             }
11141             fp0 = tcg_temp_new_i32();
11142             gen_load_fpr32(ctx, fp0, fs);
11143             gen_store_fpr32(ctx, fp0, fd);
11144             tcg_temp_free_i32(fp0);
11145             gen_set_label(l1);
11146         }
11147         break;
11148     case OPC_MOVN_S:
11149         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11150         {
11151             TCGLabel *l1 = gen_new_label();
11152             TCGv_i32 fp0;
11153
11154             if (ft != 0) {
11155                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11156                 fp0 = tcg_temp_new_i32();
11157                 gen_load_fpr32(ctx, fp0, fs);
11158                 gen_store_fpr32(ctx, fp0, fd);
11159                 tcg_temp_free_i32(fp0);
11160                 gen_set_label(l1);
11161             }
11162         }
11163         break;
11164     case OPC_RECIP_S:
11165         {
11166             TCGv_i32 fp0 = tcg_temp_new_i32();
11167
11168             gen_load_fpr32(ctx, fp0, fs);
11169             gen_helper_float_recip_s(fp0, cpu_env, fp0);
11170             gen_store_fpr32(ctx, fp0, fd);
11171             tcg_temp_free_i32(fp0);
11172         }
11173         break;
11174     case OPC_RSQRT_S:
11175         {
11176             TCGv_i32 fp0 = tcg_temp_new_i32();
11177
11178             gen_load_fpr32(ctx, fp0, fs);
11179             gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
11180             gen_store_fpr32(ctx, fp0, fd);
11181             tcg_temp_free_i32(fp0);
11182         }
11183         break;
11184     case OPC_MADDF_S:
11185         check_insn(ctx, ISA_MIPS32R6);
11186         {
11187             TCGv_i32 fp0 = tcg_temp_new_i32();
11188             TCGv_i32 fp1 = tcg_temp_new_i32();
11189             TCGv_i32 fp2 = tcg_temp_new_i32();
11190             gen_load_fpr32(ctx, fp0, fs);
11191             gen_load_fpr32(ctx, fp1, ft);
11192             gen_load_fpr32(ctx, fp2, fd);
11193             gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
11194             gen_store_fpr32(ctx, fp2, fd);
11195             tcg_temp_free_i32(fp2);
11196             tcg_temp_free_i32(fp1);
11197             tcg_temp_free_i32(fp0);
11198         }
11199         break;
11200     case OPC_MSUBF_S:
11201         check_insn(ctx, ISA_MIPS32R6);
11202         {
11203             TCGv_i32 fp0 = tcg_temp_new_i32();
11204             TCGv_i32 fp1 = tcg_temp_new_i32();
11205             TCGv_i32 fp2 = tcg_temp_new_i32();
11206             gen_load_fpr32(ctx, fp0, fs);
11207             gen_load_fpr32(ctx, fp1, ft);
11208             gen_load_fpr32(ctx, fp2, fd);
11209             gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
11210             gen_store_fpr32(ctx, fp2, fd);
11211             tcg_temp_free_i32(fp2);
11212             tcg_temp_free_i32(fp1);
11213             tcg_temp_free_i32(fp0);
11214         }
11215         break;
11216     case OPC_RINT_S:
11217         check_insn(ctx, ISA_MIPS32R6);
11218         {
11219             TCGv_i32 fp0 = tcg_temp_new_i32();
11220             gen_load_fpr32(ctx, fp0, fs);
11221             gen_helper_float_rint_s(fp0, cpu_env, fp0);
11222             gen_store_fpr32(ctx, fp0, fd);
11223             tcg_temp_free_i32(fp0);
11224         }
11225         break;
11226     case OPC_CLASS_S:
11227         check_insn(ctx, ISA_MIPS32R6);
11228         {
11229             TCGv_i32 fp0 = tcg_temp_new_i32();
11230             gen_load_fpr32(ctx, fp0, fs);
11231             gen_helper_float_class_s(fp0, cpu_env, fp0);
11232             gen_store_fpr32(ctx, fp0, fd);
11233             tcg_temp_free_i32(fp0);
11234         }
11235         break;
11236     case OPC_MIN_S: /* OPC_RECIP2_S */
11237         if (ctx->insn_flags & ISA_MIPS32R6) {
11238             /* OPC_MIN_S */
11239             TCGv_i32 fp0 = tcg_temp_new_i32();
11240             TCGv_i32 fp1 = tcg_temp_new_i32();
11241             TCGv_i32 fp2 = tcg_temp_new_i32();
11242             gen_load_fpr32(ctx, fp0, fs);
11243             gen_load_fpr32(ctx, fp1, ft);
11244             gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
11245             gen_store_fpr32(ctx, fp2, fd);
11246             tcg_temp_free_i32(fp2);
11247             tcg_temp_free_i32(fp1);
11248             tcg_temp_free_i32(fp0);
11249         } else {
11250             /* OPC_RECIP2_S */
11251             check_cp1_64bitmode(ctx);
11252             {
11253                 TCGv_i32 fp0 = tcg_temp_new_i32();
11254                 TCGv_i32 fp1 = tcg_temp_new_i32();
11255
11256                 gen_load_fpr32(ctx, fp0, fs);
11257                 gen_load_fpr32(ctx, fp1, ft);
11258                 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
11259                 tcg_temp_free_i32(fp1);
11260                 gen_store_fpr32(ctx, fp0, fd);
11261                 tcg_temp_free_i32(fp0);
11262             }
11263         }
11264         break;
11265     case OPC_MINA_S: /* OPC_RECIP1_S */
11266         if (ctx->insn_flags & ISA_MIPS32R6) {
11267             /* OPC_MINA_S */
11268             TCGv_i32 fp0 = tcg_temp_new_i32();
11269             TCGv_i32 fp1 = tcg_temp_new_i32();
11270             TCGv_i32 fp2 = tcg_temp_new_i32();
11271             gen_load_fpr32(ctx, fp0, fs);
11272             gen_load_fpr32(ctx, fp1, ft);
11273             gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
11274             gen_store_fpr32(ctx, fp2, fd);
11275             tcg_temp_free_i32(fp2);
11276             tcg_temp_free_i32(fp1);
11277             tcg_temp_free_i32(fp0);
11278         } else {
11279             /* OPC_RECIP1_S */
11280             check_cp1_64bitmode(ctx);
11281             {
11282                 TCGv_i32 fp0 = tcg_temp_new_i32();
11283
11284                 gen_load_fpr32(ctx, fp0, fs);
11285                 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
11286                 gen_store_fpr32(ctx, fp0, fd);
11287                 tcg_temp_free_i32(fp0);
11288             }
11289         }
11290         break;
11291     case OPC_MAX_S: /* OPC_RSQRT1_S */
11292         if (ctx->insn_flags & ISA_MIPS32R6) {
11293             /* OPC_MAX_S */
11294             TCGv_i32 fp0 = tcg_temp_new_i32();
11295             TCGv_i32 fp1 = tcg_temp_new_i32();
11296             gen_load_fpr32(ctx, fp0, fs);
11297             gen_load_fpr32(ctx, fp1, ft);
11298             gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
11299             gen_store_fpr32(ctx, fp1, fd);
11300             tcg_temp_free_i32(fp1);
11301             tcg_temp_free_i32(fp0);
11302         } else {
11303             /* OPC_RSQRT1_S */
11304             check_cp1_64bitmode(ctx);
11305             {
11306                 TCGv_i32 fp0 = tcg_temp_new_i32();
11307
11308                 gen_load_fpr32(ctx, fp0, fs);
11309                 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
11310                 gen_store_fpr32(ctx, fp0, fd);
11311                 tcg_temp_free_i32(fp0);
11312             }
11313         }
11314         break;
11315     case OPC_MAXA_S: /* OPC_RSQRT2_S */
11316         if (ctx->insn_flags & ISA_MIPS32R6) {
11317             /* OPC_MAXA_S */
11318             TCGv_i32 fp0 = tcg_temp_new_i32();
11319             TCGv_i32 fp1 = tcg_temp_new_i32();
11320             gen_load_fpr32(ctx, fp0, fs);
11321             gen_load_fpr32(ctx, fp1, ft);
11322             gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
11323             gen_store_fpr32(ctx, fp1, fd);
11324             tcg_temp_free_i32(fp1);
11325             tcg_temp_free_i32(fp0);
11326         } else {
11327             /* OPC_RSQRT2_S */
11328             check_cp1_64bitmode(ctx);
11329             {
11330                 TCGv_i32 fp0 = tcg_temp_new_i32();
11331                 TCGv_i32 fp1 = tcg_temp_new_i32();
11332
11333                 gen_load_fpr32(ctx, fp0, fs);
11334                 gen_load_fpr32(ctx, fp1, ft);
11335                 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
11336                 tcg_temp_free_i32(fp1);
11337                 gen_store_fpr32(ctx, fp0, fd);
11338                 tcg_temp_free_i32(fp0);
11339             }
11340         }
11341         break;
11342     case OPC_CVT_D_S:
11343         check_cp1_registers(ctx, fd);
11344         {
11345             TCGv_i32 fp32 = tcg_temp_new_i32();
11346             TCGv_i64 fp64 = tcg_temp_new_i64();
11347
11348             gen_load_fpr32(ctx, fp32, fs);
11349             gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
11350             tcg_temp_free_i32(fp32);
11351             gen_store_fpr64(ctx, fp64, fd);
11352             tcg_temp_free_i64(fp64);
11353         }
11354         break;
11355     case OPC_CVT_W_S:
11356         {
11357             TCGv_i32 fp0 = tcg_temp_new_i32();
11358
11359             gen_load_fpr32(ctx, fp0, fs);
11360             if (ctx->nan2008) {
11361                 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
11362             } else {
11363                 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
11364             }
11365             gen_store_fpr32(ctx, fp0, fd);
11366             tcg_temp_free_i32(fp0);
11367         }
11368         break;
11369     case OPC_CVT_L_S:
11370         check_cp1_64bitmode(ctx);
11371         {
11372             TCGv_i32 fp32 = tcg_temp_new_i32();
11373             TCGv_i64 fp64 = tcg_temp_new_i64();
11374
11375             gen_load_fpr32(ctx, fp32, fs);
11376             if (ctx->nan2008) {
11377                 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
11378             } else {
11379                 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
11380             }
11381             tcg_temp_free_i32(fp32);
11382             gen_store_fpr64(ctx, fp64, fd);
11383             tcg_temp_free_i64(fp64);
11384         }
11385         break;
11386     case OPC_CVT_PS_S:
11387         check_ps(ctx);
11388         {
11389             TCGv_i64 fp64 = tcg_temp_new_i64();
11390             TCGv_i32 fp32_0 = tcg_temp_new_i32();
11391             TCGv_i32 fp32_1 = tcg_temp_new_i32();
11392
11393             gen_load_fpr32(ctx, fp32_0, fs);
11394             gen_load_fpr32(ctx, fp32_1, ft);
11395             tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
11396             tcg_temp_free_i32(fp32_1);
11397             tcg_temp_free_i32(fp32_0);
11398             gen_store_fpr64(ctx, fp64, fd);
11399             tcg_temp_free_i64(fp64);
11400         }
11401         break;
11402     case OPC_CMP_F_S:
11403     case OPC_CMP_UN_S:
11404     case OPC_CMP_EQ_S:
11405     case OPC_CMP_UEQ_S:
11406     case OPC_CMP_OLT_S:
11407     case OPC_CMP_ULT_S:
11408     case OPC_CMP_OLE_S:
11409     case OPC_CMP_ULE_S:
11410     case OPC_CMP_SF_S:
11411     case OPC_CMP_NGLE_S:
11412     case OPC_CMP_SEQ_S:
11413     case OPC_CMP_NGL_S:
11414     case OPC_CMP_LT_S:
11415     case OPC_CMP_NGE_S:
11416     case OPC_CMP_LE_S:
11417     case OPC_CMP_NGT_S:
11418         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11419         if (ctx->opcode & (1 << 6)) {
11420             gen_cmpabs_s(ctx, func-48, ft, fs, cc);
11421         } else {
11422             gen_cmp_s(ctx, func-48, ft, fs, cc);
11423         }
11424         break;
11425     case OPC_ADD_D:
11426         check_cp1_registers(ctx, fs | ft | fd);
11427         {
11428             TCGv_i64 fp0 = tcg_temp_new_i64();
11429             TCGv_i64 fp1 = tcg_temp_new_i64();
11430
11431             gen_load_fpr64(ctx, fp0, fs);
11432             gen_load_fpr64(ctx, fp1, ft);
11433             gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
11434             tcg_temp_free_i64(fp1);
11435             gen_store_fpr64(ctx, fp0, fd);
11436             tcg_temp_free_i64(fp0);
11437         }
11438         break;
11439     case OPC_SUB_D:
11440         check_cp1_registers(ctx, fs | ft | fd);
11441         {
11442             TCGv_i64 fp0 = tcg_temp_new_i64();
11443             TCGv_i64 fp1 = tcg_temp_new_i64();
11444
11445             gen_load_fpr64(ctx, fp0, fs);
11446             gen_load_fpr64(ctx, fp1, ft);
11447             gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
11448             tcg_temp_free_i64(fp1);
11449             gen_store_fpr64(ctx, fp0, fd);
11450             tcg_temp_free_i64(fp0);
11451         }
11452         break;
11453     case OPC_MUL_D:
11454         check_cp1_registers(ctx, fs | ft | fd);
11455         {
11456             TCGv_i64 fp0 = tcg_temp_new_i64();
11457             TCGv_i64 fp1 = tcg_temp_new_i64();
11458
11459             gen_load_fpr64(ctx, fp0, fs);
11460             gen_load_fpr64(ctx, fp1, ft);
11461             gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
11462             tcg_temp_free_i64(fp1);
11463             gen_store_fpr64(ctx, fp0, fd);
11464             tcg_temp_free_i64(fp0);
11465         }
11466         break;
11467     case OPC_DIV_D:
11468         check_cp1_registers(ctx, fs | ft | fd);
11469         {
11470             TCGv_i64 fp0 = tcg_temp_new_i64();
11471             TCGv_i64 fp1 = tcg_temp_new_i64();
11472
11473             gen_load_fpr64(ctx, fp0, fs);
11474             gen_load_fpr64(ctx, fp1, ft);
11475             gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
11476             tcg_temp_free_i64(fp1);
11477             gen_store_fpr64(ctx, fp0, fd);
11478             tcg_temp_free_i64(fp0);
11479         }
11480         break;
11481     case OPC_SQRT_D:
11482         check_cp1_registers(ctx, fs | fd);
11483         {
11484             TCGv_i64 fp0 = tcg_temp_new_i64();
11485
11486             gen_load_fpr64(ctx, fp0, fs);
11487             gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
11488             gen_store_fpr64(ctx, fp0, fd);
11489             tcg_temp_free_i64(fp0);
11490         }
11491         break;
11492     case OPC_ABS_D:
11493         check_cp1_registers(ctx, fs | fd);
11494         {
11495             TCGv_i64 fp0 = tcg_temp_new_i64();
11496
11497             gen_load_fpr64(ctx, fp0, fs);
11498             if (ctx->abs2008) {
11499                 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11500             } else {
11501                 gen_helper_float_abs_d(fp0, fp0);
11502             }
11503             gen_store_fpr64(ctx, fp0, fd);
11504             tcg_temp_free_i64(fp0);
11505         }
11506         break;
11507     case OPC_MOV_D:
11508         check_cp1_registers(ctx, fs | fd);
11509         {
11510             TCGv_i64 fp0 = tcg_temp_new_i64();
11511
11512             gen_load_fpr64(ctx, fp0, fs);
11513             gen_store_fpr64(ctx, fp0, fd);
11514             tcg_temp_free_i64(fp0);
11515         }
11516         break;
11517     case OPC_NEG_D:
11518         check_cp1_registers(ctx, fs | fd);
11519         {
11520             TCGv_i64 fp0 = tcg_temp_new_i64();
11521
11522             gen_load_fpr64(ctx, fp0, fs);
11523             if (ctx->abs2008) {
11524                 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11525             } else {
11526                 gen_helper_float_chs_d(fp0, fp0);
11527             }
11528             gen_store_fpr64(ctx, fp0, fd);
11529             tcg_temp_free_i64(fp0);
11530         }
11531         break;
11532     case OPC_ROUND_L_D:
11533         check_cp1_64bitmode(ctx);
11534         {
11535             TCGv_i64 fp0 = tcg_temp_new_i64();
11536
11537             gen_load_fpr64(ctx, fp0, fs);
11538             if (ctx->nan2008) {
11539                 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11540             } else {
11541                 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11542             }
11543             gen_store_fpr64(ctx, fp0, fd);
11544             tcg_temp_free_i64(fp0);
11545         }
11546         break;
11547     case OPC_TRUNC_L_D:
11548         check_cp1_64bitmode(ctx);
11549         {
11550             TCGv_i64 fp0 = tcg_temp_new_i64();
11551
11552             gen_load_fpr64(ctx, fp0, fs);
11553             if (ctx->nan2008) {
11554                 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11555             } else {
11556                 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11557             }
11558             gen_store_fpr64(ctx, fp0, fd);
11559             tcg_temp_free_i64(fp0);
11560         }
11561         break;
11562     case OPC_CEIL_L_D:
11563         check_cp1_64bitmode(ctx);
11564         {
11565             TCGv_i64 fp0 = tcg_temp_new_i64();
11566
11567             gen_load_fpr64(ctx, fp0, fs);
11568             if (ctx->nan2008) {
11569                 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11570             } else {
11571                 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11572             }
11573             gen_store_fpr64(ctx, fp0, fd);
11574             tcg_temp_free_i64(fp0);
11575         }
11576         break;
11577     case OPC_FLOOR_L_D:
11578         check_cp1_64bitmode(ctx);
11579         {
11580             TCGv_i64 fp0 = tcg_temp_new_i64();
11581
11582             gen_load_fpr64(ctx, fp0, fs);
11583             if (ctx->nan2008) {
11584                 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11585             } else {
11586                 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11587             }
11588             gen_store_fpr64(ctx, fp0, fd);
11589             tcg_temp_free_i64(fp0);
11590         }
11591         break;
11592     case OPC_ROUND_W_D:
11593         check_cp1_registers(ctx, fs);
11594         {
11595             TCGv_i32 fp32 = tcg_temp_new_i32();
11596             TCGv_i64 fp64 = tcg_temp_new_i64();
11597
11598             gen_load_fpr64(ctx, fp64, fs);
11599             if (ctx->nan2008) {
11600                 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11601             } else {
11602                 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11603             }
11604             tcg_temp_free_i64(fp64);
11605             gen_store_fpr32(ctx, fp32, fd);
11606             tcg_temp_free_i32(fp32);
11607         }
11608         break;
11609     case OPC_TRUNC_W_D:
11610         check_cp1_registers(ctx, fs);
11611         {
11612             TCGv_i32 fp32 = tcg_temp_new_i32();
11613             TCGv_i64 fp64 = tcg_temp_new_i64();
11614
11615             gen_load_fpr64(ctx, fp64, fs);
11616             if (ctx->nan2008) {
11617                 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
11618             } else {
11619                 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
11620             }
11621             tcg_temp_free_i64(fp64);
11622             gen_store_fpr32(ctx, fp32, fd);
11623             tcg_temp_free_i32(fp32);
11624         }
11625         break;
11626     case OPC_CEIL_W_D:
11627         check_cp1_registers(ctx, fs);
11628         {
11629             TCGv_i32 fp32 = tcg_temp_new_i32();
11630             TCGv_i64 fp64 = tcg_temp_new_i64();
11631
11632             gen_load_fpr64(ctx, fp64, fs);
11633             if (ctx->nan2008) {
11634                 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11635             } else {
11636                 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11637             }
11638             tcg_temp_free_i64(fp64);
11639             gen_store_fpr32(ctx, fp32, fd);
11640             tcg_temp_free_i32(fp32);
11641         }
11642         break;
11643     case OPC_FLOOR_W_D:
11644         check_cp1_registers(ctx, fs);
11645         {
11646             TCGv_i32 fp32 = tcg_temp_new_i32();
11647             TCGv_i64 fp64 = tcg_temp_new_i64();
11648
11649             gen_load_fpr64(ctx, fp64, fs);
11650             if (ctx->nan2008) {
11651                 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
11652             } else {
11653                 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
11654             }
11655             tcg_temp_free_i64(fp64);
11656             gen_store_fpr32(ctx, fp32, fd);
11657             tcg_temp_free_i32(fp32);
11658         }
11659         break;
11660     case OPC_SEL_D:
11661         check_insn(ctx, ISA_MIPS32R6);
11662         gen_sel_d(ctx, op1, fd, ft, fs);
11663         break;
11664     case OPC_SELEQZ_D:
11665         check_insn(ctx, ISA_MIPS32R6);
11666         gen_sel_d(ctx, op1, fd, ft, fs);
11667         break;
11668     case OPC_SELNEZ_D:
11669         check_insn(ctx, ISA_MIPS32R6);
11670         gen_sel_d(ctx, op1, fd, ft, fs);
11671         break;
11672     case OPC_MOVCF_D:
11673         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11674         gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11675         break;
11676     case OPC_MOVZ_D:
11677         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11678         {
11679             TCGLabel *l1 = gen_new_label();
11680             TCGv_i64 fp0;
11681
11682             if (ft != 0) {
11683                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11684             }
11685             fp0 = tcg_temp_new_i64();
11686             gen_load_fpr64(ctx, fp0, fs);
11687             gen_store_fpr64(ctx, fp0, fd);
11688             tcg_temp_free_i64(fp0);
11689             gen_set_label(l1);
11690         }
11691         break;
11692     case OPC_MOVN_D:
11693         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11694         {
11695             TCGLabel *l1 = gen_new_label();
11696             TCGv_i64 fp0;
11697
11698             if (ft != 0) {
11699                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11700                 fp0 = tcg_temp_new_i64();
11701                 gen_load_fpr64(ctx, fp0, fs);
11702                 gen_store_fpr64(ctx, fp0, fd);
11703                 tcg_temp_free_i64(fp0);
11704                 gen_set_label(l1);
11705             }
11706         }
11707         break;
11708     case OPC_RECIP_D:
11709         check_cp1_registers(ctx, fs | fd);
11710         {
11711             TCGv_i64 fp0 = tcg_temp_new_i64();
11712
11713             gen_load_fpr64(ctx, fp0, fs);
11714             gen_helper_float_recip_d(fp0, cpu_env, fp0);
11715             gen_store_fpr64(ctx, fp0, fd);
11716             tcg_temp_free_i64(fp0);
11717         }
11718         break;
11719     case OPC_RSQRT_D:
11720         check_cp1_registers(ctx, fs | fd);
11721         {
11722             TCGv_i64 fp0 = tcg_temp_new_i64();
11723
11724             gen_load_fpr64(ctx, fp0, fs);
11725             gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
11726             gen_store_fpr64(ctx, fp0, fd);
11727             tcg_temp_free_i64(fp0);
11728         }
11729         break;
11730     case OPC_MADDF_D:
11731         check_insn(ctx, ISA_MIPS32R6);
11732         {
11733             TCGv_i64 fp0 = tcg_temp_new_i64();
11734             TCGv_i64 fp1 = tcg_temp_new_i64();
11735             TCGv_i64 fp2 = tcg_temp_new_i64();
11736             gen_load_fpr64(ctx, fp0, fs);
11737             gen_load_fpr64(ctx, fp1, ft);
11738             gen_load_fpr64(ctx, fp2, fd);
11739             gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
11740             gen_store_fpr64(ctx, fp2, fd);
11741             tcg_temp_free_i64(fp2);
11742             tcg_temp_free_i64(fp1);
11743             tcg_temp_free_i64(fp0);
11744         }
11745         break;
11746     case OPC_MSUBF_D:
11747         check_insn(ctx, ISA_MIPS32R6);
11748         {
11749             TCGv_i64 fp0 = tcg_temp_new_i64();
11750             TCGv_i64 fp1 = tcg_temp_new_i64();
11751             TCGv_i64 fp2 = tcg_temp_new_i64();
11752             gen_load_fpr64(ctx, fp0, fs);
11753             gen_load_fpr64(ctx, fp1, ft);
11754             gen_load_fpr64(ctx, fp2, fd);
11755             gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
11756             gen_store_fpr64(ctx, fp2, fd);
11757             tcg_temp_free_i64(fp2);
11758             tcg_temp_free_i64(fp1);
11759             tcg_temp_free_i64(fp0);
11760         }
11761         break;
11762     case OPC_RINT_D:
11763         check_insn(ctx, ISA_MIPS32R6);
11764         {
11765             TCGv_i64 fp0 = tcg_temp_new_i64();
11766             gen_load_fpr64(ctx, fp0, fs);
11767             gen_helper_float_rint_d(fp0, cpu_env, fp0);
11768             gen_store_fpr64(ctx, fp0, fd);
11769             tcg_temp_free_i64(fp0);
11770         }
11771         break;
11772     case OPC_CLASS_D:
11773         check_insn(ctx, ISA_MIPS32R6);
11774         {
11775             TCGv_i64 fp0 = tcg_temp_new_i64();
11776             gen_load_fpr64(ctx, fp0, fs);
11777             gen_helper_float_class_d(fp0, cpu_env, fp0);
11778             gen_store_fpr64(ctx, fp0, fd);
11779             tcg_temp_free_i64(fp0);
11780         }
11781         break;
11782     case OPC_MIN_D: /* OPC_RECIP2_D */
11783         if (ctx->insn_flags & ISA_MIPS32R6) {
11784             /* OPC_MIN_D */
11785             TCGv_i64 fp0 = tcg_temp_new_i64();
11786             TCGv_i64 fp1 = tcg_temp_new_i64();
11787             gen_load_fpr64(ctx, fp0, fs);
11788             gen_load_fpr64(ctx, fp1, ft);
11789             gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
11790             gen_store_fpr64(ctx, fp1, fd);
11791             tcg_temp_free_i64(fp1);
11792             tcg_temp_free_i64(fp0);
11793         } else {
11794             /* OPC_RECIP2_D */
11795             check_cp1_64bitmode(ctx);
11796             {
11797                 TCGv_i64 fp0 = tcg_temp_new_i64();
11798                 TCGv_i64 fp1 = tcg_temp_new_i64();
11799
11800                 gen_load_fpr64(ctx, fp0, fs);
11801                 gen_load_fpr64(ctx, fp1, ft);
11802                 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
11803                 tcg_temp_free_i64(fp1);
11804                 gen_store_fpr64(ctx, fp0, fd);
11805                 tcg_temp_free_i64(fp0);
11806             }
11807         }
11808         break;
11809     case OPC_MINA_D: /* OPC_RECIP1_D */
11810         if (ctx->insn_flags & ISA_MIPS32R6) {
11811             /* OPC_MINA_D */
11812             TCGv_i64 fp0 = tcg_temp_new_i64();
11813             TCGv_i64 fp1 = tcg_temp_new_i64();
11814             gen_load_fpr64(ctx, fp0, fs);
11815             gen_load_fpr64(ctx, fp1, ft);
11816             gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
11817             gen_store_fpr64(ctx, fp1, fd);
11818             tcg_temp_free_i64(fp1);
11819             tcg_temp_free_i64(fp0);
11820         } else {
11821             /* OPC_RECIP1_D */
11822             check_cp1_64bitmode(ctx);
11823             {
11824                 TCGv_i64 fp0 = tcg_temp_new_i64();
11825
11826                 gen_load_fpr64(ctx, fp0, fs);
11827                 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
11828                 gen_store_fpr64(ctx, fp0, fd);
11829                 tcg_temp_free_i64(fp0);
11830             }
11831         }
11832         break;
11833     case OPC_MAX_D: /*  OPC_RSQRT1_D */
11834         if (ctx->insn_flags & ISA_MIPS32R6) {
11835             /* OPC_MAX_D */
11836             TCGv_i64 fp0 = tcg_temp_new_i64();
11837             TCGv_i64 fp1 = tcg_temp_new_i64();
11838             gen_load_fpr64(ctx, fp0, fs);
11839             gen_load_fpr64(ctx, fp1, ft);
11840             gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
11841             gen_store_fpr64(ctx, fp1, fd);
11842             tcg_temp_free_i64(fp1);
11843             tcg_temp_free_i64(fp0);
11844         } else {
11845             /* OPC_RSQRT1_D */
11846             check_cp1_64bitmode(ctx);
11847             {
11848                 TCGv_i64 fp0 = tcg_temp_new_i64();
11849
11850                 gen_load_fpr64(ctx, fp0, fs);
11851                 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
11852                 gen_store_fpr64(ctx, fp0, fd);
11853                 tcg_temp_free_i64(fp0);
11854             }
11855         }
11856         break;
11857     case OPC_MAXA_D: /* OPC_RSQRT2_D */
11858         if (ctx->insn_flags & ISA_MIPS32R6) {
11859             /* OPC_MAXA_D */
11860             TCGv_i64 fp0 = tcg_temp_new_i64();
11861             TCGv_i64 fp1 = tcg_temp_new_i64();
11862             gen_load_fpr64(ctx, fp0, fs);
11863             gen_load_fpr64(ctx, fp1, ft);
11864             gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11865             gen_store_fpr64(ctx, fp1, fd);
11866             tcg_temp_free_i64(fp1);
11867             tcg_temp_free_i64(fp0);
11868         } else {
11869             /* OPC_RSQRT2_D */
11870             check_cp1_64bitmode(ctx);
11871             {
11872                 TCGv_i64 fp0 = tcg_temp_new_i64();
11873                 TCGv_i64 fp1 = tcg_temp_new_i64();
11874
11875                 gen_load_fpr64(ctx, fp0, fs);
11876                 gen_load_fpr64(ctx, fp1, ft);
11877                 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11878                 tcg_temp_free_i64(fp1);
11879                 gen_store_fpr64(ctx, fp0, fd);
11880                 tcg_temp_free_i64(fp0);
11881             }
11882         }
11883         break;
11884     case OPC_CMP_F_D:
11885     case OPC_CMP_UN_D:
11886     case OPC_CMP_EQ_D:
11887     case OPC_CMP_UEQ_D:
11888     case OPC_CMP_OLT_D:
11889     case OPC_CMP_ULT_D:
11890     case OPC_CMP_OLE_D:
11891     case OPC_CMP_ULE_D:
11892     case OPC_CMP_SF_D:
11893     case OPC_CMP_NGLE_D:
11894     case OPC_CMP_SEQ_D:
11895     case OPC_CMP_NGL_D:
11896     case OPC_CMP_LT_D:
11897     case OPC_CMP_NGE_D:
11898     case OPC_CMP_LE_D:
11899     case OPC_CMP_NGT_D:
11900         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11901         if (ctx->opcode & (1 << 6)) {
11902             gen_cmpabs_d(ctx, func-48, ft, fs, cc);
11903         } else {
11904             gen_cmp_d(ctx, func-48, ft, fs, cc);
11905         }
11906         break;
11907     case OPC_CVT_S_D:
11908         check_cp1_registers(ctx, fs);
11909         {
11910             TCGv_i32 fp32 = tcg_temp_new_i32();
11911             TCGv_i64 fp64 = tcg_temp_new_i64();
11912
11913             gen_load_fpr64(ctx, fp64, fs);
11914             gen_helper_float_cvts_d(fp32, cpu_env, fp64);
11915             tcg_temp_free_i64(fp64);
11916             gen_store_fpr32(ctx, fp32, fd);
11917             tcg_temp_free_i32(fp32);
11918         }
11919         break;
11920     case OPC_CVT_W_D:
11921         check_cp1_registers(ctx, fs);
11922         {
11923             TCGv_i32 fp32 = tcg_temp_new_i32();
11924             TCGv_i64 fp64 = tcg_temp_new_i64();
11925
11926             gen_load_fpr64(ctx, fp64, fs);
11927             if (ctx->nan2008) {
11928                 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11929             } else {
11930                 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11931             }
11932             tcg_temp_free_i64(fp64);
11933             gen_store_fpr32(ctx, fp32, fd);
11934             tcg_temp_free_i32(fp32);
11935         }
11936         break;
11937     case OPC_CVT_L_D:
11938         check_cp1_64bitmode(ctx);
11939         {
11940             TCGv_i64 fp0 = tcg_temp_new_i64();
11941
11942             gen_load_fpr64(ctx, fp0, fs);
11943             if (ctx->nan2008) {
11944                 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11945             } else {
11946                 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11947             }
11948             gen_store_fpr64(ctx, fp0, fd);
11949             tcg_temp_free_i64(fp0);
11950         }
11951         break;
11952     case OPC_CVT_S_W:
11953         {
11954             TCGv_i32 fp0 = tcg_temp_new_i32();
11955
11956             gen_load_fpr32(ctx, fp0, fs);
11957             gen_helper_float_cvts_w(fp0, cpu_env, fp0);
11958             gen_store_fpr32(ctx, fp0, fd);
11959             tcg_temp_free_i32(fp0);
11960         }
11961         break;
11962     case OPC_CVT_D_W:
11963         check_cp1_registers(ctx, fd);
11964         {
11965             TCGv_i32 fp32 = tcg_temp_new_i32();
11966             TCGv_i64 fp64 = tcg_temp_new_i64();
11967
11968             gen_load_fpr32(ctx, fp32, fs);
11969             gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
11970             tcg_temp_free_i32(fp32);
11971             gen_store_fpr64(ctx, fp64, fd);
11972             tcg_temp_free_i64(fp64);
11973         }
11974         break;
11975     case OPC_CVT_S_L:
11976         check_cp1_64bitmode(ctx);
11977         {
11978             TCGv_i32 fp32 = tcg_temp_new_i32();
11979             TCGv_i64 fp64 = tcg_temp_new_i64();
11980
11981             gen_load_fpr64(ctx, fp64, fs);
11982             gen_helper_float_cvts_l(fp32, cpu_env, fp64);
11983             tcg_temp_free_i64(fp64);
11984             gen_store_fpr32(ctx, fp32, fd);
11985             tcg_temp_free_i32(fp32);
11986         }
11987         break;
11988     case OPC_CVT_D_L:
11989         check_cp1_64bitmode(ctx);
11990         {
11991             TCGv_i64 fp0 = tcg_temp_new_i64();
11992
11993             gen_load_fpr64(ctx, fp0, fs);
11994             gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
11995             gen_store_fpr64(ctx, fp0, fd);
11996             tcg_temp_free_i64(fp0);
11997         }
11998         break;
11999     case OPC_CVT_PS_PW:
12000         check_ps(ctx);
12001         {
12002             TCGv_i64 fp0 = tcg_temp_new_i64();
12003
12004             gen_load_fpr64(ctx, fp0, fs);
12005             gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
12006             gen_store_fpr64(ctx, fp0, fd);
12007             tcg_temp_free_i64(fp0);
12008         }
12009         break;
12010     case OPC_ADD_PS:
12011         check_ps(ctx);
12012         {
12013             TCGv_i64 fp0 = tcg_temp_new_i64();
12014             TCGv_i64 fp1 = tcg_temp_new_i64();
12015
12016             gen_load_fpr64(ctx, fp0, fs);
12017             gen_load_fpr64(ctx, fp1, ft);
12018             gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
12019             tcg_temp_free_i64(fp1);
12020             gen_store_fpr64(ctx, fp0, fd);
12021             tcg_temp_free_i64(fp0);
12022         }
12023         break;
12024     case OPC_SUB_PS:
12025         check_ps(ctx);
12026         {
12027             TCGv_i64 fp0 = tcg_temp_new_i64();
12028             TCGv_i64 fp1 = tcg_temp_new_i64();
12029
12030             gen_load_fpr64(ctx, fp0, fs);
12031             gen_load_fpr64(ctx, fp1, ft);
12032             gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
12033             tcg_temp_free_i64(fp1);
12034             gen_store_fpr64(ctx, fp0, fd);
12035             tcg_temp_free_i64(fp0);
12036         }
12037         break;
12038     case OPC_MUL_PS:
12039         check_ps(ctx);
12040         {
12041             TCGv_i64 fp0 = tcg_temp_new_i64();
12042             TCGv_i64 fp1 = tcg_temp_new_i64();
12043
12044             gen_load_fpr64(ctx, fp0, fs);
12045             gen_load_fpr64(ctx, fp1, ft);
12046             gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
12047             tcg_temp_free_i64(fp1);
12048             gen_store_fpr64(ctx, fp0, fd);
12049             tcg_temp_free_i64(fp0);
12050         }
12051         break;
12052     case OPC_ABS_PS:
12053         check_ps(ctx);
12054         {
12055             TCGv_i64 fp0 = tcg_temp_new_i64();
12056
12057             gen_load_fpr64(ctx, fp0, fs);
12058             gen_helper_float_abs_ps(fp0, fp0);
12059             gen_store_fpr64(ctx, fp0, fd);
12060             tcg_temp_free_i64(fp0);
12061         }
12062         break;
12063     case OPC_MOV_PS:
12064         check_ps(ctx);
12065         {
12066             TCGv_i64 fp0 = tcg_temp_new_i64();
12067
12068             gen_load_fpr64(ctx, fp0, fs);
12069             gen_store_fpr64(ctx, fp0, fd);
12070             tcg_temp_free_i64(fp0);
12071         }
12072         break;
12073     case OPC_NEG_PS:
12074         check_ps(ctx);
12075         {
12076             TCGv_i64 fp0 = tcg_temp_new_i64();
12077
12078             gen_load_fpr64(ctx, fp0, fs);
12079             gen_helper_float_chs_ps(fp0, fp0);
12080             gen_store_fpr64(ctx, fp0, fd);
12081             tcg_temp_free_i64(fp0);
12082         }
12083         break;
12084     case OPC_MOVCF_PS:
12085         check_ps(ctx);
12086         gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
12087         break;
12088     case OPC_MOVZ_PS:
12089         check_ps(ctx);
12090         {
12091             TCGLabel *l1 = gen_new_label();
12092             TCGv_i64 fp0;
12093
12094             if (ft != 0)
12095                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
12096             fp0 = tcg_temp_new_i64();
12097             gen_load_fpr64(ctx, fp0, fs);
12098             gen_store_fpr64(ctx, fp0, fd);
12099             tcg_temp_free_i64(fp0);
12100             gen_set_label(l1);
12101         }
12102         break;
12103     case OPC_MOVN_PS:
12104         check_ps(ctx);
12105         {
12106             TCGLabel *l1 = gen_new_label();
12107             TCGv_i64 fp0;
12108
12109             if (ft != 0) {
12110                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
12111                 fp0 = tcg_temp_new_i64();
12112                 gen_load_fpr64(ctx, fp0, fs);
12113                 gen_store_fpr64(ctx, fp0, fd);
12114                 tcg_temp_free_i64(fp0);
12115                 gen_set_label(l1);
12116             }
12117         }
12118         break;
12119     case OPC_ADDR_PS:
12120         check_ps(ctx);
12121         {
12122             TCGv_i64 fp0 = tcg_temp_new_i64();
12123             TCGv_i64 fp1 = tcg_temp_new_i64();
12124
12125             gen_load_fpr64(ctx, fp0, ft);
12126             gen_load_fpr64(ctx, fp1, fs);
12127             gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
12128             tcg_temp_free_i64(fp1);
12129             gen_store_fpr64(ctx, fp0, fd);
12130             tcg_temp_free_i64(fp0);
12131         }
12132         break;
12133     case OPC_MULR_PS:
12134         check_ps(ctx);
12135         {
12136             TCGv_i64 fp0 = tcg_temp_new_i64();
12137             TCGv_i64 fp1 = tcg_temp_new_i64();
12138
12139             gen_load_fpr64(ctx, fp0, ft);
12140             gen_load_fpr64(ctx, fp1, fs);
12141             gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
12142             tcg_temp_free_i64(fp1);
12143             gen_store_fpr64(ctx, fp0, fd);
12144             tcg_temp_free_i64(fp0);
12145         }
12146         break;
12147     case OPC_RECIP2_PS:
12148         check_ps(ctx);
12149         {
12150             TCGv_i64 fp0 = tcg_temp_new_i64();
12151             TCGv_i64 fp1 = tcg_temp_new_i64();
12152
12153             gen_load_fpr64(ctx, fp0, fs);
12154             gen_load_fpr64(ctx, fp1, ft);
12155             gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
12156             tcg_temp_free_i64(fp1);
12157             gen_store_fpr64(ctx, fp0, fd);
12158             tcg_temp_free_i64(fp0);
12159         }
12160         break;
12161     case OPC_RECIP1_PS:
12162         check_ps(ctx);
12163         {
12164             TCGv_i64 fp0 = tcg_temp_new_i64();
12165
12166             gen_load_fpr64(ctx, fp0, fs);
12167             gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
12168             gen_store_fpr64(ctx, fp0, fd);
12169             tcg_temp_free_i64(fp0);
12170         }
12171         break;
12172     case OPC_RSQRT1_PS:
12173         check_ps(ctx);
12174         {
12175             TCGv_i64 fp0 = tcg_temp_new_i64();
12176
12177             gen_load_fpr64(ctx, fp0, fs);
12178             gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
12179             gen_store_fpr64(ctx, fp0, fd);
12180             tcg_temp_free_i64(fp0);
12181         }
12182         break;
12183     case OPC_RSQRT2_PS:
12184         check_ps(ctx);
12185         {
12186             TCGv_i64 fp0 = tcg_temp_new_i64();
12187             TCGv_i64 fp1 = tcg_temp_new_i64();
12188
12189             gen_load_fpr64(ctx, fp0, fs);
12190             gen_load_fpr64(ctx, fp1, ft);
12191             gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
12192             tcg_temp_free_i64(fp1);
12193             gen_store_fpr64(ctx, fp0, fd);
12194             tcg_temp_free_i64(fp0);
12195         }
12196         break;
12197     case OPC_CVT_S_PU:
12198         check_cp1_64bitmode(ctx);
12199         {
12200             TCGv_i32 fp0 = tcg_temp_new_i32();
12201
12202             gen_load_fpr32h(ctx, fp0, fs);
12203             gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
12204             gen_store_fpr32(ctx, fp0, fd);
12205             tcg_temp_free_i32(fp0);
12206         }
12207         break;
12208     case OPC_CVT_PW_PS:
12209         check_ps(ctx);
12210         {
12211             TCGv_i64 fp0 = tcg_temp_new_i64();
12212
12213             gen_load_fpr64(ctx, fp0, fs);
12214             gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
12215             gen_store_fpr64(ctx, fp0, fd);
12216             tcg_temp_free_i64(fp0);
12217         }
12218         break;
12219     case OPC_CVT_S_PL:
12220         check_cp1_64bitmode(ctx);
12221         {
12222             TCGv_i32 fp0 = tcg_temp_new_i32();
12223
12224             gen_load_fpr32(ctx, fp0, fs);
12225             gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
12226             gen_store_fpr32(ctx, fp0, fd);
12227             tcg_temp_free_i32(fp0);
12228         }
12229         break;
12230     case OPC_PLL_PS:
12231         check_ps(ctx);
12232         {
12233             TCGv_i32 fp0 = tcg_temp_new_i32();
12234             TCGv_i32 fp1 = tcg_temp_new_i32();
12235
12236             gen_load_fpr32(ctx, fp0, fs);
12237             gen_load_fpr32(ctx, fp1, ft);
12238             gen_store_fpr32h(ctx, fp0, fd);
12239             gen_store_fpr32(ctx, fp1, fd);
12240             tcg_temp_free_i32(fp0);
12241             tcg_temp_free_i32(fp1);
12242         }
12243         break;
12244     case OPC_PLU_PS:
12245         check_ps(ctx);
12246         {
12247             TCGv_i32 fp0 = tcg_temp_new_i32();
12248             TCGv_i32 fp1 = tcg_temp_new_i32();
12249
12250             gen_load_fpr32(ctx, fp0, fs);
12251             gen_load_fpr32h(ctx, fp1, ft);
12252             gen_store_fpr32(ctx, fp1, fd);
12253             gen_store_fpr32h(ctx, fp0, fd);
12254             tcg_temp_free_i32(fp0);
12255             tcg_temp_free_i32(fp1);
12256         }
12257         break;
12258     case OPC_PUL_PS:
12259         check_ps(ctx);
12260         {
12261             TCGv_i32 fp0 = tcg_temp_new_i32();
12262             TCGv_i32 fp1 = tcg_temp_new_i32();
12263
12264             gen_load_fpr32h(ctx, fp0, fs);
12265             gen_load_fpr32(ctx, fp1, ft);
12266             gen_store_fpr32(ctx, fp1, fd);
12267             gen_store_fpr32h(ctx, fp0, fd);
12268             tcg_temp_free_i32(fp0);
12269             tcg_temp_free_i32(fp1);
12270         }
12271         break;
12272     case OPC_PUU_PS:
12273         check_ps(ctx);
12274         {
12275             TCGv_i32 fp0 = tcg_temp_new_i32();
12276             TCGv_i32 fp1 = tcg_temp_new_i32();
12277
12278             gen_load_fpr32h(ctx, fp0, fs);
12279             gen_load_fpr32h(ctx, fp1, ft);
12280             gen_store_fpr32(ctx, fp1, fd);
12281             gen_store_fpr32h(ctx, fp0, fd);
12282             tcg_temp_free_i32(fp0);
12283             tcg_temp_free_i32(fp1);
12284         }
12285         break;
12286     case OPC_CMP_F_PS:
12287     case OPC_CMP_UN_PS:
12288     case OPC_CMP_EQ_PS:
12289     case OPC_CMP_UEQ_PS:
12290     case OPC_CMP_OLT_PS:
12291     case OPC_CMP_ULT_PS:
12292     case OPC_CMP_OLE_PS:
12293     case OPC_CMP_ULE_PS:
12294     case OPC_CMP_SF_PS:
12295     case OPC_CMP_NGLE_PS:
12296     case OPC_CMP_SEQ_PS:
12297     case OPC_CMP_NGL_PS:
12298     case OPC_CMP_LT_PS:
12299     case OPC_CMP_NGE_PS:
12300     case OPC_CMP_LE_PS:
12301     case OPC_CMP_NGT_PS:
12302         if (ctx->opcode & (1 << 6)) {
12303             gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
12304         } else {
12305             gen_cmp_ps(ctx, func-48, ft, fs, cc);
12306         }
12307         break;
12308     default:
12309         MIPS_INVAL("farith");
12310         generate_exception_end(ctx, EXCP_RI);
12311         return;
12312     }
12313 }
12314
12315 /* Coprocessor 3 (FPU) */
12316 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
12317                            int fd, int fs, int base, int index)
12318 {
12319     TCGv t0 = tcg_temp_new();
12320
12321     if (base == 0) {
12322         gen_load_gpr(t0, index);
12323     } else if (index == 0) {
12324         gen_load_gpr(t0, base);
12325     } else {
12326         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
12327     }
12328     /* Don't do NOP if destination is zero: we must perform the actual
12329        memory access. */
12330     switch (opc) {
12331     case OPC_LWXC1:
12332         check_cop1x(ctx);
12333         {
12334             TCGv_i32 fp0 = tcg_temp_new_i32();
12335
12336             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12337             tcg_gen_trunc_tl_i32(fp0, t0);
12338             gen_store_fpr32(ctx, fp0, fd);
12339             tcg_temp_free_i32(fp0);
12340         }
12341         break;
12342     case OPC_LDXC1:
12343         check_cop1x(ctx);
12344         check_cp1_registers(ctx, fd);
12345         {
12346             TCGv_i64 fp0 = tcg_temp_new_i64();
12347             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12348             gen_store_fpr64(ctx, fp0, fd);
12349             tcg_temp_free_i64(fp0);
12350         }
12351         break;
12352     case OPC_LUXC1:
12353         check_cp1_64bitmode(ctx);
12354         tcg_gen_andi_tl(t0, t0, ~0x7);
12355         {
12356             TCGv_i64 fp0 = tcg_temp_new_i64();
12357
12358             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12359             gen_store_fpr64(ctx, fp0, fd);
12360             tcg_temp_free_i64(fp0);
12361         }
12362         break;
12363     case OPC_SWXC1:
12364         check_cop1x(ctx);
12365         {
12366             TCGv_i32 fp0 = tcg_temp_new_i32();
12367             gen_load_fpr32(ctx, fp0, fs);
12368             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
12369             tcg_temp_free_i32(fp0);
12370         }
12371         break;
12372     case OPC_SDXC1:
12373         check_cop1x(ctx);
12374         check_cp1_registers(ctx, fs);
12375         {
12376             TCGv_i64 fp0 = tcg_temp_new_i64();
12377             gen_load_fpr64(ctx, fp0, fs);
12378             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12379             tcg_temp_free_i64(fp0);
12380         }
12381         break;
12382     case OPC_SUXC1:
12383         check_cp1_64bitmode(ctx);
12384         tcg_gen_andi_tl(t0, t0, ~0x7);
12385         {
12386             TCGv_i64 fp0 = tcg_temp_new_i64();
12387             gen_load_fpr64(ctx, fp0, fs);
12388             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12389             tcg_temp_free_i64(fp0);
12390         }
12391         break;
12392     }
12393     tcg_temp_free(t0);
12394 }
12395
12396 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
12397                             int fd, int fr, int fs, int ft)
12398 {
12399     switch (opc) {
12400     case OPC_ALNV_PS:
12401         check_ps(ctx);
12402         {
12403             TCGv t0 = tcg_temp_local_new();
12404             TCGv_i32 fp = tcg_temp_new_i32();
12405             TCGv_i32 fph = tcg_temp_new_i32();
12406             TCGLabel *l1 = gen_new_label();
12407             TCGLabel *l2 = gen_new_label();
12408
12409             gen_load_gpr(t0, fr);
12410             tcg_gen_andi_tl(t0, t0, 0x7);
12411
12412             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
12413             gen_load_fpr32(ctx, fp, fs);
12414             gen_load_fpr32h(ctx, fph, fs);
12415             gen_store_fpr32(ctx, fp, fd);
12416             gen_store_fpr32h(ctx, fph, fd);
12417             tcg_gen_br(l2);
12418             gen_set_label(l1);
12419             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
12420             tcg_temp_free(t0);
12421 #ifdef TARGET_WORDS_BIGENDIAN
12422             gen_load_fpr32(ctx, fp, fs);
12423             gen_load_fpr32h(ctx, fph, ft);
12424             gen_store_fpr32h(ctx, fp, fd);
12425             gen_store_fpr32(ctx, fph, fd);
12426 #else
12427             gen_load_fpr32h(ctx, fph, fs);
12428             gen_load_fpr32(ctx, fp, ft);
12429             gen_store_fpr32(ctx, fph, fd);
12430             gen_store_fpr32h(ctx, fp, fd);
12431 #endif
12432             gen_set_label(l2);
12433             tcg_temp_free_i32(fp);
12434             tcg_temp_free_i32(fph);
12435         }
12436         break;
12437     case OPC_MADD_S:
12438         check_cop1x(ctx);
12439         {
12440             TCGv_i32 fp0 = tcg_temp_new_i32();
12441             TCGv_i32 fp1 = tcg_temp_new_i32();
12442             TCGv_i32 fp2 = tcg_temp_new_i32();
12443
12444             gen_load_fpr32(ctx, fp0, fs);
12445             gen_load_fpr32(ctx, fp1, ft);
12446             gen_load_fpr32(ctx, fp2, fr);
12447             gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
12448             tcg_temp_free_i32(fp0);
12449             tcg_temp_free_i32(fp1);
12450             gen_store_fpr32(ctx, fp2, fd);
12451             tcg_temp_free_i32(fp2);
12452         }
12453         break;
12454     case OPC_MADD_D:
12455         check_cop1x(ctx);
12456         check_cp1_registers(ctx, fd | fs | ft | fr);
12457         {
12458             TCGv_i64 fp0 = tcg_temp_new_i64();
12459             TCGv_i64 fp1 = tcg_temp_new_i64();
12460             TCGv_i64 fp2 = tcg_temp_new_i64();
12461
12462             gen_load_fpr64(ctx, fp0, fs);
12463             gen_load_fpr64(ctx, fp1, ft);
12464             gen_load_fpr64(ctx, fp2, fr);
12465             gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
12466             tcg_temp_free_i64(fp0);
12467             tcg_temp_free_i64(fp1);
12468             gen_store_fpr64(ctx, fp2, fd);
12469             tcg_temp_free_i64(fp2);
12470         }
12471         break;
12472     case OPC_MADD_PS:
12473         check_ps(ctx);
12474         {
12475             TCGv_i64 fp0 = tcg_temp_new_i64();
12476             TCGv_i64 fp1 = tcg_temp_new_i64();
12477             TCGv_i64 fp2 = tcg_temp_new_i64();
12478
12479             gen_load_fpr64(ctx, fp0, fs);
12480             gen_load_fpr64(ctx, fp1, ft);
12481             gen_load_fpr64(ctx, fp2, fr);
12482             gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
12483             tcg_temp_free_i64(fp0);
12484             tcg_temp_free_i64(fp1);
12485             gen_store_fpr64(ctx, fp2, fd);
12486             tcg_temp_free_i64(fp2);
12487         }
12488         break;
12489     case OPC_MSUB_S:
12490         check_cop1x(ctx);
12491         {
12492             TCGv_i32 fp0 = tcg_temp_new_i32();
12493             TCGv_i32 fp1 = tcg_temp_new_i32();
12494             TCGv_i32 fp2 = tcg_temp_new_i32();
12495
12496             gen_load_fpr32(ctx, fp0, fs);
12497             gen_load_fpr32(ctx, fp1, ft);
12498             gen_load_fpr32(ctx, fp2, fr);
12499             gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
12500             tcg_temp_free_i32(fp0);
12501             tcg_temp_free_i32(fp1);
12502             gen_store_fpr32(ctx, fp2, fd);
12503             tcg_temp_free_i32(fp2);
12504         }
12505         break;
12506     case OPC_MSUB_D:
12507         check_cop1x(ctx);
12508         check_cp1_registers(ctx, fd | fs | ft | fr);
12509         {
12510             TCGv_i64 fp0 = tcg_temp_new_i64();
12511             TCGv_i64 fp1 = tcg_temp_new_i64();
12512             TCGv_i64 fp2 = tcg_temp_new_i64();
12513
12514             gen_load_fpr64(ctx, fp0, fs);
12515             gen_load_fpr64(ctx, fp1, ft);
12516             gen_load_fpr64(ctx, fp2, fr);
12517             gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
12518             tcg_temp_free_i64(fp0);
12519             tcg_temp_free_i64(fp1);
12520             gen_store_fpr64(ctx, fp2, fd);
12521             tcg_temp_free_i64(fp2);
12522         }
12523         break;
12524     case OPC_MSUB_PS:
12525         check_ps(ctx);
12526         {
12527             TCGv_i64 fp0 = tcg_temp_new_i64();
12528             TCGv_i64 fp1 = tcg_temp_new_i64();
12529             TCGv_i64 fp2 = tcg_temp_new_i64();
12530
12531             gen_load_fpr64(ctx, fp0, fs);
12532             gen_load_fpr64(ctx, fp1, ft);
12533             gen_load_fpr64(ctx, fp2, fr);
12534             gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
12535             tcg_temp_free_i64(fp0);
12536             tcg_temp_free_i64(fp1);
12537             gen_store_fpr64(ctx, fp2, fd);
12538             tcg_temp_free_i64(fp2);
12539         }
12540         break;
12541     case OPC_NMADD_S:
12542         check_cop1x(ctx);
12543         {
12544             TCGv_i32 fp0 = tcg_temp_new_i32();
12545             TCGv_i32 fp1 = tcg_temp_new_i32();
12546             TCGv_i32 fp2 = tcg_temp_new_i32();
12547
12548             gen_load_fpr32(ctx, fp0, fs);
12549             gen_load_fpr32(ctx, fp1, ft);
12550             gen_load_fpr32(ctx, fp2, fr);
12551             gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
12552             tcg_temp_free_i32(fp0);
12553             tcg_temp_free_i32(fp1);
12554             gen_store_fpr32(ctx, fp2, fd);
12555             tcg_temp_free_i32(fp2);
12556         }
12557         break;
12558     case OPC_NMADD_D:
12559         check_cop1x(ctx);
12560         check_cp1_registers(ctx, fd | fs | ft | fr);
12561         {
12562             TCGv_i64 fp0 = tcg_temp_new_i64();
12563             TCGv_i64 fp1 = tcg_temp_new_i64();
12564             TCGv_i64 fp2 = tcg_temp_new_i64();
12565
12566             gen_load_fpr64(ctx, fp0, fs);
12567             gen_load_fpr64(ctx, fp1, ft);
12568             gen_load_fpr64(ctx, fp2, fr);
12569             gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
12570             tcg_temp_free_i64(fp0);
12571             tcg_temp_free_i64(fp1);
12572             gen_store_fpr64(ctx, fp2, fd);
12573             tcg_temp_free_i64(fp2);
12574         }
12575         break;
12576     case OPC_NMADD_PS:
12577         check_ps(ctx);
12578         {
12579             TCGv_i64 fp0 = tcg_temp_new_i64();
12580             TCGv_i64 fp1 = tcg_temp_new_i64();
12581             TCGv_i64 fp2 = tcg_temp_new_i64();
12582
12583             gen_load_fpr64(ctx, fp0, fs);
12584             gen_load_fpr64(ctx, fp1, ft);
12585             gen_load_fpr64(ctx, fp2, fr);
12586             gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
12587             tcg_temp_free_i64(fp0);
12588             tcg_temp_free_i64(fp1);
12589             gen_store_fpr64(ctx, fp2, fd);
12590             tcg_temp_free_i64(fp2);
12591         }
12592         break;
12593     case OPC_NMSUB_S:
12594         check_cop1x(ctx);
12595         {
12596             TCGv_i32 fp0 = tcg_temp_new_i32();
12597             TCGv_i32 fp1 = tcg_temp_new_i32();
12598             TCGv_i32 fp2 = tcg_temp_new_i32();
12599
12600             gen_load_fpr32(ctx, fp0, fs);
12601             gen_load_fpr32(ctx, fp1, ft);
12602             gen_load_fpr32(ctx, fp2, fr);
12603             gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
12604             tcg_temp_free_i32(fp0);
12605             tcg_temp_free_i32(fp1);
12606             gen_store_fpr32(ctx, fp2, fd);
12607             tcg_temp_free_i32(fp2);
12608         }
12609         break;
12610     case OPC_NMSUB_D:
12611         check_cop1x(ctx);
12612         check_cp1_registers(ctx, fd | fs | ft | fr);
12613         {
12614             TCGv_i64 fp0 = tcg_temp_new_i64();
12615             TCGv_i64 fp1 = tcg_temp_new_i64();
12616             TCGv_i64 fp2 = tcg_temp_new_i64();
12617
12618             gen_load_fpr64(ctx, fp0, fs);
12619             gen_load_fpr64(ctx, fp1, ft);
12620             gen_load_fpr64(ctx, fp2, fr);
12621             gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
12622             tcg_temp_free_i64(fp0);
12623             tcg_temp_free_i64(fp1);
12624             gen_store_fpr64(ctx, fp2, fd);
12625             tcg_temp_free_i64(fp2);
12626         }
12627         break;
12628     case OPC_NMSUB_PS:
12629         check_ps(ctx);
12630         {
12631             TCGv_i64 fp0 = tcg_temp_new_i64();
12632             TCGv_i64 fp1 = tcg_temp_new_i64();
12633             TCGv_i64 fp2 = tcg_temp_new_i64();
12634
12635             gen_load_fpr64(ctx, fp0, fs);
12636             gen_load_fpr64(ctx, fp1, ft);
12637             gen_load_fpr64(ctx, fp2, fr);
12638             gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
12639             tcg_temp_free_i64(fp0);
12640             tcg_temp_free_i64(fp1);
12641             gen_store_fpr64(ctx, fp2, fd);
12642             tcg_temp_free_i64(fp2);
12643         }
12644         break;
12645     default:
12646         MIPS_INVAL("flt3_arith");
12647         generate_exception_end(ctx, EXCP_RI);
12648         return;
12649     }
12650 }
12651
12652 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
12653 {
12654     TCGv t0;
12655
12656 #if !defined(CONFIG_USER_ONLY)
12657     /* The Linux kernel will emulate rdhwr if it's not supported natively.
12658        Therefore only check the ISA in system mode.  */
12659     check_insn(ctx, ISA_MIPS32R2);
12660 #endif
12661     t0 = tcg_temp_new();
12662
12663     switch (rd) {
12664     case 0:
12665         gen_helper_rdhwr_cpunum(t0, cpu_env);
12666         gen_store_gpr(t0, rt);
12667         break;
12668     case 1:
12669         gen_helper_rdhwr_synci_step(t0, cpu_env);
12670         gen_store_gpr(t0, rt);
12671         break;
12672     case 2:
12673         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12674             gen_io_start();
12675         }
12676         gen_helper_rdhwr_cc(t0, cpu_env);
12677         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12678             gen_io_end();
12679         }
12680         gen_store_gpr(t0, rt);
12681         /* Break the TB to be able to take timer interrupts immediately
12682            after reading count. DISAS_STOP isn't sufficient, we need to ensure
12683            we break completely out of translated code.  */
12684         gen_save_pc(ctx->base.pc_next + 4);
12685         ctx->base.is_jmp = DISAS_EXIT;
12686         break;
12687     case 3:
12688         gen_helper_rdhwr_ccres(t0, cpu_env);
12689         gen_store_gpr(t0, rt);
12690         break;
12691     case 4:
12692         check_insn(ctx, ISA_MIPS32R6);
12693         if (sel != 0) {
12694             /* Performance counter registers are not implemented other than
12695              * control register 0.
12696              */
12697             generate_exception(ctx, EXCP_RI);
12698         }
12699         gen_helper_rdhwr_performance(t0, cpu_env);
12700         gen_store_gpr(t0, rt);
12701         break;
12702     case 5:
12703         check_insn(ctx, ISA_MIPS32R6);
12704         gen_helper_rdhwr_xnp(t0, cpu_env);
12705         gen_store_gpr(t0, rt);
12706         break;
12707     case 29:
12708 #if defined(CONFIG_USER_ONLY)
12709         tcg_gen_ld_tl(t0, cpu_env,
12710                       offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12711         gen_store_gpr(t0, rt);
12712         break;
12713 #else
12714         if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12715             (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12716             tcg_gen_ld_tl(t0, cpu_env,
12717                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12718             gen_store_gpr(t0, rt);
12719         } else {
12720             generate_exception_end(ctx, EXCP_RI);
12721         }
12722         break;
12723 #endif
12724     default:            /* Invalid */
12725         MIPS_INVAL("rdhwr");
12726         generate_exception_end(ctx, EXCP_RI);
12727         break;
12728     }
12729     tcg_temp_free(t0);
12730 }
12731
12732 static inline void clear_branch_hflags(DisasContext *ctx)
12733 {
12734     ctx->hflags &= ~MIPS_HFLAG_BMASK;
12735     if (ctx->base.is_jmp == DISAS_NEXT) {
12736         save_cpu_state(ctx, 0);
12737     } else {
12738         /* it is not safe to save ctx->hflags as hflags may be changed
12739            in execution time by the instruction in delay / forbidden slot. */
12740         tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
12741     }
12742 }
12743
12744 static void gen_branch(DisasContext *ctx, int insn_bytes)
12745 {
12746     if (ctx->hflags & MIPS_HFLAG_BMASK) {
12747         int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
12748         /* Branches completion */
12749         clear_branch_hflags(ctx);
12750         ctx->base.is_jmp = DISAS_NORETURN;
12751         /* FIXME: Need to clear can_do_io.  */
12752         switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
12753         case MIPS_HFLAG_FBNSLOT:
12754             gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
12755             break;
12756         case MIPS_HFLAG_B:
12757             /* unconditional branch */
12758             if (proc_hflags & MIPS_HFLAG_BX) {
12759                 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
12760             }
12761             gen_goto_tb(ctx, 0, ctx->btarget);
12762             break;
12763         case MIPS_HFLAG_BL:
12764             /* blikely taken case */
12765             gen_goto_tb(ctx, 0, ctx->btarget);
12766             break;
12767         case MIPS_HFLAG_BC:
12768             /* Conditional branch */
12769             {
12770                 TCGLabel *l1 = gen_new_label();
12771
12772                 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
12773                 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
12774                 gen_set_label(l1);
12775                 gen_goto_tb(ctx, 0, ctx->btarget);
12776             }
12777             break;
12778         case MIPS_HFLAG_BR:
12779             /* unconditional branch to register */
12780             if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
12781                 TCGv t0 = tcg_temp_new();
12782                 TCGv_i32 t1 = tcg_temp_new_i32();
12783
12784                 tcg_gen_andi_tl(t0, btarget, 0x1);
12785                 tcg_gen_trunc_tl_i32(t1, t0);
12786                 tcg_temp_free(t0);
12787                 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
12788                 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
12789                 tcg_gen_or_i32(hflags, hflags, t1);
12790                 tcg_temp_free_i32(t1);
12791
12792                 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
12793             } else {
12794                 tcg_gen_mov_tl(cpu_PC, btarget);
12795             }
12796             if (ctx->base.singlestep_enabled) {
12797                 save_cpu_state(ctx, 0);
12798                 gen_helper_raise_exception_debug(cpu_env);
12799             }
12800             tcg_gen_lookup_and_goto_ptr();
12801             break;
12802         default:
12803             fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
12804             abort();
12805         }
12806     }
12807 }
12808
12809 /* Compact Branches */
12810 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
12811                                        int rs, int rt, int32_t offset)
12812 {
12813     int bcond_compute = 0;
12814     TCGv t0 = tcg_temp_new();
12815     TCGv t1 = tcg_temp_new();
12816     int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
12817
12818     if (ctx->hflags & MIPS_HFLAG_BMASK) {
12819 #ifdef MIPS_DEBUG_DISAS
12820         LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12821                   "\n", ctx->base.pc_next);
12822 #endif
12823         generate_exception_end(ctx, EXCP_RI);
12824         goto out;
12825     }
12826
12827     /* Load needed operands and calculate btarget */
12828     switch (opc) {
12829     /* compact branch */
12830     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12831     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12832         gen_load_gpr(t0, rs);
12833         gen_load_gpr(t1, rt);
12834         bcond_compute = 1;
12835         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12836         if (rs <= rt && rs == 0) {
12837             /* OPC_BEQZALC, OPC_BNEZALC */
12838             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12839         }
12840         break;
12841     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12842     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12843         gen_load_gpr(t0, rs);
12844         gen_load_gpr(t1, rt);
12845         bcond_compute = 1;
12846         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12847         break;
12848     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12849     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12850         if (rs == 0 || rs == rt) {
12851             /* OPC_BLEZALC, OPC_BGEZALC */
12852             /* OPC_BGTZALC, OPC_BLTZALC */
12853             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12854         }
12855         gen_load_gpr(t0, rs);
12856         gen_load_gpr(t1, rt);
12857         bcond_compute = 1;
12858         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12859         break;
12860     case OPC_BC:
12861     case OPC_BALC:
12862         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12863         break;
12864     case OPC_BEQZC:
12865     case OPC_BNEZC:
12866         if (rs != 0) {
12867             /* OPC_BEQZC, OPC_BNEZC */
12868             gen_load_gpr(t0, rs);
12869             bcond_compute = 1;
12870             ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12871         } else {
12872             /* OPC_JIC, OPC_JIALC */
12873             TCGv tbase = tcg_temp_new();
12874             TCGv toffset = tcg_temp_new();
12875
12876             gen_load_gpr(tbase, rt);
12877             tcg_gen_movi_tl(toffset, offset);
12878             gen_op_addr_add(ctx, btarget, tbase, toffset);
12879             tcg_temp_free(tbase);
12880             tcg_temp_free(toffset);
12881         }
12882         break;
12883     default:
12884         MIPS_INVAL("Compact branch/jump");
12885         generate_exception_end(ctx, EXCP_RI);
12886         goto out;
12887     }
12888
12889     if (bcond_compute == 0) {
12890         /* Uncoditional compact branch */
12891         switch (opc) {
12892         case OPC_JIALC:
12893             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12894             /* Fallthrough */
12895         case OPC_JIC:
12896             ctx->hflags |= MIPS_HFLAG_BR;
12897             break;
12898         case OPC_BALC:
12899             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12900             /* Fallthrough */
12901         case OPC_BC:
12902             ctx->hflags |= MIPS_HFLAG_B;
12903             break;
12904         default:
12905             MIPS_INVAL("Compact branch/jump");
12906             generate_exception_end(ctx, EXCP_RI);
12907             goto out;
12908         }
12909
12910         /* Generating branch here as compact branches don't have delay slot */
12911         gen_branch(ctx, 4);
12912     } else {
12913         /* Conditional compact branch */
12914         TCGLabel *fs = gen_new_label();
12915         save_cpu_state(ctx, 0);
12916
12917         switch (opc) {
12918         case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12919             if (rs == 0 && rt != 0) {
12920                 /* OPC_BLEZALC */
12921                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12922             } else if (rs != 0 && rt != 0 && rs == rt) {
12923                 /* OPC_BGEZALC */
12924                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12925             } else {
12926                 /* OPC_BGEUC */
12927                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12928             }
12929             break;
12930         case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12931             if (rs == 0 && rt != 0) {
12932                 /* OPC_BGTZALC */
12933                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12934             } else if (rs != 0 && rt != 0 && rs == rt) {
12935                 /* OPC_BLTZALC */
12936                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12937             } else {
12938                 /* OPC_BLTUC */
12939                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12940             }
12941             break;
12942         case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12943             if (rs == 0 && rt != 0) {
12944                 /* OPC_BLEZC */
12945                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12946             } else if (rs != 0 && rt != 0 && rs == rt) {
12947                 /* OPC_BGEZC */
12948                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12949             } else {
12950                 /* OPC_BGEC */
12951                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12952             }
12953             break;
12954         case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12955             if (rs == 0 && rt != 0) {
12956                 /* OPC_BGTZC */
12957                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12958             } else if (rs != 0 && rt != 0 && rs == rt) {
12959                 /* OPC_BLTZC */
12960                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12961             } else {
12962                 /* OPC_BLTC */
12963                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12964             }
12965             break;
12966         case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12967         case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12968             if (rs >= rt) {
12969                 /* OPC_BOVC, OPC_BNVC */
12970                 TCGv t2 = tcg_temp_new();
12971                 TCGv t3 = tcg_temp_new();
12972                 TCGv t4 = tcg_temp_new();
12973                 TCGv input_overflow = tcg_temp_new();
12974
12975                 gen_load_gpr(t0, rs);
12976                 gen_load_gpr(t1, rt);
12977                 tcg_gen_ext32s_tl(t2, t0);
12978                 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12979                 tcg_gen_ext32s_tl(t3, t1);
12980                 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12981                 tcg_gen_or_tl(input_overflow, input_overflow, t4);
12982
12983                 tcg_gen_add_tl(t4, t2, t3);
12984                 tcg_gen_ext32s_tl(t4, t4);
12985                 tcg_gen_xor_tl(t2, t2, t3);
12986                 tcg_gen_xor_tl(t3, t4, t3);
12987                 tcg_gen_andc_tl(t2, t3, t2);
12988                 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12989                 tcg_gen_or_tl(t4, t4, input_overflow);
12990                 if (opc == OPC_BOVC) {
12991                     /* OPC_BOVC */
12992                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12993                 } else {
12994                     /* OPC_BNVC */
12995                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12996                 }
12997                 tcg_temp_free(input_overflow);
12998                 tcg_temp_free(t4);
12999                 tcg_temp_free(t3);
13000                 tcg_temp_free(t2);
13001             } else if (rs < rt && rs == 0) {
13002                 /* OPC_BEQZALC, OPC_BNEZALC */
13003                 if (opc == OPC_BEQZALC) {
13004                     /* OPC_BEQZALC */
13005                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
13006                 } else {
13007                     /* OPC_BNEZALC */
13008                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
13009                 }
13010             } else {
13011                 /* OPC_BEQC, OPC_BNEC */
13012                 if (opc == OPC_BEQC) {
13013                     /* OPC_BEQC */
13014                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
13015                 } else {
13016                     /* OPC_BNEC */
13017                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
13018                 }
13019             }
13020             break;
13021         case OPC_BEQZC:
13022             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
13023             break;
13024         case OPC_BNEZC:
13025             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
13026             break;
13027         default:
13028             MIPS_INVAL("Compact conditional branch/jump");
13029             generate_exception_end(ctx, EXCP_RI);
13030             goto out;
13031         }
13032
13033         /* Generating branch here as compact branches don't have delay slot */
13034         gen_goto_tb(ctx, 1, ctx->btarget);
13035         gen_set_label(fs);
13036
13037         ctx->hflags |= MIPS_HFLAG_FBNSLOT;
13038     }
13039
13040 out:
13041     tcg_temp_free(t0);
13042     tcg_temp_free(t1);
13043 }
13044
13045 /* ISA extensions (ASEs) */
13046 /* MIPS16 extension to MIPS32 */
13047
13048 /* MIPS16 major opcodes */
13049 enum {
13050   M16_OPC_ADDIUSP = 0x00,
13051   M16_OPC_ADDIUPC = 0x01,
13052   M16_OPC_B = 0x02,
13053   M16_OPC_JAL = 0x03,
13054   M16_OPC_BEQZ = 0x04,
13055   M16_OPC_BNEQZ = 0x05,
13056   M16_OPC_SHIFT = 0x06,
13057   M16_OPC_LD = 0x07,
13058   M16_OPC_RRIA = 0x08,
13059   M16_OPC_ADDIU8 = 0x09,
13060   M16_OPC_SLTI = 0x0a,
13061   M16_OPC_SLTIU = 0x0b,
13062   M16_OPC_I8 = 0x0c,
13063   M16_OPC_LI = 0x0d,
13064   M16_OPC_CMPI = 0x0e,
13065   M16_OPC_SD = 0x0f,
13066   M16_OPC_LB = 0x10,
13067   M16_OPC_LH = 0x11,
13068   M16_OPC_LWSP = 0x12,
13069   M16_OPC_LW = 0x13,
13070   M16_OPC_LBU = 0x14,
13071   M16_OPC_LHU = 0x15,
13072   M16_OPC_LWPC = 0x16,
13073   M16_OPC_LWU = 0x17,
13074   M16_OPC_SB = 0x18,
13075   M16_OPC_SH = 0x19,
13076   M16_OPC_SWSP = 0x1a,
13077   M16_OPC_SW = 0x1b,
13078   M16_OPC_RRR = 0x1c,
13079   M16_OPC_RR = 0x1d,
13080   M16_OPC_EXTEND = 0x1e,
13081   M16_OPC_I64 = 0x1f
13082 };
13083
13084 /* I8 funct field */
13085 enum {
13086   I8_BTEQZ = 0x0,
13087   I8_BTNEZ = 0x1,
13088   I8_SWRASP = 0x2,
13089   I8_ADJSP = 0x3,
13090   I8_SVRS = 0x4,
13091   I8_MOV32R = 0x5,
13092   I8_MOVR32 = 0x7
13093 };
13094
13095 /* RRR f field */
13096 enum {
13097   RRR_DADDU = 0x0,
13098   RRR_ADDU = 0x1,
13099   RRR_DSUBU = 0x2,
13100   RRR_SUBU = 0x3
13101 };
13102
13103 /* RR funct field */
13104 enum {
13105   RR_JR = 0x00,
13106   RR_SDBBP = 0x01,
13107   RR_SLT = 0x02,
13108   RR_SLTU = 0x03,
13109   RR_SLLV = 0x04,
13110   RR_BREAK = 0x05,
13111   RR_SRLV = 0x06,
13112   RR_SRAV = 0x07,
13113   RR_DSRL = 0x08,
13114   RR_CMP = 0x0a,
13115   RR_NEG = 0x0b,
13116   RR_AND = 0x0c,
13117   RR_OR = 0x0d,
13118   RR_XOR = 0x0e,
13119   RR_NOT = 0x0f,
13120   RR_MFHI = 0x10,
13121   RR_CNVT = 0x11,
13122   RR_MFLO = 0x12,
13123   RR_DSRA = 0x13,
13124   RR_DSLLV = 0x14,
13125   RR_DSRLV = 0x16,
13126   RR_DSRAV = 0x17,
13127   RR_MULT = 0x18,
13128   RR_MULTU = 0x19,
13129   RR_DIV = 0x1a,
13130   RR_DIVU = 0x1b,
13131   RR_DMULT = 0x1c,
13132   RR_DMULTU = 0x1d,
13133   RR_DDIV = 0x1e,
13134   RR_DDIVU = 0x1f
13135 };
13136
13137 /* I64 funct field */
13138 enum {
13139   I64_LDSP = 0x0,
13140   I64_SDSP = 0x1,
13141   I64_SDRASP = 0x2,
13142   I64_DADJSP = 0x3,
13143   I64_LDPC = 0x4,
13144   I64_DADDIU5 = 0x5,
13145   I64_DADDIUPC = 0x6,
13146   I64_DADDIUSP = 0x7
13147 };
13148
13149 /* RR ry field for CNVT */
13150 enum {
13151   RR_RY_CNVT_ZEB = 0x0,
13152   RR_RY_CNVT_ZEH = 0x1,
13153   RR_RY_CNVT_ZEW = 0x2,
13154   RR_RY_CNVT_SEB = 0x4,
13155   RR_RY_CNVT_SEH = 0x5,
13156   RR_RY_CNVT_SEW = 0x6,
13157 };
13158
13159 static int xlat (int r)
13160 {
13161   static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13162
13163   return map[r];
13164 }
13165
13166 static void gen_mips16_save (DisasContext *ctx,
13167                              int xsregs, int aregs,
13168                              int do_ra, int do_s0, int do_s1,
13169                              int framesize)
13170 {
13171     TCGv t0 = tcg_temp_new();
13172     TCGv t1 = tcg_temp_new();
13173     TCGv t2 = tcg_temp_new();
13174     int args, astatic;
13175
13176     switch (aregs) {
13177     case 0:
13178     case 1:
13179     case 2:
13180     case 3:
13181     case 11:
13182         args = 0;
13183         break;
13184     case 4:
13185     case 5:
13186     case 6:
13187     case 7:
13188         args = 1;
13189         break;
13190     case 8:
13191     case 9:
13192     case 10:
13193         args = 2;
13194         break;
13195     case 12:
13196     case 13:
13197         args = 3;
13198         break;
13199     case 14:
13200         args = 4;
13201         break;
13202     default:
13203         generate_exception_end(ctx, EXCP_RI);
13204         return;
13205     }
13206
13207     switch (args) {
13208     case 4:
13209         gen_base_offset_addr(ctx, t0, 29, 12);
13210         gen_load_gpr(t1, 7);
13211         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13212         /* Fall through */
13213     case 3:
13214         gen_base_offset_addr(ctx, t0, 29, 8);
13215         gen_load_gpr(t1, 6);
13216         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13217         /* Fall through */
13218     case 2:
13219         gen_base_offset_addr(ctx, t0, 29, 4);
13220         gen_load_gpr(t1, 5);
13221         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13222         /* Fall through */
13223     case 1:
13224         gen_base_offset_addr(ctx, t0, 29, 0);
13225         gen_load_gpr(t1, 4);
13226         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13227     }
13228
13229     gen_load_gpr(t0, 29);
13230
13231 #define DECR_AND_STORE(reg) do {                                 \
13232         tcg_gen_movi_tl(t2, -4);                                 \
13233         gen_op_addr_add(ctx, t0, t0, t2);                        \
13234         gen_load_gpr(t1, reg);                                   \
13235         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13236     } while (0)
13237
13238     if (do_ra) {
13239         DECR_AND_STORE(31);
13240     }
13241
13242     switch (xsregs) {
13243     case 7:
13244         DECR_AND_STORE(30);
13245         /* Fall through */
13246     case 6:
13247         DECR_AND_STORE(23);
13248         /* Fall through */
13249     case 5:
13250         DECR_AND_STORE(22);
13251         /* Fall through */
13252     case 4:
13253         DECR_AND_STORE(21);
13254         /* Fall through */
13255     case 3:
13256         DECR_AND_STORE(20);
13257         /* Fall through */
13258     case 2:
13259         DECR_AND_STORE(19);
13260         /* Fall through */
13261     case 1:
13262         DECR_AND_STORE(18);
13263     }
13264
13265     if (do_s1) {
13266         DECR_AND_STORE(17);
13267     }
13268     if (do_s0) {
13269         DECR_AND_STORE(16);
13270     }
13271
13272     switch (aregs) {
13273     case 0:
13274     case 4:
13275     case 8:
13276     case 12:
13277     case 14:
13278         astatic = 0;
13279         break;
13280     case 1:
13281     case 5:
13282     case 9:
13283     case 13:
13284         astatic = 1;
13285         break;
13286     case 2:
13287     case 6:
13288     case 10:
13289         astatic = 2;
13290         break;
13291     case 3:
13292     case 7:
13293         astatic = 3;
13294         break;
13295     case 11:
13296         astatic = 4;
13297         break;
13298     default:
13299         generate_exception_end(ctx, EXCP_RI);
13300         return;
13301     }
13302
13303     if (astatic > 0) {
13304         DECR_AND_STORE(7);
13305         if (astatic > 1) {
13306             DECR_AND_STORE(6);
13307             if (astatic > 2) {
13308                 DECR_AND_STORE(5);
13309                 if (astatic > 3) {
13310                     DECR_AND_STORE(4);
13311                 }
13312             }
13313         }
13314     }
13315 #undef DECR_AND_STORE
13316
13317     tcg_gen_movi_tl(t2, -framesize);
13318     gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13319     tcg_temp_free(t0);
13320     tcg_temp_free(t1);
13321     tcg_temp_free(t2);
13322 }
13323
13324 static void gen_mips16_restore (DisasContext *ctx,
13325                                 int xsregs, int aregs,
13326                                 int do_ra, int do_s0, int do_s1,
13327                                 int framesize)
13328 {
13329     int astatic;
13330     TCGv t0 = tcg_temp_new();
13331     TCGv t1 = tcg_temp_new();
13332     TCGv t2 = tcg_temp_new();
13333
13334     tcg_gen_movi_tl(t2, framesize);
13335     gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
13336
13337 #define DECR_AND_LOAD(reg) do {                            \
13338         tcg_gen_movi_tl(t2, -4);                           \
13339         gen_op_addr_add(ctx, t0, t0, t2);                  \
13340         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13341         gen_store_gpr(t1, reg);                            \
13342     } while (0)
13343
13344     if (do_ra) {
13345         DECR_AND_LOAD(31);
13346     }
13347
13348     switch (xsregs) {
13349     case 7:
13350         DECR_AND_LOAD(30);
13351         /* Fall through */
13352     case 6:
13353         DECR_AND_LOAD(23);
13354         /* Fall through */
13355     case 5:
13356         DECR_AND_LOAD(22);
13357         /* Fall through */
13358     case 4:
13359         DECR_AND_LOAD(21);
13360         /* Fall through */
13361     case 3:
13362         DECR_AND_LOAD(20);
13363         /* Fall through */
13364     case 2:
13365         DECR_AND_LOAD(19);
13366         /* Fall through */
13367     case 1:
13368         DECR_AND_LOAD(18);
13369     }
13370
13371     if (do_s1) {
13372         DECR_AND_LOAD(17);
13373     }
13374     if (do_s0) {
13375         DECR_AND_LOAD(16);
13376     }
13377
13378     switch (aregs) {
13379     case 0:
13380     case 4:
13381     case 8:
13382     case 12:
13383     case 14:
13384         astatic = 0;
13385         break;
13386     case 1:
13387     case 5:
13388     case 9:
13389     case 13:
13390         astatic = 1;
13391         break;
13392     case 2:
13393     case 6:
13394     case 10:
13395         astatic = 2;
13396         break;
13397     case 3:
13398     case 7:
13399         astatic = 3;
13400         break;
13401     case 11:
13402         astatic = 4;
13403         break;
13404     default:
13405         generate_exception_end(ctx, EXCP_RI);
13406         return;
13407     }
13408
13409     if (astatic > 0) {
13410         DECR_AND_LOAD(7);
13411         if (astatic > 1) {
13412             DECR_AND_LOAD(6);
13413             if (astatic > 2) {
13414                 DECR_AND_LOAD(5);
13415                 if (astatic > 3) {
13416                     DECR_AND_LOAD(4);
13417                 }
13418             }
13419         }
13420     }
13421 #undef DECR_AND_LOAD
13422
13423     tcg_gen_movi_tl(t2, framesize);
13424     gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13425     tcg_temp_free(t0);
13426     tcg_temp_free(t1);
13427     tcg_temp_free(t2);
13428 }
13429
13430 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
13431                          int is_64_bit, int extended)
13432 {
13433     TCGv t0;
13434
13435     if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13436         generate_exception_end(ctx, EXCP_RI);
13437         return;
13438     }
13439
13440     t0 = tcg_temp_new();
13441
13442     tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13443     tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13444     if (!is_64_bit) {
13445         tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13446     }
13447
13448     tcg_temp_free(t0);
13449 }
13450
13451 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13452                                 int16_t offset)
13453 {
13454     TCGv_i32 t0 = tcg_const_i32(op);
13455     TCGv t1 = tcg_temp_new();
13456     gen_base_offset_addr(ctx, t1, base, offset);
13457     gen_helper_cache(cpu_env, t1, t0);
13458 }
13459
13460 #if defined(TARGET_MIPS64)
13461 static void decode_i64_mips16 (DisasContext *ctx,
13462                                int ry, int funct, int16_t offset,
13463                                int extended)
13464 {
13465     switch (funct) {
13466     case I64_LDSP:
13467         check_insn(ctx, ISA_MIPS3);
13468         check_mips_64(ctx);
13469         offset = extended ? offset : offset << 3;
13470         gen_ld(ctx, OPC_LD, ry, 29, offset);
13471         break;
13472     case I64_SDSP:
13473         check_insn(ctx, ISA_MIPS3);
13474         check_mips_64(ctx);
13475         offset = extended ? offset : offset << 3;
13476         gen_st(ctx, OPC_SD, ry, 29, offset);
13477         break;
13478     case I64_SDRASP:
13479         check_insn(ctx, ISA_MIPS3);
13480         check_mips_64(ctx);
13481         offset = extended ? offset : (ctx->opcode & 0xff) << 3;
13482         gen_st(ctx, OPC_SD, 31, 29, offset);
13483         break;
13484     case I64_DADJSP:
13485         check_insn(ctx, ISA_MIPS3);
13486         check_mips_64(ctx);
13487         offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
13488         gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
13489         break;
13490     case I64_LDPC:
13491         check_insn(ctx, ISA_MIPS3);
13492         check_mips_64(ctx);
13493         if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13494             generate_exception_end(ctx, EXCP_RI);
13495         } else {
13496             offset = extended ? offset : offset << 3;
13497             gen_ld(ctx, OPC_LDPC, ry, 0, offset);
13498         }
13499         break;
13500     case I64_DADDIU5:
13501         check_insn(ctx, ISA_MIPS3);
13502         check_mips_64(ctx);
13503         offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
13504         gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
13505         break;
13506     case I64_DADDIUPC:
13507         check_insn(ctx, ISA_MIPS3);
13508         check_mips_64(ctx);
13509         offset = extended ? offset : offset << 2;
13510         gen_addiupc(ctx, ry, offset, 1, extended);
13511         break;
13512     case I64_DADDIUSP:
13513         check_insn(ctx, ISA_MIPS3);
13514         check_mips_64(ctx);
13515         offset = extended ? offset : offset << 2;
13516         gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
13517         break;
13518     }
13519 }
13520 #endif
13521
13522 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13523 {
13524     int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
13525     int op, rx, ry, funct, sa;
13526     int16_t imm, offset;
13527
13528     ctx->opcode = (ctx->opcode << 16) | extend;
13529     op = (ctx->opcode >> 11) & 0x1f;
13530     sa = (ctx->opcode >> 22) & 0x1f;
13531     funct = (ctx->opcode >> 8) & 0x7;
13532     rx = xlat((ctx->opcode >> 8) & 0x7);
13533     ry = xlat((ctx->opcode >> 5) & 0x7);
13534     offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13535                               | ((ctx->opcode >> 21) & 0x3f) << 5
13536                               | (ctx->opcode & 0x1f));
13537
13538     /* The extended opcodes cleverly reuse the opcodes from their 16-bit
13539        counterparts.  */
13540     switch (op) {
13541     case M16_OPC_ADDIUSP:
13542         gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13543         break;
13544     case M16_OPC_ADDIUPC:
13545         gen_addiupc(ctx, rx, imm, 0, 1);
13546         break;
13547     case M16_OPC_B:
13548         gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
13549         /* No delay slot, so just process as a normal instruction */
13550         break;
13551     case M16_OPC_BEQZ:
13552         gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
13553         /* No delay slot, so just process as a normal instruction */
13554         break;
13555     case M16_OPC_BNEQZ:
13556         gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
13557         /* No delay slot, so just process as a normal instruction */
13558         break;
13559     case M16_OPC_SHIFT:
13560         switch (ctx->opcode & 0x3) {
13561         case 0x0:
13562             gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13563             break;
13564         case 0x1:
13565 #if defined(TARGET_MIPS64)
13566             check_mips_64(ctx);
13567             gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13568 #else
13569             generate_exception_end(ctx, EXCP_RI);
13570 #endif
13571             break;
13572         case 0x2:
13573             gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13574             break;
13575         case 0x3:
13576             gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13577             break;
13578         }
13579         break;
13580 #if defined(TARGET_MIPS64)
13581     case M16_OPC_LD:
13582         check_insn(ctx, ISA_MIPS3);
13583         check_mips_64(ctx);
13584         gen_ld(ctx, OPC_LD, ry, rx, offset);
13585         break;
13586 #endif
13587     case M16_OPC_RRIA:
13588         imm = ctx->opcode & 0xf;
13589         imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13590         imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13591         imm = (int16_t) (imm << 1) >> 1;
13592         if ((ctx->opcode >> 4) & 0x1) {
13593 #if defined(TARGET_MIPS64)
13594             check_mips_64(ctx);
13595             gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13596 #else
13597             generate_exception_end(ctx, EXCP_RI);
13598 #endif
13599         } else {
13600             gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13601         }
13602         break;
13603     case M16_OPC_ADDIU8:
13604         gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13605         break;
13606     case M16_OPC_SLTI:
13607         gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13608         break;
13609     case M16_OPC_SLTIU:
13610         gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13611         break;
13612     case M16_OPC_I8:
13613         switch (funct) {
13614         case I8_BTEQZ:
13615             gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
13616             break;
13617         case I8_BTNEZ:
13618             gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
13619             break;
13620         case I8_SWRASP:
13621             gen_st(ctx, OPC_SW, 31, 29, imm);
13622             break;
13623         case I8_ADJSP:
13624             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
13625             break;
13626         case I8_SVRS:
13627             check_insn(ctx, ISA_MIPS32);
13628             {
13629                 int xsregs = (ctx->opcode >> 24) & 0x7;
13630                 int aregs = (ctx->opcode >> 16) & 0xf;
13631                 int do_ra = (ctx->opcode >> 6) & 0x1;
13632                 int do_s0 = (ctx->opcode >> 5) & 0x1;
13633                 int do_s1 = (ctx->opcode >> 4) & 0x1;
13634                 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
13635                                  | (ctx->opcode & 0xf)) << 3;
13636
13637                 if (ctx->opcode & (1 << 7)) {
13638                     gen_mips16_save(ctx, xsregs, aregs,
13639                                     do_ra, do_s0, do_s1,
13640                                     framesize);
13641                 } else {
13642                     gen_mips16_restore(ctx, xsregs, aregs,
13643                                        do_ra, do_s0, do_s1,
13644                                        framesize);
13645                 }
13646             }
13647             break;
13648         default:
13649             generate_exception_end(ctx, EXCP_RI);
13650             break;
13651         }
13652         break;
13653     case M16_OPC_LI:
13654         tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13655         break;
13656     case M16_OPC_CMPI:
13657         tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13658         break;
13659 #if defined(TARGET_MIPS64)
13660     case M16_OPC_SD:
13661         check_insn(ctx, ISA_MIPS3);
13662         check_mips_64(ctx);
13663         gen_st(ctx, OPC_SD, ry, rx, offset);
13664         break;
13665 #endif
13666     case M16_OPC_LB:
13667         gen_ld(ctx, OPC_LB, ry, rx, offset);
13668         break;
13669     case M16_OPC_LH:
13670         gen_ld(ctx, OPC_LH, ry, rx, offset);
13671         break;
13672     case M16_OPC_LWSP:
13673         gen_ld(ctx, OPC_LW, rx, 29, offset);
13674         break;
13675     case M16_OPC_LW:
13676         gen_ld(ctx, OPC_LW, ry, rx, offset);
13677         break;
13678     case M16_OPC_LBU:
13679         gen_ld(ctx, OPC_LBU, ry, rx, offset);
13680         break;
13681     case M16_OPC_LHU:
13682         gen_ld(ctx, OPC_LHU, ry, rx, offset);
13683         break;
13684     case M16_OPC_LWPC:
13685         gen_ld(ctx, OPC_LWPC, rx, 0, offset);
13686         break;
13687 #if defined(TARGET_MIPS64)
13688     case M16_OPC_LWU:
13689         check_insn(ctx, ISA_MIPS3);
13690         check_mips_64(ctx);
13691         gen_ld(ctx, OPC_LWU, ry, rx, offset);
13692         break;
13693 #endif
13694     case M16_OPC_SB:
13695         gen_st(ctx, OPC_SB, ry, rx, offset);
13696         break;
13697     case M16_OPC_SH:
13698         gen_st(ctx, OPC_SH, ry, rx, offset);
13699         break;
13700     case M16_OPC_SWSP:
13701         gen_st(ctx, OPC_SW, rx, 29, offset);
13702         break;
13703     case M16_OPC_SW:
13704         gen_st(ctx, OPC_SW, ry, rx, offset);
13705         break;
13706 #if defined(TARGET_MIPS64)
13707     case M16_OPC_I64:
13708         decode_i64_mips16(ctx, ry, funct, offset, 1);
13709         break;
13710 #endif
13711     default:
13712         generate_exception_end(ctx, EXCP_RI);
13713         break;
13714     }
13715
13716     return 4;
13717 }
13718
13719 static inline bool is_uhi(int sdbbp_code)
13720 {
13721 #ifdef CONFIG_USER_ONLY
13722     return false;
13723 #else
13724     return semihosting_enabled() && sdbbp_code == 1;
13725 #endif
13726 }
13727
13728 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13729 {
13730     int rx, ry;
13731     int sa;
13732     int op, cnvt_op, op1, offset;
13733     int funct;
13734     int n_bytes;
13735
13736     op = (ctx->opcode >> 11) & 0x1f;
13737     sa = (ctx->opcode >> 2) & 0x7;
13738     sa = sa == 0 ? 8 : sa;
13739     rx = xlat((ctx->opcode >> 8) & 0x7);
13740     cnvt_op = (ctx->opcode >> 5) & 0x7;
13741     ry = xlat((ctx->opcode >> 5) & 0x7);
13742     op1 = offset = ctx->opcode & 0x1f;
13743
13744     n_bytes = 2;
13745
13746     switch (op) {
13747     case M16_OPC_ADDIUSP:
13748         {
13749             int16_t imm = ((uint8_t) ctx->opcode) << 2;
13750
13751             gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13752         }
13753         break;
13754     case M16_OPC_ADDIUPC:
13755         gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
13756         break;
13757     case M16_OPC_B:
13758         offset = (ctx->opcode & 0x7ff) << 1;
13759         offset = (int16_t)(offset << 4) >> 4;
13760         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
13761         /* No delay slot, so just process as a normal instruction */
13762         break;
13763     case M16_OPC_JAL:
13764         offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
13765         offset = (((ctx->opcode & 0x1f) << 21)
13766                   | ((ctx->opcode >> 5) & 0x1f) << 16
13767                   | offset) << 2;
13768         op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
13769         gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
13770         n_bytes = 4;
13771         break;
13772     case M16_OPC_BEQZ:
13773         gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
13774                            ((int8_t)ctx->opcode) << 1, 0);
13775         /* No delay slot, so just process as a normal instruction */
13776         break;
13777     case M16_OPC_BNEQZ:
13778         gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
13779                            ((int8_t)ctx->opcode) << 1, 0);
13780         /* No delay slot, so just process as a normal instruction */
13781         break;
13782     case M16_OPC_SHIFT:
13783         switch (ctx->opcode & 0x3) {
13784         case 0x0:
13785             gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13786             break;
13787         case 0x1:
13788 #if defined(TARGET_MIPS64)
13789             check_insn(ctx, ISA_MIPS3);
13790             check_mips_64(ctx);
13791             gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13792 #else
13793             generate_exception_end(ctx, EXCP_RI);
13794 #endif
13795             break;
13796         case 0x2:
13797             gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13798             break;
13799         case 0x3:
13800             gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13801             break;
13802         }
13803         break;
13804 #if defined(TARGET_MIPS64)
13805     case M16_OPC_LD:
13806         check_insn(ctx, ISA_MIPS3);
13807         check_mips_64(ctx);
13808         gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
13809         break;
13810 #endif
13811     case M16_OPC_RRIA:
13812         {
13813             int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
13814
13815             if ((ctx->opcode >> 4) & 1) {
13816 #if defined(TARGET_MIPS64)
13817                 check_insn(ctx, ISA_MIPS3);
13818                 check_mips_64(ctx);
13819                 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13820 #else
13821                 generate_exception_end(ctx, EXCP_RI);
13822 #endif
13823             } else {
13824                 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13825             }
13826         }
13827         break;
13828     case M16_OPC_ADDIU8:
13829         {
13830             int16_t imm = (int8_t) ctx->opcode;
13831
13832             gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13833         }
13834         break;
13835     case M16_OPC_SLTI:
13836         {
13837             int16_t imm = (uint8_t) ctx->opcode;
13838             gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13839         }
13840         break;
13841     case M16_OPC_SLTIU:
13842         {
13843             int16_t imm = (uint8_t) ctx->opcode;
13844             gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13845         }
13846         break;
13847     case M16_OPC_I8:
13848         {
13849             int reg32;
13850
13851             funct = (ctx->opcode >> 8) & 0x7;
13852             switch (funct) {
13853             case I8_BTEQZ:
13854                 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
13855                                    ((int8_t)ctx->opcode) << 1, 0);
13856                 break;
13857             case I8_BTNEZ:
13858                 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
13859                                    ((int8_t)ctx->opcode) << 1, 0);
13860                 break;
13861             case I8_SWRASP:
13862                 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
13863                 break;
13864             case I8_ADJSP:
13865                 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
13866                               ((int8_t)ctx->opcode) << 3);
13867                 break;
13868             case I8_SVRS:
13869                 check_insn(ctx, ISA_MIPS32);
13870                 {
13871                     int do_ra = ctx->opcode & (1 << 6);
13872                     int do_s0 = ctx->opcode & (1 << 5);
13873                     int do_s1 = ctx->opcode & (1 << 4);
13874                     int framesize = ctx->opcode & 0xf;
13875
13876                     if (framesize == 0) {
13877                         framesize = 128;
13878                     } else {
13879                         framesize = framesize << 3;
13880                     }
13881
13882                     if (ctx->opcode & (1 << 7)) {
13883                         gen_mips16_save(ctx, 0, 0,
13884                                         do_ra, do_s0, do_s1, framesize);
13885                     } else {
13886                         gen_mips16_restore(ctx, 0, 0,
13887                                            do_ra, do_s0, do_s1, framesize);
13888                     }
13889                 }
13890                 break;
13891             case I8_MOV32R:
13892                 {
13893                     int rz = xlat(ctx->opcode & 0x7);
13894
13895                     reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
13896                         ((ctx->opcode >> 5) & 0x7);
13897                     gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
13898                 }
13899                 break;
13900             case I8_MOVR32:
13901                 reg32 = ctx->opcode & 0x1f;
13902                 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
13903                 break;
13904             default:
13905                 generate_exception_end(ctx, EXCP_RI);
13906                 break;
13907             }
13908         }
13909         break;
13910     case M16_OPC_LI:
13911         {
13912             int16_t imm = (uint8_t) ctx->opcode;
13913
13914             gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
13915         }
13916         break;
13917     case M16_OPC_CMPI:
13918         {
13919             int16_t imm = (uint8_t) ctx->opcode;
13920             gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
13921         }
13922         break;
13923 #if defined(TARGET_MIPS64)
13924     case M16_OPC_SD:
13925         check_insn(ctx, ISA_MIPS3);
13926         check_mips_64(ctx);
13927         gen_st(ctx, OPC_SD, ry, rx, offset << 3);
13928         break;
13929 #endif
13930     case M16_OPC_LB:
13931         gen_ld(ctx, OPC_LB, ry, rx, offset);
13932         break;
13933     case M16_OPC_LH:
13934         gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
13935         break;
13936     case M16_OPC_LWSP:
13937         gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13938         break;
13939     case M16_OPC_LW:
13940         gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
13941         break;
13942     case M16_OPC_LBU:
13943         gen_ld(ctx, OPC_LBU, ry, rx, offset);
13944         break;
13945     case M16_OPC_LHU:
13946         gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
13947         break;
13948     case M16_OPC_LWPC:
13949         gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
13950         break;
13951 #if defined (TARGET_MIPS64)
13952     case M16_OPC_LWU:
13953         check_insn(ctx, ISA_MIPS3);
13954         check_mips_64(ctx);
13955         gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
13956         break;
13957 #endif
13958     case M16_OPC_SB:
13959         gen_st(ctx, OPC_SB, ry, rx, offset);
13960         break;
13961     case M16_OPC_SH:
13962         gen_st(ctx, OPC_SH, ry, rx, offset << 1);
13963         break;
13964     case M16_OPC_SWSP:
13965         gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13966         break;
13967     case M16_OPC_SW:
13968         gen_st(ctx, OPC_SW, ry, rx, offset << 2);
13969         break;
13970     case M16_OPC_RRR:
13971         {
13972             int rz = xlat((ctx->opcode >> 2) & 0x7);
13973             int mips32_op;
13974
13975             switch (ctx->opcode & 0x3) {
13976             case RRR_ADDU:
13977                 mips32_op = OPC_ADDU;
13978                 break;
13979             case RRR_SUBU:
13980                 mips32_op = OPC_SUBU;
13981                 break;
13982 #if defined(TARGET_MIPS64)
13983             case RRR_DADDU:
13984                 mips32_op = OPC_DADDU;
13985                 check_insn(ctx, ISA_MIPS3);
13986                 check_mips_64(ctx);
13987                 break;
13988             case RRR_DSUBU:
13989                 mips32_op = OPC_DSUBU;
13990                 check_insn(ctx, ISA_MIPS3);
13991                 check_mips_64(ctx);
13992                 break;
13993 #endif
13994             default:
13995                 generate_exception_end(ctx, EXCP_RI);
13996                 goto done;
13997             }
13998
13999             gen_arith(ctx, mips32_op, rz, rx, ry);
14000         done:
14001             ;
14002         }
14003         break;
14004     case M16_OPC_RR:
14005         switch (op1) {
14006         case RR_JR:
14007             {
14008                 int nd = (ctx->opcode >> 7) & 0x1;
14009                 int link = (ctx->opcode >> 6) & 0x1;
14010                 int ra = (ctx->opcode >> 5) & 0x1;
14011
14012                 if (nd) {
14013                     check_insn(ctx, ISA_MIPS32);
14014                 }
14015
14016                 if (link) {
14017                     op = OPC_JALR;
14018                 } else {
14019                     op = OPC_JR;
14020                 }
14021
14022                 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
14023                                    (nd ? 0 : 2));
14024             }
14025             break;
14026         case RR_SDBBP:
14027             if (is_uhi(extract32(ctx->opcode, 5, 6))) {
14028                 gen_helper_do_semihosting(cpu_env);
14029             } else {
14030                 /* XXX: not clear which exception should be raised
14031                  *      when in debug mode...
14032                  */
14033                 check_insn(ctx, ISA_MIPS32);
14034                 generate_exception_end(ctx, EXCP_DBp);
14035             }
14036             break;
14037         case RR_SLT:
14038             gen_slt(ctx, OPC_SLT, 24, rx, ry);
14039             break;
14040         case RR_SLTU:
14041             gen_slt(ctx, OPC_SLTU, 24, rx, ry);
14042             break;
14043         case RR_BREAK:
14044             generate_exception_end(ctx, EXCP_BREAK);
14045             break;
14046         case RR_SLLV:
14047             gen_shift(ctx, OPC_SLLV, ry, rx, ry);
14048             break;
14049         case RR_SRLV:
14050             gen_shift(ctx, OPC_SRLV, ry, rx, ry);
14051             break;
14052         case RR_SRAV:
14053             gen_shift(ctx, OPC_SRAV, ry, rx, ry);
14054             break;
14055 #if defined (TARGET_MIPS64)
14056         case RR_DSRL:
14057             check_insn(ctx, ISA_MIPS3);
14058             check_mips_64(ctx);
14059             gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
14060             break;
14061 #endif
14062         case RR_CMP:
14063             gen_logic(ctx, OPC_XOR, 24, rx, ry);
14064             break;
14065         case RR_NEG:
14066             gen_arith(ctx, OPC_SUBU, rx, 0, ry);
14067             break;
14068         case RR_AND:
14069             gen_logic(ctx, OPC_AND, rx, rx, ry);
14070             break;
14071         case RR_OR:
14072             gen_logic(ctx, OPC_OR, rx, rx, ry);
14073             break;
14074         case RR_XOR:
14075             gen_logic(ctx, OPC_XOR, rx, rx, ry);
14076             break;
14077         case RR_NOT:
14078             gen_logic(ctx, OPC_NOR, rx, ry, 0);
14079             break;
14080         case RR_MFHI:
14081             gen_HILO(ctx, OPC_MFHI, 0, rx);
14082             break;
14083         case RR_CNVT:
14084             check_insn(ctx, ISA_MIPS32);
14085             switch (cnvt_op) {
14086             case RR_RY_CNVT_ZEB:
14087                 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14088                 break;
14089             case RR_RY_CNVT_ZEH:
14090                 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14091                 break;
14092             case RR_RY_CNVT_SEB:
14093                 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14094                 break;
14095             case RR_RY_CNVT_SEH:
14096                 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14097                 break;
14098 #if defined (TARGET_MIPS64)
14099             case RR_RY_CNVT_ZEW:
14100                 check_insn(ctx, ISA_MIPS64);
14101                 check_mips_64(ctx);
14102                 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14103                 break;
14104             case RR_RY_CNVT_SEW:
14105                 check_insn(ctx, ISA_MIPS64);
14106                 check_mips_64(ctx);
14107                 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14108                 break;
14109 #endif
14110             default:
14111                 generate_exception_end(ctx, EXCP_RI);
14112                 break;
14113             }
14114             break;
14115         case RR_MFLO:
14116             gen_HILO(ctx, OPC_MFLO, 0, rx);
14117             break;
14118 #if defined (TARGET_MIPS64)
14119         case RR_DSRA:
14120             check_insn(ctx, ISA_MIPS3);
14121             check_mips_64(ctx);
14122             gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
14123             break;
14124         case RR_DSLLV:
14125             check_insn(ctx, ISA_MIPS3);
14126             check_mips_64(ctx);
14127             gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
14128             break;
14129         case RR_DSRLV:
14130             check_insn(ctx, ISA_MIPS3);
14131             check_mips_64(ctx);
14132             gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
14133             break;
14134         case RR_DSRAV:
14135             check_insn(ctx, ISA_MIPS3);
14136             check_mips_64(ctx);
14137             gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
14138             break;
14139 #endif
14140         case RR_MULT:
14141             gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
14142             break;
14143         case RR_MULTU:
14144             gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
14145             break;
14146         case RR_DIV:
14147             gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
14148             break;
14149         case RR_DIVU:
14150             gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
14151             break;
14152 #if defined (TARGET_MIPS64)
14153         case RR_DMULT:
14154             check_insn(ctx, ISA_MIPS3);
14155             check_mips_64(ctx);
14156             gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
14157             break;
14158         case RR_DMULTU:
14159             check_insn(ctx, ISA_MIPS3);
14160             check_mips_64(ctx);
14161             gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
14162             break;
14163         case RR_DDIV:
14164             check_insn(ctx, ISA_MIPS3);
14165             check_mips_64(ctx);
14166             gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
14167             break;
14168         case RR_DDIVU:
14169             check_insn(ctx, ISA_MIPS3);
14170             check_mips_64(ctx);
14171             gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
14172             break;
14173 #endif
14174         default:
14175             generate_exception_end(ctx, EXCP_RI);
14176             break;
14177         }
14178         break;
14179     case M16_OPC_EXTEND:
14180         decode_extended_mips16_opc(env, ctx);
14181         n_bytes = 4;
14182         break;
14183 #if defined(TARGET_MIPS64)
14184     case M16_OPC_I64:
14185         funct = (ctx->opcode >> 8) & 0x7;
14186         decode_i64_mips16(ctx, ry, funct, offset, 0);
14187         break;
14188 #endif
14189     default:
14190         generate_exception_end(ctx, EXCP_RI);
14191         break;
14192     }
14193
14194     return n_bytes;
14195 }
14196
14197 /* microMIPS extension to MIPS32/MIPS64 */
14198
14199 /*
14200  * microMIPS32/microMIPS64 major opcodes
14201  *
14202  * 1. MIPS Architecture for Programmers Volume II-B:
14203  *      The microMIPS32 Instruction Set (Revision 3.05)
14204  *
14205  *    Table 6.2 microMIPS32 Encoding of Major Opcode Field
14206  *
14207  * 2. MIPS Architecture For Programmers Volume II-A:
14208  *      The MIPS64 Instruction Set (Revision 3.51)
14209  */
14210
14211 enum {
14212     POOL32A = 0x00,
14213     POOL16A = 0x01,
14214     LBU16 = 0x02,
14215     MOVE16 = 0x03,
14216     ADDI32 = 0x04,
14217     R6_LUI = 0x04,
14218     AUI = 0x04,
14219     LBU32 = 0x05,
14220     SB32 = 0x06,
14221     LB32 = 0x07,
14222
14223     POOL32B = 0x08,
14224     POOL16B = 0x09,
14225     LHU16 = 0x0a,
14226     ANDI16 = 0x0b,
14227     ADDIU32 = 0x0c,
14228     LHU32 = 0x0d,
14229     SH32 = 0x0e,
14230     LH32 = 0x0f,
14231
14232     POOL32I = 0x10,
14233     POOL16C = 0x11,
14234     LWSP16 = 0x12,
14235     POOL16D = 0x13,
14236     ORI32 = 0x14,
14237     POOL32F = 0x15,
14238     POOL32S = 0x16,  /* MIPS64 */
14239     DADDIU32 = 0x17, /* MIPS64 */
14240
14241     POOL32C = 0x18,
14242     LWGP16 = 0x19,
14243     LW16 = 0x1a,
14244     POOL16E = 0x1b,
14245     XORI32 = 0x1c,
14246     JALS32 = 0x1d,
14247     BOVC = 0x1d,
14248     BEQC = 0x1d,
14249     BEQZALC = 0x1d,
14250     ADDIUPC = 0x1e,
14251     PCREL = 0x1e,
14252     BNVC = 0x1f,
14253     BNEC = 0x1f,
14254     BNEZALC = 0x1f,
14255
14256     R6_BEQZC = 0x20,
14257     JIC = 0x20,
14258     POOL16F = 0x21,
14259     SB16 = 0x22,
14260     BEQZ16 = 0x23,
14261     BEQZC16 = 0x23,
14262     SLTI32 = 0x24,
14263     BEQ32 = 0x25,
14264     BC = 0x25,
14265     SWC132 = 0x26,
14266     LWC132 = 0x27,
14267
14268     /* 0x29 is reserved */
14269     RES_29 = 0x29,
14270     R6_BNEZC = 0x28,
14271     JIALC = 0x28,
14272     SH16 = 0x2a,
14273     BNEZ16 = 0x2b,
14274     BNEZC16 = 0x2b,
14275     SLTIU32 = 0x2c,
14276     BNE32 = 0x2d,
14277     BALC = 0x2d,
14278     SDC132 = 0x2e,
14279     LDC132 = 0x2f,
14280
14281     /* 0x31 is reserved */
14282     RES_31 = 0x31,
14283     BLEZALC = 0x30,
14284     BGEZALC = 0x30,
14285     BGEUC = 0x30,
14286     SWSP16 = 0x32,
14287     B16 = 0x33,
14288     BC16 = 0x33,
14289     ANDI32 = 0x34,
14290     J32 = 0x35,
14291     BGTZC = 0x35,
14292     BLTZC = 0x35,
14293     BLTC = 0x35,
14294     SD32 = 0x36, /* MIPS64 */
14295     LD32 = 0x37, /* MIPS64 */
14296
14297     /* 0x39 is reserved */
14298     RES_39 = 0x39,
14299     BGTZALC = 0x38,
14300     BLTZALC = 0x38,
14301     BLTUC = 0x38,
14302     SW16 = 0x3a,
14303     LI16 = 0x3b,
14304     JALX32 = 0x3c,
14305     JAL32 = 0x3d,
14306     BLEZC = 0x3d,
14307     BGEZC = 0x3d,
14308     BGEC = 0x3d,
14309     SW32 = 0x3e,
14310     LW32 = 0x3f
14311 };
14312
14313 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14314 enum {
14315     ADDIUPC_00 = 0x00,
14316     ADDIUPC_01 = 0x01,
14317     ADDIUPC_02 = 0x02,
14318     ADDIUPC_03 = 0x03,
14319     ADDIUPC_04 = 0x04,
14320     ADDIUPC_05 = 0x05,
14321     ADDIUPC_06 = 0x06,
14322     ADDIUPC_07 = 0x07,
14323     AUIPC = 0x1e,
14324     ALUIPC = 0x1f,
14325     LWPC_08 = 0x08,
14326     LWPC_09 = 0x09,
14327     LWPC_0A = 0x0A,
14328     LWPC_0B = 0x0B,
14329     LWPC_0C = 0x0C,
14330     LWPC_0D = 0x0D,
14331     LWPC_0E = 0x0E,
14332     LWPC_0F = 0x0F,
14333 };
14334
14335 /* POOL32A encoding of minor opcode field */
14336
14337 enum {
14338     /* These opcodes are distinguished only by bits 9..6; those bits are
14339      * what are recorded below. */
14340     SLL32 = 0x0,
14341     SRL32 = 0x1,
14342     SRA = 0x2,
14343     ROTR = 0x3,
14344     SELEQZ = 0x5,
14345     SELNEZ = 0x6,
14346     R6_RDHWR = 0x7,
14347
14348     SLLV = 0x0,
14349     SRLV = 0x1,
14350     SRAV = 0x2,
14351     ROTRV = 0x3,
14352     ADD = 0x4,
14353     ADDU32 = 0x5,
14354     SUB = 0x6,
14355     SUBU32 = 0x7,
14356     MUL = 0x8,
14357     AND = 0x9,
14358     OR32 = 0xa,
14359     NOR = 0xb,
14360     XOR32 = 0xc,
14361     SLT = 0xd,
14362     SLTU = 0xe,
14363
14364     MOVN = 0x0,
14365     R6_MUL  = 0x0,
14366     MOVZ = 0x1,
14367     MUH  = 0x1,
14368     MULU = 0x2,
14369     MUHU = 0x3,
14370     LWXS = 0x4,
14371     R6_DIV  = 0x4,
14372     MOD  = 0x5,
14373     R6_DIVU = 0x6,
14374     MODU = 0x7,
14375
14376     /* The following can be distinguished by their lower 6 bits. */
14377     BREAK32 = 0x07,
14378     INS = 0x0c,
14379     LSA = 0x0f,
14380     ALIGN = 0x1f,
14381     EXT = 0x2c,
14382     POOL32AXF = 0x3c,
14383     SIGRIE = 0x3f
14384 };
14385
14386 /* POOL32AXF encoding of minor opcode field extension */
14387
14388 /*
14389  * 1. MIPS Architecture for Programmers Volume II-B:
14390  *      The microMIPS32 Instruction Set (Revision 3.05)
14391  *
14392  *    Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14393  *
14394  * 2. MIPS Architecture for Programmers VolumeIV-e:
14395  *      The MIPS DSP Application-Specific Extension
14396  *        to the microMIPS32 Architecture (Revision 2.34)
14397  *
14398  *    Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14399  */
14400
14401 enum {
14402     /* bits 11..6 */
14403     TEQ = 0x00,
14404     TGE = 0x08,
14405     TGEU = 0x10,
14406     TLT = 0x20,
14407     TLTU = 0x28,
14408     TNE = 0x30,
14409
14410     MFC0 = 0x03,
14411     MTC0 = 0x0b,
14412
14413     /* begin of microMIPS32 DSP */
14414
14415     /* bits 13..12 for 0x01 */
14416     MFHI_ACC = 0x0,
14417     MFLO_ACC = 0x1,
14418     MTHI_ACC = 0x2,
14419     MTLO_ACC = 0x3,
14420
14421     /* bits 13..12 for 0x2a */
14422     MADD_ACC = 0x0,
14423     MADDU_ACC = 0x1,
14424     MSUB_ACC = 0x2,
14425     MSUBU_ACC = 0x3,
14426
14427     /* bits 13..12 for 0x32 */
14428     MULT_ACC = 0x0,
14429     MULTU_ACC = 0x1,
14430
14431     /* end of microMIPS32 DSP */
14432
14433     /* bits 15..12 for 0x2c */
14434     BITSWAP = 0x0,
14435     SEB = 0x2,
14436     SEH = 0x3,
14437     CLO = 0x4,
14438     CLZ = 0x5,
14439     RDHWR = 0x6,
14440     WSBH = 0x7,
14441     MULT = 0x8,
14442     MULTU = 0x9,
14443     DIV = 0xa,
14444     DIVU = 0xb,
14445     MADD = 0xc,
14446     MADDU = 0xd,
14447     MSUB = 0xe,
14448     MSUBU = 0xf,
14449
14450     /* bits 15..12 for 0x34 */
14451     MFC2 = 0x4,
14452     MTC2 = 0x5,
14453     MFHC2 = 0x8,
14454     MTHC2 = 0x9,
14455     CFC2 = 0xc,
14456     CTC2 = 0xd,
14457
14458     /* bits 15..12 for 0x3c */
14459     JALR = 0x0,
14460     JR = 0x0,                   /* alias */
14461     JALRC = 0x0,
14462     JRC = 0x0,
14463     JALR_HB = 0x1,
14464     JALRC_HB = 0x1,
14465     JALRS = 0x4,
14466     JALRS_HB = 0x5,
14467
14468     /* bits 15..12 for 0x05 */
14469     RDPGPR = 0xe,
14470     WRPGPR = 0xf,
14471
14472     /* bits 15..12 for 0x0d */
14473     TLBP = 0x0,
14474     TLBR = 0x1,
14475     TLBWI = 0x2,
14476     TLBWR = 0x3,
14477     TLBINV = 0x4,
14478     TLBINVF = 0x5,
14479     WAIT = 0x9,
14480     IRET = 0xd,
14481     DERET = 0xe,
14482     ERET = 0xf,
14483
14484     /* bits 15..12 for 0x15 */
14485     DMT = 0x0,
14486     DVPE = 0x1,
14487     EMT = 0x2,
14488     EVPE = 0x3,
14489
14490     /* bits 15..12 for 0x1d */
14491     DI = 0x4,
14492     EI = 0x5,
14493
14494     /* bits 15..12 for 0x2d */
14495     SYNC = 0x6,
14496     SYSCALL = 0x8,
14497     SDBBP = 0xd,
14498
14499     /* bits 15..12 for 0x35 */
14500     MFHI32 = 0x0,
14501     MFLO32 = 0x1,
14502     MTHI32 = 0x2,
14503     MTLO32 = 0x3,
14504 };
14505
14506 /* POOL32B encoding of minor opcode field (bits 15..12) */
14507
14508 enum {
14509     LWC2 = 0x0,
14510     LWP = 0x1,
14511     LDP = 0x4,
14512     LWM32 = 0x5,
14513     CACHE = 0x6,
14514     LDM = 0x7,
14515     SWC2 = 0x8,
14516     SWP = 0x9,
14517     SDP = 0xc,
14518     SWM32 = 0xd,
14519     SDM = 0xf
14520 };
14521
14522 /* POOL32C encoding of minor opcode field (bits 15..12) */
14523
14524 enum {
14525     LWL = 0x0,
14526     SWL = 0x8,
14527     LWR = 0x1,
14528     SWR = 0x9,
14529     PREF = 0x2,
14530     ST_EVA = 0xa,
14531     LL = 0x3,
14532     SC = 0xb,
14533     LDL = 0x4,
14534     SDL = 0xc,
14535     LDR = 0x5,
14536     SDR = 0xd,
14537     LD_EVA = 0x6,
14538     LWU = 0xe,
14539     LLD = 0x7,
14540     SCD = 0xf
14541 };
14542
14543 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14544
14545 enum {
14546     LBUE = 0x0,
14547     LHUE = 0x1,
14548     LWLE = 0x2,
14549     LWRE = 0x3,
14550     LBE = 0x4,
14551     LHE = 0x5,
14552     LLE = 0x6,
14553     LWE = 0x7,
14554 };
14555
14556 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14557
14558 enum {
14559     SWLE = 0x0,
14560     SWRE = 0x1,
14561     PREFE = 0x2,
14562     CACHEE = 0x3,
14563     SBE = 0x4,
14564     SHE = 0x5,
14565     SCE = 0x6,
14566     SWE = 0x7,
14567 };
14568
14569 /* POOL32F encoding of minor opcode field (bits 5..0) */
14570
14571 enum {
14572     /* These are the bit 7..6 values */
14573     ADD_FMT = 0x0,
14574
14575     SUB_FMT = 0x1,
14576
14577     MUL_FMT = 0x2,
14578
14579     DIV_FMT = 0x3,
14580
14581     /* These are the bit 8..6 values */
14582     MOVN_FMT = 0x0,
14583     RSQRT2_FMT = 0x0,
14584     MOVF_FMT = 0x0,
14585     RINT_FMT = 0x0,
14586     SELNEZ_FMT = 0x0,
14587
14588     MOVZ_FMT = 0x1,
14589     LWXC1 = 0x1,
14590     MOVT_FMT = 0x1,
14591     CLASS_FMT = 0x1,
14592     SELEQZ_FMT = 0x1,
14593
14594     PLL_PS = 0x2,
14595     SWXC1 = 0x2,
14596     SEL_FMT = 0x2,
14597
14598     PLU_PS = 0x3,
14599     LDXC1 = 0x3,
14600
14601     MOVN_FMT_04 = 0x4,
14602     PUL_PS = 0x4,
14603     SDXC1 = 0x4,
14604     RECIP2_FMT = 0x4,
14605
14606     MOVZ_FMT_05 = 0x05,
14607     PUU_PS = 0x5,
14608     LUXC1 = 0x5,
14609
14610     CVT_PS_S = 0x6,
14611     SUXC1 = 0x6,
14612     ADDR_PS = 0x6,
14613     PREFX = 0x6,
14614     MADDF_FMT = 0x6,
14615
14616     MULR_PS = 0x7,
14617     MSUBF_FMT = 0x7,
14618
14619     MADD_S = 0x01,
14620     MADD_D = 0x09,
14621     MADD_PS = 0x11,
14622     ALNV_PS = 0x19,
14623     MSUB_S = 0x21,
14624     MSUB_D = 0x29,
14625     MSUB_PS = 0x31,
14626
14627     NMADD_S = 0x02,
14628     NMADD_D = 0x0a,
14629     NMADD_PS = 0x12,
14630     NMSUB_S = 0x22,
14631     NMSUB_D = 0x2a,
14632     NMSUB_PS = 0x32,
14633
14634     MIN_FMT = 0x3,
14635     MAX_FMT = 0xb,
14636     MINA_FMT = 0x23,
14637     MAXA_FMT = 0x2b,
14638     POOL32FXF = 0x3b,
14639
14640     CABS_COND_FMT = 0x1c,              /* MIPS3D */
14641     C_COND_FMT = 0x3c,
14642
14643     CMP_CONDN_S = 0x5,
14644     CMP_CONDN_D = 0x15
14645 };
14646
14647 /* POOL32Fxf encoding of minor opcode extension field */
14648
14649 enum {
14650     CVT_L = 0x04,
14651     RSQRT_FMT = 0x08,
14652     FLOOR_L = 0x0c,
14653     CVT_PW_PS = 0x1c,
14654     CVT_W = 0x24,
14655     SQRT_FMT = 0x28,
14656     FLOOR_W = 0x2c,
14657     CVT_PS_PW = 0x3c,
14658     CFC1 = 0x40,
14659     RECIP_FMT = 0x48,
14660     CEIL_L = 0x4c,
14661     CTC1 = 0x60,
14662     CEIL_W = 0x6c,
14663     MFC1 = 0x80,
14664     CVT_S_PL = 0x84,
14665     TRUNC_L = 0x8c,
14666     MTC1 = 0xa0,
14667     CVT_S_PU = 0xa4,
14668     TRUNC_W = 0xac,
14669     MFHC1 = 0xc0,
14670     ROUND_L = 0xcc,
14671     MTHC1 = 0xe0,
14672     ROUND_W = 0xec,
14673
14674     MOV_FMT = 0x01,
14675     MOVF = 0x05,
14676     ABS_FMT = 0x0d,
14677     RSQRT1_FMT = 0x1d,
14678     MOVT = 0x25,
14679     NEG_FMT = 0x2d,
14680     CVT_D = 0x4d,
14681     RECIP1_FMT = 0x5d,
14682     CVT_S = 0x6d
14683 };
14684
14685 /* POOL32I encoding of minor opcode field (bits 25..21) */
14686
14687 enum {
14688     BLTZ = 0x00,
14689     BLTZAL = 0x01,
14690     BGEZ = 0x02,
14691     BGEZAL = 0x03,
14692     BLEZ = 0x04,
14693     BNEZC = 0x05,
14694     BGTZ = 0x06,
14695     BEQZC = 0x07,
14696     TLTI = 0x08,
14697     BC1EQZC = 0x08,
14698     TGEI = 0x09,
14699     BC1NEZC = 0x09,
14700     TLTIU = 0x0a,
14701     BC2EQZC = 0x0a,
14702     TGEIU = 0x0b,
14703     BC2NEZC = 0x0a,
14704     TNEI = 0x0c,
14705     R6_SYNCI = 0x0c,
14706     LUI = 0x0d,
14707     TEQI = 0x0e,
14708     SYNCI = 0x10,
14709     BLTZALS = 0x11,
14710     BGEZALS = 0x13,
14711     BC2F = 0x14,
14712     BC2T = 0x15,
14713     BPOSGE64 = 0x1a,
14714     BPOSGE32 = 0x1b,
14715     /* These overlap and are distinguished by bit16 of the instruction */
14716     BC1F = 0x1c,
14717     BC1T = 0x1d,
14718     BC1ANY2F = 0x1c,
14719     BC1ANY2T = 0x1d,
14720     BC1ANY4F = 0x1e,
14721     BC1ANY4T = 0x1f
14722 };
14723
14724 /* POOL16A encoding of minor opcode field */
14725
14726 enum {
14727     ADDU16 = 0x0,
14728     SUBU16 = 0x1
14729 };
14730
14731 /* POOL16B encoding of minor opcode field */
14732
14733 enum {
14734     SLL16 = 0x0,
14735     SRL16 = 0x1
14736 };
14737
14738 /* POOL16C encoding of minor opcode field */
14739
14740 enum {
14741     NOT16 = 0x00,
14742     XOR16 = 0x04,
14743     AND16 = 0x08,
14744     OR16 = 0x0c,
14745     LWM16 = 0x10,
14746     SWM16 = 0x14,
14747     JR16 = 0x18,
14748     JRC16 = 0x1a,
14749     JALR16 = 0x1c,
14750     JALR16S = 0x1e,
14751     MFHI16 = 0x20,
14752     MFLO16 = 0x24,
14753     BREAK16 = 0x28,
14754     SDBBP16 = 0x2c,
14755     JRADDIUSP = 0x30
14756 };
14757
14758 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14759
14760 enum {
14761     R6_NOT16    = 0x00,
14762     R6_AND16    = 0x01,
14763     R6_LWM16    = 0x02,
14764     R6_JRC16    = 0x03,
14765     MOVEP       = 0x04,
14766     MOVEP_05    = 0x05,
14767     MOVEP_06    = 0x06,
14768     MOVEP_07    = 0x07,
14769     R6_XOR16    = 0x08,
14770     R6_OR16     = 0x09,
14771     R6_SWM16    = 0x0a,
14772     JALRC16     = 0x0b,
14773     MOVEP_0C    = 0x0c,
14774     MOVEP_0D    = 0x0d,
14775     MOVEP_0E    = 0x0e,
14776     MOVEP_0F    = 0x0f,
14777     JRCADDIUSP  = 0x13,
14778     R6_BREAK16  = 0x1b,
14779     R6_SDBBP16  = 0x3b
14780 };
14781
14782 /* POOL16D encoding of minor opcode field */
14783
14784 enum {
14785     ADDIUS5 = 0x0,
14786     ADDIUSP = 0x1
14787 };
14788
14789 /* POOL16E encoding of minor opcode field */
14790
14791 enum {
14792     ADDIUR2 = 0x0,
14793     ADDIUR1SP = 0x1
14794 };
14795
14796 static int mmreg (int r)
14797 {
14798     static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14799
14800     return map[r];
14801 }
14802
14803 /* Used for 16-bit store instructions.  */
14804 static int mmreg2 (int r)
14805 {
14806     static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14807
14808     return map[r];
14809 }
14810
14811 #define uMIPS_RD(op) ((op >> 7) & 0x7)
14812 #define uMIPS_RS(op) ((op >> 4) & 0x7)
14813 #define uMIPS_RS2(op) uMIPS_RS(op)
14814 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
14815 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14816 #define uMIPS_RS5(op) (op & 0x1f)
14817
14818 /* Signed immediate */
14819 #define SIMM(op, start, width)                                          \
14820     ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
14821                << (32-width))                                           \
14822      >> (32-width))
14823 /* Zero-extended immediate */
14824 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
14825
14826 static void gen_addiur1sp(DisasContext *ctx)
14827 {
14828     int rd = mmreg(uMIPS_RD(ctx->opcode));
14829
14830     gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
14831 }
14832
14833 static void gen_addiur2(DisasContext *ctx)
14834 {
14835     static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14836     int rd = mmreg(uMIPS_RD(ctx->opcode));
14837     int rs = mmreg(uMIPS_RS(ctx->opcode));
14838
14839     gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
14840 }
14841
14842 static void gen_addiusp(DisasContext *ctx)
14843 {
14844     int encoded = ZIMM(ctx->opcode, 1, 9);
14845     int decoded;
14846
14847     if (encoded <= 1) {
14848         decoded = 256 + encoded;
14849     } else if (encoded <= 255) {
14850         decoded = encoded;
14851     } else if (encoded <= 509) {
14852         decoded = encoded - 512;
14853     } else {
14854         decoded = encoded - 768;
14855     }
14856
14857     gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
14858 }
14859
14860 static void gen_addius5(DisasContext *ctx)
14861 {
14862     int imm = SIMM(ctx->opcode, 1, 4);
14863     int rd = (ctx->opcode >> 5) & 0x1f;
14864
14865     gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
14866 }
14867
14868 static void gen_andi16(DisasContext *ctx)
14869 {
14870     static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14871                                  31, 32, 63, 64, 255, 32768, 65535 };
14872     int rd = mmreg(uMIPS_RD(ctx->opcode));
14873     int rs = mmreg(uMIPS_RS(ctx->opcode));
14874     int encoded = ZIMM(ctx->opcode, 0, 4);
14875
14876     gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
14877 }
14878
14879 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
14880                                int base, int16_t offset)
14881 {
14882     TCGv t0, t1;
14883     TCGv_i32 t2;
14884
14885     if (ctx->hflags & MIPS_HFLAG_BMASK) {
14886         generate_exception_end(ctx, EXCP_RI);
14887         return;
14888     }
14889
14890     t0 = tcg_temp_new();
14891
14892     gen_base_offset_addr(ctx, t0, base, offset);
14893
14894     t1 = tcg_const_tl(reglist);
14895     t2 = tcg_const_i32(ctx->mem_idx);
14896
14897     save_cpu_state(ctx, 1);
14898     switch (opc) {
14899     case LWM32:
14900         gen_helper_lwm(cpu_env, t0, t1, t2);
14901         break;
14902     case SWM32:
14903         gen_helper_swm(cpu_env, t0, t1, t2);
14904         break;
14905 #ifdef TARGET_MIPS64
14906     case LDM:
14907         gen_helper_ldm(cpu_env, t0, t1, t2);
14908         break;
14909     case SDM:
14910         gen_helper_sdm(cpu_env, t0, t1, t2);
14911         break;
14912 #endif
14913     }
14914     tcg_temp_free(t0);
14915     tcg_temp_free(t1);
14916     tcg_temp_free_i32(t2);
14917 }
14918
14919
14920 static void gen_pool16c_insn(DisasContext *ctx)
14921 {
14922     int rd = mmreg((ctx->opcode >> 3) & 0x7);
14923     int rs = mmreg(ctx->opcode & 0x7);
14924
14925     switch (((ctx->opcode) >> 4) & 0x3f) {
14926     case NOT16 + 0:
14927     case NOT16 + 1:
14928     case NOT16 + 2:
14929     case NOT16 + 3:
14930         gen_logic(ctx, OPC_NOR, rd, rs, 0);
14931         break;
14932     case XOR16 + 0:
14933     case XOR16 + 1:
14934     case XOR16 + 2:
14935     case XOR16 + 3:
14936         gen_logic(ctx, OPC_XOR, rd, rd, rs);
14937         break;
14938     case AND16 + 0:
14939     case AND16 + 1:
14940     case AND16 + 2:
14941     case AND16 + 3:
14942         gen_logic(ctx, OPC_AND, rd, rd, rs);
14943         break;
14944     case OR16 + 0:
14945     case OR16 + 1:
14946     case OR16 + 2:
14947     case OR16 + 3:
14948         gen_logic(ctx, OPC_OR, rd, rd, rs);
14949         break;
14950     case LWM16 + 0:
14951     case LWM16 + 1:
14952     case LWM16 + 2:
14953     case LWM16 + 3:
14954         {
14955             static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14956             int offset = ZIMM(ctx->opcode, 0, 4);
14957
14958             gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14959                               29, offset << 2);
14960         }
14961         break;
14962     case SWM16 + 0:
14963     case SWM16 + 1:
14964     case SWM16 + 2:
14965     case SWM16 + 3:
14966         {
14967             static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14968             int offset = ZIMM(ctx->opcode, 0, 4);
14969
14970             gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
14971                               29, offset << 2);
14972         }
14973         break;
14974     case JR16 + 0:
14975     case JR16 + 1:
14976         {
14977             int reg = ctx->opcode & 0x1f;
14978
14979             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
14980         }
14981         break;
14982     case JRC16 + 0:
14983     case JRC16 + 1:
14984         {
14985             int reg = ctx->opcode & 0x1f;
14986             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
14987             /* Let normal delay slot handling in our caller take us
14988                to the branch target.  */
14989         }
14990         break;
14991     case JALR16 + 0:
14992     case JALR16 + 1:
14993         gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
14994         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14995         break;
14996     case JALR16S + 0:
14997     case JALR16S + 1:
14998         gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
14999         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15000         break;
15001     case MFHI16 + 0:
15002     case MFHI16 + 1:
15003         gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
15004         break;
15005     case MFLO16 + 0:
15006     case MFLO16 + 1:
15007         gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
15008         break;
15009     case BREAK16:
15010         generate_exception_end(ctx, EXCP_BREAK);
15011         break;
15012     case SDBBP16:
15013         if (is_uhi(extract32(ctx->opcode, 0, 4))) {
15014             gen_helper_do_semihosting(cpu_env);
15015         } else {
15016             /* XXX: not clear which exception should be raised
15017              *      when in debug mode...
15018              */
15019             check_insn(ctx, ISA_MIPS32);
15020             generate_exception_end(ctx, EXCP_DBp);
15021         }
15022         break;
15023     case JRADDIUSP + 0:
15024     case JRADDIUSP + 1:
15025         {
15026             int imm = ZIMM(ctx->opcode, 0, 5);
15027             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15028             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15029             /* Let normal delay slot handling in our caller take us
15030                to the branch target.  */
15031         }
15032         break;
15033     default:
15034         generate_exception_end(ctx, EXCP_RI);
15035         break;
15036     }
15037 }
15038
15039 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
15040                              int enc_rs)
15041 {
15042     int rd, rs, re, rt;
15043     static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15044     static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15045     static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15046     rd = rd_enc[enc_dest];
15047     re = re_enc[enc_dest];
15048     rs = rs_rt_enc[enc_rs];
15049     rt = rs_rt_enc[enc_rt];
15050     if (rs) {
15051         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
15052     } else {
15053         tcg_gen_movi_tl(cpu_gpr[rd], 0);
15054     }
15055     if (rt) {
15056         tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
15057     } else {
15058         tcg_gen_movi_tl(cpu_gpr[re], 0);
15059     }
15060 }
15061
15062 static void gen_pool16c_r6_insn(DisasContext *ctx)
15063 {
15064     int rt = mmreg((ctx->opcode >> 7) & 0x7);
15065     int rs = mmreg((ctx->opcode >> 4) & 0x7);
15066
15067     switch (ctx->opcode & 0xf) {
15068     case R6_NOT16:
15069         gen_logic(ctx, OPC_NOR, rt, rs, 0);
15070         break;
15071     case R6_AND16:
15072         gen_logic(ctx, OPC_AND, rt, rt, rs);
15073         break;
15074     case R6_LWM16:
15075         {
15076             int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15077             int offset = extract32(ctx->opcode, 4, 4);
15078             gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
15079         }
15080         break;
15081     case R6_JRC16: /* JRCADDIUSP */
15082         if ((ctx->opcode >> 4) & 1) {
15083             /* JRCADDIUSP */
15084             int imm = extract32(ctx->opcode, 5, 5);
15085             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15086             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15087         } else {
15088             /* JRC16 */
15089             rs = extract32(ctx->opcode, 5, 5);
15090             gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
15091         }
15092         break;
15093     case MOVEP:
15094     case MOVEP_05:
15095     case MOVEP_06:
15096     case MOVEP_07:
15097     case MOVEP_0C:
15098     case MOVEP_0D:
15099     case MOVEP_0E:
15100     case MOVEP_0F:
15101         {
15102             int enc_dest = uMIPS_RD(ctx->opcode);
15103             int enc_rt = uMIPS_RS2(ctx->opcode);
15104             int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
15105             gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15106         }
15107         break;
15108     case R6_XOR16:
15109         gen_logic(ctx, OPC_XOR, rt, rt, rs);
15110         break;
15111     case R6_OR16:
15112         gen_logic(ctx, OPC_OR, rt, rt, rs);
15113         break;
15114     case R6_SWM16:
15115         {
15116             int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15117             int offset = extract32(ctx->opcode, 4, 4);
15118             gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
15119         }
15120         break;
15121     case JALRC16: /* BREAK16, SDBBP16 */
15122         switch (ctx->opcode & 0x3f) {
15123         case JALRC16:
15124         case JALRC16 + 0x20:
15125             /* JALRC16 */
15126             gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
15127                                31, 0, 0);
15128             break;
15129         case R6_BREAK16:
15130             /* BREAK16 */
15131             generate_exception(ctx, EXCP_BREAK);
15132             break;
15133         case R6_SDBBP16:
15134             /* SDBBP16 */
15135             if (is_uhi(extract32(ctx->opcode, 6, 4))) {
15136                 gen_helper_do_semihosting(cpu_env);
15137             } else {
15138                 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15139                     generate_exception(ctx, EXCP_RI);
15140                 } else {
15141                     generate_exception(ctx, EXCP_DBp);
15142                 }
15143             }
15144             break;
15145         }
15146         break;
15147     default:
15148         generate_exception(ctx, EXCP_RI);
15149         break;
15150     }
15151 }
15152
15153 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
15154 {
15155     TCGv t0 = tcg_temp_new();
15156     TCGv t1 = tcg_temp_new();
15157
15158     gen_load_gpr(t0, base);
15159
15160     if (index != 0) {
15161         gen_load_gpr(t1, index);
15162         tcg_gen_shli_tl(t1, t1, 2);
15163         gen_op_addr_add(ctx, t0, t1, t0);
15164     }
15165
15166     tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15167     gen_store_gpr(t1, rd);
15168
15169     tcg_temp_free(t0);
15170     tcg_temp_free(t1);
15171 }
15172
15173 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
15174                            int base, int16_t offset)
15175 {
15176     TCGv t0, t1;
15177
15178     if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
15179         generate_exception_end(ctx, EXCP_RI);
15180         return;
15181     }
15182
15183     t0 = tcg_temp_new();
15184     t1 = tcg_temp_new();
15185
15186     gen_base_offset_addr(ctx, t0, base, offset);
15187
15188     switch (opc) {
15189     case LWP:
15190         if (rd == base) {
15191             generate_exception_end(ctx, EXCP_RI);
15192             return;
15193         }
15194         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15195         gen_store_gpr(t1, rd);
15196         tcg_gen_movi_tl(t1, 4);
15197         gen_op_addr_add(ctx, t0, t0, t1);
15198         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15199         gen_store_gpr(t1, rd+1);
15200         break;
15201     case SWP:
15202         gen_load_gpr(t1, rd);
15203         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15204         tcg_gen_movi_tl(t1, 4);
15205         gen_op_addr_add(ctx, t0, t0, t1);
15206         gen_load_gpr(t1, rd+1);
15207         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15208         break;
15209 #ifdef TARGET_MIPS64
15210     case LDP:
15211         if (rd == base) {
15212             generate_exception_end(ctx, EXCP_RI);
15213             return;
15214         }
15215         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15216         gen_store_gpr(t1, rd);
15217         tcg_gen_movi_tl(t1, 8);
15218         gen_op_addr_add(ctx, t0, t0, t1);
15219         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15220         gen_store_gpr(t1, rd+1);
15221         break;
15222     case SDP:
15223         gen_load_gpr(t1, rd);
15224         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15225         tcg_gen_movi_tl(t1, 8);
15226         gen_op_addr_add(ctx, t0, t0, t1);
15227         gen_load_gpr(t1, rd+1);
15228         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15229         break;
15230 #endif
15231     }
15232     tcg_temp_free(t0);
15233     tcg_temp_free(t1);
15234 }
15235
15236 static void gen_sync(int stype)
15237 {
15238     TCGBar tcg_mo = TCG_BAR_SC;
15239
15240     switch (stype) {
15241     case 0x4: /* SYNC_WMB */
15242         tcg_mo |= TCG_MO_ST_ST;
15243         break;
15244     case 0x10: /* SYNC_MB */
15245         tcg_mo |= TCG_MO_ALL;
15246         break;
15247     case 0x11: /* SYNC_ACQUIRE */
15248         tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
15249         break;
15250     case 0x12: /* SYNC_RELEASE */
15251         tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
15252         break;
15253     case 0x13: /* SYNC_RMB */
15254         tcg_mo |= TCG_MO_LD_LD;
15255         break;
15256     default:
15257         tcg_mo |= TCG_MO_ALL;
15258         break;
15259     }
15260
15261     tcg_gen_mb(tcg_mo);
15262 }
15263
15264 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
15265 {
15266     int extension = (ctx->opcode >> 6) & 0x3f;
15267     int minor = (ctx->opcode >> 12) & 0xf;
15268     uint32_t mips32_op;
15269
15270     switch (extension) {
15271     case TEQ:
15272         mips32_op = OPC_TEQ;
15273         goto do_trap;
15274     case TGE:
15275         mips32_op = OPC_TGE;
15276         goto do_trap;
15277     case TGEU:
15278         mips32_op = OPC_TGEU;
15279         goto do_trap;
15280     case TLT:
15281         mips32_op = OPC_TLT;
15282         goto do_trap;
15283     case TLTU:
15284         mips32_op = OPC_TLTU;
15285         goto do_trap;
15286     case TNE:
15287         mips32_op = OPC_TNE;
15288     do_trap:
15289         gen_trap(ctx, mips32_op, rs, rt, -1);
15290         break;
15291 #ifndef CONFIG_USER_ONLY
15292     case MFC0:
15293     case MFC0 + 32:
15294         check_cp0_enabled(ctx);
15295         if (rt == 0) {
15296             /* Treat as NOP. */
15297             break;
15298         }
15299         gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
15300         break;
15301     case MTC0:
15302     case MTC0 + 32:
15303         check_cp0_enabled(ctx);
15304         {
15305             TCGv t0 = tcg_temp_new();
15306
15307             gen_load_gpr(t0, rt);
15308             gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
15309             tcg_temp_free(t0);
15310         }
15311         break;
15312 #endif
15313     case 0x2a:
15314         switch (minor & 3) {
15315         case MADD_ACC:
15316             gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
15317             break;
15318         case MADDU_ACC:
15319             gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
15320             break;
15321         case MSUB_ACC:
15322             gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
15323             break;
15324         case MSUBU_ACC:
15325             gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
15326             break;
15327         default:
15328             goto pool32axf_invalid;
15329         }
15330         break;
15331     case 0x32:
15332         switch (minor & 3) {
15333         case MULT_ACC:
15334             gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
15335             break;
15336         case MULTU_ACC:
15337             gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
15338             break;
15339         default:
15340             goto pool32axf_invalid;
15341         }
15342         break;
15343     case 0x2c:
15344         switch (minor) {
15345         case BITSWAP:
15346             check_insn(ctx, ISA_MIPS32R6);
15347             gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
15348             break;
15349         case SEB:
15350             gen_bshfl(ctx, OPC_SEB, rs, rt);
15351             break;
15352         case SEH:
15353             gen_bshfl(ctx, OPC_SEH, rs, rt);
15354             break;
15355         case CLO:
15356             mips32_op = OPC_CLO;
15357             goto do_cl;
15358         case CLZ:
15359             mips32_op = OPC_CLZ;
15360         do_cl:
15361             check_insn(ctx, ISA_MIPS32);
15362             gen_cl(ctx, mips32_op, rt, rs);
15363             break;
15364         case RDHWR:
15365             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15366             gen_rdhwr(ctx, rt, rs, 0);
15367             break;
15368         case WSBH:
15369             gen_bshfl(ctx, OPC_WSBH, rs, rt);
15370             break;
15371         case MULT:
15372             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15373             mips32_op = OPC_MULT;
15374             goto do_mul;
15375         case MULTU:
15376             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15377             mips32_op = OPC_MULTU;
15378             goto do_mul;
15379         case DIV:
15380             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15381             mips32_op = OPC_DIV;
15382             goto do_div;
15383         case DIVU:
15384             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15385             mips32_op = OPC_DIVU;
15386             goto do_div;
15387         do_div:
15388             check_insn(ctx, ISA_MIPS32);
15389             gen_muldiv(ctx, mips32_op, 0, rs, rt);
15390             break;
15391         case MADD:
15392             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15393             mips32_op = OPC_MADD;
15394             goto do_mul;
15395         case MADDU:
15396             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15397             mips32_op = OPC_MADDU;
15398             goto do_mul;
15399         case MSUB:
15400             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15401             mips32_op = OPC_MSUB;
15402             goto do_mul;
15403         case MSUBU:
15404             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15405             mips32_op = OPC_MSUBU;
15406         do_mul:
15407             check_insn(ctx, ISA_MIPS32);
15408             gen_muldiv(ctx, mips32_op, 0, rs, rt);
15409             break;
15410         default:
15411             goto pool32axf_invalid;
15412         }
15413         break;
15414     case 0x34:
15415         switch (minor) {
15416         case MFC2:
15417         case MTC2:
15418         case MFHC2:
15419         case MTHC2:
15420         case CFC2:
15421         case CTC2:
15422             generate_exception_err(ctx, EXCP_CpU, 2);
15423             break;
15424         default:
15425             goto pool32axf_invalid;
15426         }
15427         break;
15428     case 0x3c:
15429         switch (minor) {
15430         case JALR:    /* JALRC */
15431         case JALR_HB: /* JALRC_HB */
15432             if (ctx->insn_flags & ISA_MIPS32R6) {
15433                 /* JALRC, JALRC_HB */
15434                 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15435             } else {
15436                 /* JALR, JALR_HB */
15437                 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15438                 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15439             }
15440             break;
15441         case JALRS:
15442         case JALRS_HB:
15443             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15444             gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15445             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15446             break;
15447         default:
15448             goto pool32axf_invalid;
15449         }
15450         break;
15451     case 0x05:
15452         switch (minor) {
15453         case RDPGPR:
15454             check_cp0_enabled(ctx);
15455             check_insn(ctx, ISA_MIPS32R2);
15456             gen_load_srsgpr(rs, rt);
15457             break;
15458         case WRPGPR:
15459             check_cp0_enabled(ctx);
15460             check_insn(ctx, ISA_MIPS32R2);
15461             gen_store_srsgpr(rs, rt);
15462             break;
15463         default:
15464             goto pool32axf_invalid;
15465         }
15466         break;
15467 #ifndef CONFIG_USER_ONLY
15468     case 0x0d:
15469         switch (minor) {
15470         case TLBP:
15471             mips32_op = OPC_TLBP;
15472             goto do_cp0;
15473         case TLBR:
15474             mips32_op = OPC_TLBR;
15475             goto do_cp0;
15476         case TLBWI:
15477             mips32_op = OPC_TLBWI;
15478             goto do_cp0;
15479         case TLBWR:
15480             mips32_op = OPC_TLBWR;
15481             goto do_cp0;
15482         case TLBINV:
15483             mips32_op = OPC_TLBINV;
15484             goto do_cp0;
15485         case TLBINVF:
15486             mips32_op = OPC_TLBINVF;
15487             goto do_cp0;
15488         case WAIT:
15489             mips32_op = OPC_WAIT;
15490             goto do_cp0;
15491         case DERET:
15492             mips32_op = OPC_DERET;
15493             goto do_cp0;
15494         case ERET:
15495             mips32_op = OPC_ERET;
15496         do_cp0:
15497             gen_cp0(env, ctx, mips32_op, rt, rs);
15498             break;
15499         default:
15500             goto pool32axf_invalid;
15501         }
15502         break;
15503     case 0x1d:
15504         switch (minor) {
15505         case DI:
15506             check_cp0_enabled(ctx);
15507             {
15508                 TCGv t0 = tcg_temp_new();
15509
15510                 save_cpu_state(ctx, 1);
15511                 gen_helper_di(t0, cpu_env);
15512                 gen_store_gpr(t0, rs);
15513                 /* Stop translation as we may have switched the execution mode */
15514                 ctx->base.is_jmp = DISAS_STOP;
15515                 tcg_temp_free(t0);
15516             }
15517             break;
15518         case EI:
15519             check_cp0_enabled(ctx);
15520             {
15521                 TCGv t0 = tcg_temp_new();
15522
15523                 save_cpu_state(ctx, 1);
15524                 gen_helper_ei(t0, cpu_env);
15525                 gen_store_gpr(t0, rs);
15526                 /* DISAS_STOP isn't sufficient, we need to ensure we break out
15527                    of translated code to check for pending interrupts.  */
15528                 gen_save_pc(ctx->base.pc_next + 4);
15529                 ctx->base.is_jmp = DISAS_EXIT;
15530                 tcg_temp_free(t0);
15531             }
15532             break;
15533         default:
15534             goto pool32axf_invalid;
15535         }
15536         break;
15537 #endif
15538     case 0x2d:
15539         switch (minor) {
15540         case SYNC:
15541             gen_sync(extract32(ctx->opcode, 16, 5));
15542             break;
15543         case SYSCALL:
15544             generate_exception_end(ctx, EXCP_SYSCALL);
15545             break;
15546         case SDBBP:
15547             if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15548                 gen_helper_do_semihosting(cpu_env);
15549             } else {
15550                 check_insn(ctx, ISA_MIPS32);
15551                 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15552                     generate_exception_end(ctx, EXCP_RI);
15553                 } else {
15554                     generate_exception_end(ctx, EXCP_DBp);
15555                 }
15556             }
15557             break;
15558         default:
15559             goto pool32axf_invalid;
15560         }
15561         break;
15562     case 0x01:
15563         switch (minor & 3) {
15564         case MFHI_ACC:
15565             gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
15566             break;
15567         case MFLO_ACC:
15568             gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
15569             break;
15570         case MTHI_ACC:
15571             gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
15572             break;
15573         case MTLO_ACC:
15574             gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
15575             break;
15576         default:
15577             goto pool32axf_invalid;
15578         }
15579         break;
15580     case 0x35:
15581         check_insn_opc_removed(ctx, ISA_MIPS32R6);
15582         switch (minor) {
15583         case MFHI32:
15584             gen_HILO(ctx, OPC_MFHI, 0, rs);
15585             break;
15586         case MFLO32:
15587             gen_HILO(ctx, OPC_MFLO, 0, rs);
15588             break;
15589         case MTHI32:
15590             gen_HILO(ctx, OPC_MTHI, 0, rs);
15591             break;
15592         case MTLO32:
15593             gen_HILO(ctx, OPC_MTLO, 0, rs);
15594             break;
15595         default:
15596             goto pool32axf_invalid;
15597         }
15598         break;
15599     default:
15600     pool32axf_invalid:
15601         MIPS_INVAL("pool32axf");
15602         generate_exception_end(ctx, EXCP_RI);
15603         break;
15604     }
15605 }
15606
15607 /* Values for microMIPS fmt field.  Variable-width, depending on which
15608    formats the instruction supports.  */
15609
15610 enum {
15611     FMT_SD_S = 0,
15612     FMT_SD_D = 1,
15613
15614     FMT_SDPS_S = 0,
15615     FMT_SDPS_D = 1,
15616     FMT_SDPS_PS = 2,
15617
15618     FMT_SWL_S = 0,
15619     FMT_SWL_W = 1,
15620     FMT_SWL_L = 2,
15621
15622     FMT_DWL_D = 0,
15623     FMT_DWL_W = 1,
15624     FMT_DWL_L = 2
15625 };
15626
15627 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
15628 {
15629     int extension = (ctx->opcode >> 6) & 0x3ff;
15630     uint32_t mips32_op;
15631
15632 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
15633 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
15634 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
15635
15636     switch (extension) {
15637     case FLOAT_1BIT_FMT(CFC1, 0):
15638         mips32_op = OPC_CFC1;
15639         goto do_cp1;
15640     case FLOAT_1BIT_FMT(CTC1, 0):
15641         mips32_op = OPC_CTC1;
15642         goto do_cp1;
15643     case FLOAT_1BIT_FMT(MFC1, 0):
15644         mips32_op = OPC_MFC1;
15645         goto do_cp1;
15646     case FLOAT_1BIT_FMT(MTC1, 0):
15647         mips32_op = OPC_MTC1;
15648         goto do_cp1;
15649     case FLOAT_1BIT_FMT(MFHC1, 0):
15650         mips32_op = OPC_MFHC1;
15651         goto do_cp1;
15652     case FLOAT_1BIT_FMT(MTHC1, 0):
15653         mips32_op = OPC_MTHC1;
15654     do_cp1:
15655         gen_cp1(ctx, mips32_op, rt, rs);
15656         break;
15657
15658         /* Reciprocal square root */
15659     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15660         mips32_op = OPC_RSQRT_S;
15661         goto do_unaryfp;
15662     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15663         mips32_op = OPC_RSQRT_D;
15664         goto do_unaryfp;
15665
15666         /* Square root */
15667     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15668         mips32_op = OPC_SQRT_S;
15669         goto do_unaryfp;
15670     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15671         mips32_op = OPC_SQRT_D;
15672         goto do_unaryfp;
15673
15674         /* Reciprocal */
15675     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15676         mips32_op = OPC_RECIP_S;
15677         goto do_unaryfp;
15678     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15679         mips32_op = OPC_RECIP_D;
15680         goto do_unaryfp;
15681
15682         /* Floor */
15683     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15684         mips32_op = OPC_FLOOR_L_S;
15685         goto do_unaryfp;
15686     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15687         mips32_op = OPC_FLOOR_L_D;
15688         goto do_unaryfp;
15689     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15690         mips32_op = OPC_FLOOR_W_S;
15691         goto do_unaryfp;
15692     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15693         mips32_op = OPC_FLOOR_W_D;
15694         goto do_unaryfp;
15695
15696         /* Ceiling */
15697     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15698         mips32_op = OPC_CEIL_L_S;
15699         goto do_unaryfp;
15700     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
15701         mips32_op = OPC_CEIL_L_D;
15702         goto do_unaryfp;
15703     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
15704         mips32_op = OPC_CEIL_W_S;
15705         goto do_unaryfp;
15706     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
15707         mips32_op = OPC_CEIL_W_D;
15708         goto do_unaryfp;
15709
15710         /* Truncation */
15711     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
15712         mips32_op = OPC_TRUNC_L_S;
15713         goto do_unaryfp;
15714     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
15715         mips32_op = OPC_TRUNC_L_D;
15716         goto do_unaryfp;
15717     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
15718         mips32_op = OPC_TRUNC_W_S;
15719         goto do_unaryfp;
15720     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
15721         mips32_op = OPC_TRUNC_W_D;
15722         goto do_unaryfp;
15723
15724         /* Round */
15725     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
15726         mips32_op = OPC_ROUND_L_S;
15727         goto do_unaryfp;
15728     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
15729         mips32_op = OPC_ROUND_L_D;
15730         goto do_unaryfp;
15731     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
15732         mips32_op = OPC_ROUND_W_S;
15733         goto do_unaryfp;
15734     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
15735         mips32_op = OPC_ROUND_W_D;
15736         goto do_unaryfp;
15737
15738         /* Integer to floating-point conversion */
15739     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
15740         mips32_op = OPC_CVT_L_S;
15741         goto do_unaryfp;
15742     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
15743         mips32_op = OPC_CVT_L_D;
15744         goto do_unaryfp;
15745     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
15746         mips32_op = OPC_CVT_W_S;
15747         goto do_unaryfp;
15748     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
15749         mips32_op = OPC_CVT_W_D;
15750         goto do_unaryfp;
15751
15752         /* Paired-foo conversions */
15753     case FLOAT_1BIT_FMT(CVT_S_PL, 0):
15754         mips32_op = OPC_CVT_S_PL;
15755         goto do_unaryfp;
15756     case FLOAT_1BIT_FMT(CVT_S_PU, 0):
15757         mips32_op = OPC_CVT_S_PU;
15758         goto do_unaryfp;
15759     case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
15760         mips32_op = OPC_CVT_PW_PS;
15761         goto do_unaryfp;
15762     case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
15763         mips32_op = OPC_CVT_PS_PW;
15764         goto do_unaryfp;
15765
15766         /* Floating-point moves */
15767     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
15768         mips32_op = OPC_MOV_S;
15769         goto do_unaryfp;
15770     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
15771         mips32_op = OPC_MOV_D;
15772         goto do_unaryfp;
15773     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
15774         mips32_op = OPC_MOV_PS;
15775         goto do_unaryfp;
15776
15777         /* Absolute value */
15778     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
15779         mips32_op = OPC_ABS_S;
15780         goto do_unaryfp;
15781     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
15782         mips32_op = OPC_ABS_D;
15783         goto do_unaryfp;
15784     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
15785         mips32_op = OPC_ABS_PS;
15786         goto do_unaryfp;
15787
15788         /* Negation */
15789     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
15790         mips32_op = OPC_NEG_S;
15791         goto do_unaryfp;
15792     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
15793         mips32_op = OPC_NEG_D;
15794         goto do_unaryfp;
15795     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
15796         mips32_op = OPC_NEG_PS;
15797         goto do_unaryfp;
15798
15799         /* Reciprocal square root step */
15800     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
15801         mips32_op = OPC_RSQRT1_S;
15802         goto do_unaryfp;
15803     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
15804         mips32_op = OPC_RSQRT1_D;
15805         goto do_unaryfp;
15806     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
15807         mips32_op = OPC_RSQRT1_PS;
15808         goto do_unaryfp;
15809
15810         /* Reciprocal step */
15811     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
15812         mips32_op = OPC_RECIP1_S;
15813         goto do_unaryfp;
15814     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
15815         mips32_op = OPC_RECIP1_S;
15816         goto do_unaryfp;
15817     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
15818         mips32_op = OPC_RECIP1_PS;
15819         goto do_unaryfp;
15820
15821         /* Conversions from double */
15822     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
15823         mips32_op = OPC_CVT_D_S;
15824         goto do_unaryfp;
15825     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
15826         mips32_op = OPC_CVT_D_W;
15827         goto do_unaryfp;
15828     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
15829         mips32_op = OPC_CVT_D_L;
15830         goto do_unaryfp;
15831
15832         /* Conversions from single */
15833     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
15834         mips32_op = OPC_CVT_S_D;
15835         goto do_unaryfp;
15836     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
15837         mips32_op = OPC_CVT_S_W;
15838         goto do_unaryfp;
15839     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
15840         mips32_op = OPC_CVT_S_L;
15841     do_unaryfp:
15842         gen_farith(ctx, mips32_op, -1, rs, rt, 0);
15843         break;
15844
15845         /* Conditional moves on floating-point codes */
15846     case COND_FLOAT_MOV(MOVT, 0):
15847     case COND_FLOAT_MOV(MOVT, 1):
15848     case COND_FLOAT_MOV(MOVT, 2):
15849     case COND_FLOAT_MOV(MOVT, 3):
15850     case COND_FLOAT_MOV(MOVT, 4):
15851     case COND_FLOAT_MOV(MOVT, 5):
15852     case COND_FLOAT_MOV(MOVT, 6):
15853     case COND_FLOAT_MOV(MOVT, 7):
15854         check_insn_opc_removed(ctx, ISA_MIPS32R6);
15855         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
15856         break;
15857     case COND_FLOAT_MOV(MOVF, 0):
15858     case COND_FLOAT_MOV(MOVF, 1):
15859     case COND_FLOAT_MOV(MOVF, 2):
15860     case COND_FLOAT_MOV(MOVF, 3):
15861     case COND_FLOAT_MOV(MOVF, 4):
15862     case COND_FLOAT_MOV(MOVF, 5):
15863     case COND_FLOAT_MOV(MOVF, 6):
15864     case COND_FLOAT_MOV(MOVF, 7):
15865         check_insn_opc_removed(ctx, ISA_MIPS32R6);
15866         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
15867         break;
15868     default:
15869         MIPS_INVAL("pool32fxf");
15870         generate_exception_end(ctx, EXCP_RI);
15871         break;
15872     }
15873 }
15874
15875 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
15876 {
15877     int32_t offset;
15878     uint16_t insn;
15879     int rt, rs, rd, rr;
15880     int16_t imm;
15881     uint32_t op, minor, minor2, mips32_op;
15882     uint32_t cond, fmt, cc;
15883
15884     insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
15885     ctx->opcode = (ctx->opcode << 16) | insn;
15886
15887     rt = (ctx->opcode >> 21) & 0x1f;
15888     rs = (ctx->opcode >> 16) & 0x1f;
15889     rd = (ctx->opcode >> 11) & 0x1f;
15890     rr = (ctx->opcode >> 6) & 0x1f;
15891     imm = (int16_t) ctx->opcode;
15892
15893     op = (ctx->opcode >> 26) & 0x3f;
15894     switch (op) {
15895     case POOL32A:
15896         minor = ctx->opcode & 0x3f;
15897         switch (minor) {
15898         case 0x00:
15899             minor = (ctx->opcode >> 6) & 0xf;
15900             switch (minor) {
15901             case SLL32:
15902                 mips32_op = OPC_SLL;
15903                 goto do_shifti;
15904             case SRA:
15905                 mips32_op = OPC_SRA;
15906                 goto do_shifti;
15907             case SRL32:
15908                 mips32_op = OPC_SRL;
15909                 goto do_shifti;
15910             case ROTR:
15911                 mips32_op = OPC_ROTR;
15912             do_shifti:
15913                 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
15914                 break;
15915             case SELEQZ:
15916                 check_insn(ctx, ISA_MIPS32R6);
15917                 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
15918                 break;
15919             case SELNEZ:
15920                 check_insn(ctx, ISA_MIPS32R6);
15921                 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
15922                 break;
15923             case R6_RDHWR:
15924                 check_insn(ctx, ISA_MIPS32R6);
15925                 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
15926                 break;
15927             default:
15928                 goto pool32a_invalid;
15929             }
15930             break;
15931         case 0x10:
15932             minor = (ctx->opcode >> 6) & 0xf;
15933             switch (minor) {
15934                 /* Arithmetic */
15935             case ADD:
15936                 mips32_op = OPC_ADD;
15937                 goto do_arith;
15938             case ADDU32:
15939                 mips32_op = OPC_ADDU;
15940                 goto do_arith;
15941             case SUB:
15942                 mips32_op = OPC_SUB;
15943                 goto do_arith;
15944             case SUBU32:
15945                 mips32_op = OPC_SUBU;
15946                 goto do_arith;
15947             case MUL:
15948                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15949                 mips32_op = OPC_MUL;
15950             do_arith:
15951                 gen_arith(ctx, mips32_op, rd, rs, rt);
15952                 break;
15953                 /* Shifts */
15954             case SLLV:
15955                 mips32_op = OPC_SLLV;
15956                 goto do_shift;
15957             case SRLV:
15958                 mips32_op = OPC_SRLV;
15959                 goto do_shift;
15960             case SRAV:
15961                 mips32_op = OPC_SRAV;
15962                 goto do_shift;
15963             case ROTRV:
15964                 mips32_op = OPC_ROTRV;
15965             do_shift:
15966                 gen_shift(ctx, mips32_op, rd, rs, rt);
15967                 break;
15968                 /* Logical operations */
15969             case AND:
15970                 mips32_op = OPC_AND;
15971                 goto do_logic;
15972             case OR32:
15973                 mips32_op = OPC_OR;
15974                 goto do_logic;
15975             case NOR:
15976                 mips32_op = OPC_NOR;
15977                 goto do_logic;
15978             case XOR32:
15979                 mips32_op = OPC_XOR;
15980             do_logic:
15981                 gen_logic(ctx, mips32_op, rd, rs, rt);
15982                 break;
15983                 /* Set less than */
15984             case SLT:
15985                 mips32_op = OPC_SLT;
15986                 goto do_slt;
15987             case SLTU:
15988                 mips32_op = OPC_SLTU;
15989             do_slt:
15990                 gen_slt(ctx, mips32_op, rd, rs, rt);
15991                 break;
15992             default:
15993                 goto pool32a_invalid;
15994             }
15995             break;
15996         case 0x18:
15997             minor = (ctx->opcode >> 6) & 0xf;
15998             switch (minor) {
15999                 /* Conditional moves */
16000             case MOVN: /* MUL */
16001                 if (ctx->insn_flags & ISA_MIPS32R6) {
16002                     /* MUL */
16003                     gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
16004                 } else {
16005                     /* MOVN */
16006                     gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
16007                 }
16008                 break;
16009             case MOVZ: /* MUH */
16010                 if (ctx->insn_flags & ISA_MIPS32R6) {
16011                     /* MUH */
16012                     gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
16013                 } else {
16014                     /* MOVZ */
16015                     gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
16016                 }
16017                 break;
16018             case MULU:
16019                 check_insn(ctx, ISA_MIPS32R6);
16020                 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
16021                 break;
16022             case MUHU:
16023                 check_insn(ctx, ISA_MIPS32R6);
16024                 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
16025                 break;
16026             case LWXS: /* DIV */
16027                 if (ctx->insn_flags & ISA_MIPS32R6) {
16028                     /* DIV */
16029                     gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
16030                 } else {
16031                     /* LWXS */
16032                     gen_ldxs(ctx, rs, rt, rd);
16033                 }
16034                 break;
16035             case MOD:
16036                 check_insn(ctx, ISA_MIPS32R6);
16037                 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
16038                 break;
16039             case R6_DIVU:
16040                 check_insn(ctx, ISA_MIPS32R6);
16041                 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
16042                 break;
16043             case MODU:
16044                 check_insn(ctx, ISA_MIPS32R6);
16045                 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
16046                 break;
16047             default:
16048                 goto pool32a_invalid;
16049             }
16050             break;
16051         case INS:
16052             gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
16053             return;
16054         case LSA:
16055             check_insn(ctx, ISA_MIPS32R6);
16056             gen_lsa(ctx, OPC_LSA, rd, rs, rt,
16057                     extract32(ctx->opcode, 9, 2));
16058             break;
16059         case ALIGN:
16060             check_insn(ctx, ISA_MIPS32R6);
16061             gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
16062             break;
16063         case EXT:
16064             gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
16065             return;
16066         case POOL32AXF:
16067             gen_pool32axf(env, ctx, rt, rs);
16068             break;
16069         case BREAK32:
16070             generate_exception_end(ctx, EXCP_BREAK);
16071             break;
16072         case SIGRIE:
16073             check_insn(ctx, ISA_MIPS32R6);
16074             generate_exception_end(ctx, EXCP_RI);
16075             break;
16076         default:
16077         pool32a_invalid:
16078                 MIPS_INVAL("pool32a");
16079                 generate_exception_end(ctx, EXCP_RI);
16080                 break;
16081         }
16082         break;
16083     case POOL32B:
16084         minor = (ctx->opcode >> 12) & 0xf;
16085         switch (minor) {
16086         case CACHE:
16087             check_cp0_enabled(ctx);
16088             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16089                 gen_cache_operation(ctx, rt, rs, imm);
16090             }
16091             break;
16092         case LWC2:
16093         case SWC2:
16094             /* COP2: Not implemented. */
16095             generate_exception_err(ctx, EXCP_CpU, 2);
16096             break;
16097 #ifdef TARGET_MIPS64
16098         case LDP:
16099         case SDP:
16100             check_insn(ctx, ISA_MIPS3);
16101             check_mips_64(ctx);
16102 #endif
16103             /* fall through */
16104         case LWP:
16105         case SWP:
16106             gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16107             break;
16108 #ifdef TARGET_MIPS64
16109         case LDM:
16110         case SDM:
16111             check_insn(ctx, ISA_MIPS3);
16112             check_mips_64(ctx);
16113 #endif
16114             /* fall through */
16115         case LWM32:
16116         case SWM32:
16117             gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16118             break;
16119         default:
16120             MIPS_INVAL("pool32b");
16121             generate_exception_end(ctx, EXCP_RI);
16122             break;
16123         }
16124         break;
16125     case POOL32F:
16126         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
16127             minor = ctx->opcode & 0x3f;
16128             check_cp1_enabled(ctx);
16129             switch (minor) {
16130             case ALNV_PS:
16131                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16132                 mips32_op = OPC_ALNV_PS;
16133                 goto do_madd;
16134             case MADD_S:
16135                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16136                 mips32_op = OPC_MADD_S;
16137                 goto do_madd;
16138             case MADD_D:
16139                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16140                 mips32_op = OPC_MADD_D;
16141                 goto do_madd;
16142             case MADD_PS:
16143                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16144                 mips32_op = OPC_MADD_PS;
16145                 goto do_madd;
16146             case MSUB_S:
16147                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16148                 mips32_op = OPC_MSUB_S;
16149                 goto do_madd;
16150             case MSUB_D:
16151                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16152                 mips32_op = OPC_MSUB_D;
16153                 goto do_madd;
16154             case MSUB_PS:
16155                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16156                 mips32_op = OPC_MSUB_PS;
16157                 goto do_madd;
16158             case NMADD_S:
16159                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16160                 mips32_op = OPC_NMADD_S;
16161                 goto do_madd;
16162             case NMADD_D:
16163                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16164                 mips32_op = OPC_NMADD_D;
16165                 goto do_madd;
16166             case NMADD_PS:
16167                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16168                 mips32_op = OPC_NMADD_PS;
16169                 goto do_madd;
16170             case NMSUB_S:
16171                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16172                 mips32_op = OPC_NMSUB_S;
16173                 goto do_madd;
16174             case NMSUB_D:
16175                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16176                 mips32_op = OPC_NMSUB_D;
16177                 goto do_madd;
16178             case NMSUB_PS:
16179                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16180                 mips32_op = OPC_NMSUB_PS;
16181             do_madd:
16182                 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
16183                 break;
16184             case CABS_COND_FMT:
16185                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16186                 cond = (ctx->opcode >> 6) & 0xf;
16187                 cc = (ctx->opcode >> 13) & 0x7;
16188                 fmt = (ctx->opcode >> 10) & 0x3;
16189                 switch (fmt) {
16190                 case 0x0:
16191                     gen_cmpabs_s(ctx, cond, rt, rs, cc);
16192                     break;
16193                 case 0x1:
16194                     gen_cmpabs_d(ctx, cond, rt, rs, cc);
16195                     break;
16196                 case 0x2:
16197                     gen_cmpabs_ps(ctx, cond, rt, rs, cc);
16198                     break;
16199                 default:
16200                     goto pool32f_invalid;
16201                 }
16202                 break;
16203             case C_COND_FMT:
16204                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16205                 cond = (ctx->opcode >> 6) & 0xf;
16206                 cc = (ctx->opcode >> 13) & 0x7;
16207                 fmt = (ctx->opcode >> 10) & 0x3;
16208                 switch (fmt) {
16209                 case 0x0:
16210                     gen_cmp_s(ctx, cond, rt, rs, cc);
16211                     break;
16212                 case 0x1:
16213                     gen_cmp_d(ctx, cond, rt, rs, cc);
16214                     break;
16215                 case 0x2:
16216                     gen_cmp_ps(ctx, cond, rt, rs, cc);
16217                     break;
16218                 default:
16219                     goto pool32f_invalid;
16220                 }
16221                 break;
16222             case CMP_CONDN_S:
16223                 check_insn(ctx, ISA_MIPS32R6);
16224                 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16225                 break;
16226             case CMP_CONDN_D:
16227                 check_insn(ctx, ISA_MIPS32R6);
16228                 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16229                 break;
16230             case POOL32FXF:
16231                 gen_pool32fxf(ctx, rt, rs);
16232                 break;
16233             case 0x00:
16234                 /* PLL foo */
16235                 switch ((ctx->opcode >> 6) & 0x7) {
16236                 case PLL_PS:
16237                     mips32_op = OPC_PLL_PS;
16238                     goto do_ps;
16239                 case PLU_PS:
16240                     mips32_op = OPC_PLU_PS;
16241                     goto do_ps;
16242                 case PUL_PS:
16243                     mips32_op = OPC_PUL_PS;
16244                     goto do_ps;
16245                 case PUU_PS:
16246                     mips32_op = OPC_PUU_PS;
16247                     goto do_ps;
16248                 case CVT_PS_S:
16249                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16250                     mips32_op = OPC_CVT_PS_S;
16251                 do_ps:
16252                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16253                     break;
16254                 default:
16255                     goto pool32f_invalid;
16256                 }
16257                 break;
16258             case MIN_FMT:
16259                 check_insn(ctx, ISA_MIPS32R6);
16260                 switch ((ctx->opcode >> 9) & 0x3) {
16261                 case FMT_SDPS_S:
16262                     gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
16263                     break;
16264                 case FMT_SDPS_D:
16265                     gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
16266                     break;
16267                 default:
16268                     goto pool32f_invalid;
16269                 }
16270                 break;
16271             case 0x08:
16272                 /* [LS][WDU]XC1 */
16273                 switch ((ctx->opcode >> 6) & 0x7) {
16274                 case LWXC1:
16275                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16276                     mips32_op = OPC_LWXC1;
16277                     goto do_ldst_cp1;
16278                 case SWXC1:
16279                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16280                     mips32_op = OPC_SWXC1;
16281                     goto do_ldst_cp1;
16282                 case LDXC1:
16283                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16284                     mips32_op = OPC_LDXC1;
16285                     goto do_ldst_cp1;
16286                 case SDXC1:
16287                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16288                     mips32_op = OPC_SDXC1;
16289                     goto do_ldst_cp1;
16290                 case LUXC1:
16291                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16292                     mips32_op = OPC_LUXC1;
16293                     goto do_ldst_cp1;
16294                 case SUXC1:
16295                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16296                     mips32_op = OPC_SUXC1;
16297                 do_ldst_cp1:
16298                     gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
16299                     break;
16300                 default:
16301                     goto pool32f_invalid;
16302                 }
16303                 break;
16304             case MAX_FMT:
16305                 check_insn(ctx, ISA_MIPS32R6);
16306                 switch ((ctx->opcode >> 9) & 0x3) {
16307                 case FMT_SDPS_S:
16308                     gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
16309                     break;
16310                 case FMT_SDPS_D:
16311                     gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
16312                     break;
16313                 default:
16314                     goto pool32f_invalid;
16315                 }
16316                 break;
16317             case 0x18:
16318                 /* 3D insns */
16319                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16320                 fmt = (ctx->opcode >> 9) & 0x3;
16321                 switch ((ctx->opcode >> 6) & 0x7) {
16322                 case RSQRT2_FMT:
16323                     switch (fmt) {
16324                     case FMT_SDPS_S:
16325                         mips32_op = OPC_RSQRT2_S;
16326                         goto do_3d;
16327                     case FMT_SDPS_D:
16328                         mips32_op = OPC_RSQRT2_D;
16329                         goto do_3d;
16330                     case FMT_SDPS_PS:
16331                         mips32_op = OPC_RSQRT2_PS;
16332                         goto do_3d;
16333                     default:
16334                         goto pool32f_invalid;
16335                     }
16336                     break;
16337                 case RECIP2_FMT:
16338                     switch (fmt) {
16339                     case FMT_SDPS_S:
16340                         mips32_op = OPC_RECIP2_S;
16341                         goto do_3d;
16342                     case FMT_SDPS_D:
16343                         mips32_op = OPC_RECIP2_D;
16344                         goto do_3d;
16345                     case FMT_SDPS_PS:
16346                         mips32_op = OPC_RECIP2_PS;
16347                         goto do_3d;
16348                     default:
16349                         goto pool32f_invalid;
16350                     }
16351                     break;
16352                 case ADDR_PS:
16353                     mips32_op = OPC_ADDR_PS;
16354                     goto do_3d;
16355                 case MULR_PS:
16356                     mips32_op = OPC_MULR_PS;
16357                 do_3d:
16358                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16359                     break;
16360                 default:
16361                     goto pool32f_invalid;
16362                 }
16363                 break;
16364             case 0x20:
16365                 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16366                 cc = (ctx->opcode >> 13) & 0x7;
16367                 fmt = (ctx->opcode >> 9) & 0x3;
16368                 switch ((ctx->opcode >> 6) & 0x7) {
16369                 case MOVF_FMT: /* RINT_FMT */
16370                     if (ctx->insn_flags & ISA_MIPS32R6) {
16371                         /* RINT_FMT */
16372                         switch (fmt) {
16373                         case FMT_SDPS_S:
16374                             gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
16375                             break;
16376                         case FMT_SDPS_D:
16377                             gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
16378                             break;
16379                         default:
16380                             goto pool32f_invalid;
16381                         }
16382                     } else {
16383                         /* MOVF_FMT */
16384                         switch (fmt) {
16385                         case FMT_SDPS_S:
16386                             gen_movcf_s(ctx, rs, rt, cc, 0);
16387                             break;
16388                         case FMT_SDPS_D:
16389                             gen_movcf_d(ctx, rs, rt, cc, 0);
16390                             break;
16391                         case FMT_SDPS_PS:
16392                             check_ps(ctx);
16393                             gen_movcf_ps(ctx, rs, rt, cc, 0);
16394                             break;
16395                         default:
16396                             goto pool32f_invalid;
16397                         }
16398                     }
16399                     break;
16400                 case MOVT_FMT: /* CLASS_FMT */
16401                     if (ctx->insn_flags & ISA_MIPS32R6) {
16402                         /* CLASS_FMT */
16403                         switch (fmt) {
16404                         case FMT_SDPS_S:
16405                             gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
16406                             break;
16407                         case FMT_SDPS_D:
16408                             gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
16409                             break;
16410                         default:
16411                             goto pool32f_invalid;
16412                         }
16413                     } else {
16414                         /* MOVT_FMT */
16415                         switch (fmt) {
16416                         case FMT_SDPS_S:
16417                             gen_movcf_s(ctx, rs, rt, cc, 1);
16418                             break;
16419                         case FMT_SDPS_D:
16420                             gen_movcf_d(ctx, rs, rt, cc, 1);
16421                             break;
16422                         case FMT_SDPS_PS:
16423                             check_ps(ctx);
16424                             gen_movcf_ps(ctx, rs, rt, cc, 1);
16425                             break;
16426                         default:
16427                             goto pool32f_invalid;
16428                         }
16429                     }
16430                     break;
16431                 case PREFX:
16432                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16433                     break;
16434                 default:
16435                     goto pool32f_invalid;
16436                 }
16437                 break;
16438 #define FINSN_3ARG_SDPS(prfx)                           \
16439                 switch ((ctx->opcode >> 8) & 0x3) {     \
16440                 case FMT_SDPS_S:                        \
16441                     mips32_op = OPC_##prfx##_S;         \
16442                     goto do_fpop;                       \
16443                 case FMT_SDPS_D:                        \
16444                     mips32_op = OPC_##prfx##_D;         \
16445                     goto do_fpop;                       \
16446                 case FMT_SDPS_PS:                       \
16447                     check_ps(ctx);                      \
16448                     mips32_op = OPC_##prfx##_PS;        \
16449                     goto do_fpop;                       \
16450                 default:                                \
16451                     goto pool32f_invalid;               \
16452                 }
16453             case MINA_FMT:
16454                 check_insn(ctx, ISA_MIPS32R6);
16455                 switch ((ctx->opcode >> 9) & 0x3) {
16456                 case FMT_SDPS_S:
16457                     gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16458                     break;
16459                 case FMT_SDPS_D:
16460                     gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16461                     break;
16462                 default:
16463                     goto pool32f_invalid;
16464                 }
16465                 break;
16466             case MAXA_FMT:
16467                 check_insn(ctx, ISA_MIPS32R6);
16468                 switch ((ctx->opcode >> 9) & 0x3) {
16469                 case FMT_SDPS_S:
16470                     gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16471                     break;
16472                 case FMT_SDPS_D:
16473                     gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16474                     break;
16475                 default:
16476                     goto pool32f_invalid;
16477                 }
16478                 break;
16479             case 0x30:
16480                 /* regular FP ops */
16481                 switch ((ctx->opcode >> 6) & 0x3) {
16482                 case ADD_FMT:
16483                     FINSN_3ARG_SDPS(ADD);
16484                     break;
16485                 case SUB_FMT:
16486                     FINSN_3ARG_SDPS(SUB);
16487                     break;
16488                 case MUL_FMT:
16489                     FINSN_3ARG_SDPS(MUL);
16490                     break;
16491                 case DIV_FMT:
16492                     fmt = (ctx->opcode >> 8) & 0x3;
16493                     if (fmt == 1) {
16494                         mips32_op = OPC_DIV_D;
16495                     } else if (fmt == 0) {
16496                         mips32_op = OPC_DIV_S;
16497                     } else {
16498                         goto pool32f_invalid;
16499                     }
16500                     goto do_fpop;
16501                 default:
16502                     goto pool32f_invalid;
16503                 }
16504                 break;
16505             case 0x38:
16506                 /* cmovs */
16507                 switch ((ctx->opcode >> 6) & 0x7) {
16508                 case MOVN_FMT: /* SELEQZ_FMT */
16509                     if (ctx->insn_flags & ISA_MIPS32R6) {
16510                         /* SELEQZ_FMT */
16511                         switch ((ctx->opcode >> 9) & 0x3) {
16512                         case FMT_SDPS_S:
16513                             gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
16514                             break;
16515                         case FMT_SDPS_D:
16516                             gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
16517                             break;
16518                         default:
16519                             goto pool32f_invalid;
16520                         }
16521                     } else {
16522                         /* MOVN_FMT */
16523                         FINSN_3ARG_SDPS(MOVN);
16524                     }
16525                     break;
16526                 case MOVN_FMT_04:
16527                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16528                     FINSN_3ARG_SDPS(MOVN);
16529                     break;
16530                 case MOVZ_FMT: /* SELNEZ_FMT */
16531                     if (ctx->insn_flags & ISA_MIPS32R6) {
16532                         /* SELNEZ_FMT */
16533                         switch ((ctx->opcode >> 9) & 0x3) {
16534                         case FMT_SDPS_S:
16535                             gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
16536                             break;
16537                         case FMT_SDPS_D:
16538                             gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
16539                             break;
16540                         default:
16541                             goto pool32f_invalid;
16542                         }
16543                     } else {
16544                         /* MOVZ_FMT */
16545                         FINSN_3ARG_SDPS(MOVZ);
16546                     }
16547                     break;
16548                 case MOVZ_FMT_05:
16549                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16550                     FINSN_3ARG_SDPS(MOVZ);
16551                     break;
16552                 case SEL_FMT:
16553                     check_insn(ctx, ISA_MIPS32R6);
16554                     switch ((ctx->opcode >> 9) & 0x3) {
16555                     case FMT_SDPS_S:
16556                         gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16557                         break;
16558                     case FMT_SDPS_D:
16559                         gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16560                         break;
16561                     default:
16562                         goto pool32f_invalid;
16563                     }
16564                     break;
16565                 case MADDF_FMT:
16566                     check_insn(ctx, ISA_MIPS32R6);
16567                     switch ((ctx->opcode >> 9) & 0x3) {
16568                     case FMT_SDPS_S:
16569                         mips32_op = OPC_MADDF_S;
16570                         goto do_fpop;
16571                     case FMT_SDPS_D:
16572                         mips32_op = OPC_MADDF_D;
16573                         goto do_fpop;
16574                     default:
16575                         goto pool32f_invalid;
16576                     }
16577                     break;
16578                 case MSUBF_FMT:
16579                     check_insn(ctx, ISA_MIPS32R6);
16580                     switch ((ctx->opcode >> 9) & 0x3) {
16581                     case FMT_SDPS_S:
16582                         mips32_op = OPC_MSUBF_S;
16583                         goto do_fpop;
16584                     case FMT_SDPS_D:
16585                         mips32_op = OPC_MSUBF_D;
16586                         goto do_fpop;
16587                     default:
16588                         goto pool32f_invalid;
16589                     }
16590                     break;
16591                 default:
16592                     goto pool32f_invalid;
16593                 }
16594                 break;
16595             do_fpop:
16596                 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16597                 break;
16598             default:
16599             pool32f_invalid:
16600                 MIPS_INVAL("pool32f");
16601                 generate_exception_end(ctx, EXCP_RI);
16602                 break;
16603             }
16604         } else {
16605             generate_exception_err(ctx, EXCP_CpU, 1);
16606         }
16607         break;
16608     case POOL32I:
16609         minor = (ctx->opcode >> 21) & 0x1f;
16610         switch (minor) {
16611         case BLTZ:
16612             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16613             gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
16614             break;
16615         case BLTZAL:
16616             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16617             gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
16618             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16619             break;
16620         case BLTZALS:
16621             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16622             gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
16623             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16624             break;
16625         case BGEZ:
16626             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16627             gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
16628             break;
16629         case BGEZAL:
16630             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16631             gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
16632             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16633             break;
16634         case BGEZALS:
16635             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16636             gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16637             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16638             break;
16639         case BLEZ:
16640             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16641             gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16642             break;
16643         case BGTZ:
16644             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16645             gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
16646             break;
16647
16648             /* Traps */
16649         case TLTI: /* BC1EQZC */
16650             if (ctx->insn_flags & ISA_MIPS32R6) {
16651                 /* BC1EQZC */
16652                 check_cp1_enabled(ctx);
16653                 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16654             } else {
16655                 /* TLTI */
16656                 mips32_op = OPC_TLTI;
16657                 goto do_trapi;
16658             }
16659             break;
16660         case TGEI: /* BC1NEZC */
16661             if (ctx->insn_flags & ISA_MIPS32R6) {
16662                 /* BC1NEZC */
16663                 check_cp1_enabled(ctx);
16664                 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16665             } else {
16666                 /* TGEI */
16667                 mips32_op = OPC_TGEI;
16668                 goto do_trapi;
16669             }
16670             break;
16671         case TLTIU:
16672             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16673             mips32_op = OPC_TLTIU;
16674             goto do_trapi;
16675         case TGEIU:
16676             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16677             mips32_op = OPC_TGEIU;
16678             goto do_trapi;
16679         case TNEI: /* SYNCI */
16680             if (ctx->insn_flags & ISA_MIPS32R6) {
16681                 /* SYNCI */
16682                 /* Break the TB to be able to sync copied instructions
16683                    immediately */
16684                 ctx->base.is_jmp = DISAS_STOP;
16685             } else {
16686                 /* TNEI */
16687                 mips32_op = OPC_TNEI;
16688                 goto do_trapi;
16689             }
16690             break;
16691         case TEQI:
16692             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16693             mips32_op = OPC_TEQI;
16694         do_trapi:
16695             gen_trap(ctx, mips32_op, rs, -1, imm);
16696             break;
16697
16698         case BNEZC:
16699         case BEQZC:
16700             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16701             gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
16702                                4, rs, 0, imm << 1, 0);
16703             /* Compact branches don't have a delay slot, so just let
16704                the normal delay slot handling take us to the branch
16705                target. */
16706             break;
16707         case LUI:
16708             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16709             gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
16710             break;
16711         case SYNCI:
16712             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16713             /* Break the TB to be able to sync copied instructions
16714                immediately */
16715             ctx->base.is_jmp = DISAS_STOP;
16716             break;
16717         case BC2F:
16718         case BC2T:
16719             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16720             /* COP2: Not implemented. */
16721             generate_exception_err(ctx, EXCP_CpU, 2);
16722             break;
16723         case BC1F:
16724             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16725             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
16726             goto do_cp1branch;
16727         case BC1T:
16728             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16729             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
16730             goto do_cp1branch;
16731         case BC1ANY4F:
16732             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16733             mips32_op = OPC_BC1FANY4;
16734             goto do_cp1mips3d;
16735         case BC1ANY4T:
16736             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16737             mips32_op = OPC_BC1TANY4;
16738         do_cp1mips3d:
16739             check_cop1x(ctx);
16740             check_insn(ctx, ASE_MIPS3D);
16741             /* Fall through */
16742         do_cp1branch:
16743             if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16744                 check_cp1_enabled(ctx);
16745                 gen_compute_branch1(ctx, mips32_op,
16746                                     (ctx->opcode >> 18) & 0x7, imm << 1);
16747             } else {
16748                 generate_exception_err(ctx, EXCP_CpU, 1);
16749             }
16750             break;
16751         case BPOSGE64:
16752         case BPOSGE32:
16753             /* MIPS DSP: not implemented */
16754             /* Fall through */
16755         default:
16756             MIPS_INVAL("pool32i");
16757             generate_exception_end(ctx, EXCP_RI);
16758             break;
16759         }
16760         break;
16761     case POOL32C:
16762         minor = (ctx->opcode >> 12) & 0xf;
16763         offset = sextract32(ctx->opcode, 0,
16764                             (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
16765         switch (minor) {
16766         case LWL:
16767             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16768             mips32_op = OPC_LWL;
16769             goto do_ld_lr;
16770         case SWL:
16771             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16772             mips32_op = OPC_SWL;
16773             goto do_st_lr;
16774         case LWR:
16775             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16776             mips32_op = OPC_LWR;
16777             goto do_ld_lr;
16778         case SWR:
16779             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16780             mips32_op = OPC_SWR;
16781             goto do_st_lr;
16782 #if defined(TARGET_MIPS64)
16783         case LDL:
16784             check_insn(ctx, ISA_MIPS3);
16785             check_mips_64(ctx);
16786             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16787             mips32_op = OPC_LDL;
16788             goto do_ld_lr;
16789         case SDL:
16790             check_insn(ctx, ISA_MIPS3);
16791             check_mips_64(ctx);
16792             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16793             mips32_op = OPC_SDL;
16794             goto do_st_lr;
16795         case LDR:
16796             check_insn(ctx, ISA_MIPS3);
16797             check_mips_64(ctx);
16798             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16799             mips32_op = OPC_LDR;
16800             goto do_ld_lr;
16801         case SDR:
16802             check_insn(ctx, ISA_MIPS3);
16803             check_mips_64(ctx);
16804             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16805             mips32_op = OPC_SDR;
16806             goto do_st_lr;
16807         case LWU:
16808             check_insn(ctx, ISA_MIPS3);
16809             check_mips_64(ctx);
16810             mips32_op = OPC_LWU;
16811             goto do_ld_lr;
16812         case LLD:
16813             check_insn(ctx, ISA_MIPS3);
16814             check_mips_64(ctx);
16815             mips32_op = OPC_LLD;
16816             goto do_ld_lr;
16817 #endif
16818         case LL:
16819             mips32_op = OPC_LL;
16820             goto do_ld_lr;
16821         do_ld_lr:
16822             gen_ld(ctx, mips32_op, rt, rs, offset);
16823             break;
16824         do_st_lr:
16825             gen_st(ctx, mips32_op, rt, rs, offset);
16826             break;
16827         case SC:
16828             gen_st_cond(ctx, rt, rs, offset, MO_TESL, false);
16829             break;
16830 #if defined(TARGET_MIPS64)
16831         case SCD:
16832             check_insn(ctx, ISA_MIPS3);
16833             check_mips_64(ctx);
16834             gen_st_cond(ctx, rt, rs, offset, MO_TEQ, false);
16835             break;
16836 #endif
16837         case LD_EVA:
16838             if (!ctx->eva) {
16839                 MIPS_INVAL("pool32c ld-eva");
16840                 generate_exception_end(ctx, EXCP_RI);
16841                 break;
16842             }
16843             check_cp0_enabled(ctx);
16844
16845             minor2 = (ctx->opcode >> 9) & 0x7;
16846             offset = sextract32(ctx->opcode, 0, 9);
16847             switch (minor2) {
16848             case LBUE:
16849                 mips32_op = OPC_LBUE;
16850                 goto do_ld_lr;
16851             case LHUE:
16852                 mips32_op = OPC_LHUE;
16853                 goto do_ld_lr;
16854             case LWLE:
16855                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16856                 mips32_op = OPC_LWLE;
16857                 goto do_ld_lr;
16858             case LWRE:
16859                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16860                 mips32_op = OPC_LWRE;
16861                 goto do_ld_lr;
16862             case LBE:
16863                 mips32_op = OPC_LBE;
16864                 goto do_ld_lr;
16865             case LHE:
16866                 mips32_op = OPC_LHE;
16867                 goto do_ld_lr;
16868             case LLE:
16869                 mips32_op = OPC_LLE;
16870                 goto do_ld_lr;
16871             case LWE:
16872                 mips32_op = OPC_LWE;
16873                 goto do_ld_lr;
16874             };
16875             break;
16876         case ST_EVA:
16877             if (!ctx->eva) {
16878                 MIPS_INVAL("pool32c st-eva");
16879                 generate_exception_end(ctx, EXCP_RI);
16880                 break;
16881             }
16882             check_cp0_enabled(ctx);
16883
16884             minor2 = (ctx->opcode >> 9) & 0x7;
16885             offset = sextract32(ctx->opcode, 0, 9);
16886             switch (minor2) {
16887             case SWLE:
16888                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16889                 mips32_op = OPC_SWLE;
16890                 goto do_st_lr;
16891             case SWRE:
16892                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16893                 mips32_op = OPC_SWRE;
16894                 goto do_st_lr;
16895             case PREFE:
16896                 /* Treat as no-op */
16897                 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16898                     /* hint codes 24-31 are reserved and signal RI */
16899                     generate_exception(ctx, EXCP_RI);
16900                 }
16901                 break;
16902             case CACHEE:
16903                 /* Treat as no-op */
16904                 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16905                     gen_cache_operation(ctx, rt, rs, offset);
16906                 }
16907                 break;
16908             case SBE:
16909                 mips32_op = OPC_SBE;
16910                 goto do_st_lr;
16911             case SHE:
16912                 mips32_op = OPC_SHE;
16913                 goto do_st_lr;
16914             case SCE:
16915                 gen_st_cond(ctx, rt, rs, offset, MO_TESL, true);
16916                 break;
16917             case SWE:
16918                 mips32_op = OPC_SWE;
16919                 goto do_st_lr;
16920             };
16921             break;
16922         case PREF:
16923             /* Treat as no-op */
16924             if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16925                 /* hint codes 24-31 are reserved and signal RI */
16926                 generate_exception(ctx, EXCP_RI);
16927             }
16928             break;
16929         default:
16930             MIPS_INVAL("pool32c");
16931             generate_exception_end(ctx, EXCP_RI);
16932             break;
16933         }
16934         break;
16935     case ADDI32: /* AUI, LUI */
16936         if (ctx->insn_flags & ISA_MIPS32R6) {
16937             /* AUI, LUI */
16938             gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
16939         } else {
16940             /* ADDI32 */
16941             mips32_op = OPC_ADDI;
16942             goto do_addi;
16943         }
16944         break;
16945     case ADDIU32:
16946         mips32_op = OPC_ADDIU;
16947     do_addi:
16948         gen_arith_imm(ctx, mips32_op, rt, rs, imm);
16949         break;
16950
16951         /* Logical operations */
16952     case ORI32:
16953         mips32_op = OPC_ORI;
16954         goto do_logici;
16955     case XORI32:
16956         mips32_op = OPC_XORI;
16957         goto do_logici;
16958     case ANDI32:
16959         mips32_op = OPC_ANDI;
16960     do_logici:
16961         gen_logic_imm(ctx, mips32_op, rt, rs, imm);
16962         break;
16963
16964         /* Set less than immediate */
16965     case SLTI32:
16966         mips32_op = OPC_SLTI;
16967         goto do_slti;
16968     case SLTIU32:
16969         mips32_op = OPC_SLTIU;
16970     do_slti:
16971         gen_slt_imm(ctx, mips32_op, rt, rs, imm);
16972         break;
16973     case JALX32:
16974         check_insn_opc_removed(ctx, ISA_MIPS32R6);
16975         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
16976         gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
16977         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16978         break;
16979     case JALS32: /* BOVC, BEQC, BEQZALC */
16980         if (ctx->insn_flags & ISA_MIPS32R6) {
16981             if (rs >= rt) {
16982                 /* BOVC */
16983                 mips32_op = OPC_BOVC;
16984             } else if (rs < rt && rs == 0) {
16985                 /* BEQZALC */
16986                 mips32_op = OPC_BEQZALC;
16987             } else {
16988                 /* BEQC */
16989                 mips32_op = OPC_BEQC;
16990             }
16991             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16992         } else {
16993             /* JALS32 */
16994             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
16995             gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
16996             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16997         }
16998         break;
16999     case BEQ32: /* BC */
17000         if (ctx->insn_flags & ISA_MIPS32R6) {
17001             /* BC */
17002             gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
17003                                        sextract32(ctx->opcode << 1, 0, 27));
17004         } else {
17005             /* BEQ32 */
17006             gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
17007         }
17008         break;
17009     case BNE32: /* BALC */
17010         if (ctx->insn_flags & ISA_MIPS32R6) {
17011             /* BALC */
17012             gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
17013                                        sextract32(ctx->opcode << 1, 0, 27));
17014         } else {
17015             /* BNE32 */
17016             gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
17017         }
17018         break;
17019     case J32: /* BGTZC, BLTZC, BLTC */
17020         if (ctx->insn_flags & ISA_MIPS32R6) {
17021             if (rs == 0 && rt != 0) {
17022                 /* BGTZC */
17023                 mips32_op = OPC_BGTZC;
17024             } else if (rs != 0 && rt != 0 && rs == rt) {
17025                 /* BLTZC */
17026                 mips32_op = OPC_BLTZC;
17027             } else {
17028                 /* BLTC */
17029                 mips32_op = OPC_BLTC;
17030             }
17031             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17032         } else {
17033             /* J32 */
17034             gen_compute_branch(ctx, OPC_J, 4, rt, rs,
17035                                (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17036         }
17037         break;
17038     case JAL32: /* BLEZC, BGEZC, BGEC */
17039         if (ctx->insn_flags & ISA_MIPS32R6) {
17040             if (rs == 0 && rt != 0) {
17041                 /* BLEZC */
17042                 mips32_op = OPC_BLEZC;
17043             } else if (rs != 0 && rt != 0 && rs == rt) {
17044                 /* BGEZC */
17045                 mips32_op = OPC_BGEZC;
17046             } else {
17047                 /* BGEC */
17048                 mips32_op = OPC_BGEC;
17049             }
17050             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17051         } else {
17052             /* JAL32 */
17053             gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
17054                                (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17055             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17056         }
17057         break;
17058         /* Floating point (COP1) */
17059     case LWC132:
17060         mips32_op = OPC_LWC1;
17061         goto do_cop1;
17062     case LDC132:
17063         mips32_op = OPC_LDC1;
17064         goto do_cop1;
17065     case SWC132:
17066         mips32_op = OPC_SWC1;
17067         goto do_cop1;
17068     case SDC132:
17069         mips32_op = OPC_SDC1;
17070     do_cop1:
17071         gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
17072         break;
17073     case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17074         if (ctx->insn_flags & ISA_MIPS32R6) {
17075             /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17076             switch ((ctx->opcode >> 16) & 0x1f) {
17077             case ADDIUPC_00:
17078             case ADDIUPC_01:
17079             case ADDIUPC_02:
17080             case ADDIUPC_03:
17081             case ADDIUPC_04:
17082             case ADDIUPC_05:
17083             case ADDIUPC_06:
17084             case ADDIUPC_07:
17085                 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
17086                 break;
17087             case AUIPC:
17088                 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
17089                 break;
17090             case ALUIPC:
17091                 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
17092                 break;
17093             case LWPC_08:
17094             case LWPC_09:
17095             case LWPC_0A:
17096             case LWPC_0B:
17097             case LWPC_0C:
17098             case LWPC_0D:
17099             case LWPC_0E:
17100             case LWPC_0F:
17101                 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
17102                 break;
17103             default:
17104                 generate_exception(ctx, EXCP_RI);
17105                 break;
17106             }
17107         } else {
17108             /* ADDIUPC */
17109             int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
17110             offset = SIMM(ctx->opcode, 0, 23) << 2;
17111
17112             gen_addiupc(ctx, reg, offset, 0, 0);
17113         }
17114         break;
17115     case BNVC: /* BNEC, BNEZALC */
17116         check_insn(ctx, ISA_MIPS32R6);
17117         if (rs >= rt) {
17118             /* BNVC */
17119             mips32_op = OPC_BNVC;
17120         } else if (rs < rt && rs == 0) {
17121             /* BNEZALC */
17122             mips32_op = OPC_BNEZALC;
17123         } else {
17124             /* BNEC */
17125             mips32_op = OPC_BNEC;
17126         }
17127         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17128         break;
17129     case R6_BNEZC: /* JIALC */
17130         check_insn(ctx, ISA_MIPS32R6);
17131         if (rt != 0) {
17132             /* BNEZC */
17133             gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
17134                                        sextract32(ctx->opcode << 1, 0, 22));
17135         } else {
17136             /* JIALC */
17137             gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
17138         }
17139         break;
17140     case R6_BEQZC: /* JIC */
17141         check_insn(ctx, ISA_MIPS32R6);
17142         if (rt != 0) {
17143             /* BEQZC */
17144             gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
17145                                        sextract32(ctx->opcode << 1, 0, 22));
17146         } else {
17147             /* JIC */
17148             gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
17149         }
17150         break;
17151     case BLEZALC: /* BGEZALC, BGEUC */
17152         check_insn(ctx, ISA_MIPS32R6);
17153         if (rs == 0 && rt != 0) {
17154             /* BLEZALC */
17155             mips32_op = OPC_BLEZALC;
17156         } else if (rs != 0 && rt != 0 && rs == rt) {
17157             /* BGEZALC */
17158             mips32_op = OPC_BGEZALC;
17159         } else {
17160             /* BGEUC */
17161             mips32_op = OPC_BGEUC;
17162         }
17163         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17164         break;
17165     case BGTZALC: /* BLTZALC, BLTUC */
17166         check_insn(ctx, ISA_MIPS32R6);
17167         if (rs == 0 && rt != 0) {
17168             /* BGTZALC */
17169             mips32_op = OPC_BGTZALC;
17170         } else if (rs != 0 && rt != 0 && rs == rt) {
17171             /* BLTZALC */
17172             mips32_op = OPC_BLTZALC;
17173         } else {
17174             /* BLTUC */
17175             mips32_op = OPC_BLTUC;
17176         }
17177         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17178         break;
17179         /* Loads and stores */
17180     case LB32:
17181         mips32_op = OPC_LB;
17182         goto do_ld;
17183     case LBU32:
17184         mips32_op = OPC_LBU;
17185         goto do_ld;
17186     case LH32:
17187         mips32_op = OPC_LH;
17188         goto do_ld;
17189     case LHU32:
17190         mips32_op = OPC_LHU;
17191         goto do_ld;
17192     case LW32:
17193         mips32_op = OPC_LW;
17194         goto do_ld;
17195 #ifdef TARGET_MIPS64
17196     case LD32:
17197         check_insn(ctx, ISA_MIPS3);
17198         check_mips_64(ctx);
17199         mips32_op = OPC_LD;
17200         goto do_ld;
17201     case SD32:
17202         check_insn(ctx, ISA_MIPS3);
17203         check_mips_64(ctx);
17204         mips32_op = OPC_SD;
17205         goto do_st;
17206 #endif
17207     case SB32:
17208         mips32_op = OPC_SB;
17209         goto do_st;
17210     case SH32:
17211         mips32_op = OPC_SH;
17212         goto do_st;
17213     case SW32:
17214         mips32_op = OPC_SW;
17215         goto do_st;
17216     do_ld:
17217         gen_ld(ctx, mips32_op, rt, rs, imm);
17218         break;
17219     do_st:
17220         gen_st(ctx, mips32_op, rt, rs, imm);
17221         break;
17222     default:
17223         generate_exception_end(ctx, EXCP_RI);
17224         break;
17225     }
17226 }
17227
17228 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
17229 {
17230     uint32_t op;
17231
17232     /* make sure instructions are on a halfword boundary */
17233     if (ctx->base.pc_next & 0x1) {
17234         env->CP0_BadVAddr = ctx->base.pc_next;
17235         generate_exception_end(ctx, EXCP_AdEL);
17236         return 2;
17237     }
17238
17239     op = (ctx->opcode >> 10) & 0x3f;
17240     /* Enforce properly-sized instructions in a delay slot */
17241     if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
17242         switch (op & 0x7) { /* MSB-3..MSB-5 */
17243         case 0:
17244         /* POOL32A, POOL32B, POOL32I, POOL32C */
17245         case 4:
17246         /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17247         case 5:
17248         /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17249         case 6:
17250         /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17251         case 7:
17252         /* LB32, LH32, LWC132, LDC132, LW32 */
17253             if (ctx->hflags & MIPS_HFLAG_BDS16) {
17254                 generate_exception_end(ctx, EXCP_RI);
17255                 return 2;
17256             }
17257             break;
17258         case 1:
17259         /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17260         case 2:
17261         /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17262         case 3:
17263         /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17264             if (ctx->hflags & MIPS_HFLAG_BDS32) {
17265                 generate_exception_end(ctx, EXCP_RI);
17266                 return 2;
17267             }
17268             break;
17269         }
17270     }
17271
17272     switch (op) {
17273     case POOL16A:
17274         {
17275             int rd = mmreg(uMIPS_RD(ctx->opcode));
17276             int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
17277             int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
17278             uint32_t opc = 0;
17279
17280             switch (ctx->opcode & 0x1) {
17281             case ADDU16:
17282                 opc = OPC_ADDU;
17283                 break;
17284             case SUBU16:
17285                 opc = OPC_SUBU;
17286                 break;
17287             }
17288             if (ctx->insn_flags & ISA_MIPS32R6) {
17289                 /* In the Release 6 the register number location in
17290                  * the instruction encoding has changed.
17291                  */
17292                 gen_arith(ctx, opc, rs1, rd, rs2);
17293             } else {
17294                 gen_arith(ctx, opc, rd, rs1, rs2);
17295             }
17296         }
17297         break;
17298     case POOL16B:
17299         {
17300             int rd = mmreg(uMIPS_RD(ctx->opcode));
17301             int rs = mmreg(uMIPS_RS(ctx->opcode));
17302             int amount = (ctx->opcode >> 1) & 0x7;
17303             uint32_t opc = 0;
17304             amount = amount == 0 ? 8 : amount;
17305
17306             switch (ctx->opcode & 0x1) {
17307             case SLL16:
17308                 opc = OPC_SLL;
17309                 break;
17310             case SRL16:
17311                 opc = OPC_SRL;
17312                 break;
17313             }
17314
17315             gen_shift_imm(ctx, opc, rd, rs, amount);
17316         }
17317         break;
17318     case POOL16C:
17319         if (ctx->insn_flags & ISA_MIPS32R6) {
17320             gen_pool16c_r6_insn(ctx);
17321         } else {
17322             gen_pool16c_insn(ctx);
17323         }
17324         break;
17325     case LWGP16:
17326         {
17327             int rd = mmreg(uMIPS_RD(ctx->opcode));
17328             int rb = 28;            /* GP */
17329             int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
17330
17331             gen_ld(ctx, OPC_LW, rd, rb, offset);
17332         }
17333         break;
17334     case POOL16F:
17335         check_insn_opc_removed(ctx, ISA_MIPS32R6);
17336         if (ctx->opcode & 1) {
17337             generate_exception_end(ctx, EXCP_RI);
17338         } else {
17339             /* MOVEP */
17340             int enc_dest = uMIPS_RD(ctx->opcode);
17341             int enc_rt = uMIPS_RS2(ctx->opcode);
17342             int enc_rs = uMIPS_RS1(ctx->opcode);
17343             gen_movep(ctx, enc_dest, enc_rt, enc_rs);
17344         }
17345         break;
17346     case LBU16:
17347         {
17348             int rd = mmreg(uMIPS_RD(ctx->opcode));
17349             int rb = mmreg(uMIPS_RS(ctx->opcode));
17350             int16_t offset = ZIMM(ctx->opcode, 0, 4);
17351             offset = (offset == 0xf ? -1 : offset);
17352
17353             gen_ld(ctx, OPC_LBU, rd, rb, offset);
17354         }
17355         break;
17356     case LHU16:
17357         {
17358             int rd = mmreg(uMIPS_RD(ctx->opcode));
17359             int rb = mmreg(uMIPS_RS(ctx->opcode));
17360             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17361
17362             gen_ld(ctx, OPC_LHU, rd, rb, offset);
17363         }
17364         break;
17365     case LWSP16:
17366         {
17367             int rd = (ctx->opcode >> 5) & 0x1f;
17368             int rb = 29;            /* SP */
17369             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17370
17371             gen_ld(ctx, OPC_LW, rd, rb, offset);
17372         }
17373         break;
17374     case LW16:
17375         {
17376             int rd = mmreg(uMIPS_RD(ctx->opcode));
17377             int rb = mmreg(uMIPS_RS(ctx->opcode));
17378             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17379
17380             gen_ld(ctx, OPC_LW, rd, rb, offset);
17381         }
17382         break;
17383     case SB16:
17384         {
17385             int rd = mmreg2(uMIPS_RD(ctx->opcode));
17386             int rb = mmreg(uMIPS_RS(ctx->opcode));
17387             int16_t offset = ZIMM(ctx->opcode, 0, 4);
17388
17389             gen_st(ctx, OPC_SB, rd, rb, offset);
17390         }
17391         break;
17392     case SH16:
17393         {
17394             int rd = mmreg2(uMIPS_RD(ctx->opcode));
17395             int rb = mmreg(uMIPS_RS(ctx->opcode));
17396             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17397
17398             gen_st(ctx, OPC_SH, rd, rb, offset);
17399         }
17400         break;
17401     case SWSP16:
17402         {
17403             int rd = (ctx->opcode >> 5) & 0x1f;
17404             int rb = 29;            /* SP */
17405             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17406
17407             gen_st(ctx, OPC_SW, rd, rb, offset);
17408         }
17409         break;
17410     case SW16:
17411         {
17412             int rd = mmreg2(uMIPS_RD(ctx->opcode));
17413             int rb = mmreg(uMIPS_RS(ctx->opcode));
17414             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17415
17416             gen_st(ctx, OPC_SW, rd, rb, offset);
17417         }
17418         break;
17419     case MOVE16:
17420         {
17421             int rd = uMIPS_RD5(ctx->opcode);
17422             int rs = uMIPS_RS5(ctx->opcode);
17423
17424             gen_arith(ctx, OPC_ADDU, rd, rs, 0);
17425         }
17426         break;
17427     case ANDI16:
17428         gen_andi16(ctx);
17429         break;
17430     case POOL16D:
17431         switch (ctx->opcode & 0x1) {
17432         case ADDIUS5:
17433             gen_addius5(ctx);
17434             break;
17435         case ADDIUSP:
17436             gen_addiusp(ctx);
17437             break;
17438         }
17439         break;
17440     case POOL16E:
17441         switch (ctx->opcode & 0x1) {
17442         case ADDIUR2:
17443             gen_addiur2(ctx);
17444             break;
17445         case ADDIUR1SP:
17446             gen_addiur1sp(ctx);
17447             break;
17448         }
17449         break;
17450     case B16: /* BC16 */
17451         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
17452                            sextract32(ctx->opcode, 0, 10) << 1,
17453                            (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17454         break;
17455     case BNEZ16: /* BNEZC16 */
17456     case BEQZ16: /* BEQZC16 */
17457         gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17458                            mmreg(uMIPS_RD(ctx->opcode)),
17459                            0, sextract32(ctx->opcode, 0, 7) << 1,
17460                            (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17461
17462         break;
17463     case LI16:
17464         {
17465             int reg = mmreg(uMIPS_RD(ctx->opcode));
17466             int imm = ZIMM(ctx->opcode, 0, 7);
17467
17468             imm = (imm == 0x7f ? -1 : imm);
17469             tcg_gen_movi_tl(cpu_gpr[reg], imm);
17470         }
17471         break;
17472     case RES_29:
17473     case RES_31:
17474     case RES_39:
17475         generate_exception_end(ctx, EXCP_RI);
17476         break;
17477     default:
17478         decode_micromips32_opc(env, ctx);
17479         return 4;
17480     }
17481
17482     return 2;
17483 }
17484
17485 /*
17486  *
17487  * nanoMIPS opcodes
17488  *
17489  */
17490
17491 /* MAJOR, P16, and P32 pools opcodes */
17492 enum {
17493     NM_P_ADDIU      = 0x00,
17494     NM_ADDIUPC      = 0x01,
17495     NM_MOVE_BALC    = 0x02,
17496     NM_P16_MV       = 0x04,
17497     NM_LW16         = 0x05,
17498     NM_BC16         = 0x06,
17499     NM_P16_SR       = 0x07,
17500
17501     NM_POOL32A      = 0x08,
17502     NM_P_BAL        = 0x0a,
17503     NM_P16_SHIFT    = 0x0c,
17504     NM_LWSP16       = 0x0d,
17505     NM_BALC16       = 0x0e,
17506     NM_P16_4X4      = 0x0f,
17507
17508     NM_P_GP_W       = 0x10,
17509     NM_P_GP_BH      = 0x11,
17510     NM_P_J          = 0x12,
17511     NM_P16C         = 0x14,
17512     NM_LWGP16       = 0x15,
17513     NM_P16_LB       = 0x17,
17514
17515     NM_P48I         = 0x18,
17516     NM_P16_A1       = 0x1c,
17517     NM_LW4X4        = 0x1d,
17518     NM_P16_LH       = 0x1f,
17519
17520     NM_P_U12        = 0x20,
17521     NM_P_LS_U12     = 0x21,
17522     NM_P_BR1        = 0x22,
17523     NM_P16_A2       = 0x24,
17524     NM_SW16         = 0x25,
17525     NM_BEQZC16      = 0x26,
17526
17527     NM_POOL32F      = 0x28,
17528     NM_P_LS_S9      = 0x29,
17529     NM_P_BR2        = 0x2a,
17530
17531     NM_P16_ADDU     = 0x2c,
17532     NM_SWSP16       = 0x2d,
17533     NM_BNEZC16      = 0x2e,
17534     NM_MOVEP        = 0x2f,
17535
17536     NM_POOL32S      = 0x30,
17537     NM_P_BRI        = 0x32,
17538     NM_LI16         = 0x34,
17539     NM_SWGP16       = 0x35,
17540     NM_P16_BR       = 0x36,
17541
17542     NM_P_LUI        = 0x38,
17543     NM_ANDI16       = 0x3c,
17544     NM_SW4X4        = 0x3d,
17545     NM_MOVEPREV     = 0x3f,
17546 };
17547
17548 /* POOL32A instruction pool */
17549 enum {
17550     NM_POOL32A0    = 0x00,
17551     NM_SPECIAL2    = 0x01,
17552     NM_COP2_1      = 0x02,
17553     NM_UDI         = 0x03,
17554     NM_POOL32A5    = 0x05,
17555     NM_POOL32A7    = 0x07,
17556 };
17557
17558 /* P.GP.W instruction pool */
17559 enum {
17560     NM_ADDIUGP_W = 0x00,
17561     NM_LWGP      = 0x02,
17562     NM_SWGP      = 0x03,
17563 };
17564
17565 /* P48I instruction pool */
17566 enum {
17567     NM_LI48        = 0x00,
17568     NM_ADDIU48     = 0x01,
17569     NM_ADDIUGP48   = 0x02,
17570     NM_ADDIUPC48   = 0x03,
17571     NM_LWPC48      = 0x0b,
17572     NM_SWPC48      = 0x0f,
17573 };
17574
17575 /* P.U12 instruction pool */
17576 enum {
17577     NM_ORI      = 0x00,
17578     NM_XORI     = 0x01,
17579     NM_ANDI     = 0x02,
17580     NM_P_SR     = 0x03,
17581     NM_SLTI     = 0x04,
17582     NM_SLTIU    = 0x05,
17583     NM_SEQI     = 0x06,
17584     NM_ADDIUNEG = 0x08,
17585     NM_P_SHIFT  = 0x0c,
17586     NM_P_ROTX   = 0x0d,
17587     NM_P_INS    = 0x0e,
17588     NM_P_EXT    = 0x0f,
17589 };
17590
17591 /* POOL32F instruction pool */
17592 enum {
17593     NM_POOL32F_0   = 0x00,
17594     NM_POOL32F_3   = 0x03,
17595     NM_POOL32F_5   = 0x05,
17596 };
17597
17598 /* POOL32S instruction pool */
17599 enum {
17600     NM_POOL32S_0   = 0x00,
17601     NM_POOL32S_4   = 0x04,
17602 };
17603
17604 /* P.LUI instruction pool */
17605 enum {
17606     NM_LUI      = 0x00,
17607     NM_ALUIPC   = 0x01,
17608 };
17609
17610 /* P.GP.BH instruction pool */
17611 enum {
17612     NM_LBGP      = 0x00,
17613     NM_SBGP      = 0x01,
17614     NM_LBUGP     = 0x02,
17615     NM_ADDIUGP_B = 0x03,
17616     NM_P_GP_LH   = 0x04,
17617     NM_P_GP_SH   = 0x05,
17618     NM_P_GP_CP1  = 0x06,
17619 };
17620
17621 /* P.LS.U12 instruction pool */
17622 enum {
17623     NM_LB        = 0x00,
17624     NM_SB        = 0x01,
17625     NM_LBU       = 0x02,
17626     NM_P_PREFU12 = 0x03,
17627     NM_LH        = 0x04,
17628     NM_SH        = 0x05,
17629     NM_LHU       = 0x06,
17630     NM_LWU       = 0x07,
17631     NM_LW        = 0x08,
17632     NM_SW        = 0x09,
17633     NM_LWC1      = 0x0a,
17634     NM_SWC1      = 0x0b,
17635     NM_LDC1      = 0x0e,
17636     NM_SDC1      = 0x0f,
17637 };
17638
17639 /* P.LS.S9 instruction pool */
17640 enum {
17641     NM_P_LS_S0         = 0x00,
17642     NM_P_LS_S1         = 0x01,
17643     NM_P_LS_E0         = 0x02,
17644     NM_P_LS_WM         = 0x04,
17645     NM_P_LS_UAWM       = 0x05,
17646 };
17647
17648 /* P.BAL instruction pool */
17649 enum {
17650     NM_BC       = 0x00,
17651     NM_BALC     = 0x01,
17652 };
17653
17654 /* P.J instruction pool */
17655 enum {
17656     NM_JALRC    = 0x00,
17657     NM_JALRC_HB = 0x01,
17658     NM_P_BALRSC = 0x08,
17659 };
17660
17661 /* P.BR1 instruction pool */
17662 enum {
17663     NM_BEQC     = 0x00,
17664     NM_P_BR3A   = 0x01,
17665     NM_BGEC     = 0x02,
17666     NM_BGEUC    = 0x03,
17667 };
17668
17669 /* P.BR2 instruction pool */
17670 enum {
17671     NM_BNEC     = 0x00,
17672     NM_BLTC     = 0x02,
17673     NM_BLTUC    = 0x03,
17674 };
17675
17676 /* P.BRI instruction pool */
17677 enum {
17678     NM_BEQIC    = 0x00,
17679     NM_BBEQZC   = 0x01,
17680     NM_BGEIC    = 0x02,
17681     NM_BGEIUC   = 0x03,
17682     NM_BNEIC    = 0x04,
17683     NM_BBNEZC   = 0x05,
17684     NM_BLTIC    = 0x06,
17685     NM_BLTIUC   = 0x07,
17686 };
17687
17688 /* P16.SHIFT instruction pool */
17689 enum {
17690     NM_SLL16    = 0x00,
17691     NM_SRL16    = 0x01,
17692 };
17693
17694 /* POOL16C instruction pool */
17695 enum {
17696     NM_POOL16C_0  = 0x00,
17697     NM_LWXS16     = 0x01,
17698 };
17699
17700 /* P16.A1 instruction pool */
17701 enum {
17702     NM_ADDIUR1SP = 0x01,
17703 };
17704
17705 /* P16.A2 instruction pool */
17706 enum {
17707     NM_ADDIUR2  = 0x00,
17708     NM_P_ADDIURS5  = 0x01,
17709 };
17710
17711 /* P16.ADDU instruction pool */
17712 enum {
17713     NM_ADDU16     = 0x00,
17714     NM_SUBU16     = 0x01,
17715 };
17716
17717 /* P16.SR instruction pool */
17718 enum {
17719     NM_SAVE16        = 0x00,
17720     NM_RESTORE_JRC16 = 0x01,
17721 };
17722
17723 /* P16.4X4 instruction pool */
17724 enum {
17725     NM_ADDU4X4      = 0x00,
17726     NM_MUL4X4       = 0x01,
17727 };
17728
17729 /* P16.LB instruction pool */
17730 enum {
17731     NM_LB16       = 0x00,
17732     NM_SB16       = 0x01,
17733     NM_LBU16      = 0x02,
17734 };
17735
17736 /* P16.LH  instruction pool */
17737 enum {
17738     NM_LH16     = 0x00,
17739     NM_SH16     = 0x01,
17740     NM_LHU16    = 0x02,
17741 };
17742
17743 /* P.RI instruction pool */
17744 enum {
17745     NM_SIGRIE       = 0x00,
17746     NM_P_SYSCALL    = 0x01,
17747     NM_BREAK        = 0x02,
17748     NM_SDBBP        = 0x03,
17749 };
17750
17751 /* POOL32A0 instruction pool */
17752 enum {
17753     NM_P_TRAP   = 0x00,
17754     NM_SEB      = 0x01,
17755     NM_SLLV     = 0x02,
17756     NM_MUL      = 0x03,
17757     NM_MFC0     = 0x06,
17758     NM_MFHC0    = 0x07,
17759     NM_SEH      = 0x09,
17760     NM_SRLV     = 0x0a,
17761     NM_MUH      = 0x0b,
17762     NM_MTC0     = 0x0e,
17763     NM_MTHC0    = 0x0f,
17764     NM_SRAV     = 0x12,
17765     NM_MULU     = 0x13,
17766     NM_ROTRV    = 0x1a,
17767     NM_MUHU     = 0x1b,
17768     NM_ADD      = 0x22,
17769     NM_DIV      = 0x23,
17770     NM_ADDU     = 0x2a,
17771     NM_MOD      = 0x2b,
17772     NM_SUB      = 0x32,
17773     NM_DIVU     = 0x33,
17774     NM_RDHWR    = 0x38,
17775     NM_SUBU     = 0x3a,
17776     NM_MODU     = 0x3b,
17777     NM_P_CMOVE  = 0x42,
17778     NM_FORK     = 0x45,
17779     NM_MFTR     = 0x46,
17780     NM_MFHTR    = 0x47,
17781     NM_AND      = 0x4a,
17782     NM_YIELD    = 0x4d,
17783     NM_MTTR     = 0x4e,
17784     NM_MTHTR    = 0x4f,
17785     NM_OR       = 0x52,
17786     NM_D_E_MT_VPE = 0x56,
17787     NM_NOR      = 0x5a,
17788     NM_XOR      = 0x62,
17789     NM_SLT      = 0x6a,
17790     NM_P_SLTU   = 0x72,
17791     NM_SOV      = 0x7a,
17792 };
17793
17794 /* CRC32 instruction pool */
17795 enum {
17796     NM_CRC32B   = 0x00,
17797     NM_CRC32H   = 0x01,
17798     NM_CRC32W   = 0x02,
17799     NM_CRC32CB  = 0x04,
17800     NM_CRC32CH  = 0x05,
17801     NM_CRC32CW  = 0x06,
17802 };
17803
17804 /* POOL32A5 instruction pool */
17805 enum {
17806     NM_CMP_EQ_PH        = 0x00,
17807     NM_CMP_LT_PH        = 0x08,
17808     NM_CMP_LE_PH        = 0x10,
17809     NM_CMPGU_EQ_QB      = 0x18,
17810     NM_CMPGU_LT_QB      = 0x20,
17811     NM_CMPGU_LE_QB      = 0x28,
17812     NM_CMPGDU_EQ_QB     = 0x30,
17813     NM_CMPGDU_LT_QB     = 0x38,
17814     NM_CMPGDU_LE_QB     = 0x40,
17815     NM_CMPU_EQ_QB       = 0x48,
17816     NM_CMPU_LT_QB       = 0x50,
17817     NM_CMPU_LE_QB       = 0x58,
17818     NM_ADDQ_S_W         = 0x60,
17819     NM_SUBQ_S_W         = 0x68,
17820     NM_ADDSC            = 0x70,
17821     NM_ADDWC            = 0x78,
17822
17823     NM_ADDQ_S_PH   = 0x01,
17824     NM_ADDQH_R_PH  = 0x09,
17825     NM_ADDQH_R_W   = 0x11,
17826     NM_ADDU_S_QB   = 0x19,
17827     NM_ADDU_S_PH   = 0x21,
17828     NM_ADDUH_R_QB  = 0x29,
17829     NM_SHRAV_R_PH  = 0x31,
17830     NM_SHRAV_R_QB  = 0x39,
17831     NM_SUBQ_S_PH   = 0x41,
17832     NM_SUBQH_R_PH  = 0x49,
17833     NM_SUBQH_R_W   = 0x51,
17834     NM_SUBU_S_QB   = 0x59,
17835     NM_SUBU_S_PH   = 0x61,
17836     NM_SUBUH_R_QB  = 0x69,
17837     NM_SHLLV_S_PH  = 0x71,
17838     NM_PRECR_SRA_R_PH_W = 0x79,
17839
17840     NM_MULEU_S_PH_QBL   = 0x12,
17841     NM_MULEU_S_PH_QBR   = 0x1a,
17842     NM_MULQ_RS_PH       = 0x22,
17843     NM_MULQ_S_PH        = 0x2a,
17844     NM_MULQ_RS_W        = 0x32,
17845     NM_MULQ_S_W         = 0x3a,
17846     NM_APPEND           = 0x42,
17847     NM_MODSUB           = 0x52,
17848     NM_SHRAV_R_W        = 0x5a,
17849     NM_SHRLV_PH         = 0x62,
17850     NM_SHRLV_QB         = 0x6a,
17851     NM_SHLLV_QB         = 0x72,
17852     NM_SHLLV_S_W        = 0x7a,
17853
17854     NM_SHILO            = 0x03,
17855
17856     NM_MULEQ_S_W_PHL    = 0x04,
17857     NM_MULEQ_S_W_PHR    = 0x0c,
17858
17859     NM_MUL_S_PH         = 0x05,
17860     NM_PRECR_QB_PH      = 0x0d,
17861     NM_PRECRQ_QB_PH     = 0x15,
17862     NM_PRECRQ_PH_W      = 0x1d,
17863     NM_PRECRQ_RS_PH_W   = 0x25,
17864     NM_PRECRQU_S_QB_PH  = 0x2d,
17865     NM_PACKRL_PH        = 0x35,
17866     NM_PICK_QB          = 0x3d,
17867     NM_PICK_PH          = 0x45,
17868
17869     NM_SHRA_R_W         = 0x5e,
17870     NM_SHRA_R_PH        = 0x66,
17871     NM_SHLL_S_PH        = 0x76,
17872     NM_SHLL_S_W         = 0x7e,
17873
17874     NM_REPL_PH          = 0x07
17875 };
17876
17877 /* POOL32A7 instruction pool */
17878 enum {
17879     NM_P_LSX        = 0x00,
17880     NM_LSA          = 0x01,
17881     NM_EXTW         = 0x03,
17882     NM_POOL32AXF    = 0x07,
17883 };
17884
17885 /* P.SR instruction pool */
17886 enum {
17887     NM_PP_SR           = 0x00,
17888     NM_P_SR_F          = 0x01,
17889 };
17890
17891 /* P.SHIFT instruction pool */
17892 enum {
17893     NM_P_SLL        = 0x00,
17894     NM_SRL          = 0x02,
17895     NM_SRA          = 0x04,
17896     NM_ROTR         = 0x06,
17897 };
17898
17899 /* P.ROTX instruction pool */
17900 enum {
17901     NM_ROTX         = 0x00,
17902 };
17903
17904 /* P.INS instruction pool */
17905 enum {
17906     NM_INS          = 0x00,
17907 };
17908
17909 /* P.EXT instruction pool */
17910 enum {
17911     NM_EXT          = 0x00,
17912 };
17913
17914 /* POOL32F_0 (fmt) instruction pool */
17915 enum {
17916     NM_RINT_S              = 0x04,
17917     NM_RINT_D              = 0x44,
17918     NM_ADD_S               = 0x06,
17919     NM_SELEQZ_S            = 0x07,
17920     NM_SELEQZ_D            = 0x47,
17921     NM_CLASS_S             = 0x0c,
17922     NM_CLASS_D             = 0x4c,
17923     NM_SUB_S               = 0x0e,
17924     NM_SELNEZ_S            = 0x0f,
17925     NM_SELNEZ_D            = 0x4f,
17926     NM_MUL_S               = 0x16,
17927     NM_SEL_S               = 0x17,
17928     NM_SEL_D               = 0x57,
17929     NM_DIV_S               = 0x1e,
17930     NM_ADD_D               = 0x26,
17931     NM_SUB_D               = 0x2e,
17932     NM_MUL_D               = 0x36,
17933     NM_MADDF_S             = 0x37,
17934     NM_MADDF_D             = 0x77,
17935     NM_DIV_D               = 0x3e,
17936     NM_MSUBF_S             = 0x3f,
17937     NM_MSUBF_D             = 0x7f,
17938 };
17939
17940 /* POOL32F_3  instruction pool */
17941 enum {
17942     NM_MIN_FMT         = 0x00,
17943     NM_MAX_FMT         = 0x01,
17944     NM_MINA_FMT        = 0x04,
17945     NM_MAXA_FMT        = 0x05,
17946     NM_POOL32FXF       = 0x07,
17947 };
17948
17949 /* POOL32F_5  instruction pool */
17950 enum {
17951     NM_CMP_CONDN_S     = 0x00,
17952     NM_CMP_CONDN_D     = 0x02,
17953 };
17954
17955 /* P.GP.LH instruction pool */
17956 enum {
17957     NM_LHGP    = 0x00,
17958     NM_LHUGP   = 0x01,
17959 };
17960
17961 /* P.GP.SH instruction pool */
17962 enum {
17963     NM_SHGP    = 0x00,
17964 };
17965
17966 /* P.GP.CP1 instruction pool */
17967 enum {
17968     NM_LWC1GP       = 0x00,
17969     NM_SWC1GP       = 0x01,
17970     NM_LDC1GP       = 0x02,
17971     NM_SDC1GP       = 0x03,
17972 };
17973
17974 /* P.LS.S0 instruction pool */
17975 enum {
17976     NM_LBS9     = 0x00,
17977     NM_LHS9     = 0x04,
17978     NM_LWS9     = 0x08,
17979     NM_LDS9     = 0x0c,
17980
17981     NM_SBS9     = 0x01,
17982     NM_SHS9     = 0x05,
17983     NM_SWS9     = 0x09,
17984     NM_SDS9     = 0x0d,
17985
17986     NM_LBUS9    = 0x02,
17987     NM_LHUS9    = 0x06,
17988     NM_LWC1S9   = 0x0a,
17989     NM_LDC1S9   = 0x0e,
17990
17991     NM_P_PREFS9 = 0x03,
17992     NM_LWUS9    = 0x07,
17993     NM_SWC1S9   = 0x0b,
17994     NM_SDC1S9   = 0x0f,
17995 };
17996
17997 /* P.LS.S1 instruction pool */
17998 enum {
17999     NM_ASET_ACLR = 0x02,
18000     NM_UALH      = 0x04,
18001     NM_UASH      = 0x05,
18002     NM_CACHE     = 0x07,
18003     NM_P_LL      = 0x0a,
18004     NM_P_SC      = 0x0b,
18005 };
18006
18007 /* P.LS.E0 instruction pool */
18008 enum {
18009     NM_LBE      = 0x00,
18010     NM_SBE      = 0x01,
18011     NM_LBUE     = 0x02,
18012     NM_P_PREFE  = 0x03,
18013     NM_LHE      = 0x04,
18014     NM_SHE      = 0x05,
18015     NM_LHUE     = 0x06,
18016     NM_CACHEE   = 0x07,
18017     NM_LWE      = 0x08,
18018     NM_SWE      = 0x09,
18019     NM_P_LLE    = 0x0a,
18020     NM_P_SCE    = 0x0b,
18021 };
18022
18023 /* P.PREFE instruction pool */
18024 enum {
18025     NM_SYNCIE   = 0x00,
18026     NM_PREFE    = 0x01,
18027 };
18028
18029 /* P.LLE instruction pool */
18030 enum {
18031     NM_LLE      = 0x00,
18032     NM_LLWPE    = 0x01,
18033 };
18034
18035 /* P.SCE instruction pool */
18036 enum {
18037     NM_SCE      = 0x00,
18038     NM_SCWPE    = 0x01,
18039 };
18040
18041 /* P.LS.WM instruction pool */
18042 enum {
18043     NM_LWM       = 0x00,
18044     NM_SWM       = 0x01,
18045 };
18046
18047 /* P.LS.UAWM instruction pool */
18048 enum {
18049     NM_UALWM       = 0x00,
18050     NM_UASWM       = 0x01,
18051 };
18052
18053 /* P.BR3A instruction pool */
18054 enum {
18055     NM_BC1EQZC          = 0x00,
18056     NM_BC1NEZC          = 0x01,
18057     NM_BC2EQZC          = 0x02,
18058     NM_BC2NEZC          = 0x03,
18059     NM_BPOSGE32C        = 0x04,
18060 };
18061
18062 /* P16.RI instruction pool */
18063 enum {
18064     NM_P16_SYSCALL  = 0x01,
18065     NM_BREAK16      = 0x02,
18066     NM_SDBBP16      = 0x03,
18067 };
18068
18069 /* POOL16C_0 instruction pool */
18070 enum {
18071     NM_POOL16C_00      = 0x00,
18072 };
18073
18074 /* P16.JRC instruction pool */
18075 enum {
18076     NM_JRC          = 0x00,
18077     NM_JALRC16      = 0x01,
18078 };
18079
18080 /* P.SYSCALL instruction pool */
18081 enum {
18082     NM_SYSCALL      = 0x00,
18083     NM_HYPCALL      = 0x01,
18084 };
18085
18086 /* P.TRAP instruction pool */
18087 enum {
18088     NM_TEQ          = 0x00,
18089     NM_TNE          = 0x01,
18090 };
18091
18092 /* P.CMOVE instruction pool */
18093 enum {
18094     NM_MOVZ            = 0x00,
18095     NM_MOVN            = 0x01,
18096 };
18097
18098 /* POOL32Axf instruction pool */
18099 enum {
18100     NM_POOL32AXF_1 = 0x01,
18101     NM_POOL32AXF_2 = 0x02,
18102     NM_POOL32AXF_4 = 0x04,
18103     NM_POOL32AXF_5 = 0x05,
18104     NM_POOL32AXF_7 = 0x07,
18105 };
18106
18107 /* POOL32Axf_1 instruction pool */
18108 enum {
18109     NM_POOL32AXF_1_0 = 0x00,
18110     NM_POOL32AXF_1_1 = 0x01,
18111     NM_POOL32AXF_1_3 = 0x03,
18112     NM_POOL32AXF_1_4 = 0x04,
18113     NM_POOL32AXF_1_5 = 0x05,
18114     NM_POOL32AXF_1_7 = 0x07,
18115 };
18116
18117 /* POOL32Axf_2 instruction pool */
18118 enum {
18119     NM_POOL32AXF_2_0_7     = 0x00,
18120     NM_POOL32AXF_2_8_15    = 0x01,
18121     NM_POOL32AXF_2_16_23   = 0x02,
18122     NM_POOL32AXF_2_24_31   = 0x03,
18123 };
18124
18125 /* POOL32Axf_7 instruction pool */
18126 enum {
18127     NM_SHRA_R_QB    = 0x0,
18128     NM_SHRL_PH      = 0x1,
18129     NM_REPL_QB      = 0x2,
18130 };
18131
18132 /* POOL32Axf_1_0 instruction pool */
18133 enum {
18134     NM_MFHI = 0x0,
18135     NM_MFLO = 0x1,
18136     NM_MTHI = 0x2,
18137     NM_MTLO = 0x3,
18138 };
18139
18140 /* POOL32Axf_1_1 instruction pool */
18141 enum {
18142     NM_MTHLIP = 0x0,
18143     NM_SHILOV = 0x1,
18144 };
18145
18146 /* POOL32Axf_1_3 instruction pool */
18147 enum {
18148     NM_RDDSP    = 0x0,
18149     NM_WRDSP    = 0x1,
18150     NM_EXTP     = 0x2,
18151     NM_EXTPDP   = 0x3,
18152 };
18153
18154 /* POOL32Axf_1_4 instruction pool */
18155 enum {
18156     NM_SHLL_QB  = 0x0,
18157     NM_SHRL_QB  = 0x1,
18158 };
18159
18160 /* POOL32Axf_1_5 instruction pool */
18161 enum {
18162     NM_MAQ_S_W_PHR   = 0x0,
18163     NM_MAQ_S_W_PHL   = 0x1,
18164     NM_MAQ_SA_W_PHR  = 0x2,
18165     NM_MAQ_SA_W_PHL  = 0x3,
18166 };
18167
18168 /* POOL32Axf_1_7 instruction pool */
18169 enum {
18170     NM_EXTR_W       = 0x0,
18171     NM_EXTR_R_W     = 0x1,
18172     NM_EXTR_RS_W    = 0x2,
18173     NM_EXTR_S_H     = 0x3,
18174 };
18175
18176 /* POOL32Axf_2_0_7 instruction pool */
18177 enum {
18178     NM_DPA_W_PH     = 0x0,
18179     NM_DPAQ_S_W_PH  = 0x1,
18180     NM_DPS_W_PH     = 0x2,
18181     NM_DPSQ_S_W_PH  = 0x3,
18182     NM_BALIGN       = 0x4,
18183     NM_MADD         = 0x5,
18184     NM_MULT         = 0x6,
18185     NM_EXTRV_W      = 0x7,
18186 };
18187
18188 /* POOL32Axf_2_8_15 instruction pool */
18189 enum {
18190     NM_DPAX_W_PH    = 0x0,
18191     NM_DPAQ_SA_L_W  = 0x1,
18192     NM_DPSX_W_PH    = 0x2,
18193     NM_DPSQ_SA_L_W  = 0x3,
18194     NM_MADDU        = 0x5,
18195     NM_MULTU        = 0x6,
18196     NM_EXTRV_R_W    = 0x7,
18197 };
18198
18199 /* POOL32Axf_2_16_23 instruction pool */
18200 enum {
18201     NM_DPAU_H_QBL       = 0x0,
18202     NM_DPAQX_S_W_PH     = 0x1,
18203     NM_DPSU_H_QBL       = 0x2,
18204     NM_DPSQX_S_W_PH     = 0x3,
18205     NM_EXTPV            = 0x4,
18206     NM_MSUB             = 0x5,
18207     NM_MULSA_W_PH       = 0x6,
18208     NM_EXTRV_RS_W       = 0x7,
18209 };
18210
18211 /* POOL32Axf_2_24_31 instruction pool */
18212 enum {
18213     NM_DPAU_H_QBR       = 0x0,
18214     NM_DPAQX_SA_W_PH    = 0x1,
18215     NM_DPSU_H_QBR       = 0x2,
18216     NM_DPSQX_SA_W_PH    = 0x3,
18217     NM_EXTPDPV          = 0x4,
18218     NM_MSUBU            = 0x5,
18219     NM_MULSAQ_S_W_PH    = 0x6,
18220     NM_EXTRV_S_H        = 0x7,
18221 };
18222
18223 /* POOL32Axf_{4, 5} instruction pool */
18224 enum {
18225     NM_CLO      = 0x25,
18226     NM_CLZ      = 0x2d,
18227
18228     NM_TLBP     = 0x01,
18229     NM_TLBR     = 0x09,
18230     NM_TLBWI    = 0x11,
18231     NM_TLBWR    = 0x19,
18232     NM_TLBINV   = 0x03,
18233     NM_TLBINVF  = 0x0b,
18234     NM_DI       = 0x23,
18235     NM_EI       = 0x2b,
18236     NM_RDPGPR   = 0x70,
18237     NM_WRPGPR   = 0x78,
18238     NM_WAIT     = 0x61,
18239     NM_DERET    = 0x71,
18240     NM_ERETX    = 0x79,
18241
18242     /* nanoMIPS DSP instructions */
18243     NM_ABSQ_S_QB        = 0x00,
18244     NM_ABSQ_S_PH        = 0x08,
18245     NM_ABSQ_S_W         = 0x10,
18246     NM_PRECEQ_W_PHL     = 0x28,
18247     NM_PRECEQ_W_PHR     = 0x30,
18248     NM_PRECEQU_PH_QBL   = 0x38,
18249     NM_PRECEQU_PH_QBR   = 0x48,
18250     NM_PRECEU_PH_QBL    = 0x58,
18251     NM_PRECEU_PH_QBR    = 0x68,
18252     NM_PRECEQU_PH_QBLA  = 0x39,
18253     NM_PRECEQU_PH_QBRA  = 0x49,
18254     NM_PRECEU_PH_QBLA   = 0x59,
18255     NM_PRECEU_PH_QBRA   = 0x69,
18256     NM_REPLV_PH         = 0x01,
18257     NM_REPLV_QB         = 0x09,
18258     NM_BITREV           = 0x18,
18259     NM_INSV             = 0x20,
18260     NM_RADDU_W_QB       = 0x78,
18261
18262     NM_BITSWAP          = 0x05,
18263     NM_WSBH             = 0x3d,
18264 };
18265
18266 /* PP.SR instruction pool */
18267 enum {
18268     NM_SAVE         = 0x00,
18269     NM_RESTORE      = 0x02,
18270     NM_RESTORE_JRC  = 0x03,
18271 };
18272
18273 /* P.SR.F instruction pool */
18274 enum {
18275     NM_SAVEF        = 0x00,
18276     NM_RESTOREF     = 0x01,
18277 };
18278
18279 /* P16.SYSCALL  instruction pool */
18280 enum {
18281     NM_SYSCALL16     = 0x00,
18282     NM_HYPCALL16     = 0x01,
18283 };
18284
18285 /* POOL16C_00 instruction pool */
18286 enum {
18287     NM_NOT16           = 0x00,
18288     NM_XOR16           = 0x01,
18289     NM_AND16           = 0x02,
18290     NM_OR16            = 0x03,
18291 };
18292
18293 /* PP.LSX and PP.LSXS instruction pool */
18294 enum {
18295     NM_LBX      = 0x00,
18296     NM_LHX      = 0x04,
18297     NM_LWX      = 0x08,
18298     NM_LDX      = 0x0c,
18299
18300     NM_SBX      = 0x01,
18301     NM_SHX      = 0x05,
18302     NM_SWX      = 0x09,
18303     NM_SDX      = 0x0d,
18304
18305     NM_LBUX     = 0x02,
18306     NM_LHUX     = 0x06,
18307     NM_LWC1X    = 0x0a,
18308     NM_LDC1X    = 0x0e,
18309
18310     NM_LWUX     = 0x07,
18311     NM_SWC1X    = 0x0b,
18312     NM_SDC1X    = 0x0f,
18313
18314     NM_LHXS     = 0x04,
18315     NM_LWXS     = 0x08,
18316     NM_LDXS     = 0x0c,
18317
18318     NM_SHXS     = 0x05,
18319     NM_SWXS     = 0x09,
18320     NM_SDXS     = 0x0d,
18321
18322     NM_LHUXS    = 0x06,
18323     NM_LWC1XS   = 0x0a,
18324     NM_LDC1XS   = 0x0e,
18325
18326     NM_LWUXS    = 0x07,
18327     NM_SWC1XS   = 0x0b,
18328     NM_SDC1XS   = 0x0f,
18329 };
18330
18331 /* ERETx instruction pool */
18332 enum {
18333     NM_ERET     = 0x00,
18334     NM_ERETNC   = 0x01,
18335 };
18336
18337 /* POOL32FxF_{0, 1} insturction pool */
18338 enum {
18339     NM_CFC1     = 0x40,
18340     NM_CTC1     = 0x60,
18341     NM_MFC1     = 0x80,
18342     NM_MTC1     = 0xa0,
18343     NM_MFHC1    = 0xc0,
18344     NM_MTHC1    = 0xe0,
18345
18346     NM_CVT_S_PL = 0x84,
18347     NM_CVT_S_PU = 0xa4,
18348
18349     NM_CVT_L_S     = 0x004,
18350     NM_CVT_L_D     = 0x104,
18351     NM_CVT_W_S     = 0x024,
18352     NM_CVT_W_D     = 0x124,
18353
18354     NM_RSQRT_S     = 0x008,
18355     NM_RSQRT_D     = 0x108,
18356
18357     NM_SQRT_S      = 0x028,
18358     NM_SQRT_D      = 0x128,
18359
18360     NM_RECIP_S     = 0x048,
18361     NM_RECIP_D     = 0x148,
18362
18363     NM_FLOOR_L_S   = 0x00c,
18364     NM_FLOOR_L_D   = 0x10c,
18365
18366     NM_FLOOR_W_S   = 0x02c,
18367     NM_FLOOR_W_D   = 0x12c,
18368
18369     NM_CEIL_L_S    = 0x04c,
18370     NM_CEIL_L_D    = 0x14c,
18371     NM_CEIL_W_S    = 0x06c,
18372     NM_CEIL_W_D    = 0x16c,
18373     NM_TRUNC_L_S   = 0x08c,
18374     NM_TRUNC_L_D   = 0x18c,
18375     NM_TRUNC_W_S   = 0x0ac,
18376     NM_TRUNC_W_D   = 0x1ac,
18377     NM_ROUND_L_S   = 0x0cc,
18378     NM_ROUND_L_D   = 0x1cc,
18379     NM_ROUND_W_S   = 0x0ec,
18380     NM_ROUND_W_D   = 0x1ec,
18381
18382     NM_MOV_S       = 0x01,
18383     NM_MOV_D       = 0x81,
18384     NM_ABS_S       = 0x0d,
18385     NM_ABS_D       = 0x8d,
18386     NM_NEG_S       = 0x2d,
18387     NM_NEG_D       = 0xad,
18388     NM_CVT_D_S     = 0x04d,
18389     NM_CVT_D_W     = 0x0cd,
18390     NM_CVT_D_L     = 0x14d,
18391     NM_CVT_S_D     = 0x06d,
18392     NM_CVT_S_W     = 0x0ed,
18393     NM_CVT_S_L     = 0x16d,
18394 };
18395
18396 /* P.LL instruction pool */
18397 enum {
18398     NM_LL       = 0x00,
18399     NM_LLWP     = 0x01,
18400 };
18401
18402 /* P.SC instruction pool */
18403 enum {
18404     NM_SC       = 0x00,
18405     NM_SCWP     = 0x01,
18406 };
18407
18408 /* P.DVP instruction pool */
18409 enum {
18410     NM_DVP      = 0x00,
18411     NM_EVP      = 0x01,
18412 };
18413
18414
18415 /*
18416  *
18417  * nanoMIPS decoding engine
18418  *
18419  */
18420
18421
18422 /* extraction utilities */
18423
18424 #define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
18425 #define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
18426 #define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
18427 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18428 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18429
18430 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18431 static inline int decode_gpr_gpr3(int r)
18432 {
18433     static const int map[] = { 16, 17, 18, 19,  4,  5,  6,  7 };
18434
18435     return map[r & 0x7];
18436 }
18437
18438 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18439 static inline int decode_gpr_gpr3_src_store(int r)
18440 {
18441     static const int map[] = {  0, 17, 18, 19,  4,  5,  6,  7 };
18442
18443     return map[r & 0x7];
18444 }
18445
18446 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18447 static inline int decode_gpr_gpr4(int r)
18448 {
18449     static const int map[] = {  8,  9, 10, 11,  4,  5,  6,  7,
18450                                16, 17, 18, 19, 20, 21, 22, 23 };
18451
18452     return map[r & 0xf];
18453 }
18454
18455 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18456 static inline int decode_gpr_gpr4_zero(int r)
18457 {
18458     static const int map[] = {  8,  9, 10,  0,  4,  5,  6,  7,
18459                                16, 17, 18, 19, 20, 21, 22, 23 };
18460
18461     return map[r & 0xf];
18462 }
18463
18464
18465 static void gen_adjust_sp(DisasContext *ctx, int u)
18466 {
18467     gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18468 }
18469
18470 static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18471                      uint8_t gp, uint16_t u)
18472 {
18473     int counter = 0;
18474     TCGv va = tcg_temp_new();
18475     TCGv t0 = tcg_temp_new();
18476
18477     while (counter != count) {
18478         bool use_gp = gp && (counter == count - 1);
18479         int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18480         int this_offset = -((counter + 1) << 2);
18481         gen_base_offset_addr(ctx, va, 29, this_offset);
18482         gen_load_gpr(t0, this_rt);
18483         tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18484                            (MO_TEUL | ctx->default_tcg_memop_mask));
18485         counter++;
18486     }
18487
18488     /* adjust stack pointer */
18489     gen_adjust_sp(ctx, -u);
18490
18491     tcg_temp_free(t0);
18492     tcg_temp_free(va);
18493 }
18494
18495 static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18496                         uint8_t gp, uint16_t u)
18497 {
18498     int counter = 0;
18499     TCGv va = tcg_temp_new();
18500     TCGv t0 = tcg_temp_new();
18501
18502     while (counter != count) {
18503         bool use_gp = gp && (counter == count - 1);
18504         int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18505         int this_offset = u - ((counter + 1) << 2);
18506         gen_base_offset_addr(ctx, va, 29, this_offset);
18507         tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18508                         ctx->default_tcg_memop_mask);
18509         tcg_gen_ext32s_tl(t0, t0);
18510         gen_store_gpr(t0, this_rt);
18511         counter++;
18512     }
18513
18514     /* adjust stack pointer */
18515     gen_adjust_sp(ctx, u);
18516
18517     tcg_temp_free(t0);
18518     tcg_temp_free(va);
18519 }
18520
18521 static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18522 {
18523     int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
18524     int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
18525
18526     switch (extract32(ctx->opcode, 2, 2)) {
18527     case NM_NOT16:
18528         gen_logic(ctx, OPC_NOR, rt, rs, 0);
18529         break;
18530     case NM_AND16:
18531         gen_logic(ctx, OPC_AND, rt, rt, rs);
18532         break;
18533     case NM_XOR16:
18534         gen_logic(ctx, OPC_XOR, rt, rt, rs);
18535         break;
18536     case NM_OR16:
18537         gen_logic(ctx, OPC_OR, rt, rt, rs);
18538         break;
18539     }
18540 }
18541
18542 static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18543 {
18544     int rt = extract32(ctx->opcode, 21, 5);
18545     int rs = extract32(ctx->opcode, 16, 5);
18546     int rd = extract32(ctx->opcode, 11, 5);
18547
18548     switch (extract32(ctx->opcode, 3, 7)) {
18549     case NM_P_TRAP:
18550         switch (extract32(ctx->opcode, 10, 1)) {
18551         case NM_TEQ:
18552             check_nms(ctx);
18553             gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18554             break;
18555         case NM_TNE:
18556             check_nms(ctx);
18557             gen_trap(ctx, OPC_TNE, rs, rt, -1);
18558             break;
18559         }
18560         break;
18561     case NM_RDHWR:
18562         check_nms(ctx);
18563         gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18564         break;
18565     case NM_SEB:
18566         check_nms(ctx);
18567         gen_bshfl(ctx, OPC_SEB, rs, rt);
18568         break;
18569     case NM_SEH:
18570         gen_bshfl(ctx, OPC_SEH, rs, rt);
18571         break;
18572     case NM_SLLV:
18573         gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18574         break;
18575     case NM_SRLV:
18576         gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18577         break;
18578     case NM_SRAV:
18579         gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18580         break;
18581     case NM_ROTRV:
18582         gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18583         break;
18584     case NM_ADD:
18585         gen_arith(ctx, OPC_ADD, rd, rs, rt);
18586         break;
18587     case NM_ADDU:
18588         gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18589         break;
18590     case NM_SUB:
18591         check_nms(ctx);
18592         gen_arith(ctx, OPC_SUB, rd, rs, rt);
18593         break;
18594     case NM_SUBU:
18595         gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18596         break;
18597     case NM_P_CMOVE:
18598         switch (extract32(ctx->opcode, 10, 1)) {
18599         case NM_MOVZ:
18600             gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18601             break;
18602         case NM_MOVN:
18603             gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18604             break;
18605         }
18606         break;
18607     case NM_AND:
18608         gen_logic(ctx, OPC_AND, rd, rs, rt);
18609         break;
18610     case NM_OR:
18611         gen_logic(ctx, OPC_OR, rd, rs, rt);
18612         break;
18613     case NM_NOR:
18614         gen_logic(ctx, OPC_NOR, rd, rs, rt);
18615         break;
18616     case NM_XOR:
18617         gen_logic(ctx, OPC_XOR, rd, rs, rt);
18618         break;
18619     case NM_SLT:
18620         gen_slt(ctx, OPC_SLT, rd, rs, rt);
18621         break;
18622     case NM_P_SLTU:
18623         if (rd == 0) {
18624             /* P_DVP */
18625 #ifndef CONFIG_USER_ONLY
18626             TCGv t0 = tcg_temp_new();
18627             switch (extract32(ctx->opcode, 10, 1)) {
18628             case NM_DVP:
18629                 if (ctx->vp) {
18630                     check_cp0_enabled(ctx);
18631                     gen_helper_dvp(t0, cpu_env);
18632                     gen_store_gpr(t0, rt);
18633                 }
18634                 break;
18635             case NM_EVP:
18636                 if (ctx->vp) {
18637                     check_cp0_enabled(ctx);
18638                     gen_helper_evp(t0, cpu_env);
18639                     gen_store_gpr(t0, rt);
18640                 }
18641                 break;
18642             }
18643             tcg_temp_free(t0);
18644 #endif
18645         } else {
18646             gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18647         }
18648         break;
18649     case NM_SOV:
18650         {
18651             TCGv t0 = tcg_temp_new();
18652             TCGv t1 = tcg_temp_new();
18653             TCGv t2 = tcg_temp_new();
18654
18655             gen_load_gpr(t1, rs);
18656             gen_load_gpr(t2, rt);
18657             tcg_gen_add_tl(t0, t1, t2);
18658             tcg_gen_ext32s_tl(t0, t0);
18659             tcg_gen_xor_tl(t1, t1, t2);
18660             tcg_gen_xor_tl(t2, t0, t2);
18661             tcg_gen_andc_tl(t1, t2, t1);
18662
18663             /* operands of same sign, result different sign */
18664             tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18665             gen_store_gpr(t0, rd);
18666
18667             tcg_temp_free(t0);
18668             tcg_temp_free(t1);
18669             tcg_temp_free(t2);
18670         }
18671         break;
18672     case NM_MUL:
18673         gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18674         break;
18675     case NM_MUH:
18676         gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18677         break;
18678     case NM_MULU:
18679         gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18680         break;
18681     case NM_MUHU:
18682         gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18683         break;
18684     case NM_DIV:
18685         gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18686         break;
18687     case NM_MOD:
18688         gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18689         break;
18690     case NM_DIVU:
18691         gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18692         break;
18693     case NM_MODU:
18694         gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
18695         break;
18696 #ifndef CONFIG_USER_ONLY
18697     case NM_MFC0:
18698         check_cp0_enabled(ctx);
18699         if (rt == 0) {
18700             /* Treat as NOP. */
18701             break;
18702         }
18703         gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
18704         break;
18705     case NM_MTC0:
18706         check_cp0_enabled(ctx);
18707         {
18708             TCGv t0 = tcg_temp_new();
18709
18710             gen_load_gpr(t0, rt);
18711             gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
18712             tcg_temp_free(t0);
18713         }
18714         break;
18715     case NM_D_E_MT_VPE:
18716         {
18717             uint8_t sc = extract32(ctx->opcode, 10, 1);
18718             TCGv t0 = tcg_temp_new();
18719
18720             switch (sc) {
18721             case 0:
18722                 if (rs == 1) {
18723                     /* DMT */
18724                     check_cp0_mt(ctx);
18725                     gen_helper_dmt(t0);
18726                     gen_store_gpr(t0, rt);
18727                 } else if (rs == 0) {
18728                     /* DVPE */
18729                     check_cp0_mt(ctx);
18730                     gen_helper_dvpe(t0, cpu_env);
18731                     gen_store_gpr(t0, rt);
18732                 } else {
18733                     generate_exception_end(ctx, EXCP_RI);
18734                 }
18735                 break;
18736             case 1:
18737                 if (rs == 1) {
18738                     /* EMT */
18739                     check_cp0_mt(ctx);
18740                     gen_helper_emt(t0);
18741                     gen_store_gpr(t0, rt);
18742                 } else if (rs == 0) {
18743                     /* EVPE */
18744                     check_cp0_mt(ctx);
18745                     gen_helper_evpe(t0, cpu_env);
18746                     gen_store_gpr(t0, rt);
18747                 } else {
18748                     generate_exception_end(ctx, EXCP_RI);
18749                 }
18750                 break;
18751             }
18752
18753             tcg_temp_free(t0);
18754         }
18755         break;
18756     case NM_FORK:
18757         check_mt(ctx);
18758         {
18759             TCGv t0 = tcg_temp_new();
18760             TCGv t1 = tcg_temp_new();
18761
18762             gen_load_gpr(t0, rt);
18763             gen_load_gpr(t1, rs);
18764             gen_helper_fork(t0, t1);
18765             tcg_temp_free(t0);
18766             tcg_temp_free(t1);
18767         }
18768         break;
18769     case NM_MFTR:
18770     case NM_MFHTR:
18771         check_cp0_enabled(ctx);
18772         if (rd == 0) {
18773             /* Treat as NOP. */
18774             return;
18775         }
18776         gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18777                  extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18778         break;
18779     case NM_MTTR:
18780     case NM_MTHTR:
18781         check_cp0_enabled(ctx);
18782         gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18783                  extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18784         break;
18785     case NM_YIELD:
18786         check_mt(ctx);
18787         {
18788             TCGv t0 = tcg_temp_new();
18789
18790             gen_load_gpr(t0, rs);
18791             gen_helper_yield(t0, cpu_env, t0);
18792             gen_store_gpr(t0, rt);
18793             tcg_temp_free(t0);
18794         }
18795         break;
18796 #endif
18797     default:
18798         generate_exception_end(ctx, EXCP_RI);
18799         break;
18800     }
18801 }
18802
18803 /* dsp */
18804 static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
18805                                             int ret, int v1, int v2)
18806 {
18807     TCGv_i32 t0;
18808     TCGv v0_t;
18809     TCGv v1_t;
18810
18811     t0 = tcg_temp_new_i32();
18812
18813     v0_t = tcg_temp_new();
18814     v1_t = tcg_temp_new();
18815
18816     tcg_gen_movi_i32(t0, v2 >> 3);
18817
18818     gen_load_gpr(v0_t, ret);
18819     gen_load_gpr(v1_t, v1);
18820
18821     switch (opc) {
18822     case NM_MAQ_S_W_PHR:
18823         check_dsp(ctx);
18824         gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
18825         break;
18826     case NM_MAQ_S_W_PHL:
18827         check_dsp(ctx);
18828         gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
18829         break;
18830     case NM_MAQ_SA_W_PHR:
18831         check_dsp(ctx);
18832         gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
18833         break;
18834     case NM_MAQ_SA_W_PHL:
18835         check_dsp(ctx);
18836         gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
18837         break;
18838     default:
18839         generate_exception_end(ctx, EXCP_RI);
18840         break;
18841     }
18842
18843     tcg_temp_free_i32(t0);
18844
18845     tcg_temp_free(v0_t);
18846     tcg_temp_free(v1_t);
18847 }
18848
18849
18850 static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
18851                                     int ret, int v1, int v2)
18852 {
18853     int16_t imm;
18854     TCGv t0 = tcg_temp_new();
18855     TCGv t1 = tcg_temp_new();
18856     TCGv v0_t = tcg_temp_new();
18857
18858     gen_load_gpr(v0_t, v1);
18859
18860     switch (opc) {
18861     case NM_POOL32AXF_1_0:
18862         check_dsp(ctx);
18863         switch (extract32(ctx->opcode, 12, 2)) {
18864         case NM_MFHI:
18865             gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
18866             break;
18867         case NM_MFLO:
18868             gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
18869             break;
18870         case NM_MTHI:
18871             gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
18872             break;
18873         case NM_MTLO:
18874             gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
18875             break;
18876         }
18877         break;
18878     case NM_POOL32AXF_1_1:
18879         check_dsp(ctx);
18880         switch (extract32(ctx->opcode, 12, 2)) {
18881         case NM_MTHLIP:
18882             tcg_gen_movi_tl(t0, v2);
18883             gen_helper_mthlip(t0, v0_t, cpu_env);
18884             break;
18885         case NM_SHILOV:
18886             tcg_gen_movi_tl(t0, v2 >> 3);
18887             gen_helper_shilo(t0, v0_t, cpu_env);
18888             break;
18889         default:
18890             generate_exception_end(ctx, EXCP_RI);
18891             break;
18892         }
18893         break;
18894     case NM_POOL32AXF_1_3:
18895         check_dsp(ctx);
18896         imm = extract32(ctx->opcode, 14, 7);
18897         switch (extract32(ctx->opcode, 12, 2)) {
18898         case NM_RDDSP:
18899             tcg_gen_movi_tl(t0, imm);
18900             gen_helper_rddsp(t0, t0, cpu_env);
18901             gen_store_gpr(t0, ret);
18902             break;
18903         case NM_WRDSP:
18904             gen_load_gpr(t0, ret);
18905             tcg_gen_movi_tl(t1, imm);
18906             gen_helper_wrdsp(t0, t1, cpu_env);
18907             break;
18908         case NM_EXTP:
18909             tcg_gen_movi_tl(t0, v2 >> 3);
18910             tcg_gen_movi_tl(t1, v1);
18911             gen_helper_extp(t0, t0, t1, cpu_env);
18912             gen_store_gpr(t0, ret);
18913             break;
18914         case NM_EXTPDP:
18915             tcg_gen_movi_tl(t0, v2 >> 3);
18916             tcg_gen_movi_tl(t1, v1);
18917             gen_helper_extpdp(t0, t0, t1, cpu_env);
18918             gen_store_gpr(t0, ret);
18919             break;
18920         }
18921         break;
18922     case NM_POOL32AXF_1_4:
18923         check_dsp(ctx);
18924         tcg_gen_movi_tl(t0, v2 >> 2);
18925         switch (extract32(ctx->opcode, 12, 1)) {
18926         case NM_SHLL_QB:
18927             gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
18928             gen_store_gpr(t0, ret);
18929             break;
18930         case NM_SHRL_QB:
18931             gen_helper_shrl_qb(t0, t0, v0_t);
18932             gen_store_gpr(t0, ret);
18933             break;
18934         }
18935         break;
18936     case NM_POOL32AXF_1_5:
18937         opc = extract32(ctx->opcode, 12, 2);
18938         gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
18939         break;
18940     case NM_POOL32AXF_1_7:
18941         check_dsp(ctx);
18942         tcg_gen_movi_tl(t0, v2 >> 3);
18943         tcg_gen_movi_tl(t1, v1);
18944         switch (extract32(ctx->opcode, 12, 2)) {
18945         case NM_EXTR_W:
18946             gen_helper_extr_w(t0, t0, t1, cpu_env);
18947             gen_store_gpr(t0, ret);
18948             break;
18949         case NM_EXTR_R_W:
18950             gen_helper_extr_r_w(t0, t0, t1, cpu_env);
18951             gen_store_gpr(t0, ret);
18952             break;
18953         case NM_EXTR_RS_W:
18954             gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
18955             gen_store_gpr(t0, ret);
18956             break;
18957         case NM_EXTR_S_H:
18958             gen_helper_extr_s_h(t0, t0, t1, cpu_env);
18959             gen_store_gpr(t0, ret);
18960             break;
18961         }
18962         break;
18963     default:
18964         generate_exception_end(ctx, EXCP_RI);
18965         break;
18966     }
18967
18968     tcg_temp_free(t0);
18969     tcg_temp_free(t1);
18970     tcg_temp_free(v0_t);
18971 }
18972
18973 static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
18974                                     TCGv v0, TCGv v1, int rd)
18975 {
18976     TCGv_i32 t0;
18977
18978     t0 = tcg_temp_new_i32();
18979
18980     tcg_gen_movi_i32(t0, rd >> 3);
18981
18982     switch (opc) {
18983     case NM_POOL32AXF_2_0_7:
18984         switch (extract32(ctx->opcode, 9, 3)) {
18985         case NM_DPA_W_PH:
18986             check_dsp_r2(ctx);
18987             gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
18988             break;
18989         case NM_DPAQ_S_W_PH:
18990             check_dsp(ctx);
18991             gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
18992             break;
18993         case NM_DPS_W_PH:
18994             check_dsp_r2(ctx);
18995             gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
18996             break;
18997         case NM_DPSQ_S_W_PH:
18998             check_dsp(ctx);
18999             gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
19000             break;
19001         default:
19002             generate_exception_end(ctx, EXCP_RI);
19003             break;
19004         }
19005         break;
19006     case NM_POOL32AXF_2_8_15:
19007         switch (extract32(ctx->opcode, 9, 3)) {
19008         case NM_DPAX_W_PH:
19009             check_dsp_r2(ctx);
19010             gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
19011             break;
19012         case NM_DPAQ_SA_L_W:
19013             check_dsp(ctx);
19014             gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
19015             break;
19016         case NM_DPSX_W_PH:
19017             check_dsp_r2(ctx);
19018             gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
19019             break;
19020         case NM_DPSQ_SA_L_W:
19021             check_dsp(ctx);
19022             gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
19023             break;
19024         default:
19025             generate_exception_end(ctx, EXCP_RI);
19026             break;
19027         }
19028         break;
19029     case NM_POOL32AXF_2_16_23:
19030         switch (extract32(ctx->opcode, 9, 3)) {
19031         case NM_DPAU_H_QBL:
19032             check_dsp(ctx);
19033             gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
19034             break;
19035         case NM_DPAQX_S_W_PH:
19036             check_dsp_r2(ctx);
19037             gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
19038             break;
19039         case NM_DPSU_H_QBL:
19040             check_dsp(ctx);
19041             gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
19042             break;
19043         case NM_DPSQX_S_W_PH:
19044             check_dsp_r2(ctx);
19045             gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
19046             break;
19047         case NM_MULSA_W_PH:
19048             check_dsp_r2(ctx);
19049             gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
19050             break;
19051         default:
19052             generate_exception_end(ctx, EXCP_RI);
19053             break;
19054         }
19055         break;
19056     case NM_POOL32AXF_2_24_31:
19057         switch (extract32(ctx->opcode, 9, 3)) {
19058         case NM_DPAU_H_QBR:
19059             check_dsp(ctx);
19060             gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
19061             break;
19062         case NM_DPAQX_SA_W_PH:
19063             check_dsp_r2(ctx);
19064             gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
19065             break;
19066         case NM_DPSU_H_QBR:
19067             check_dsp(ctx);
19068             gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
19069             break;
19070         case NM_DPSQX_SA_W_PH:
19071             check_dsp_r2(ctx);
19072             gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
19073             break;
19074         case NM_MULSAQ_S_W_PH:
19075             check_dsp(ctx);
19076             gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
19077             break;
19078         default:
19079             generate_exception_end(ctx, EXCP_RI);
19080             break;
19081         }
19082         break;
19083     default:
19084         generate_exception_end(ctx, EXCP_RI);
19085         break;
19086     }
19087
19088     tcg_temp_free_i32(t0);
19089 }
19090
19091 static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
19092                                           int rt, int rs, int rd)
19093 {
19094     int ret = rt;
19095     TCGv t0 = tcg_temp_new();
19096     TCGv t1 = tcg_temp_new();
19097     TCGv v0_t = tcg_temp_new();
19098     TCGv v1_t = tcg_temp_new();
19099
19100     gen_load_gpr(v0_t, rt);
19101     gen_load_gpr(v1_t, rs);
19102
19103     switch (opc) {
19104     case NM_POOL32AXF_2_0_7:
19105         switch (extract32(ctx->opcode, 9, 3)) {
19106         case NM_DPA_W_PH:
19107         case NM_DPAQ_S_W_PH:
19108         case NM_DPS_W_PH:
19109         case NM_DPSQ_S_W_PH:
19110             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19111             break;
19112         case NM_BALIGN:
19113             check_dsp_r2(ctx);
19114             if (rt != 0) {
19115                 gen_load_gpr(t0, rs);
19116                 rd &= 3;
19117                 if (rd != 0 && rd != 2) {
19118                     tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
19119                     tcg_gen_ext32u_tl(t0, t0);
19120                     tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
19121                     tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
19122                 }
19123                 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
19124             }
19125             break;
19126         case NM_MADD:
19127             check_dsp(ctx);
19128             {
19129                 int acc = extract32(ctx->opcode, 14, 2);
19130                 TCGv_i64 t2 = tcg_temp_new_i64();
19131                 TCGv_i64 t3 = tcg_temp_new_i64();
19132
19133                 gen_load_gpr(t0, rt);
19134                 gen_load_gpr(t1, rs);
19135                 tcg_gen_ext_tl_i64(t2, t0);
19136                 tcg_gen_ext_tl_i64(t3, t1);
19137                 tcg_gen_mul_i64(t2, t2, t3);
19138                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19139                 tcg_gen_add_i64(t2, t2, t3);
19140                 tcg_temp_free_i64(t3);
19141                 gen_move_low32(cpu_LO[acc], t2);
19142                 gen_move_high32(cpu_HI[acc], t2);
19143                 tcg_temp_free_i64(t2);
19144             }
19145             break;
19146         case NM_MULT:
19147             check_dsp(ctx);
19148             {
19149                 int acc = extract32(ctx->opcode, 14, 2);
19150                 TCGv_i32 t2 = tcg_temp_new_i32();
19151                 TCGv_i32 t3 = tcg_temp_new_i32();
19152
19153                 gen_load_gpr(t0, rs);
19154                 gen_load_gpr(t1, rt);
19155                 tcg_gen_trunc_tl_i32(t2, t0);
19156                 tcg_gen_trunc_tl_i32(t3, t1);
19157                 tcg_gen_muls2_i32(t2, t3, t2, t3);
19158                 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19159                 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19160                 tcg_temp_free_i32(t2);
19161                 tcg_temp_free_i32(t3);
19162             }
19163             break;
19164         case NM_EXTRV_W:
19165             check_dsp(ctx);
19166             gen_load_gpr(v1_t, rs);
19167             tcg_gen_movi_tl(t0, rd >> 3);
19168             gen_helper_extr_w(t0, t0, v1_t, cpu_env);
19169             gen_store_gpr(t0, ret);
19170             break;
19171         }
19172         break;
19173     case NM_POOL32AXF_2_8_15:
19174         switch (extract32(ctx->opcode, 9, 3)) {
19175         case NM_DPAX_W_PH:
19176         case NM_DPAQ_SA_L_W:
19177         case NM_DPSX_W_PH:
19178         case NM_DPSQ_SA_L_W:
19179             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19180             break;
19181         case NM_MADDU:
19182             check_dsp(ctx);
19183             {
19184                 int acc = extract32(ctx->opcode, 14, 2);
19185                 TCGv_i64 t2 = tcg_temp_new_i64();
19186                 TCGv_i64 t3 = tcg_temp_new_i64();
19187
19188                 gen_load_gpr(t0, rs);
19189                 gen_load_gpr(t1, rt);
19190                 tcg_gen_ext32u_tl(t0, t0);
19191                 tcg_gen_ext32u_tl(t1, t1);
19192                 tcg_gen_extu_tl_i64(t2, t0);
19193                 tcg_gen_extu_tl_i64(t3, t1);
19194                 tcg_gen_mul_i64(t2, t2, t3);
19195                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19196                 tcg_gen_add_i64(t2, t2, t3);
19197                 tcg_temp_free_i64(t3);
19198                 gen_move_low32(cpu_LO[acc], t2);
19199                 gen_move_high32(cpu_HI[acc], t2);
19200                 tcg_temp_free_i64(t2);
19201             }
19202             break;
19203         case NM_MULTU:
19204             check_dsp(ctx);
19205             {
19206                 int acc = extract32(ctx->opcode, 14, 2);
19207                 TCGv_i32 t2 = tcg_temp_new_i32();
19208                 TCGv_i32 t3 = tcg_temp_new_i32();
19209
19210                 gen_load_gpr(t0, rs);
19211                 gen_load_gpr(t1, rt);
19212                 tcg_gen_trunc_tl_i32(t2, t0);
19213                 tcg_gen_trunc_tl_i32(t3, t1);
19214                 tcg_gen_mulu2_i32(t2, t3, t2, t3);
19215                 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19216                 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19217                 tcg_temp_free_i32(t2);
19218                 tcg_temp_free_i32(t3);
19219             }
19220             break;
19221         case NM_EXTRV_R_W:
19222             check_dsp(ctx);
19223             tcg_gen_movi_tl(t0, rd >> 3);
19224             gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
19225             gen_store_gpr(t0, ret);
19226             break;
19227         default:
19228             generate_exception_end(ctx, EXCP_RI);
19229             break;
19230         }
19231         break;
19232     case NM_POOL32AXF_2_16_23:
19233         switch (extract32(ctx->opcode, 9, 3)) {
19234         case NM_DPAU_H_QBL:
19235         case NM_DPAQX_S_W_PH:
19236         case NM_DPSU_H_QBL:
19237         case NM_DPSQX_S_W_PH:
19238         case NM_MULSA_W_PH:
19239             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19240             break;
19241         case NM_EXTPV:
19242             check_dsp(ctx);
19243             tcg_gen_movi_tl(t0, rd >> 3);
19244             gen_helper_extp(t0, t0, v1_t, cpu_env);
19245             gen_store_gpr(t0, ret);
19246             break;
19247         case NM_MSUB:
19248             check_dsp(ctx);
19249             {
19250                 int acc = extract32(ctx->opcode, 14, 2);
19251                 TCGv_i64 t2 = tcg_temp_new_i64();
19252                 TCGv_i64 t3 = tcg_temp_new_i64();
19253
19254                 gen_load_gpr(t0, rs);
19255                 gen_load_gpr(t1, rt);
19256                 tcg_gen_ext_tl_i64(t2, t0);
19257                 tcg_gen_ext_tl_i64(t3, t1);
19258                 tcg_gen_mul_i64(t2, t2, t3);
19259                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19260                 tcg_gen_sub_i64(t2, t3, t2);
19261                 tcg_temp_free_i64(t3);
19262                 gen_move_low32(cpu_LO[acc], t2);
19263                 gen_move_high32(cpu_HI[acc], t2);
19264                 tcg_temp_free_i64(t2);
19265             }
19266             break;
19267         case NM_EXTRV_RS_W:
19268             check_dsp(ctx);
19269             tcg_gen_movi_tl(t0, rd >> 3);
19270             gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
19271             gen_store_gpr(t0, ret);
19272             break;
19273         }
19274         break;
19275     case NM_POOL32AXF_2_24_31:
19276         switch (extract32(ctx->opcode, 9, 3)) {
19277         case NM_DPAU_H_QBR:
19278         case NM_DPAQX_SA_W_PH:
19279         case NM_DPSU_H_QBR:
19280         case NM_DPSQX_SA_W_PH:
19281         case NM_MULSAQ_S_W_PH:
19282             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19283             break;
19284         case NM_EXTPDPV:
19285             check_dsp(ctx);
19286             tcg_gen_movi_tl(t0, rd >> 3);
19287             gen_helper_extpdp(t0, t0, v1_t, cpu_env);
19288             gen_store_gpr(t0, ret);
19289             break;
19290         case NM_MSUBU:
19291             check_dsp(ctx);
19292             {
19293                 int acc = extract32(ctx->opcode, 14, 2);
19294                 TCGv_i64 t2 = tcg_temp_new_i64();
19295                 TCGv_i64 t3 = tcg_temp_new_i64();
19296
19297                 gen_load_gpr(t0, rs);
19298                 gen_load_gpr(t1, rt);
19299                 tcg_gen_ext32u_tl(t0, t0);
19300                 tcg_gen_ext32u_tl(t1, t1);
19301                 tcg_gen_extu_tl_i64(t2, t0);
19302                 tcg_gen_extu_tl_i64(t3, t1);
19303                 tcg_gen_mul_i64(t2, t2, t3);
19304                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19305                 tcg_gen_sub_i64(t2, t3, t2);
19306                 tcg_temp_free_i64(t3);
19307                 gen_move_low32(cpu_LO[acc], t2);
19308                 gen_move_high32(cpu_HI[acc], t2);
19309                 tcg_temp_free_i64(t2);
19310             }
19311             break;
19312         case NM_EXTRV_S_H:
19313             check_dsp(ctx);
19314             tcg_gen_movi_tl(t0, rd >> 3);
19315             gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
19316             gen_store_gpr(t0, ret);
19317             break;
19318         }
19319         break;
19320     default:
19321         generate_exception_end(ctx, EXCP_RI);
19322         break;
19323     }
19324
19325     tcg_temp_free(t0);
19326     tcg_temp_free(t1);
19327
19328     tcg_temp_free(v0_t);
19329     tcg_temp_free(v1_t);
19330 }
19331
19332 static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
19333                                           int rt, int rs)
19334 {
19335     int ret = rt;
19336     TCGv t0 = tcg_temp_new();
19337     TCGv v0_t = tcg_temp_new();
19338
19339     gen_load_gpr(v0_t, rs);
19340
19341     switch (opc) {
19342     case NM_ABSQ_S_QB:
19343         check_dsp_r2(ctx);
19344         gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
19345         gen_store_gpr(v0_t, ret);
19346         break;
19347     case NM_ABSQ_S_PH:
19348         check_dsp(ctx);
19349         gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
19350         gen_store_gpr(v0_t, ret);
19351         break;
19352     case NM_ABSQ_S_W:
19353         check_dsp(ctx);
19354         gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
19355         gen_store_gpr(v0_t, ret);
19356         break;
19357     case NM_PRECEQ_W_PHL:
19358         check_dsp(ctx);
19359         tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
19360         tcg_gen_ext32s_tl(v0_t, v0_t);
19361         gen_store_gpr(v0_t, ret);
19362         break;
19363     case NM_PRECEQ_W_PHR:
19364         check_dsp(ctx);
19365         tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
19366         tcg_gen_shli_tl(v0_t, v0_t, 16);
19367         tcg_gen_ext32s_tl(v0_t, v0_t);
19368         gen_store_gpr(v0_t, ret);
19369         break;
19370     case NM_PRECEQU_PH_QBL:
19371         check_dsp(ctx);
19372         gen_helper_precequ_ph_qbl(v0_t, v0_t);
19373         gen_store_gpr(v0_t, ret);
19374         break;
19375     case NM_PRECEQU_PH_QBR:
19376         check_dsp(ctx);
19377         gen_helper_precequ_ph_qbr(v0_t, v0_t);
19378         gen_store_gpr(v0_t, ret);
19379         break;
19380     case NM_PRECEQU_PH_QBLA:
19381         check_dsp(ctx);
19382         gen_helper_precequ_ph_qbla(v0_t, v0_t);
19383         gen_store_gpr(v0_t, ret);
19384         break;
19385     case NM_PRECEQU_PH_QBRA:
19386         check_dsp(ctx);
19387         gen_helper_precequ_ph_qbra(v0_t, v0_t);
19388         gen_store_gpr(v0_t, ret);
19389         break;
19390     case NM_PRECEU_PH_QBL:
19391         check_dsp(ctx);
19392         gen_helper_preceu_ph_qbl(v0_t, v0_t);
19393         gen_store_gpr(v0_t, ret);
19394         break;
19395     case NM_PRECEU_PH_QBR:
19396         check_dsp(ctx);
19397         gen_helper_preceu_ph_qbr(v0_t, v0_t);
19398         gen_store_gpr(v0_t, ret);
19399         break;
19400     case NM_PRECEU_PH_QBLA:
19401         check_dsp(ctx);
19402         gen_helper_preceu_ph_qbla(v0_t, v0_t);
19403         gen_store_gpr(v0_t, ret);
19404         break;
19405     case NM_PRECEU_PH_QBRA:
19406         check_dsp(ctx);
19407         gen_helper_preceu_ph_qbra(v0_t, v0_t);
19408         gen_store_gpr(v0_t, ret);
19409         break;
19410     case NM_REPLV_PH:
19411         check_dsp(ctx);
19412         tcg_gen_ext16u_tl(v0_t, v0_t);
19413         tcg_gen_shli_tl(t0, v0_t, 16);
19414         tcg_gen_or_tl(v0_t, v0_t, t0);
19415         tcg_gen_ext32s_tl(v0_t, v0_t);
19416         gen_store_gpr(v0_t, ret);
19417         break;
19418     case NM_REPLV_QB:
19419         check_dsp(ctx);
19420         tcg_gen_ext8u_tl(v0_t, v0_t);
19421         tcg_gen_shli_tl(t0, v0_t, 8);
19422         tcg_gen_or_tl(v0_t, v0_t, t0);
19423         tcg_gen_shli_tl(t0, v0_t, 16);
19424         tcg_gen_or_tl(v0_t, v0_t, t0);
19425         tcg_gen_ext32s_tl(v0_t, v0_t);
19426         gen_store_gpr(v0_t, ret);
19427         break;
19428     case NM_BITREV:
19429         check_dsp(ctx);
19430         gen_helper_bitrev(v0_t, v0_t);
19431         gen_store_gpr(v0_t, ret);
19432         break;
19433     case NM_INSV:
19434         check_dsp(ctx);
19435         {
19436             TCGv tv0 = tcg_temp_new();
19437
19438             gen_load_gpr(tv0, rt);
19439             gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19440             gen_store_gpr(v0_t, ret);
19441             tcg_temp_free(tv0);
19442         }
19443         break;
19444     case NM_RADDU_W_QB:
19445         check_dsp(ctx);
19446         gen_helper_raddu_w_qb(v0_t, v0_t);
19447         gen_store_gpr(v0_t, ret);
19448         break;
19449     case NM_BITSWAP:
19450         gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19451         break;
19452     case NM_CLO:
19453         check_nms(ctx);
19454         gen_cl(ctx, OPC_CLO, ret, rs);
19455         break;
19456     case NM_CLZ:
19457         check_nms(ctx);
19458         gen_cl(ctx, OPC_CLZ, ret, rs);
19459         break;
19460     case NM_WSBH:
19461         gen_bshfl(ctx, OPC_WSBH, ret, rs);
19462         break;
19463     default:
19464         generate_exception_end(ctx, EXCP_RI);
19465         break;
19466     }
19467
19468     tcg_temp_free(v0_t);
19469     tcg_temp_free(t0);
19470 }
19471
19472 static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19473                                           int rt, int rs, int rd)
19474 {
19475     TCGv t0 = tcg_temp_new();
19476     TCGv rs_t = tcg_temp_new();
19477
19478     gen_load_gpr(rs_t, rs);
19479
19480     switch (opc) {
19481     case NM_SHRA_R_QB:
19482         check_dsp_r2(ctx);
19483         tcg_gen_movi_tl(t0, rd >> 2);
19484         switch (extract32(ctx->opcode, 12, 1)) {
19485         case 0:
19486             /* NM_SHRA_QB */
19487             gen_helper_shra_qb(t0, t0, rs_t);
19488             gen_store_gpr(t0, rt);
19489             break;
19490         case 1:
19491             /* NM_SHRA_R_QB */
19492             gen_helper_shra_r_qb(t0, t0, rs_t);
19493             gen_store_gpr(t0, rt);
19494             break;
19495         }
19496         break;
19497     case NM_SHRL_PH:
19498         check_dsp_r2(ctx);
19499         tcg_gen_movi_tl(t0, rd >> 1);
19500         gen_helper_shrl_ph(t0, t0, rs_t);
19501         gen_store_gpr(t0, rt);
19502         break;
19503     case NM_REPL_QB:
19504         check_dsp(ctx);
19505         {
19506             int16_t imm;
19507             target_long result;
19508             imm = extract32(ctx->opcode, 13, 8);
19509             result = (uint32_t)imm << 24 |
19510                      (uint32_t)imm << 16 |
19511                      (uint32_t)imm << 8  |
19512                      (uint32_t)imm;
19513             result = (int32_t)result;
19514             tcg_gen_movi_tl(t0, result);
19515             gen_store_gpr(t0, rt);
19516         }
19517         break;
19518     default:
19519         generate_exception_end(ctx, EXCP_RI);
19520         break;
19521     }
19522     tcg_temp_free(t0);
19523     tcg_temp_free(rs_t);
19524 }
19525
19526
19527 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19528 {
19529     int rt = extract32(ctx->opcode, 21, 5);
19530     int rs = extract32(ctx->opcode, 16, 5);
19531     int rd = extract32(ctx->opcode, 11, 5);
19532
19533     switch (extract32(ctx->opcode, 6, 3)) {
19534     case NM_POOL32AXF_1:
19535         {
19536             int32_t op1 = extract32(ctx->opcode, 9, 3);
19537             gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19538         }
19539         break;
19540     case NM_POOL32AXF_2:
19541         {
19542             int32_t op1 = extract32(ctx->opcode, 12, 2);
19543             gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19544         }
19545         break;
19546     case NM_POOL32AXF_4:
19547         {
19548             int32_t op1 = extract32(ctx->opcode, 9, 7);
19549             gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19550         }
19551         break;
19552     case NM_POOL32AXF_5:
19553         switch (extract32(ctx->opcode, 9, 7)) {
19554 #ifndef CONFIG_USER_ONLY
19555         case NM_TLBP:
19556             gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19557             break;
19558         case NM_TLBR:
19559             gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19560             break;
19561         case NM_TLBWI:
19562             gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19563             break;
19564         case NM_TLBWR:
19565             gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19566             break;
19567         case NM_TLBINV:
19568             gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19569             break;
19570         case NM_TLBINVF:
19571             gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19572             break;
19573         case NM_DI:
19574             check_cp0_enabled(ctx);
19575             {
19576                 TCGv t0 = tcg_temp_new();
19577
19578                 save_cpu_state(ctx, 1);
19579                 gen_helper_di(t0, cpu_env);
19580                 gen_store_gpr(t0, rt);
19581             /* Stop translation as we may have switched the execution mode */
19582                 ctx->base.is_jmp = DISAS_STOP;
19583                 tcg_temp_free(t0);
19584             }
19585             break;
19586         case NM_EI:
19587             check_cp0_enabled(ctx);
19588             {
19589                 TCGv t0 = tcg_temp_new();
19590
19591                 save_cpu_state(ctx, 1);
19592                 gen_helper_ei(t0, cpu_env);
19593                 gen_store_gpr(t0, rt);
19594             /* Stop translation as we may have switched the execution mode */
19595                 ctx->base.is_jmp = DISAS_STOP;
19596                 tcg_temp_free(t0);
19597             }
19598             break;
19599         case NM_RDPGPR:
19600             gen_load_srsgpr(rs, rt);
19601             break;
19602         case NM_WRPGPR:
19603             gen_store_srsgpr(rs, rt);
19604             break;
19605         case NM_WAIT:
19606             gen_cp0(env, ctx, OPC_WAIT, 0, 0);
19607             break;
19608         case NM_DERET:
19609             gen_cp0(env, ctx, OPC_DERET, 0, 0);
19610             break;
19611         case NM_ERETX:
19612             gen_cp0(env, ctx, OPC_ERET, 0, 0);
19613             break;
19614 #endif
19615         default:
19616             generate_exception_end(ctx, EXCP_RI);
19617             break;
19618         }
19619         break;
19620     case NM_POOL32AXF_7:
19621         {
19622             int32_t op1 = extract32(ctx->opcode, 9, 3);
19623             gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
19624         }
19625         break;
19626     default:
19627         generate_exception_end(ctx, EXCP_RI);
19628         break;
19629     }
19630 }
19631
19632 /* Immediate Value Compact Branches */
19633 static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19634                                    int rt, int32_t imm, int32_t offset)
19635 {
19636     TCGCond cond;
19637     int bcond_compute = 0;
19638     TCGv t0 = tcg_temp_new();
19639     TCGv t1 = tcg_temp_new();
19640
19641     gen_load_gpr(t0, rt);
19642     tcg_gen_movi_tl(t1, imm);
19643     ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19644
19645     /* Load needed operands and calculate btarget */
19646     switch (opc) {
19647     case NM_BEQIC:
19648         if (rt == 0 && imm == 0) {
19649             /* Unconditional branch */
19650         } else if (rt == 0 && imm != 0) {
19651             /* Treat as NOP */
19652             goto out;
19653         } else {
19654             bcond_compute = 1;
19655             cond = TCG_COND_EQ;
19656         }
19657         break;
19658     case NM_BBEQZC:
19659     case NM_BBNEZC:
19660         check_nms(ctx);
19661         if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19662             generate_exception_end(ctx, EXCP_RI);
19663             goto out;
19664         } else if (rt == 0 && opc == NM_BBEQZC) {
19665             /* Unconditional branch */
19666         } else if (rt == 0 && opc == NM_BBNEZC) {
19667             /* Treat as NOP */
19668             goto out;
19669         } else {
19670             tcg_gen_shri_tl(t0, t0, imm);
19671             tcg_gen_andi_tl(t0, t0, 1);
19672             tcg_gen_movi_tl(t1, 0);
19673             bcond_compute = 1;
19674             if (opc == NM_BBEQZC) {
19675                 cond = TCG_COND_EQ;
19676             } else {
19677                 cond = TCG_COND_NE;
19678             }
19679         }
19680         break;
19681     case NM_BNEIC:
19682         if (rt == 0 && imm == 0) {
19683             /* Treat as NOP */
19684             goto out;
19685         } else if (rt == 0 && imm != 0) {
19686             /* Unconditional branch */
19687         } else {
19688             bcond_compute = 1;
19689             cond = TCG_COND_NE;
19690         }
19691         break;
19692     case NM_BGEIC:
19693         if (rt == 0 && imm == 0) {
19694             /* Unconditional branch */
19695         } else  {
19696             bcond_compute = 1;
19697             cond = TCG_COND_GE;
19698         }
19699         break;
19700     case NM_BLTIC:
19701         bcond_compute = 1;
19702         cond = TCG_COND_LT;
19703         break;
19704     case NM_BGEIUC:
19705         if (rt == 0 && imm == 0) {
19706             /* Unconditional branch */
19707         } else  {
19708             bcond_compute = 1;
19709             cond = TCG_COND_GEU;
19710         }
19711         break;
19712     case NM_BLTIUC:
19713         bcond_compute = 1;
19714         cond = TCG_COND_LTU;
19715         break;
19716     default:
19717         MIPS_INVAL("Immediate Value Compact branch");
19718         generate_exception_end(ctx, EXCP_RI);
19719         goto out;
19720     }
19721
19722     /* branch completion */
19723     clear_branch_hflags(ctx);
19724     ctx->base.is_jmp = DISAS_NORETURN;
19725
19726     if (bcond_compute == 0) {
19727         /* Uncoditional compact branch */
19728         gen_goto_tb(ctx, 0, ctx->btarget);
19729     } else {
19730         /* Conditional compact branch */
19731         TCGLabel *fs = gen_new_label();
19732
19733         tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
19734
19735         gen_goto_tb(ctx, 1, ctx->btarget);
19736         gen_set_label(fs);
19737
19738         gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19739     }
19740
19741 out:
19742     tcg_temp_free(t0);
19743     tcg_temp_free(t1);
19744 }
19745
19746 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19747 static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
19748                                                 int rt)
19749 {
19750     TCGv t0 = tcg_temp_new();
19751     TCGv t1 = tcg_temp_new();
19752
19753     /* load rs */
19754     gen_load_gpr(t0, rs);
19755
19756     /* link */
19757     if (rt != 0) {
19758         tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
19759     }
19760
19761     /* calculate btarget */
19762     tcg_gen_shli_tl(t0, t0, 1);
19763     tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
19764     gen_op_addr_add(ctx, btarget, t1, t0);
19765
19766     /* branch completion */
19767     clear_branch_hflags(ctx);
19768     ctx->base.is_jmp = DISAS_NORETURN;
19769
19770     /* unconditional branch to register */
19771     tcg_gen_mov_tl(cpu_PC, btarget);
19772     tcg_gen_lookup_and_goto_ptr();
19773
19774     tcg_temp_free(t0);
19775     tcg_temp_free(t1);
19776 }
19777
19778 /* nanoMIPS Branches */
19779 static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
19780                                        int rs, int rt, int32_t offset)
19781 {
19782     int bcond_compute = 0;
19783     TCGv t0 = tcg_temp_new();
19784     TCGv t1 = tcg_temp_new();
19785
19786     /* Load needed operands and calculate btarget */
19787     switch (opc) {
19788     /* compact branch */
19789     case OPC_BGEC:
19790     case OPC_BLTC:
19791         gen_load_gpr(t0, rs);
19792         gen_load_gpr(t1, rt);
19793         bcond_compute = 1;
19794         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19795         break;
19796     case OPC_BGEUC:
19797     case OPC_BLTUC:
19798         if (rs == 0 || rs == rt) {
19799             /* OPC_BLEZALC, OPC_BGEZALC */
19800             /* OPC_BGTZALC, OPC_BLTZALC */
19801             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
19802         }
19803         gen_load_gpr(t0, rs);
19804         gen_load_gpr(t1, rt);
19805         bcond_compute = 1;
19806         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19807         break;
19808     case OPC_BC:
19809         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19810         break;
19811     case OPC_BEQZC:
19812         if (rs != 0) {
19813             /* OPC_BEQZC, OPC_BNEZC */
19814             gen_load_gpr(t0, rs);
19815             bcond_compute = 1;
19816             ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19817         } else {
19818             /* OPC_JIC, OPC_JIALC */
19819             TCGv tbase = tcg_temp_new();
19820             TCGv toffset = tcg_temp_new();
19821
19822             gen_load_gpr(tbase, rt);
19823             tcg_gen_movi_tl(toffset, offset);
19824             gen_op_addr_add(ctx, btarget, tbase, toffset);
19825             tcg_temp_free(tbase);
19826             tcg_temp_free(toffset);
19827         }
19828         break;
19829     default:
19830         MIPS_INVAL("Compact branch/jump");
19831         generate_exception_end(ctx, EXCP_RI);
19832         goto out;
19833     }
19834
19835     if (bcond_compute == 0) {
19836         /* Uncoditional compact branch */
19837         switch (opc) {
19838         case OPC_BC:
19839             gen_goto_tb(ctx, 0, ctx->btarget);
19840             break;
19841         default:
19842             MIPS_INVAL("Compact branch/jump");
19843             generate_exception_end(ctx, EXCP_RI);
19844             goto out;
19845         }
19846     } else {
19847         /* Conditional compact branch */
19848         TCGLabel *fs = gen_new_label();
19849
19850         switch (opc) {
19851         case OPC_BGEUC:
19852             if (rs == 0 && rt != 0) {
19853                 /* OPC_BLEZALC */
19854                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19855             } else if (rs != 0 && rt != 0 && rs == rt) {
19856                 /* OPC_BGEZALC */
19857                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19858             } else {
19859                 /* OPC_BGEUC */
19860                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
19861             }
19862             break;
19863         case OPC_BLTUC:
19864             if (rs == 0 && rt != 0) {
19865                 /* OPC_BGTZALC */
19866                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19867             } else if (rs != 0 && rt != 0 && rs == rt) {
19868                 /* OPC_BLTZALC */
19869                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19870             } else {
19871                 /* OPC_BLTUC */
19872                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
19873             }
19874             break;
19875         case OPC_BGEC:
19876             if (rs == 0 && rt != 0) {
19877                 /* OPC_BLEZC */
19878                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19879             } else if (rs != 0 && rt != 0 && rs == rt) {
19880                 /* OPC_BGEZC */
19881                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19882             } else {
19883                 /* OPC_BGEC */
19884                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
19885             }
19886             break;
19887         case OPC_BLTC:
19888             if (rs == 0 && rt != 0) {
19889                 /* OPC_BGTZC */
19890                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19891             } else if (rs != 0 && rt != 0 && rs == rt) {
19892                 /* OPC_BLTZC */
19893                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19894             } else {
19895                 /* OPC_BLTC */
19896                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
19897             }
19898             break;
19899         case OPC_BEQZC:
19900             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
19901             break;
19902         default:
19903             MIPS_INVAL("Compact conditional branch/jump");
19904             generate_exception_end(ctx, EXCP_RI);
19905             goto out;
19906         }
19907
19908         /* branch completion */
19909         clear_branch_hflags(ctx);
19910         ctx->base.is_jmp = DISAS_NORETURN;
19911
19912         /* Generating branch here as compact branches don't have delay slot */
19913         gen_goto_tb(ctx, 1, ctx->btarget);
19914         gen_set_label(fs);
19915
19916         gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19917     }
19918
19919 out:
19920     tcg_temp_free(t0);
19921     tcg_temp_free(t1);
19922 }
19923
19924
19925 /* nanoMIPS CP1 Branches */
19926 static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
19927                                    int32_t ft, int32_t offset)
19928 {
19929     target_ulong btarget;
19930     TCGv_i64 t0 = tcg_temp_new_i64();
19931
19932     gen_load_fpr64(ctx, t0, ft);
19933     tcg_gen_andi_i64(t0, t0, 1);
19934
19935     btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19936
19937     switch (op) {
19938     case NM_BC1EQZC:
19939         tcg_gen_xori_i64(t0, t0, 1);
19940         ctx->hflags |= MIPS_HFLAG_BC;
19941         break;
19942     case NM_BC1NEZC:
19943         /* t0 already set */
19944         ctx->hflags |= MIPS_HFLAG_BC;
19945         break;
19946     default:
19947         MIPS_INVAL("cp1 cond branch");
19948         generate_exception_end(ctx, EXCP_RI);
19949         goto out;
19950     }
19951
19952     tcg_gen_trunc_i64_tl(bcond, t0);
19953
19954     ctx->btarget = btarget;
19955
19956 out:
19957     tcg_temp_free_i64(t0);
19958 }
19959
19960
19961 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
19962 {
19963     TCGv t0, t1;
19964     t0 = tcg_temp_new();
19965     t1 = tcg_temp_new();
19966
19967     gen_load_gpr(t0, rs);
19968     gen_load_gpr(t1, rt);
19969
19970     if ((extract32(ctx->opcode, 6, 1)) == 1) {
19971         /* PP.LSXS instructions require shifting */
19972         switch (extract32(ctx->opcode, 7, 4)) {
19973         case NM_SHXS:
19974             check_nms(ctx);
19975         case NM_LHXS:
19976         case NM_LHUXS:
19977             tcg_gen_shli_tl(t0, t0, 1);
19978             break;
19979         case NM_SWXS:
19980             check_nms(ctx);
19981         case NM_LWXS:
19982         case NM_LWC1XS:
19983         case NM_SWC1XS:
19984             tcg_gen_shli_tl(t0, t0, 2);
19985             break;
19986         case NM_LDC1XS:
19987         case NM_SDC1XS:
19988             tcg_gen_shli_tl(t0, t0, 3);
19989             break;
19990         }
19991     }
19992     gen_op_addr_add(ctx, t0, t0, t1);
19993
19994     switch (extract32(ctx->opcode, 7, 4)) {
19995     case NM_LBX:
19996         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19997                            MO_SB);
19998         gen_store_gpr(t0, rd);
19999         break;
20000     case NM_LHX:
20001     /*case NM_LHXS:*/
20002         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20003                            MO_TESW);
20004         gen_store_gpr(t0, rd);
20005         break;
20006     case NM_LWX:
20007     /*case NM_LWXS:*/
20008         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20009                            MO_TESL);
20010         gen_store_gpr(t0, rd);
20011         break;
20012     case NM_LBUX:
20013         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20014                            MO_UB);
20015         gen_store_gpr(t0, rd);
20016         break;
20017     case NM_LHUX:
20018     /*case NM_LHUXS:*/
20019         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20020                            MO_TEUW);
20021         gen_store_gpr(t0, rd);
20022         break;
20023     case NM_SBX:
20024         check_nms(ctx);
20025         gen_load_gpr(t1, rd);
20026         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20027                            MO_8);
20028         break;
20029     case NM_SHX:
20030     /*case NM_SHXS:*/
20031         check_nms(ctx);
20032         gen_load_gpr(t1, rd);
20033         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20034                            MO_TEUW);
20035         break;
20036     case NM_SWX:
20037     /*case NM_SWXS:*/
20038         check_nms(ctx);
20039         gen_load_gpr(t1, rd);
20040         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20041                            MO_TEUL);
20042         break;
20043     case NM_LWC1X:
20044     /*case NM_LWC1XS:*/
20045     case NM_LDC1X:
20046     /*case NM_LDC1XS:*/
20047     case NM_SWC1X:
20048     /*case NM_SWC1XS:*/
20049     case NM_SDC1X:
20050     /*case NM_SDC1XS:*/
20051         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
20052             check_cp1_enabled(ctx);
20053             switch (extract32(ctx->opcode, 7, 4)) {
20054             case NM_LWC1X:
20055             /*case NM_LWC1XS:*/
20056                 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
20057                 break;
20058             case NM_LDC1X:
20059             /*case NM_LDC1XS:*/
20060                 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
20061                 break;
20062             case NM_SWC1X:
20063             /*case NM_SWC1XS:*/
20064                 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
20065                 break;
20066             case NM_SDC1X:
20067             /*case NM_SDC1XS:*/
20068                 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
20069                 break;
20070             }
20071         } else {
20072             generate_exception_err(ctx, EXCP_CpU, 1);
20073         }
20074         break;
20075     default:
20076         generate_exception_end(ctx, EXCP_RI);
20077         break;
20078     }
20079
20080     tcg_temp_free(t0);
20081     tcg_temp_free(t1);
20082 }
20083
20084 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
20085 {
20086     int rt, rs, rd;
20087
20088     rt = extract32(ctx->opcode, 21, 5);
20089     rs = extract32(ctx->opcode, 16, 5);
20090     rd = extract32(ctx->opcode, 11, 5);
20091
20092     if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
20093         generate_exception_end(ctx, EXCP_RI);
20094         return;
20095     }
20096     check_cp1_enabled(ctx);
20097     switch (extract32(ctx->opcode, 0, 3)) {
20098     case NM_POOL32F_0:
20099         switch (extract32(ctx->opcode, 3, 7)) {
20100         case NM_RINT_S:
20101             gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
20102             break;
20103         case NM_RINT_D:
20104             gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
20105             break;
20106         case NM_CLASS_S:
20107             gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
20108             break;
20109         case NM_CLASS_D:
20110             gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
20111             break;
20112         case NM_ADD_S:
20113             gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
20114             break;
20115         case NM_ADD_D:
20116             gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
20117             break;
20118         case NM_SUB_S:
20119             gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
20120             break;
20121         case NM_SUB_D:
20122             gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
20123             break;
20124         case NM_MUL_S:
20125             gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
20126             break;
20127         case NM_MUL_D:
20128             gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
20129             break;
20130         case NM_DIV_S:
20131             gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
20132             break;
20133         case NM_DIV_D:
20134             gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
20135             break;
20136         case NM_SELEQZ_S:
20137             gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
20138             break;
20139         case NM_SELEQZ_D:
20140             gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
20141             break;
20142         case NM_SELNEZ_S:
20143             gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
20144             break;
20145         case NM_SELNEZ_D:
20146             gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
20147             break;
20148         case NM_SEL_S:
20149             gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
20150             break;
20151         case NM_SEL_D:
20152             gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
20153             break;
20154         case NM_MADDF_S:
20155             gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
20156             break;
20157         case NM_MADDF_D:
20158             gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
20159             break;
20160         case NM_MSUBF_S:
20161             gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
20162             break;
20163         case NM_MSUBF_D:
20164             gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
20165             break;
20166         default:
20167             generate_exception_end(ctx, EXCP_RI);
20168             break;
20169         }
20170         break;
20171     case NM_POOL32F_3:
20172         switch (extract32(ctx->opcode, 3, 3)) {
20173         case NM_MIN_FMT:
20174             switch (extract32(ctx->opcode, 9, 1)) {
20175             case FMT_SDPS_S:
20176                 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
20177                 break;
20178             case FMT_SDPS_D:
20179                 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
20180                 break;
20181             }
20182             break;
20183         case NM_MAX_FMT:
20184             switch (extract32(ctx->opcode, 9, 1)) {
20185             case FMT_SDPS_S:
20186                 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
20187                 break;
20188             case FMT_SDPS_D:
20189                 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
20190                 break;
20191             }
20192             break;
20193         case NM_MINA_FMT:
20194             switch (extract32(ctx->opcode, 9, 1)) {
20195             case FMT_SDPS_S:
20196                 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
20197                 break;
20198             case FMT_SDPS_D:
20199                 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
20200                 break;
20201             }
20202             break;
20203         case NM_MAXA_FMT:
20204             switch (extract32(ctx->opcode, 9, 1)) {
20205             case FMT_SDPS_S:
20206                 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
20207                 break;
20208             case FMT_SDPS_D:
20209                 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
20210                 break;
20211             }
20212             break;
20213         case NM_POOL32FXF:
20214             switch (extract32(ctx->opcode, 6, 8)) {
20215             case NM_CFC1:
20216                 gen_cp1(ctx, OPC_CFC1, rt, rs);
20217                 break;
20218             case NM_CTC1:
20219                 gen_cp1(ctx, OPC_CTC1, rt, rs);
20220                 break;
20221             case NM_MFC1:
20222                 gen_cp1(ctx, OPC_MFC1, rt, rs);
20223                 break;
20224             case NM_MTC1:
20225                 gen_cp1(ctx, OPC_MTC1, rt, rs);
20226                 break;
20227             case NM_MFHC1:
20228                 gen_cp1(ctx, OPC_MFHC1, rt, rs);
20229                 break;
20230             case NM_MTHC1:
20231                 gen_cp1(ctx, OPC_MTHC1, rt, rs);
20232                 break;
20233             case NM_CVT_S_PL:
20234                 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
20235                 break;
20236             case NM_CVT_S_PU:
20237                 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
20238                 break;
20239             default:
20240                 switch (extract32(ctx->opcode, 6, 9)) {
20241                 case NM_CVT_L_S:
20242                     gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
20243                     break;
20244                 case NM_CVT_L_D:
20245                     gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
20246                     break;
20247                 case NM_CVT_W_S:
20248                     gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
20249                     break;
20250                 case NM_CVT_W_D:
20251                     gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
20252                     break;
20253                 case NM_RSQRT_S:
20254                     gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
20255                     break;
20256                 case NM_RSQRT_D:
20257                     gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
20258                     break;
20259                 case NM_SQRT_S:
20260                     gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
20261                     break;
20262                 case NM_SQRT_D:
20263                     gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
20264                     break;
20265                 case NM_RECIP_S:
20266                     gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
20267                     break;
20268                 case NM_RECIP_D:
20269                     gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
20270                     break;
20271                 case NM_FLOOR_L_S:
20272                     gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
20273                     break;
20274                 case NM_FLOOR_L_D:
20275                     gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
20276                     break;
20277                 case NM_FLOOR_W_S:
20278                     gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
20279                     break;
20280                 case NM_FLOOR_W_D:
20281                     gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
20282                     break;
20283                 case NM_CEIL_L_S:
20284                     gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
20285                     break;
20286                 case NM_CEIL_L_D:
20287                     gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
20288                     break;
20289                 case NM_CEIL_W_S:
20290                     gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
20291                     break;
20292                 case NM_CEIL_W_D:
20293                     gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
20294                     break;
20295                 case NM_TRUNC_L_S:
20296                     gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
20297                     break;
20298                 case NM_TRUNC_L_D:
20299                     gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
20300                     break;
20301                 case NM_TRUNC_W_S:
20302                     gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
20303                     break;
20304                 case NM_TRUNC_W_D:
20305                     gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
20306                     break;
20307                 case NM_ROUND_L_S:
20308                     gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
20309                     break;
20310                 case NM_ROUND_L_D:
20311                     gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
20312                     break;
20313                 case NM_ROUND_W_S:
20314                     gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
20315                     break;
20316                 case NM_ROUND_W_D:
20317                     gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
20318                     break;
20319                 case NM_MOV_S:
20320                     gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
20321                     break;
20322                 case NM_MOV_D:
20323                     gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
20324                     break;
20325                 case NM_ABS_S:
20326                     gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
20327                     break;
20328                 case NM_ABS_D:
20329                     gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
20330                     break;
20331                 case NM_NEG_S:
20332                     gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
20333                     break;
20334                 case NM_NEG_D:
20335                     gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
20336                     break;
20337                 case NM_CVT_D_S:
20338                     gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
20339                     break;
20340                 case NM_CVT_D_W:
20341                     gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
20342                     break;
20343                 case NM_CVT_D_L:
20344                     gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
20345                     break;
20346                 case NM_CVT_S_D:
20347                     gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
20348                     break;
20349                 case NM_CVT_S_W:
20350                     gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
20351                     break;
20352                 case NM_CVT_S_L:
20353                     gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
20354                     break;
20355                 default:
20356                     generate_exception_end(ctx, EXCP_RI);
20357                     break;
20358                 }
20359                 break;
20360             }
20361             break;
20362         }
20363         break;
20364     case NM_POOL32F_5:
20365         switch (extract32(ctx->opcode, 3, 3)) {
20366         case NM_CMP_CONDN_S:
20367             gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20368             break;
20369         case NM_CMP_CONDN_D:
20370             gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20371             break;
20372         default:
20373             generate_exception_end(ctx, EXCP_RI);
20374             break;
20375         }
20376         break;
20377     default:
20378         generate_exception_end(ctx, EXCP_RI);
20379         break;
20380     }
20381 }
20382
20383 static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
20384                                        int rd, int rs, int rt)
20385 {
20386     int ret = rd;
20387     TCGv t0 = tcg_temp_new();
20388     TCGv v1_t = tcg_temp_new();
20389     TCGv v2_t = tcg_temp_new();
20390
20391     gen_load_gpr(v1_t, rs);
20392     gen_load_gpr(v2_t, rt);
20393
20394     switch (opc) {
20395     case NM_CMP_EQ_PH:
20396         check_dsp(ctx);
20397         gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
20398         break;
20399     case NM_CMP_LT_PH:
20400         check_dsp(ctx);
20401         gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
20402         break;
20403     case NM_CMP_LE_PH:
20404         check_dsp(ctx);
20405         gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
20406         break;
20407     case NM_CMPU_EQ_QB:
20408         check_dsp(ctx);
20409         gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
20410         break;
20411     case NM_CMPU_LT_QB:
20412         check_dsp(ctx);
20413         gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
20414         break;
20415     case NM_CMPU_LE_QB:
20416         check_dsp(ctx);
20417         gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
20418         break;
20419     case NM_CMPGU_EQ_QB:
20420         check_dsp(ctx);
20421         gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20422         gen_store_gpr(v1_t, ret);
20423         break;
20424     case NM_CMPGU_LT_QB:
20425         check_dsp(ctx);
20426         gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20427         gen_store_gpr(v1_t, ret);
20428         break;
20429     case NM_CMPGU_LE_QB:
20430         check_dsp(ctx);
20431         gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20432         gen_store_gpr(v1_t, ret);
20433         break;
20434     case NM_CMPGDU_EQ_QB:
20435         check_dsp_r2(ctx);
20436         gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20437         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20438         gen_store_gpr(v1_t, ret);
20439         break;
20440     case NM_CMPGDU_LT_QB:
20441         check_dsp_r2(ctx);
20442         gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20443         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20444         gen_store_gpr(v1_t, ret);
20445         break;
20446     case NM_CMPGDU_LE_QB:
20447         check_dsp_r2(ctx);
20448         gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20449         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20450         gen_store_gpr(v1_t, ret);
20451         break;
20452     case NM_PACKRL_PH:
20453         check_dsp(ctx);
20454         gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20455         gen_store_gpr(v1_t, ret);
20456         break;
20457     case NM_PICK_QB:
20458         check_dsp(ctx);
20459         gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20460         gen_store_gpr(v1_t, ret);
20461         break;
20462     case NM_PICK_PH:
20463         check_dsp(ctx);
20464         gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20465         gen_store_gpr(v1_t, ret);
20466         break;
20467     case NM_ADDQ_S_W:
20468         check_dsp(ctx);
20469         gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20470         gen_store_gpr(v1_t, ret);
20471         break;
20472     case NM_SUBQ_S_W:
20473         check_dsp(ctx);
20474         gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20475         gen_store_gpr(v1_t, ret);
20476         break;
20477     case NM_ADDSC:
20478         check_dsp(ctx);
20479         gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20480         gen_store_gpr(v1_t, ret);
20481         break;
20482     case NM_ADDWC:
20483         check_dsp(ctx);
20484         gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20485         gen_store_gpr(v1_t, ret);
20486         break;
20487     case NM_ADDQ_S_PH:
20488         check_dsp(ctx);
20489         switch (extract32(ctx->opcode, 10, 1)) {
20490         case 0:
20491             /* ADDQ_PH */
20492             gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20493             gen_store_gpr(v1_t, ret);
20494             break;
20495         case 1:
20496             /* ADDQ_S_PH */
20497             gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20498             gen_store_gpr(v1_t, ret);
20499             break;
20500         }
20501         break;
20502     case NM_ADDQH_R_PH:
20503         check_dsp_r2(ctx);
20504         switch (extract32(ctx->opcode, 10, 1)) {
20505         case 0:
20506             /* ADDQH_PH */
20507             gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20508             gen_store_gpr(v1_t, ret);
20509             break;
20510         case 1:
20511             /* ADDQH_R_PH */
20512             gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20513             gen_store_gpr(v1_t, ret);
20514             break;
20515         }
20516         break;
20517     case NM_ADDQH_R_W:
20518         check_dsp_r2(ctx);
20519         switch (extract32(ctx->opcode, 10, 1)) {
20520         case 0:
20521             /* ADDQH_W */
20522             gen_helper_addqh_w(v1_t, v1_t, v2_t);
20523             gen_store_gpr(v1_t, ret);
20524             break;
20525         case 1:
20526             /* ADDQH_R_W */
20527             gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20528             gen_store_gpr(v1_t, ret);
20529             break;
20530         }
20531         break;
20532     case NM_ADDU_S_QB:
20533         check_dsp(ctx);
20534         switch (extract32(ctx->opcode, 10, 1)) {
20535         case 0:
20536             /* ADDU_QB */
20537             gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20538             gen_store_gpr(v1_t, ret);
20539             break;
20540         case 1:
20541             /* ADDU_S_QB */
20542             gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20543             gen_store_gpr(v1_t, ret);
20544             break;
20545         }
20546         break;
20547     case NM_ADDU_S_PH:
20548         check_dsp_r2(ctx);
20549         switch (extract32(ctx->opcode, 10, 1)) {
20550         case 0:
20551             /* ADDU_PH */
20552             gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20553             gen_store_gpr(v1_t, ret);
20554             break;
20555         case 1:
20556             /* ADDU_S_PH */
20557             gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20558             gen_store_gpr(v1_t, ret);
20559             break;
20560         }
20561         break;
20562     case NM_ADDUH_R_QB:
20563         check_dsp_r2(ctx);
20564         switch (extract32(ctx->opcode, 10, 1)) {
20565         case 0:
20566             /* ADDUH_QB */
20567             gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20568             gen_store_gpr(v1_t, ret);
20569             break;
20570         case 1:
20571             /* ADDUH_R_QB */
20572             gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20573             gen_store_gpr(v1_t, ret);
20574             break;
20575         }
20576         break;
20577     case NM_SHRAV_R_PH:
20578         check_dsp(ctx);
20579         switch (extract32(ctx->opcode, 10, 1)) {
20580         case 0:
20581             /* SHRAV_PH */
20582             gen_helper_shra_ph(v1_t, v1_t, v2_t);
20583             gen_store_gpr(v1_t, ret);
20584             break;
20585         case 1:
20586             /* SHRAV_R_PH */
20587             gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20588             gen_store_gpr(v1_t, ret);
20589             break;
20590         }
20591         break;
20592     case NM_SHRAV_R_QB:
20593         check_dsp_r2(ctx);
20594         switch (extract32(ctx->opcode, 10, 1)) {
20595         case 0:
20596             /* SHRAV_QB */
20597             gen_helper_shra_qb(v1_t, v1_t, v2_t);
20598             gen_store_gpr(v1_t, ret);
20599             break;
20600         case 1:
20601             /* SHRAV_R_QB */
20602             gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20603             gen_store_gpr(v1_t, ret);
20604             break;
20605         }
20606         break;
20607     case NM_SUBQ_S_PH:
20608         check_dsp(ctx);
20609         switch (extract32(ctx->opcode, 10, 1)) {
20610         case 0:
20611             /* SUBQ_PH */
20612             gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
20613             gen_store_gpr(v1_t, ret);
20614             break;
20615         case 1:
20616             /* SUBQ_S_PH */
20617             gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20618             gen_store_gpr(v1_t, ret);
20619             break;
20620         }
20621         break;
20622     case NM_SUBQH_R_PH:
20623         check_dsp_r2(ctx);
20624         switch (extract32(ctx->opcode, 10, 1)) {
20625         case 0:
20626             /* SUBQH_PH */
20627             gen_helper_subqh_ph(v1_t, v1_t, v2_t);
20628             gen_store_gpr(v1_t, ret);
20629             break;
20630         case 1:
20631             /* SUBQH_R_PH */
20632             gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
20633             gen_store_gpr(v1_t, ret);
20634             break;
20635         }
20636         break;
20637     case NM_SUBQH_R_W:
20638         check_dsp_r2(ctx);
20639         switch (extract32(ctx->opcode, 10, 1)) {
20640         case 0:
20641             /* SUBQH_W */
20642             gen_helper_subqh_w(v1_t, v1_t, v2_t);
20643             gen_store_gpr(v1_t, ret);
20644             break;
20645         case 1:
20646             /* SUBQH_R_W */
20647             gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20648             gen_store_gpr(v1_t, ret);
20649             break;
20650         }
20651         break;
20652     case NM_SUBU_S_QB:
20653         check_dsp(ctx);
20654         switch (extract32(ctx->opcode, 10, 1)) {
20655         case 0:
20656             /* SUBU_QB */
20657             gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20658             gen_store_gpr(v1_t, ret);
20659             break;
20660         case 1:
20661             /* SUBU_S_QB */
20662             gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20663             gen_store_gpr(v1_t, ret);
20664             break;
20665         }
20666         break;
20667     case NM_SUBU_S_PH:
20668         check_dsp_r2(ctx);
20669         switch (extract32(ctx->opcode, 10, 1)) {
20670         case 0:
20671             /* SUBU_PH */
20672             gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20673             gen_store_gpr(v1_t, ret);
20674             break;
20675         case 1:
20676             /* SUBU_S_PH */
20677             gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20678             gen_store_gpr(v1_t, ret);
20679             break;
20680         }
20681         break;
20682     case NM_SUBUH_R_QB:
20683         check_dsp_r2(ctx);
20684         switch (extract32(ctx->opcode, 10, 1)) {
20685         case 0:
20686             /* SUBUH_QB */
20687             gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20688             gen_store_gpr(v1_t, ret);
20689             break;
20690         case 1:
20691             /* SUBUH_R_QB */
20692             gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
20693             gen_store_gpr(v1_t, ret);
20694             break;
20695         }
20696         break;
20697     case NM_SHLLV_S_PH:
20698         check_dsp(ctx);
20699         switch (extract32(ctx->opcode, 10, 1)) {
20700         case 0:
20701             /* SHLLV_PH */
20702             gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
20703             gen_store_gpr(v1_t, ret);
20704             break;
20705         case 1:
20706             /* SHLLV_S_PH */
20707             gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
20708             gen_store_gpr(v1_t, ret);
20709             break;
20710         }
20711         break;
20712     case NM_PRECR_SRA_R_PH_W:
20713         check_dsp_r2(ctx);
20714         switch (extract32(ctx->opcode, 10, 1)) {
20715         case 0:
20716             /* PRECR_SRA_PH_W */
20717             {
20718                 TCGv_i32 sa_t = tcg_const_i32(rd);
20719                 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
20720                                           cpu_gpr[rt]);
20721                 gen_store_gpr(v1_t, rt);
20722                 tcg_temp_free_i32(sa_t);
20723             }
20724             break;
20725         case 1:
20726             /* PRECR_SRA_R_PH_W */
20727             {
20728                 TCGv_i32 sa_t = tcg_const_i32(rd);
20729                 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
20730                                             cpu_gpr[rt]);
20731                 gen_store_gpr(v1_t, rt);
20732                 tcg_temp_free_i32(sa_t);
20733             }
20734             break;
20735        }
20736         break;
20737     case NM_MULEU_S_PH_QBL:
20738         check_dsp(ctx);
20739         gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
20740         gen_store_gpr(v1_t, ret);
20741         break;
20742     case NM_MULEU_S_PH_QBR:
20743         check_dsp(ctx);
20744         gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
20745         gen_store_gpr(v1_t, ret);
20746         break;
20747     case NM_MULQ_RS_PH:
20748         check_dsp(ctx);
20749         gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
20750         gen_store_gpr(v1_t, ret);
20751         break;
20752     case NM_MULQ_S_PH:
20753         check_dsp_r2(ctx);
20754         gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20755         gen_store_gpr(v1_t, ret);
20756         break;
20757     case NM_MULQ_RS_W:
20758         check_dsp_r2(ctx);
20759         gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
20760         gen_store_gpr(v1_t, ret);
20761         break;
20762     case NM_MULQ_S_W:
20763         check_dsp_r2(ctx);
20764         gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
20765         gen_store_gpr(v1_t, ret);
20766         break;
20767     case NM_APPEND:
20768         check_dsp_r2(ctx);
20769         gen_load_gpr(t0, rs);
20770         if (rd != 0) {
20771             tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
20772         }
20773         tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20774         break;
20775     case NM_MODSUB:
20776         check_dsp(ctx);
20777         gen_helper_modsub(v1_t, v1_t, v2_t);
20778         gen_store_gpr(v1_t, ret);
20779         break;
20780     case NM_SHRAV_R_W:
20781         check_dsp(ctx);
20782         gen_helper_shra_r_w(v1_t, v1_t, v2_t);
20783         gen_store_gpr(v1_t, ret);
20784         break;
20785     case NM_SHRLV_PH:
20786         check_dsp_r2(ctx);
20787         gen_helper_shrl_ph(v1_t, v1_t, v2_t);
20788         gen_store_gpr(v1_t, ret);
20789         break;
20790     case NM_SHRLV_QB:
20791         check_dsp(ctx);
20792         gen_helper_shrl_qb(v1_t, v1_t, v2_t);
20793         gen_store_gpr(v1_t, ret);
20794         break;
20795     case NM_SHLLV_QB:
20796         check_dsp(ctx);
20797         gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
20798         gen_store_gpr(v1_t, ret);
20799         break;
20800     case NM_SHLLV_S_W:
20801         check_dsp(ctx);
20802         gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
20803         gen_store_gpr(v1_t, ret);
20804         break;
20805     case NM_SHILO:
20806         check_dsp(ctx);
20807         {
20808             TCGv tv0 = tcg_temp_new();
20809             TCGv tv1 = tcg_temp_new();
20810             int16_t imm = extract32(ctx->opcode, 16, 7);
20811
20812             tcg_gen_movi_tl(tv0, rd >> 3);
20813             tcg_gen_movi_tl(tv1, imm);
20814             gen_helper_shilo(tv0, tv1, cpu_env);
20815         }
20816         break;
20817     case NM_MULEQ_S_W_PHL:
20818         check_dsp(ctx);
20819         gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
20820         gen_store_gpr(v1_t, ret);
20821         break;
20822     case NM_MULEQ_S_W_PHR:
20823         check_dsp(ctx);
20824         gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
20825         gen_store_gpr(v1_t, ret);
20826         break;
20827     case NM_MUL_S_PH:
20828         check_dsp_r2(ctx);
20829         switch (extract32(ctx->opcode, 10, 1)) {
20830         case 0:
20831             /* MUL_PH */
20832             gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
20833             gen_store_gpr(v1_t, ret);
20834             break;
20835         case 1:
20836             /* MUL_S_PH */
20837             gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
20838             gen_store_gpr(v1_t, ret);
20839             break;
20840         }
20841         break;
20842     case NM_PRECR_QB_PH:
20843         check_dsp_r2(ctx);
20844         gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
20845         gen_store_gpr(v1_t, ret);
20846         break;
20847     case NM_PRECRQ_QB_PH:
20848         check_dsp(ctx);
20849         gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
20850         gen_store_gpr(v1_t, ret);
20851         break;
20852     case NM_PRECRQ_PH_W:
20853         check_dsp(ctx);
20854         gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
20855         gen_store_gpr(v1_t, ret);
20856         break;
20857     case NM_PRECRQ_RS_PH_W:
20858         check_dsp(ctx);
20859         gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
20860         gen_store_gpr(v1_t, ret);
20861         break;
20862     case NM_PRECRQU_S_QB_PH:
20863         check_dsp(ctx);
20864         gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
20865         gen_store_gpr(v1_t, ret);
20866         break;
20867     case NM_SHRA_R_W:
20868         check_dsp(ctx);
20869         tcg_gen_movi_tl(t0, rd);
20870         gen_helper_shra_r_w(v1_t, t0, v1_t);
20871         gen_store_gpr(v1_t, rt);
20872         break;
20873     case NM_SHRA_R_PH:
20874         check_dsp(ctx);
20875         tcg_gen_movi_tl(t0, rd >> 1);
20876         switch (extract32(ctx->opcode, 10, 1)) {
20877         case 0:
20878             /* SHRA_PH */
20879             gen_helper_shra_ph(v1_t, t0, v1_t);
20880             gen_store_gpr(v1_t, rt);
20881             break;
20882         case 1:
20883             /* SHRA_R_PH */
20884             gen_helper_shra_r_ph(v1_t, t0, v1_t);
20885             gen_store_gpr(v1_t, rt);
20886             break;
20887         }
20888         break;
20889     case NM_SHLL_S_PH:
20890         check_dsp(ctx);
20891         tcg_gen_movi_tl(t0, rd >> 1);
20892         switch (extract32(ctx->opcode, 10, 2)) {
20893         case 0:
20894             /* SHLL_PH */
20895             gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
20896             gen_store_gpr(v1_t, rt);
20897             break;
20898         case 2:
20899             /* SHLL_S_PH */
20900             gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
20901             gen_store_gpr(v1_t, rt);
20902             break;
20903         default:
20904             generate_exception_end(ctx, EXCP_RI);
20905             break;
20906         }
20907         break;
20908     case NM_SHLL_S_W:
20909         check_dsp(ctx);
20910         tcg_gen_movi_tl(t0, rd);
20911         gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
20912         gen_store_gpr(v1_t, rt);
20913         break;
20914     case NM_REPL_PH:
20915         check_dsp(ctx);
20916         {
20917             int16_t imm;
20918             imm = sextract32(ctx->opcode, 11, 11);
20919             imm = (int16_t)(imm << 6) >> 6;
20920             if (rt != 0) {
20921                 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
20922             }
20923         }
20924         break;
20925     default:
20926         generate_exception_end(ctx, EXCP_RI);
20927         break;
20928     }
20929 }
20930
20931 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
20932 {
20933     uint16_t insn;
20934     uint32_t op;
20935     int rt, rs, rd;
20936     int offset;
20937     int imm;
20938
20939     insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
20940     ctx->opcode = (ctx->opcode << 16) | insn;
20941
20942     rt = extract32(ctx->opcode, 21, 5);
20943     rs = extract32(ctx->opcode, 16, 5);
20944     rd = extract32(ctx->opcode, 11, 5);
20945
20946     op = extract32(ctx->opcode, 26, 6);
20947     switch (op) {
20948     case NM_P_ADDIU:
20949         if (rt == 0) {
20950             /* P.RI */
20951             switch (extract32(ctx->opcode, 19, 2)) {
20952             case NM_SIGRIE:
20953             default:
20954                 generate_exception_end(ctx, EXCP_RI);
20955                 break;
20956             case NM_P_SYSCALL:
20957                 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
20958                     generate_exception_end(ctx, EXCP_SYSCALL);
20959                 } else {
20960                     generate_exception_end(ctx, EXCP_RI);
20961                 }
20962                 break;
20963             case NM_BREAK:
20964                 generate_exception_end(ctx, EXCP_BREAK);
20965                 break;
20966             case NM_SDBBP:
20967                 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
20968                     gen_helper_do_semihosting(cpu_env);
20969                 } else {
20970                     if (ctx->hflags & MIPS_HFLAG_SBRI) {
20971                         generate_exception_end(ctx, EXCP_RI);
20972                     } else {
20973                         generate_exception_end(ctx, EXCP_DBp);
20974                     }
20975                 }
20976                 break;
20977             }
20978         } else {
20979             /* NM_ADDIU */
20980             imm = extract32(ctx->opcode, 0, 16);
20981             if (rs != 0) {
20982                 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
20983             } else {
20984                 tcg_gen_movi_tl(cpu_gpr[rt], imm);
20985             }
20986             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20987         }
20988         break;
20989     case NM_ADDIUPC:
20990         if (rt != 0) {
20991             offset = sextract32(ctx->opcode, 0, 1) << 21 |
20992                      extract32(ctx->opcode, 1, 20) << 1;
20993             target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
20994             tcg_gen_movi_tl(cpu_gpr[rt], addr);
20995         }
20996         break;
20997     case NM_POOL32A:
20998         switch (ctx->opcode & 0x07) {
20999         case NM_POOL32A0:
21000             gen_pool32a0_nanomips_insn(env, ctx);
21001             break;
21002         case NM_POOL32A5:
21003             {
21004                 int32_t op1 = extract32(ctx->opcode, 3, 7);
21005                 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
21006             }
21007             break;
21008         case NM_POOL32A7:
21009             switch (extract32(ctx->opcode, 3, 3)) {
21010             case NM_P_LSX:
21011                 gen_p_lsx(ctx, rd, rs, rt);
21012                 break;
21013             case NM_LSA:
21014                 /* In nanoMIPS, the shift field directly encodes the shift
21015                  * amount, meaning that the supported shift values are in
21016                  * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
21017                 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
21018                         extract32(ctx->opcode, 9, 2) - 1);
21019                 break;
21020             case NM_EXTW:
21021                 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
21022                 break;
21023             case NM_POOL32AXF:
21024                 gen_pool32axf_nanomips_insn(env, ctx);
21025                 break;
21026             default:
21027                 generate_exception_end(ctx, EXCP_RI);
21028                 break;
21029             }
21030             break;
21031         default:
21032             generate_exception_end(ctx, EXCP_RI);
21033             break;
21034         }
21035         break;
21036     case NM_P_GP_W:
21037         switch (ctx->opcode & 0x03) {
21038         case NM_ADDIUGP_W:
21039             if (rt != 0) {
21040                 offset = extract32(ctx->opcode, 0, 21);
21041                 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
21042             }
21043             break;
21044         case NM_LWGP:
21045             gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21046             break;
21047         case NM_SWGP:
21048             gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21049             break;
21050         default:
21051             generate_exception_end(ctx, EXCP_RI);
21052             break;
21053         }
21054         break;
21055     case NM_P48I:
21056         {
21057             insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
21058             target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
21059             switch (extract32(ctx->opcode, 16, 5)) {
21060             case NM_LI48:
21061                 check_nms(ctx);
21062                 if (rt != 0) {
21063                     tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
21064                 }
21065                 break;
21066             case NM_ADDIU48:
21067                 check_nms(ctx);
21068                 if (rt != 0) {
21069                     tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
21070                     tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21071                 }
21072                 break;
21073             case NM_ADDIUGP48:
21074                 check_nms(ctx);
21075                 if (rt != 0) {
21076                     gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
21077                 }
21078                 break;
21079             case NM_ADDIUPC48:
21080                 check_nms(ctx);
21081                 if (rt != 0) {
21082                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21083                                                 addr_off);
21084
21085                     tcg_gen_movi_tl(cpu_gpr[rt], addr);
21086                 }
21087                 break;
21088             case NM_LWPC48:
21089                 check_nms(ctx);
21090                 if (rt != 0) {
21091                     TCGv t0;
21092                     t0 = tcg_temp_new();
21093
21094                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21095                                                 addr_off);
21096
21097                     tcg_gen_movi_tl(t0, addr);
21098                     tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
21099                     tcg_temp_free(t0);
21100                 }
21101                 break;
21102             case NM_SWPC48:
21103                 check_nms(ctx);
21104                 {
21105                     TCGv t0, t1;
21106                     t0 = tcg_temp_new();
21107                     t1 = tcg_temp_new();
21108
21109                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21110                                                 addr_off);
21111
21112                     tcg_gen_movi_tl(t0, addr);
21113                     gen_load_gpr(t1, rt);
21114
21115                     tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
21116
21117                     tcg_temp_free(t0);
21118                     tcg_temp_free(t1);
21119                 }
21120                 break;
21121             default:
21122                 generate_exception_end(ctx, EXCP_RI);
21123                 break;
21124             }
21125             return 6;
21126         }
21127     case NM_P_U12:
21128         switch (extract32(ctx->opcode, 12, 4)) {
21129         case NM_ORI:
21130             gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
21131             break;
21132         case NM_XORI:
21133             gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
21134             break;
21135         case NM_ANDI:
21136             gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
21137             break;
21138         case NM_P_SR:
21139             switch (extract32(ctx->opcode, 20, 1)) {
21140             case NM_PP_SR:
21141                 switch (ctx->opcode & 3) {
21142                 case NM_SAVE:
21143                     gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
21144                              extract32(ctx->opcode, 2, 1),
21145                              extract32(ctx->opcode, 3, 9) << 3);
21146                     break;
21147                 case NM_RESTORE:
21148                 case NM_RESTORE_JRC:
21149                     gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
21150                                 extract32(ctx->opcode, 2, 1),
21151                                 extract32(ctx->opcode, 3, 9) << 3);
21152                     if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
21153                         gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21154                     }
21155                     break;
21156                 default:
21157                     generate_exception_end(ctx, EXCP_RI);
21158                     break;
21159                 }
21160                 break;
21161             case NM_P_SR_F:
21162                 generate_exception_end(ctx, EXCP_RI);
21163                 break;
21164             }
21165             break;
21166         case NM_SLTI:
21167             gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
21168             break;
21169         case NM_SLTIU:
21170             gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
21171             break;
21172         case NM_SEQI:
21173             {
21174                 TCGv t0 = tcg_temp_new();
21175
21176                 imm = extract32(ctx->opcode, 0, 12);
21177                 gen_load_gpr(t0, rs);
21178                 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
21179                 gen_store_gpr(t0, rt);
21180
21181                 tcg_temp_free(t0);
21182             }
21183             break;
21184         case NM_ADDIUNEG:
21185             imm = (int16_t) extract32(ctx->opcode, 0, 12);
21186             gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
21187             break;
21188         case NM_P_SHIFT:
21189             {
21190                 int shift = extract32(ctx->opcode, 0, 5);
21191                 switch (extract32(ctx->opcode, 5, 4)) {
21192                 case NM_P_SLL:
21193                     if (rt == 0 && shift == 0) {
21194                         /* NOP */
21195                     } else if (rt == 0 && shift == 3) {
21196                         /* EHB - treat as NOP */
21197                     } else if (rt == 0 && shift == 5) {
21198                         /* PAUSE - treat as NOP */
21199                     } else if (rt == 0 && shift == 6) {
21200                         /* SYNC */
21201                         gen_sync(extract32(ctx->opcode, 16, 5));
21202                     } else {
21203                         /* SLL */
21204                         gen_shift_imm(ctx, OPC_SLL, rt, rs,
21205                                       extract32(ctx->opcode, 0, 5));
21206                     }
21207                     break;
21208                 case NM_SRL:
21209                     gen_shift_imm(ctx, OPC_SRL, rt, rs,
21210                                   extract32(ctx->opcode, 0, 5));
21211                     break;
21212                 case NM_SRA:
21213                     gen_shift_imm(ctx, OPC_SRA, rt, rs,
21214                                   extract32(ctx->opcode, 0, 5));
21215                     break;
21216                 case NM_ROTR:
21217                     gen_shift_imm(ctx, OPC_ROTR, rt, rs,
21218                                   extract32(ctx->opcode, 0, 5));
21219                     break;
21220                 }
21221             }
21222             break;
21223         case NM_P_ROTX:
21224             check_nms(ctx);
21225             if (rt != 0) {
21226                 TCGv t0 = tcg_temp_new();
21227                 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
21228                 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
21229                                                 << 1);
21230                 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
21231
21232                 gen_load_gpr(t0, rs);
21233                 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
21234                 tcg_temp_free(t0);
21235
21236                 tcg_temp_free_i32(shift);
21237                 tcg_temp_free_i32(shiftx);
21238                 tcg_temp_free_i32(stripe);
21239             }
21240             break;
21241         case NM_P_INS:
21242             switch (((ctx->opcode >> 10) & 2) |
21243                     (extract32(ctx->opcode, 5, 1))) {
21244             case NM_INS:
21245                 check_nms(ctx);
21246                 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
21247                            extract32(ctx->opcode, 6, 5));
21248                 break;
21249             default:
21250                 generate_exception_end(ctx, EXCP_RI);
21251                 break;
21252             }
21253             break;
21254         case NM_P_EXT:
21255             switch (((ctx->opcode >> 10) & 2) |
21256                     (extract32(ctx->opcode, 5, 1))) {
21257             case NM_EXT:
21258                 check_nms(ctx);
21259                 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
21260                            extract32(ctx->opcode, 6, 5));
21261                 break;
21262             default:
21263                 generate_exception_end(ctx, EXCP_RI);
21264                 break;
21265             }
21266             break;
21267         default:
21268             generate_exception_end(ctx, EXCP_RI);
21269             break;
21270         }
21271         break;
21272     case NM_POOL32F:
21273         gen_pool32f_nanomips_insn(ctx);
21274         break;
21275     case NM_POOL32S:
21276         break;
21277     case NM_P_LUI:
21278         switch (extract32(ctx->opcode, 1, 1)) {
21279         case NM_LUI:
21280             if (rt != 0) {
21281                 tcg_gen_movi_tl(cpu_gpr[rt],
21282                                 sextract32(ctx->opcode, 0, 1) << 31 |
21283                                 extract32(ctx->opcode, 2, 10) << 21 |
21284                                 extract32(ctx->opcode, 12, 9) << 12);
21285             }
21286             break;
21287         case NM_ALUIPC:
21288             if (rt != 0) {
21289                 offset = sextract32(ctx->opcode, 0, 1) << 31 |
21290                          extract32(ctx->opcode, 2, 10) << 21 |
21291                          extract32(ctx->opcode, 12, 9) << 12;
21292                 target_long addr;
21293                 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
21294                 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21295             }
21296             break;
21297         }
21298         break;
21299     case NM_P_GP_BH:
21300         {
21301             uint32_t u = extract32(ctx->opcode, 0, 18);
21302
21303             switch (extract32(ctx->opcode, 18, 3)) {
21304             case NM_LBGP:
21305                 gen_ld(ctx, OPC_LB, rt, 28, u);
21306                 break;
21307             case NM_SBGP:
21308                 gen_st(ctx, OPC_SB, rt, 28, u);
21309                 break;
21310             case NM_LBUGP:
21311                 gen_ld(ctx, OPC_LBU, rt, 28, u);
21312                 break;
21313             case NM_ADDIUGP_B:
21314                 if (rt != 0) {
21315                     gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
21316                 }
21317                 break;
21318             case NM_P_GP_LH:
21319                 u &= ~1;
21320                 switch (ctx->opcode & 1) {
21321                 case NM_LHGP:
21322                     gen_ld(ctx, OPC_LH, rt, 28, u);
21323                     break;
21324                 case NM_LHUGP:
21325                     gen_ld(ctx, OPC_LHU, rt, 28, u);
21326                     break;
21327                 }
21328                 break;
21329             case NM_P_GP_SH:
21330                 u &= ~1;
21331                 switch (ctx->opcode & 1) {
21332                 case NM_SHGP:
21333                     gen_st(ctx, OPC_SH, rt, 28, u);
21334                     break;
21335                 default:
21336                     generate_exception_end(ctx, EXCP_RI);
21337                     break;
21338                 }
21339                 break;
21340             case NM_P_GP_CP1:
21341                 u &= ~0x3;
21342                 switch (ctx->opcode & 0x3) {
21343                 case NM_LWC1GP:
21344                     gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
21345                     break;
21346                 case NM_LDC1GP:
21347                     gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
21348                     break;
21349                 case NM_SWC1GP:
21350                     gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
21351                     break;
21352                 case NM_SDC1GP:
21353                     gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
21354                     break;
21355                 }
21356                 break;
21357             default:
21358                 generate_exception_end(ctx, EXCP_RI);
21359                 break;
21360             }
21361         }
21362         break;
21363     case NM_P_LS_U12:
21364         {
21365             uint32_t u = extract32(ctx->opcode, 0, 12);
21366
21367             switch (extract32(ctx->opcode, 12, 4)) {
21368             case NM_P_PREFU12:
21369                 if (rt == 31) {
21370                     /* SYNCI */
21371                     /* Break the TB to be able to sync copied instructions
21372                        immediately */
21373                     ctx->base.is_jmp = DISAS_STOP;
21374                 } else {
21375                     /* PREF */
21376                     /* Treat as NOP. */
21377                 }
21378                 break;
21379             case NM_LB:
21380                 gen_ld(ctx, OPC_LB, rt, rs, u);
21381                 break;
21382             case NM_LH:
21383                 gen_ld(ctx, OPC_LH, rt, rs, u);
21384                 break;
21385             case NM_LW:
21386                 gen_ld(ctx, OPC_LW, rt, rs, u);
21387                 break;
21388             case NM_LBU:
21389                 gen_ld(ctx, OPC_LBU, rt, rs, u);
21390                 break;
21391             case NM_LHU:
21392                 gen_ld(ctx, OPC_LHU, rt, rs, u);
21393                 break;
21394             case NM_SB:
21395                 gen_st(ctx, OPC_SB, rt, rs, u);
21396                 break;
21397             case NM_SH:
21398                 gen_st(ctx, OPC_SH, rt, rs, u);
21399                 break;
21400             case NM_SW:
21401                 gen_st(ctx, OPC_SW, rt, rs, u);
21402                 break;
21403             case NM_LWC1:
21404                 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
21405                 break;
21406             case NM_LDC1:
21407                 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
21408                 break;
21409             case NM_SWC1:
21410                 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
21411                 break;
21412             case NM_SDC1:
21413                 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
21414                 break;
21415             default:
21416                 generate_exception_end(ctx, EXCP_RI);
21417                 break;
21418             }
21419         }
21420         break;
21421     case NM_P_LS_S9:
21422         {
21423             int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
21424                         extract32(ctx->opcode, 0, 8);
21425
21426             switch (extract32(ctx->opcode, 8, 3)) {
21427             case NM_P_LS_S0:
21428                 switch (extract32(ctx->opcode, 11, 4)) {
21429                 case NM_LBS9:
21430                     gen_ld(ctx, OPC_LB, rt, rs, s);
21431                     break;
21432                 case NM_LHS9:
21433                     gen_ld(ctx, OPC_LH, rt, rs, s);
21434                     break;
21435                 case NM_LWS9:
21436                     gen_ld(ctx, OPC_LW, rt, rs, s);
21437                     break;
21438                 case NM_LBUS9:
21439                     gen_ld(ctx, OPC_LBU, rt, rs, s);
21440                     break;
21441                 case NM_LHUS9:
21442                     gen_ld(ctx, OPC_LHU, rt, rs, s);
21443                     break;
21444                 case NM_SBS9:
21445                     gen_st(ctx, OPC_SB, rt, rs, s);
21446                     break;
21447                 case NM_SHS9:
21448                     gen_st(ctx, OPC_SH, rt, rs, s);
21449                     break;
21450                 case NM_SWS9:
21451                     gen_st(ctx, OPC_SW, rt, rs, s);
21452                     break;
21453                 case NM_LWC1S9:
21454                     gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21455                     break;
21456                 case NM_LDC1S9:
21457                     gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21458                     break;
21459                 case NM_SWC1S9:
21460                     gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21461                     break;
21462                 case NM_SDC1S9:
21463                     gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21464                     break;
21465                 case NM_P_PREFS9:
21466                     if (rt == 31) {
21467                         /* SYNCI */
21468                         /* Break the TB to be able to sync copied instructions
21469                            immediately */
21470                         ctx->base.is_jmp = DISAS_STOP;
21471                     } else {
21472                         /* PREF */
21473                         /* Treat as NOP. */
21474                     }
21475                     break;
21476                 default:
21477                     generate_exception_end(ctx, EXCP_RI);
21478                     break;
21479                 }
21480                 break;
21481             case NM_P_LS_S1:
21482                 switch (extract32(ctx->opcode, 11, 4)) {
21483                 case NM_UALH:
21484                 case NM_UASH:
21485                     check_nms(ctx);
21486                     {
21487                         TCGv t0 = tcg_temp_new();
21488                         TCGv t1 = tcg_temp_new();
21489
21490                         gen_base_offset_addr(ctx, t0, rs, s);
21491
21492                         switch (extract32(ctx->opcode, 11, 4)) {
21493                         case NM_UALH:
21494                             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21495                                                MO_UNALN);
21496                             gen_store_gpr(t0, rt);
21497                             break;
21498                         case NM_UASH:
21499                             gen_load_gpr(t1, rt);
21500                             tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21501                                                MO_UNALN);
21502                             break;
21503                         }
21504                         tcg_temp_free(t0);
21505                         tcg_temp_free(t1);
21506                     }
21507                     break;
21508                 case NM_P_LL:
21509                     switch (ctx->opcode & 0x03) {
21510                     case NM_LL:
21511                         gen_ld(ctx, OPC_LL, rt, rs, s);
21512                         break;
21513                     case NM_LLWP:
21514                         check_xnp(ctx);
21515                         gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21516                         break;
21517                     }
21518                     break;
21519                 case NM_P_SC:
21520                     switch (ctx->opcode & 0x03) {
21521                     case NM_SC:
21522                         gen_st_cond(ctx, rt, rs, s, MO_TESL, false);
21523                         break;
21524                     case NM_SCWP:
21525                         check_xnp(ctx);
21526                         gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
21527                                  false);
21528                         break;
21529                     }
21530                     break;
21531                 case NM_CACHE:
21532                     check_cp0_enabled(ctx);
21533                     if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21534                         gen_cache_operation(ctx, rt, rs, s);
21535                     }
21536                     break;
21537                 }
21538                 break;
21539             case NM_P_LS_E0:
21540                 switch (extract32(ctx->opcode, 11, 4)) {
21541                 case NM_LBE:
21542                     check_eva(ctx);
21543                     check_cp0_enabled(ctx);
21544                     gen_ld(ctx, OPC_LBE, rt, rs, s);
21545                     break;
21546                 case NM_SBE:
21547                     check_eva(ctx);
21548                     check_cp0_enabled(ctx);
21549                     gen_st(ctx, OPC_SBE, rt, rs, s);
21550                     break;
21551                 case NM_LBUE:
21552                     check_eva(ctx);
21553                     check_cp0_enabled(ctx);
21554                     gen_ld(ctx, OPC_LBUE, rt, rs, s);
21555                     break;
21556                 case NM_P_PREFE:
21557                     if (rt == 31) {
21558                         /* case NM_SYNCIE */
21559                         check_eva(ctx);
21560                         check_cp0_enabled(ctx);
21561                         /* Break the TB to be able to sync copied instructions
21562                            immediately */
21563                         ctx->base.is_jmp = DISAS_STOP;
21564                     } else {
21565                         /* case NM_PREFE */
21566                         check_eva(ctx);
21567                         check_cp0_enabled(ctx);
21568                         /* Treat as NOP. */
21569                     }
21570                     break;
21571                 case NM_LHE:
21572                     check_eva(ctx);
21573                     check_cp0_enabled(ctx);
21574                     gen_ld(ctx, OPC_LHE, rt, rs, s);
21575                     break;
21576                 case NM_SHE:
21577                     check_eva(ctx);
21578                     check_cp0_enabled(ctx);
21579                     gen_st(ctx, OPC_SHE, rt, rs, s);
21580                     break;
21581                 case NM_LHUE:
21582                     check_eva(ctx);
21583                     check_cp0_enabled(ctx);
21584                     gen_ld(ctx, OPC_LHUE, rt, rs, s);
21585                     break;
21586                 case NM_CACHEE:
21587                     check_nms_dl_il_sl_tl_l2c(ctx);
21588                     gen_cache_operation(ctx, rt, rs, s);
21589                     break;
21590                 case NM_LWE:
21591                     check_eva(ctx);
21592                     check_cp0_enabled(ctx);
21593                     gen_ld(ctx, OPC_LWE, rt, rs, s);
21594                     break;
21595                 case NM_SWE:
21596                     check_eva(ctx);
21597                     check_cp0_enabled(ctx);
21598                     gen_st(ctx, OPC_SWE, rt, rs, s);
21599                     break;
21600                 case NM_P_LLE:
21601                     switch (extract32(ctx->opcode, 2, 2)) {
21602                     case NM_LLE:
21603                         check_xnp(ctx);
21604                         check_eva(ctx);
21605                         check_cp0_enabled(ctx);
21606                         gen_ld(ctx, OPC_LLE, rt, rs, s);
21607                         break;
21608                     case NM_LLWPE:
21609                         check_xnp(ctx);
21610                         check_eva(ctx);
21611                         check_cp0_enabled(ctx);
21612                         gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21613                         break;
21614                     default:
21615                         generate_exception_end(ctx, EXCP_RI);
21616                         break;
21617                     }
21618                     break;
21619                 case NM_P_SCE:
21620                     switch (extract32(ctx->opcode, 2, 2)) {
21621                     case NM_SCE:
21622                         check_xnp(ctx);
21623                         check_eva(ctx);
21624                         check_cp0_enabled(ctx);
21625                         gen_st_cond(ctx, rt, rs, s, MO_TESL, true);
21626                         break;
21627                     case NM_SCWPE:
21628                         check_xnp(ctx);
21629                         check_eva(ctx);
21630                         check_cp0_enabled(ctx);
21631                         gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
21632                                  true);
21633                         break;
21634                     default:
21635                         generate_exception_end(ctx, EXCP_RI);
21636                         break;
21637                     }
21638                     break;
21639                 }
21640                 break;
21641             case NM_P_LS_WM:
21642             case NM_P_LS_UAWM:
21643                 check_nms(ctx);
21644                 {
21645                     int count = extract32(ctx->opcode, 12, 3);
21646                     int counter = 0;
21647
21648                     offset = sextract32(ctx->opcode, 15, 1) << 8 |
21649                              extract32(ctx->opcode, 0, 8);
21650                     TCGv va = tcg_temp_new();
21651                     TCGv t1 = tcg_temp_new();
21652                     TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21653                                       NM_P_LS_UAWM ? MO_UNALN : 0;
21654
21655                     count = (count == 0) ? 8 : count;
21656                     while (counter != count) {
21657                         int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21658                         int this_offset = offset + (counter << 2);
21659
21660                         gen_base_offset_addr(ctx, va, rs, this_offset);
21661
21662                         switch (extract32(ctx->opcode, 11, 1)) {
21663                         case NM_LWM:
21664                             tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21665                                                memop | MO_TESL);
21666                             gen_store_gpr(t1, this_rt);
21667                             if ((this_rt == rs) &&
21668                                 (counter != (count - 1))) {
21669                                 /* UNPREDICTABLE */
21670                             }
21671                             break;
21672                         case NM_SWM:
21673                             this_rt = (rt == 0) ? 0 : this_rt;
21674                             gen_load_gpr(t1, this_rt);
21675                             tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21676                                                memop | MO_TEUL);
21677                             break;
21678                         }
21679                         counter++;
21680                     }
21681                     tcg_temp_free(va);
21682                     tcg_temp_free(t1);
21683                 }
21684                 break;
21685             default:
21686                 generate_exception_end(ctx, EXCP_RI);
21687                 break;
21688             }
21689         }
21690         break;
21691     case NM_MOVE_BALC:
21692         check_nms(ctx);
21693         {
21694             TCGv t0 = tcg_temp_new();
21695             int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
21696                         extract32(ctx->opcode, 1, 20) << 1;
21697             rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
21698             rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
21699                             extract32(ctx->opcode, 21, 3));
21700             gen_load_gpr(t0, rt);
21701             tcg_gen_mov_tl(cpu_gpr[rd], t0);
21702             gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21703             tcg_temp_free(t0);
21704         }
21705         break;
21706     case NM_P_BAL:
21707         {
21708             int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
21709                         extract32(ctx->opcode, 1, 24) << 1;
21710
21711             if ((extract32(ctx->opcode, 25, 1)) == 0) {
21712                 /* BC */
21713                 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
21714             } else {
21715                 /* BALC */
21716                 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21717             }
21718         }
21719         break;
21720     case NM_P_J:
21721         switch (extract32(ctx->opcode, 12, 4)) {
21722         case NM_JALRC:
21723         case NM_JALRC_HB:
21724             gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
21725             break;
21726         case NM_P_BALRSC:
21727             gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
21728             break;
21729         default:
21730             generate_exception_end(ctx, EXCP_RI);
21731             break;
21732         }
21733         break;
21734     case NM_P_BR1:
21735         {
21736             int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21737                         extract32(ctx->opcode, 1, 13) << 1;
21738             switch (extract32(ctx->opcode, 14, 2)) {
21739             case NM_BEQC:
21740                 check_nms(ctx);
21741                 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
21742                 break;
21743             case NM_P_BR3A:
21744                 s = sextract32(ctx->opcode, 0, 1) << 14 |
21745                     extract32(ctx->opcode, 1, 13) << 1;
21746                 check_cp1_enabled(ctx);
21747                 switch (extract32(ctx->opcode, 16, 5)) {
21748                 case NM_BC1EQZC:
21749                     gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
21750                     break;
21751                 case NM_BC1NEZC:
21752                     gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
21753                     break;
21754                 case NM_BPOSGE32C:
21755                     check_dsp_r3(ctx);
21756                     {
21757                         int32_t imm = extract32(ctx->opcode, 1, 13) |
21758                                       extract32(ctx->opcode, 0, 1) << 13;
21759
21760                         gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
21761                                               imm);
21762                     }
21763                     break;
21764                 default:
21765                     generate_exception_end(ctx, EXCP_RI);
21766                     break;
21767                 }
21768                 break;
21769             case NM_BGEC:
21770                 if (rs == rt) {
21771                     gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
21772                 } else {
21773                     gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
21774                 }
21775                 break;
21776             case NM_BGEUC:
21777                 if (rs == rt || rt == 0) {
21778                     gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
21779                 } else if (rs == 0) {
21780                     gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
21781                 } else {
21782                     gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
21783                 }
21784                 break;
21785             }
21786         }
21787         break;
21788     case NM_P_BR2:
21789         {
21790             int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21791                         extract32(ctx->opcode, 1, 13) << 1;
21792             switch (extract32(ctx->opcode, 14, 2)) {
21793             case NM_BNEC:
21794                 check_nms(ctx);
21795                 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
21796                 break;
21797             case NM_BLTC:
21798                 if (rs != 0 && rt != 0 && rs == rt) {
21799                     /* NOP */
21800                     ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21801                 } else {
21802                     gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
21803                 }
21804                 break;
21805             case NM_BLTUC:
21806                 if (rs == 0 || rs == rt) {
21807                     /* NOP */
21808                     ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21809                 } else {
21810                     gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
21811                 }
21812                 break;
21813             default:
21814                 generate_exception_end(ctx, EXCP_RI);
21815                 break;
21816             }
21817         }
21818         break;
21819     case NM_P_BRI:
21820         {
21821             int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
21822                         extract32(ctx->opcode, 1, 10) << 1;
21823             uint32_t u = extract32(ctx->opcode, 11, 7);
21824
21825             gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
21826                                    rt, u, s);
21827         }
21828         break;
21829     default:
21830         generate_exception_end(ctx, EXCP_RI);
21831         break;
21832     }
21833     return 4;
21834 }
21835
21836 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
21837 {
21838     uint32_t op;
21839     int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
21840     int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
21841     int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx->opcode));
21842     int offset;
21843     int imm;
21844
21845     /* make sure instructions are on a halfword boundary */
21846     if (ctx->base.pc_next & 0x1) {
21847         TCGv tmp = tcg_const_tl(ctx->base.pc_next);
21848         tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
21849         tcg_temp_free(tmp);
21850         generate_exception_end(ctx, EXCP_AdEL);
21851         return 2;
21852     }
21853
21854     op = extract32(ctx->opcode, 10, 6);
21855     switch (op) {
21856     case NM_P16_MV:
21857         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21858         if (rt != 0) {
21859             /* MOVE */
21860             rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
21861             gen_arith(ctx, OPC_ADDU, rt, rs, 0);
21862         } else {
21863             /* P16.RI */
21864             switch (extract32(ctx->opcode, 3, 2)) {
21865             case NM_P16_SYSCALL:
21866                 if (extract32(ctx->opcode, 2, 1) == 0) {
21867                     generate_exception_end(ctx, EXCP_SYSCALL);
21868                 } else {
21869                     generate_exception_end(ctx, EXCP_RI);
21870                 }
21871                 break;
21872             case NM_BREAK16:
21873                 generate_exception_end(ctx, EXCP_BREAK);
21874                 break;
21875             case NM_SDBBP16:
21876                 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
21877                     gen_helper_do_semihosting(cpu_env);
21878                 } else {
21879                     if (ctx->hflags & MIPS_HFLAG_SBRI) {
21880                         generate_exception_end(ctx, EXCP_RI);
21881                     } else {
21882                         generate_exception_end(ctx, EXCP_DBp);
21883                     }
21884                 }
21885                 break;
21886             default:
21887                 generate_exception_end(ctx, EXCP_RI);
21888                 break;
21889             }
21890         }
21891         break;
21892     case NM_P16_SHIFT:
21893         {
21894             int shift = extract32(ctx->opcode, 0, 3);
21895             uint32_t opc = 0;
21896             shift = (shift == 0) ? 8 : shift;
21897
21898             switch (extract32(ctx->opcode, 3, 1)) {
21899             case NM_SLL16:
21900                 opc = OPC_SLL;
21901                 break;
21902             case NM_SRL16:
21903                 opc = OPC_SRL;
21904                 break;
21905             }
21906             gen_shift_imm(ctx, opc, rt, rs, shift);
21907         }
21908         break;
21909     case NM_P16C:
21910         switch (ctx->opcode & 1) {
21911         case NM_POOL16C_0:
21912             gen_pool16c_nanomips_insn(ctx);
21913             break;
21914         case NM_LWXS16:
21915             gen_ldxs(ctx, rt, rs, rd);
21916             break;
21917         }
21918         break;
21919     case NM_P16_A1:
21920         switch (extract32(ctx->opcode, 6, 1)) {
21921         case NM_ADDIUR1SP:
21922             imm = extract32(ctx->opcode, 0, 6) << 2;
21923             gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
21924             break;
21925         default:
21926             generate_exception_end(ctx, EXCP_RI);
21927             break;
21928         }
21929         break;
21930     case NM_P16_A2:
21931         switch (extract32(ctx->opcode, 3, 1)) {
21932         case NM_ADDIUR2:
21933             imm = extract32(ctx->opcode, 0, 3) << 2;
21934             gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
21935             break;
21936         case NM_P_ADDIURS5:
21937             rt = extract32(ctx->opcode, 5, 5);
21938             if (rt != 0) {
21939                 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21940                 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
21941                       (extract32(ctx->opcode, 0, 3));
21942                 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
21943             }
21944             break;
21945         }
21946         break;
21947     case NM_P16_ADDU:
21948         switch (ctx->opcode & 0x1) {
21949         case NM_ADDU16:
21950             gen_arith(ctx, OPC_ADDU, rd, rs, rt);
21951             break;
21952         case NM_SUBU16:
21953             gen_arith(ctx, OPC_SUBU, rd, rs, rt);
21954             break;
21955         }
21956         break;
21957     case NM_P16_4X4:
21958         rt = (extract32(ctx->opcode, 9, 1) << 3) |
21959               extract32(ctx->opcode, 5, 3);
21960         rs = (extract32(ctx->opcode, 4, 1) << 3) |
21961               extract32(ctx->opcode, 0, 3);
21962         rt = decode_gpr_gpr4(rt);
21963         rs = decode_gpr_gpr4(rs);
21964         switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
21965                 (extract32(ctx->opcode, 3, 1))) {
21966         case NM_ADDU4X4:
21967             check_nms(ctx);
21968             gen_arith(ctx, OPC_ADDU, rt, rs, rt);
21969             break;
21970         case NM_MUL4X4:
21971             check_nms(ctx);
21972             gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
21973             break;
21974         default:
21975             generate_exception_end(ctx, EXCP_RI);
21976             break;
21977         }
21978         break;
21979     case NM_LI16:
21980         {
21981             int imm = extract32(ctx->opcode, 0, 7);
21982             imm = (imm == 0x7f ? -1 : imm);
21983             if (rt != 0) {
21984                 tcg_gen_movi_tl(cpu_gpr[rt], imm);
21985             }
21986         }
21987         break;
21988     case NM_ANDI16:
21989         {
21990             uint32_t u = extract32(ctx->opcode, 0, 4);
21991             u = (u == 12) ? 0xff :
21992                 (u == 13) ? 0xffff : u;
21993             gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
21994         }
21995         break;
21996     case NM_P16_LB:
21997         offset = extract32(ctx->opcode, 0, 2);
21998         switch (extract32(ctx->opcode, 2, 2)) {
21999         case NM_LB16:
22000             gen_ld(ctx, OPC_LB, rt, rs, offset);
22001             break;
22002         case NM_SB16:
22003             rt = decode_gpr_gpr3_src_store(
22004                      NANOMIPS_EXTRACT_RT3(ctx->opcode));
22005             gen_st(ctx, OPC_SB, rt, rs, offset);
22006             break;
22007         case NM_LBU16:
22008             gen_ld(ctx, OPC_LBU, rt, rs, offset);
22009             break;
22010         default:
22011             generate_exception_end(ctx, EXCP_RI);
22012             break;
22013         }
22014         break;
22015     case NM_P16_LH:
22016         offset = extract32(ctx->opcode, 1, 2) << 1;
22017         switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
22018         case NM_LH16:
22019             gen_ld(ctx, OPC_LH, rt, rs, offset);
22020             break;
22021         case NM_SH16:
22022             rt = decode_gpr_gpr3_src_store(
22023                      NANOMIPS_EXTRACT_RT3(ctx->opcode));
22024             gen_st(ctx, OPC_SH, rt, rs, offset);
22025             break;
22026         case NM_LHU16:
22027             gen_ld(ctx, OPC_LHU, rt, rs, offset);
22028             break;
22029         default:
22030             generate_exception_end(ctx, EXCP_RI);
22031             break;
22032         }
22033         break;
22034     case NM_LW16:
22035         offset = extract32(ctx->opcode, 0, 4) << 2;
22036         gen_ld(ctx, OPC_LW, rt, rs, offset);
22037         break;
22038     case NM_LWSP16:
22039         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22040         offset = extract32(ctx->opcode, 0, 5) << 2;
22041         gen_ld(ctx, OPC_LW, rt, 29, offset);
22042         break;
22043     case NM_LW4X4:
22044         check_nms(ctx);
22045         rt = (extract32(ctx->opcode, 9, 1) << 3) |
22046              extract32(ctx->opcode, 5, 3);
22047         rs = (extract32(ctx->opcode, 4, 1) << 3) |
22048              extract32(ctx->opcode, 0, 3);
22049         offset = (extract32(ctx->opcode, 3, 1) << 3) |
22050                  (extract32(ctx->opcode, 8, 1) << 2);
22051         rt = decode_gpr_gpr4(rt);
22052         rs = decode_gpr_gpr4(rs);
22053         gen_ld(ctx, OPC_LW, rt, rs, offset);
22054         break;
22055     case NM_SW4X4:
22056         check_nms(ctx);
22057         rt = (extract32(ctx->opcode, 9, 1) << 3) |
22058              extract32(ctx->opcode, 5, 3);
22059         rs = (extract32(ctx->opcode, 4, 1) << 3) |
22060              extract32(ctx->opcode, 0, 3);
22061         offset = (extract32(ctx->opcode, 3, 1) << 3) |
22062                  (extract32(ctx->opcode, 8, 1) << 2);
22063         rt = decode_gpr_gpr4_zero(rt);
22064         rs = decode_gpr_gpr4(rs);
22065         gen_st(ctx, OPC_SW, rt, rs, offset);
22066         break;
22067     case NM_LWGP16:
22068         offset = extract32(ctx->opcode, 0, 7) << 2;
22069         gen_ld(ctx, OPC_LW, rt, 28, offset);
22070         break;
22071     case NM_SWSP16:
22072         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22073         offset = extract32(ctx->opcode, 0, 5) << 2;
22074         gen_st(ctx, OPC_SW, rt, 29, offset);
22075         break;
22076     case NM_SW16:
22077         rt = decode_gpr_gpr3_src_store(
22078                  NANOMIPS_EXTRACT_RT3(ctx->opcode));
22079         rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
22080         offset = extract32(ctx->opcode, 0, 4) << 2;
22081         gen_st(ctx, OPC_SW, rt, rs, offset);
22082         break;
22083     case NM_SWGP16:
22084         rt = decode_gpr_gpr3_src_store(
22085                  NANOMIPS_EXTRACT_RT3(ctx->opcode));
22086         offset = extract32(ctx->opcode, 0, 7) << 2;
22087         gen_st(ctx, OPC_SW, rt, 28, offset);
22088         break;
22089     case NM_BC16:
22090         gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
22091                            (sextract32(ctx->opcode, 0, 1) << 10) |
22092                            (extract32(ctx->opcode, 1, 9) << 1));
22093         break;
22094     case NM_BALC16:
22095         gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
22096                            (sextract32(ctx->opcode, 0, 1) << 10) |
22097                            (extract32(ctx->opcode, 1, 9) << 1));
22098         break;
22099     case NM_BEQZC16:
22100         gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
22101                            (sextract32(ctx->opcode, 0, 1) << 7) |
22102                            (extract32(ctx->opcode, 1, 6) << 1));
22103         break;
22104     case NM_BNEZC16:
22105         gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
22106                            (sextract32(ctx->opcode, 0, 1) << 7) |
22107                            (extract32(ctx->opcode, 1, 6) << 1));
22108         break;
22109     case NM_P16_BR:
22110         switch (ctx->opcode & 0xf) {
22111         case 0:
22112             /* P16.JRC */
22113             switch (extract32(ctx->opcode, 4, 1)) {
22114             case NM_JRC:
22115                 gen_compute_branch_nm(ctx, OPC_JR, 2,
22116                                    extract32(ctx->opcode, 5, 5), 0, 0);
22117                 break;
22118             case NM_JALRC16:
22119                 gen_compute_branch_nm(ctx, OPC_JALR, 2,
22120                                    extract32(ctx->opcode, 5, 5), 31, 0);
22121                 break;
22122             }
22123             break;
22124         default:
22125             {
22126                 /* P16.BRI */
22127                 uint32_t opc = extract32(ctx->opcode, 4, 3) <
22128                                extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
22129                 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
22130                                    extract32(ctx->opcode, 0, 4) << 1);
22131             }
22132             break;
22133         }
22134         break;
22135     case NM_P16_SR:
22136         {
22137             int count = extract32(ctx->opcode, 0, 4);
22138             int u = extract32(ctx->opcode, 4, 4) << 4;
22139
22140             rt = 30 + extract32(ctx->opcode, 9, 1);
22141             switch (extract32(ctx->opcode, 8, 1)) {
22142             case NM_SAVE16:
22143                 gen_save(ctx, rt, count, 0, u);
22144                 break;
22145             case NM_RESTORE_JRC16:
22146                 gen_restore(ctx, rt, count, 0, u);
22147                 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
22148                 break;
22149             }
22150         }
22151         break;
22152     case NM_MOVEP:
22153     case NM_MOVEPREV:
22154         check_nms(ctx);
22155         {
22156             static const int gpr2reg1[] = {4, 5, 6, 7};
22157             static const int gpr2reg2[] = {5, 6, 7, 8};
22158             int re;
22159             int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
22160                       extract32(ctx->opcode, 8, 1);
22161             int r1 = gpr2reg1[rd2];
22162             int r2 = gpr2reg2[rd2];
22163             int r3 = extract32(ctx->opcode, 4, 1) << 3 |
22164                      extract32(ctx->opcode, 0, 3);
22165             int r4 = extract32(ctx->opcode, 9, 1) << 3 |
22166                      extract32(ctx->opcode, 5, 3);
22167             TCGv t0 = tcg_temp_new();
22168             TCGv t1 = tcg_temp_new();
22169             if (op == NM_MOVEP) {
22170                 rd = r1;
22171                 re = r2;
22172                 rs = decode_gpr_gpr4_zero(r3);
22173                 rt = decode_gpr_gpr4_zero(r4);
22174             } else {
22175                 rd = decode_gpr_gpr4(r3);
22176                 re = decode_gpr_gpr4(r4);
22177                 rs = r1;
22178                 rt = r2;
22179             }
22180             gen_load_gpr(t0, rs);
22181             gen_load_gpr(t1, rt);
22182             tcg_gen_mov_tl(cpu_gpr[rd], t0);
22183             tcg_gen_mov_tl(cpu_gpr[re], t1);
22184             tcg_temp_free(t0);
22185             tcg_temp_free(t1);
22186         }
22187         break;
22188     default:
22189         return decode_nanomips_32_48_opc(env, ctx);
22190     }
22191
22192     return 2;
22193 }
22194
22195
22196 /* SmartMIPS extension to MIPS32 */
22197
22198 #if defined(TARGET_MIPS64)
22199
22200 /* MDMX extension to MIPS64 */
22201
22202 #endif
22203
22204 /* MIPSDSP functions. */
22205 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
22206                            int rd, int base, int offset)
22207 {
22208     TCGv t0;
22209
22210     check_dsp(ctx);
22211     t0 = tcg_temp_new();
22212
22213     if (base == 0) {
22214         gen_load_gpr(t0, offset);
22215     } else if (offset == 0) {
22216         gen_load_gpr(t0, base);
22217     } else {
22218         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
22219     }
22220
22221     switch (opc) {
22222     case OPC_LBUX:
22223         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
22224         gen_store_gpr(t0, rd);
22225         break;
22226     case OPC_LHX:
22227         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
22228         gen_store_gpr(t0, rd);
22229         break;
22230     case OPC_LWX:
22231         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
22232         gen_store_gpr(t0, rd);
22233         break;
22234 #if defined(TARGET_MIPS64)
22235     case OPC_LDX:
22236         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
22237         gen_store_gpr(t0, rd);
22238         break;
22239 #endif
22240     }
22241     tcg_temp_free(t0);
22242 }
22243
22244 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
22245                               int ret, int v1, int v2)
22246 {
22247     TCGv v1_t;
22248     TCGv v2_t;
22249
22250     if (ret == 0) {
22251         /* Treat as NOP. */
22252         return;
22253     }
22254
22255     v1_t = tcg_temp_new();
22256     v2_t = tcg_temp_new();
22257
22258     gen_load_gpr(v1_t, v1);
22259     gen_load_gpr(v2_t, v2);
22260
22261     switch (op1) {
22262     /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22263     case OPC_MULT_G_2E:
22264         check_dsp_r2(ctx);
22265         switch (op2) {
22266         case OPC_ADDUH_QB:
22267             gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
22268             break;
22269         case OPC_ADDUH_R_QB:
22270             gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22271             break;
22272         case OPC_ADDQH_PH:
22273             gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
22274             break;
22275         case OPC_ADDQH_R_PH:
22276             gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22277             break;
22278         case OPC_ADDQH_W:
22279             gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
22280             break;
22281         case OPC_ADDQH_R_W:
22282             gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22283             break;
22284         case OPC_SUBUH_QB:
22285             gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
22286             break;
22287         case OPC_SUBUH_R_QB:
22288             gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22289             break;
22290         case OPC_SUBQH_PH:
22291             gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
22292             break;
22293         case OPC_SUBQH_R_PH:
22294             gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22295             break;
22296         case OPC_SUBQH_W:
22297             gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
22298             break;
22299         case OPC_SUBQH_R_W:
22300             gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22301             break;
22302         }
22303         break;
22304     case OPC_ABSQ_S_PH_DSP:
22305         switch (op2) {
22306         case OPC_ABSQ_S_QB:
22307             check_dsp_r2(ctx);
22308             gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
22309             break;
22310         case OPC_ABSQ_S_PH:
22311             check_dsp(ctx);
22312             gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
22313             break;
22314         case OPC_ABSQ_S_W:
22315             check_dsp(ctx);
22316             gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
22317             break;
22318         case OPC_PRECEQ_W_PHL:
22319             check_dsp(ctx);
22320             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
22321             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22322             break;
22323         case OPC_PRECEQ_W_PHR:
22324             check_dsp(ctx);
22325             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
22326             tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
22327             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22328             break;
22329         case OPC_PRECEQU_PH_QBL:
22330             check_dsp(ctx);
22331             gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
22332             break;
22333         case OPC_PRECEQU_PH_QBR:
22334             check_dsp(ctx);
22335             gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
22336             break;
22337         case OPC_PRECEQU_PH_QBLA:
22338             check_dsp(ctx);
22339             gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
22340             break;
22341         case OPC_PRECEQU_PH_QBRA:
22342             check_dsp(ctx);
22343             gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
22344             break;
22345         case OPC_PRECEU_PH_QBL:
22346             check_dsp(ctx);
22347             gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
22348             break;
22349         case OPC_PRECEU_PH_QBR:
22350             check_dsp(ctx);
22351             gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
22352             break;
22353         case OPC_PRECEU_PH_QBLA:
22354             check_dsp(ctx);
22355             gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
22356             break;
22357         case OPC_PRECEU_PH_QBRA:
22358             check_dsp(ctx);
22359             gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
22360             break;
22361         }
22362         break;
22363     case OPC_ADDU_QB_DSP:
22364         switch (op2) {
22365         case OPC_ADDQ_PH:
22366             check_dsp(ctx);
22367             gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22368             break;
22369         case OPC_ADDQ_S_PH:
22370             check_dsp(ctx);
22371             gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22372             break;
22373         case OPC_ADDQ_S_W:
22374             check_dsp(ctx);
22375             gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22376             break;
22377         case OPC_ADDU_QB:
22378             check_dsp(ctx);
22379             gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22380             break;
22381         case OPC_ADDU_S_QB:
22382             check_dsp(ctx);
22383             gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22384             break;
22385         case OPC_ADDU_PH:
22386             check_dsp_r2(ctx);
22387             gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22388             break;
22389         case OPC_ADDU_S_PH:
22390             check_dsp_r2(ctx);
22391             gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22392             break;
22393         case OPC_SUBQ_PH:
22394             check_dsp(ctx);
22395             gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22396             break;
22397         case OPC_SUBQ_S_PH:
22398             check_dsp(ctx);
22399             gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22400             break;
22401         case OPC_SUBQ_S_W:
22402             check_dsp(ctx);
22403             gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22404             break;
22405         case OPC_SUBU_QB:
22406             check_dsp(ctx);
22407             gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22408             break;
22409         case OPC_SUBU_S_QB:
22410             check_dsp(ctx);
22411             gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22412             break;
22413         case OPC_SUBU_PH:
22414             check_dsp_r2(ctx);
22415             gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22416             break;
22417         case OPC_SUBU_S_PH:
22418             check_dsp_r2(ctx);
22419             gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22420             break;
22421         case OPC_ADDSC:
22422             check_dsp(ctx);
22423             gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22424             break;
22425         case OPC_ADDWC:
22426             check_dsp(ctx);
22427             gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22428             break;
22429         case OPC_MODSUB:
22430             check_dsp(ctx);
22431             gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
22432             break;
22433         case OPC_RADDU_W_QB:
22434             check_dsp(ctx);
22435             gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
22436             break;
22437         }
22438         break;
22439     case OPC_CMPU_EQ_QB_DSP:
22440         switch (op2) {
22441         case OPC_PRECR_QB_PH:
22442             check_dsp_r2(ctx);
22443             gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22444             break;
22445         case OPC_PRECRQ_QB_PH:
22446             check_dsp(ctx);
22447             gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22448             break;
22449         case OPC_PRECR_SRA_PH_W:
22450             check_dsp_r2(ctx);
22451             {
22452                 TCGv_i32 sa_t = tcg_const_i32(v2);
22453                 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
22454                                           cpu_gpr[ret]);
22455                 tcg_temp_free_i32(sa_t);
22456                 break;
22457             }
22458         case OPC_PRECR_SRA_R_PH_W:
22459             check_dsp_r2(ctx);
22460             {
22461                 TCGv_i32 sa_t = tcg_const_i32(v2);
22462                 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
22463                                             cpu_gpr[ret]);
22464                 tcg_temp_free_i32(sa_t);
22465                 break;
22466             }
22467         case OPC_PRECRQ_PH_W:
22468             check_dsp(ctx);
22469             gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
22470             break;
22471         case OPC_PRECRQ_RS_PH_W:
22472             check_dsp(ctx);
22473             gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22474             break;
22475         case OPC_PRECRQU_S_QB_PH:
22476             check_dsp(ctx);
22477             gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22478             break;
22479         }
22480         break;
22481 #ifdef TARGET_MIPS64
22482     case OPC_ABSQ_S_QH_DSP:
22483         switch (op2) {
22484         case OPC_PRECEQ_L_PWL:
22485             check_dsp(ctx);
22486             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
22487             break;
22488         case OPC_PRECEQ_L_PWR:
22489             check_dsp(ctx);
22490             tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
22491             break;
22492         case OPC_PRECEQ_PW_QHL:
22493             check_dsp(ctx);
22494             gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
22495             break;
22496         case OPC_PRECEQ_PW_QHR:
22497             check_dsp(ctx);
22498             gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
22499             break;
22500         case OPC_PRECEQ_PW_QHLA:
22501             check_dsp(ctx);
22502             gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
22503             break;
22504         case OPC_PRECEQ_PW_QHRA:
22505             check_dsp(ctx);
22506             gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
22507             break;
22508         case OPC_PRECEQU_QH_OBL:
22509             check_dsp(ctx);
22510             gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
22511             break;
22512         case OPC_PRECEQU_QH_OBR:
22513             check_dsp(ctx);
22514             gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
22515             break;
22516         case OPC_PRECEQU_QH_OBLA:
22517             check_dsp(ctx);
22518             gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
22519             break;
22520         case OPC_PRECEQU_QH_OBRA:
22521             check_dsp(ctx);
22522             gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
22523             break;
22524         case OPC_PRECEU_QH_OBL:
22525             check_dsp(ctx);
22526             gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
22527             break;
22528         case OPC_PRECEU_QH_OBR:
22529             check_dsp(ctx);
22530             gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
22531             break;
22532         case OPC_PRECEU_QH_OBLA:
22533             check_dsp(ctx);
22534             gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
22535             break;
22536         case OPC_PRECEU_QH_OBRA:
22537             check_dsp(ctx);
22538             gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
22539             break;
22540         case OPC_ABSQ_S_OB:
22541             check_dsp_r2(ctx);
22542             gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22543             break;
22544         case OPC_ABSQ_S_PW:
22545             check_dsp(ctx);
22546             gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22547             break;
22548         case OPC_ABSQ_S_QH:
22549             check_dsp(ctx);
22550             gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22551             break;
22552         }
22553         break;
22554     case OPC_ADDU_OB_DSP:
22555         switch (op2) {
22556         case OPC_RADDU_L_OB:
22557             check_dsp(ctx);
22558             gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22559             break;
22560         case OPC_SUBQ_PW:
22561             check_dsp(ctx);
22562             gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22563             break;
22564         case OPC_SUBQ_S_PW:
22565             check_dsp(ctx);
22566             gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22567             break;
22568         case OPC_SUBQ_QH:
22569             check_dsp(ctx);
22570             gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22571             break;
22572         case OPC_SUBQ_S_QH:
22573             check_dsp(ctx);
22574             gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22575             break;
22576         case OPC_SUBU_OB:
22577             check_dsp(ctx);
22578             gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22579             break;
22580         case OPC_SUBU_S_OB:
22581             check_dsp(ctx);
22582             gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22583             break;
22584         case OPC_SUBU_QH:
22585             check_dsp_r2(ctx);
22586             gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22587             break;
22588         case OPC_SUBU_S_QH:
22589             check_dsp_r2(ctx);
22590             gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22591             break;
22592         case OPC_SUBUH_OB:
22593             check_dsp_r2(ctx);
22594             gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22595             break;
22596         case OPC_SUBUH_R_OB:
22597             check_dsp_r2(ctx);
22598             gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22599             break;
22600         case OPC_ADDQ_PW:
22601             check_dsp(ctx);
22602             gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22603             break;
22604         case OPC_ADDQ_S_PW:
22605             check_dsp(ctx);
22606             gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22607             break;
22608         case OPC_ADDQ_QH:
22609             check_dsp(ctx);
22610             gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22611             break;
22612         case OPC_ADDQ_S_QH:
22613             check_dsp(ctx);
22614             gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22615             break;
22616         case OPC_ADDU_OB:
22617             check_dsp(ctx);
22618             gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22619             break;
22620         case OPC_ADDU_S_OB:
22621             check_dsp(ctx);
22622             gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22623             break;
22624         case OPC_ADDU_QH:
22625             check_dsp_r2(ctx);
22626             gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22627             break;
22628         case OPC_ADDU_S_QH:
22629             check_dsp_r2(ctx);
22630             gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22631             break;
22632         case OPC_ADDUH_OB:
22633             check_dsp_r2(ctx);
22634             gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22635             break;
22636         case OPC_ADDUH_R_OB:
22637             check_dsp_r2(ctx);
22638             gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22639             break;
22640         }
22641         break;
22642     case OPC_CMPU_EQ_OB_DSP:
22643         switch (op2) {
22644         case OPC_PRECR_OB_QH:
22645             check_dsp_r2(ctx);
22646             gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22647             break;
22648         case OPC_PRECR_SRA_QH_PW:
22649             check_dsp_r2(ctx);
22650             {
22651                 TCGv_i32 ret_t = tcg_const_i32(ret);
22652                 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22653                 tcg_temp_free_i32(ret_t);
22654                 break;
22655             }
22656         case OPC_PRECR_SRA_R_QH_PW:
22657             check_dsp_r2(ctx);
22658             {
22659                 TCGv_i32 sa_v = tcg_const_i32(ret);
22660                 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22661                 tcg_temp_free_i32(sa_v);
22662                 break;
22663             }
22664         case OPC_PRECRQ_OB_QH:
22665             check_dsp(ctx);
22666             gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22667             break;
22668         case OPC_PRECRQ_PW_L:
22669             check_dsp(ctx);
22670             gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22671             break;
22672         case OPC_PRECRQ_QH_PW:
22673             check_dsp(ctx);
22674             gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22675             break;
22676         case OPC_PRECRQ_RS_QH_PW:
22677             check_dsp(ctx);
22678             gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22679             break;
22680         case OPC_PRECRQU_S_OB_QH:
22681             check_dsp(ctx);
22682             gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22683             break;
22684         }
22685         break;
22686 #endif
22687     }
22688
22689     tcg_temp_free(v1_t);
22690     tcg_temp_free(v2_t);
22691 }
22692
22693 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
22694                               int ret, int v1, int v2)
22695 {
22696     uint32_t op2;
22697     TCGv t0;
22698     TCGv v1_t;
22699     TCGv v2_t;
22700
22701     if (ret == 0) {
22702         /* Treat as NOP. */
22703         return;
22704     }
22705
22706     t0 = tcg_temp_new();
22707     v1_t = tcg_temp_new();
22708     v2_t = tcg_temp_new();
22709
22710     tcg_gen_movi_tl(t0, v1);
22711     gen_load_gpr(v1_t, v1);
22712     gen_load_gpr(v2_t, v2);
22713
22714     switch (opc) {
22715     case OPC_SHLL_QB_DSP:
22716         {
22717             op2 = MASK_SHLL_QB(ctx->opcode);
22718             switch (op2) {
22719             case OPC_SHLL_QB:
22720                 check_dsp(ctx);
22721                 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
22722                 break;
22723             case OPC_SHLLV_QB:
22724                 check_dsp(ctx);
22725                 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22726                 break;
22727             case OPC_SHLL_PH:
22728                 check_dsp(ctx);
22729                 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22730                 break;
22731             case OPC_SHLLV_PH:
22732                 check_dsp(ctx);
22733                 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22734                 break;
22735             case OPC_SHLL_S_PH:
22736                 check_dsp(ctx);
22737                 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22738                 break;
22739             case OPC_SHLLV_S_PH:
22740                 check_dsp(ctx);
22741                 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22742                 break;
22743             case OPC_SHLL_S_W:
22744                 check_dsp(ctx);
22745                 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
22746                 break;
22747             case OPC_SHLLV_S_W:
22748                 check_dsp(ctx);
22749                 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22750                 break;
22751             case OPC_SHRL_QB:
22752                 check_dsp(ctx);
22753                 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
22754                 break;
22755             case OPC_SHRLV_QB:
22756                 check_dsp(ctx);
22757                 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
22758                 break;
22759             case OPC_SHRL_PH:
22760                 check_dsp_r2(ctx);
22761                 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
22762                 break;
22763             case OPC_SHRLV_PH:
22764                 check_dsp_r2(ctx);
22765                 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
22766                 break;
22767             case OPC_SHRA_QB:
22768                 check_dsp_r2(ctx);
22769                 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
22770                 break;
22771             case OPC_SHRA_R_QB:
22772                 check_dsp_r2(ctx);
22773                 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
22774                 break;
22775             case OPC_SHRAV_QB:
22776                 check_dsp_r2(ctx);
22777                 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
22778                 break;
22779             case OPC_SHRAV_R_QB:
22780                 check_dsp_r2(ctx);
22781                 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
22782                 break;
22783             case OPC_SHRA_PH:
22784                 check_dsp(ctx);
22785                 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
22786                 break;
22787             case OPC_SHRA_R_PH:
22788                 check_dsp(ctx);
22789                 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
22790                 break;
22791             case OPC_SHRAV_PH:
22792                 check_dsp(ctx);
22793                 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
22794                 break;
22795             case OPC_SHRAV_R_PH:
22796                 check_dsp(ctx);
22797                 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
22798                 break;
22799             case OPC_SHRA_R_W:
22800                 check_dsp(ctx);
22801                 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
22802                 break;
22803             case OPC_SHRAV_R_W:
22804                 check_dsp(ctx);
22805                 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
22806                 break;
22807             default:            /* Invalid */
22808                 MIPS_INVAL("MASK SHLL.QB");
22809                 generate_exception_end(ctx, EXCP_RI);
22810                 break;
22811             }
22812             break;
22813         }
22814 #ifdef TARGET_MIPS64
22815     case OPC_SHLL_OB_DSP:
22816         op2 = MASK_SHLL_OB(ctx->opcode);
22817         switch (op2) {
22818         case OPC_SHLL_PW:
22819             check_dsp(ctx);
22820             gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22821             break;
22822         case OPC_SHLLV_PW:
22823             check_dsp(ctx);
22824             gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22825             break;
22826         case OPC_SHLL_S_PW:
22827             check_dsp(ctx);
22828             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22829             break;
22830         case OPC_SHLLV_S_PW:
22831             check_dsp(ctx);
22832             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22833             break;
22834         case OPC_SHLL_OB:
22835             check_dsp(ctx);
22836             gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
22837             break;
22838         case OPC_SHLLV_OB:
22839             check_dsp(ctx);
22840             gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22841             break;
22842         case OPC_SHLL_QH:
22843             check_dsp(ctx);
22844             gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22845             break;
22846         case OPC_SHLLV_QH:
22847             check_dsp(ctx);
22848             gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22849             break;
22850         case OPC_SHLL_S_QH:
22851             check_dsp(ctx);
22852             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22853             break;
22854         case OPC_SHLLV_S_QH:
22855             check_dsp(ctx);
22856             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22857             break;
22858         case OPC_SHRA_OB:
22859             check_dsp_r2(ctx);
22860             gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
22861             break;
22862         case OPC_SHRAV_OB:
22863             check_dsp_r2(ctx);
22864             gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
22865             break;
22866         case OPC_SHRA_R_OB:
22867             check_dsp_r2(ctx);
22868             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
22869             break;
22870         case OPC_SHRAV_R_OB:
22871             check_dsp_r2(ctx);
22872             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
22873             break;
22874         case OPC_SHRA_PW:
22875             check_dsp(ctx);
22876             gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
22877             break;
22878         case OPC_SHRAV_PW:
22879             check_dsp(ctx);
22880             gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
22881             break;
22882         case OPC_SHRA_R_PW:
22883             check_dsp(ctx);
22884             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
22885             break;
22886         case OPC_SHRAV_R_PW:
22887             check_dsp(ctx);
22888             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
22889             break;
22890         case OPC_SHRA_QH:
22891             check_dsp(ctx);
22892             gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
22893             break;
22894         case OPC_SHRAV_QH:
22895             check_dsp(ctx);
22896             gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
22897             break;
22898         case OPC_SHRA_R_QH:
22899             check_dsp(ctx);
22900             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
22901             break;
22902         case OPC_SHRAV_R_QH:
22903             check_dsp(ctx);
22904             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
22905             break;
22906         case OPC_SHRL_OB:
22907             check_dsp(ctx);
22908             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
22909             break;
22910         case OPC_SHRLV_OB:
22911             check_dsp(ctx);
22912             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
22913             break;
22914         case OPC_SHRL_QH:
22915             check_dsp_r2(ctx);
22916             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
22917             break;
22918         case OPC_SHRLV_QH:
22919             check_dsp_r2(ctx);
22920             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
22921             break;
22922         default:            /* Invalid */
22923             MIPS_INVAL("MASK SHLL.OB");
22924             generate_exception_end(ctx, EXCP_RI);
22925             break;
22926         }
22927         break;
22928 #endif
22929     }
22930
22931     tcg_temp_free(t0);
22932     tcg_temp_free(v1_t);
22933     tcg_temp_free(v2_t);
22934 }
22935
22936 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
22937                                  int ret, int v1, int v2, int check_ret)
22938 {
22939     TCGv_i32 t0;
22940     TCGv v1_t;
22941     TCGv v2_t;
22942
22943     if ((ret == 0) && (check_ret == 1)) {
22944         /* Treat as NOP. */
22945         return;
22946     }
22947
22948     t0 = tcg_temp_new_i32();
22949     v1_t = tcg_temp_new();
22950     v2_t = tcg_temp_new();
22951
22952     tcg_gen_movi_i32(t0, ret);
22953     gen_load_gpr(v1_t, v1);
22954     gen_load_gpr(v2_t, v2);
22955
22956     switch (op1) {
22957     /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22958      * the same mask and op1. */
22959     case OPC_MULT_G_2E:
22960         check_dsp_r2(ctx);
22961         switch (op2) {
22962         case  OPC_MUL_PH:
22963             gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22964             break;
22965         case  OPC_MUL_S_PH:
22966             gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22967             break;
22968         case OPC_MULQ_S_W:
22969             gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22970             break;
22971         case OPC_MULQ_RS_W:
22972             gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22973             break;
22974         }
22975         break;
22976     case OPC_DPA_W_PH_DSP:
22977         switch (op2) {
22978         case OPC_DPAU_H_QBL:
22979             check_dsp(ctx);
22980             gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
22981             break;
22982         case OPC_DPAU_H_QBR:
22983             check_dsp(ctx);
22984             gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
22985             break;
22986         case OPC_DPSU_H_QBL:
22987             check_dsp(ctx);
22988             gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
22989             break;
22990         case OPC_DPSU_H_QBR:
22991             check_dsp(ctx);
22992             gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
22993             break;
22994         case OPC_DPA_W_PH:
22995             check_dsp_r2(ctx);
22996             gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
22997             break;
22998         case OPC_DPAX_W_PH:
22999             check_dsp_r2(ctx);
23000             gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
23001             break;
23002         case OPC_DPAQ_S_W_PH:
23003             check_dsp(ctx);
23004             gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23005             break;
23006         case OPC_DPAQX_S_W_PH:
23007             check_dsp_r2(ctx);
23008             gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23009             break;
23010         case OPC_DPAQX_SA_W_PH:
23011             check_dsp_r2(ctx);
23012             gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23013             break;
23014         case OPC_DPS_W_PH:
23015             check_dsp_r2(ctx);
23016             gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
23017             break;
23018         case OPC_DPSX_W_PH:
23019             check_dsp_r2(ctx);
23020             gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
23021             break;
23022         case OPC_DPSQ_S_W_PH:
23023             check_dsp(ctx);
23024             gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23025             break;
23026         case OPC_DPSQX_S_W_PH:
23027             check_dsp_r2(ctx);
23028             gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23029             break;
23030         case OPC_DPSQX_SA_W_PH:
23031             check_dsp_r2(ctx);
23032             gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23033             break;
23034         case OPC_MULSAQ_S_W_PH:
23035             check_dsp(ctx);
23036             gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23037             break;
23038         case OPC_DPAQ_SA_L_W:
23039             check_dsp(ctx);
23040             gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23041             break;
23042         case OPC_DPSQ_SA_L_W:
23043             check_dsp(ctx);
23044             gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23045             break;
23046         case OPC_MAQ_S_W_PHL:
23047             check_dsp(ctx);
23048             gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
23049             break;
23050         case OPC_MAQ_S_W_PHR:
23051             check_dsp(ctx);
23052             gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
23053             break;
23054         case OPC_MAQ_SA_W_PHL:
23055             check_dsp(ctx);
23056             gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
23057             break;
23058         case OPC_MAQ_SA_W_PHR:
23059             check_dsp(ctx);
23060             gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
23061             break;
23062         case OPC_MULSA_W_PH:
23063             check_dsp_r2(ctx);
23064             gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
23065             break;
23066         }
23067         break;
23068 #ifdef TARGET_MIPS64
23069     case OPC_DPAQ_W_QH_DSP:
23070         {
23071             int ac = ret & 0x03;
23072             tcg_gen_movi_i32(t0, ac);
23073
23074             switch (op2) {
23075             case OPC_DMADD:
23076                 check_dsp(ctx);
23077                 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
23078                 break;
23079             case OPC_DMADDU:
23080                 check_dsp(ctx);
23081                 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
23082                 break;
23083             case OPC_DMSUB:
23084                 check_dsp(ctx);
23085                 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
23086                 break;
23087             case OPC_DMSUBU:
23088                 check_dsp(ctx);
23089                 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
23090                 break;
23091             case OPC_DPA_W_QH:
23092                 check_dsp_r2(ctx);
23093                 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
23094                 break;
23095             case OPC_DPAQ_S_W_QH:
23096                 check_dsp(ctx);
23097                 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23098                 break;
23099             case OPC_DPAQ_SA_L_PW:
23100                 check_dsp(ctx);
23101                 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23102                 break;
23103             case OPC_DPAU_H_OBL:
23104                 check_dsp(ctx);
23105                 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
23106                 break;
23107             case OPC_DPAU_H_OBR:
23108                 check_dsp(ctx);
23109                 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
23110                 break;
23111             case OPC_DPS_W_QH:
23112                 check_dsp_r2(ctx);
23113                 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
23114                 break;
23115             case OPC_DPSQ_S_W_QH:
23116                 check_dsp(ctx);
23117                 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23118                 break;
23119             case OPC_DPSQ_SA_L_PW:
23120                 check_dsp(ctx);
23121                 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23122                 break;
23123             case OPC_DPSU_H_OBL:
23124                 check_dsp(ctx);
23125                 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
23126                 break;
23127             case OPC_DPSU_H_OBR:
23128                 check_dsp(ctx);
23129                 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
23130                 break;
23131             case OPC_MAQ_S_L_PWL:
23132                 check_dsp(ctx);
23133                 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
23134                 break;
23135             case OPC_MAQ_S_L_PWR:
23136                 check_dsp(ctx);
23137                 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
23138                 break;
23139             case OPC_MAQ_S_W_QHLL:
23140                 check_dsp(ctx);
23141                 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
23142                 break;
23143             case OPC_MAQ_SA_W_QHLL:
23144                 check_dsp(ctx);
23145                 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
23146                 break;
23147             case OPC_MAQ_S_W_QHLR:
23148                 check_dsp(ctx);
23149                 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
23150                 break;
23151             case OPC_MAQ_SA_W_QHLR:
23152                 check_dsp(ctx);
23153                 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
23154                 break;
23155             case OPC_MAQ_S_W_QHRL:
23156                 check_dsp(ctx);
23157                 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
23158                 break;
23159             case OPC_MAQ_SA_W_QHRL:
23160                 check_dsp(ctx);
23161                 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
23162                 break;
23163             case OPC_MAQ_S_W_QHRR:
23164                 check_dsp(ctx);
23165                 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
23166                 break;
23167             case OPC_MAQ_SA_W_QHRR:
23168                 check_dsp(ctx);
23169                 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
23170                 break;
23171             case OPC_MULSAQ_S_L_PW:
23172                 check_dsp(ctx);
23173                 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
23174                 break;
23175             case OPC_MULSAQ_S_W_QH:
23176                 check_dsp(ctx);
23177                 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23178                 break;
23179             }
23180         }
23181         break;
23182 #endif
23183     case OPC_ADDU_QB_DSP:
23184         switch (op2) {
23185         case OPC_MULEU_S_PH_QBL:
23186             check_dsp(ctx);
23187             gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23188             break;
23189         case OPC_MULEU_S_PH_QBR:
23190             check_dsp(ctx);
23191             gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23192             break;
23193         case OPC_MULQ_RS_PH:
23194             check_dsp(ctx);
23195             gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23196             break;
23197         case OPC_MULEQ_S_W_PHL:
23198             check_dsp(ctx);
23199             gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23200             break;
23201         case OPC_MULEQ_S_W_PHR:
23202             check_dsp(ctx);
23203             gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23204             break;
23205         case OPC_MULQ_S_PH:
23206             check_dsp_r2(ctx);
23207             gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23208             break;
23209         }
23210         break;
23211 #ifdef TARGET_MIPS64
23212     case OPC_ADDU_OB_DSP:
23213         switch (op2) {
23214         case OPC_MULEQ_S_PW_QHL:
23215             check_dsp(ctx);
23216             gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23217             break;
23218         case OPC_MULEQ_S_PW_QHR:
23219             check_dsp(ctx);
23220             gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23221             break;
23222         case OPC_MULEU_S_QH_OBL:
23223             check_dsp(ctx);
23224             gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23225             break;
23226         case OPC_MULEU_S_QH_OBR:
23227             check_dsp(ctx);
23228             gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23229             break;
23230         case OPC_MULQ_RS_QH:
23231             check_dsp(ctx);
23232             gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23233             break;
23234         }
23235         break;
23236 #endif
23237     }
23238
23239     tcg_temp_free_i32(t0);
23240     tcg_temp_free(v1_t);
23241     tcg_temp_free(v2_t);
23242 }
23243
23244 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23245                                 int ret, int val)
23246 {
23247     int16_t imm;
23248     TCGv t0;
23249     TCGv val_t;
23250
23251     if (ret == 0) {
23252         /* Treat as NOP. */
23253         return;
23254     }
23255
23256     t0 = tcg_temp_new();
23257     val_t = tcg_temp_new();
23258     gen_load_gpr(val_t, val);
23259
23260     switch (op1) {
23261     case OPC_ABSQ_S_PH_DSP:
23262         switch (op2) {
23263         case OPC_BITREV:
23264             check_dsp(ctx);
23265             gen_helper_bitrev(cpu_gpr[ret], val_t);
23266             break;
23267         case OPC_REPL_QB:
23268             check_dsp(ctx);
23269             {
23270                 target_long result;
23271                 imm = (ctx->opcode >> 16) & 0xFF;
23272                 result = (uint32_t)imm << 24 |
23273                          (uint32_t)imm << 16 |
23274                          (uint32_t)imm << 8  |
23275                          (uint32_t)imm;
23276                 result = (int32_t)result;
23277                 tcg_gen_movi_tl(cpu_gpr[ret], result);
23278             }
23279             break;
23280         case OPC_REPLV_QB:
23281             check_dsp(ctx);
23282             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23283             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23284             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23285             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23286             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23287             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23288             break;
23289         case OPC_REPL_PH:
23290             check_dsp(ctx);
23291             {
23292                 imm = (ctx->opcode >> 16) & 0x03FF;
23293                 imm = (int16_t)(imm << 6) >> 6;
23294                 tcg_gen_movi_tl(cpu_gpr[ret], \
23295                                 (target_long)((int32_t)imm << 16 | \
23296                                 (uint16_t)imm));
23297             }
23298             break;
23299         case OPC_REPLV_PH:
23300             check_dsp(ctx);
23301             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23302             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23303             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23304             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23305             break;
23306         }
23307         break;
23308 #ifdef TARGET_MIPS64
23309     case OPC_ABSQ_S_QH_DSP:
23310         switch (op2) {
23311         case OPC_REPL_OB:
23312             check_dsp(ctx);
23313             {
23314                 target_long temp;
23315
23316                 imm = (ctx->opcode >> 16) & 0xFF;
23317                 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
23318                 temp = (temp << 16) | temp;
23319                 temp = (temp << 32) | temp;
23320                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23321                 break;
23322             }
23323         case OPC_REPL_PW:
23324             check_dsp(ctx);
23325             {
23326                 target_long temp;
23327
23328                 imm = (ctx->opcode >> 16) & 0x03FF;
23329                 imm = (int16_t)(imm << 6) >> 6;
23330                 temp = ((target_long)imm << 32) \
23331                        | ((target_long)imm & 0xFFFFFFFF);
23332                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23333                 break;
23334             }
23335         case OPC_REPL_QH:
23336             check_dsp(ctx);
23337             {
23338                 target_long temp;
23339
23340                 imm = (ctx->opcode >> 16) & 0x03FF;
23341                 imm = (int16_t)(imm << 6) >> 6;
23342
23343                 temp = ((uint64_t)(uint16_t)imm << 48) |
23344                        ((uint64_t)(uint16_t)imm << 32) |
23345                        ((uint64_t)(uint16_t)imm << 16) |
23346                        (uint64_t)(uint16_t)imm;
23347                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23348                 break;
23349             }
23350         case OPC_REPLV_OB:
23351             check_dsp(ctx);
23352             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23353             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23354             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23355             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23356             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23357             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23358             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23359             break;
23360         case OPC_REPLV_PW:
23361             check_dsp(ctx);
23362             tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
23363             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23364             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23365             break;
23366         case OPC_REPLV_QH:
23367             check_dsp(ctx);
23368             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23369             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23370             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23371             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23372             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23373             break;
23374         }
23375         break;
23376 #endif
23377     }
23378     tcg_temp_free(t0);
23379     tcg_temp_free(val_t);
23380 }
23381
23382 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
23383                                      uint32_t op1, uint32_t op2,
23384                                      int ret, int v1, int v2, int check_ret)
23385 {
23386     TCGv t1;
23387     TCGv v1_t;
23388     TCGv v2_t;
23389
23390     if ((ret == 0) && (check_ret == 1)) {
23391         /* Treat as NOP. */
23392         return;
23393     }
23394
23395     t1 = tcg_temp_new();
23396     v1_t = tcg_temp_new();
23397     v2_t = tcg_temp_new();
23398
23399     gen_load_gpr(v1_t, v1);
23400     gen_load_gpr(v2_t, v2);
23401
23402     switch (op1) {
23403     case OPC_CMPU_EQ_QB_DSP:
23404         switch (op2) {
23405         case OPC_CMPU_EQ_QB:
23406             check_dsp(ctx);
23407             gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
23408             break;
23409         case OPC_CMPU_LT_QB:
23410             check_dsp(ctx);
23411             gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
23412             break;
23413         case OPC_CMPU_LE_QB:
23414             check_dsp(ctx);
23415             gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
23416             break;
23417         case OPC_CMPGU_EQ_QB:
23418             check_dsp(ctx);
23419             gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
23420             break;
23421         case OPC_CMPGU_LT_QB:
23422             check_dsp(ctx);
23423             gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
23424             break;
23425         case OPC_CMPGU_LE_QB:
23426             check_dsp(ctx);
23427             gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
23428             break;
23429         case OPC_CMPGDU_EQ_QB:
23430             check_dsp_r2(ctx);
23431             gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
23432             tcg_gen_mov_tl(cpu_gpr[ret], t1);
23433             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23434             tcg_gen_shli_tl(t1, t1, 24);
23435             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23436             break;
23437         case OPC_CMPGDU_LT_QB:
23438             check_dsp_r2(ctx);
23439             gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
23440             tcg_gen_mov_tl(cpu_gpr[ret], t1);
23441             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23442             tcg_gen_shli_tl(t1, t1, 24);
23443             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23444             break;
23445         case OPC_CMPGDU_LE_QB:
23446             check_dsp_r2(ctx);
23447             gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
23448             tcg_gen_mov_tl(cpu_gpr[ret], t1);
23449             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23450             tcg_gen_shli_tl(t1, t1, 24);
23451             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23452             break;
23453         case OPC_CMP_EQ_PH:
23454             check_dsp(ctx);
23455             gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
23456             break;
23457         case OPC_CMP_LT_PH:
23458             check_dsp(ctx);
23459             gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
23460             break;
23461         case OPC_CMP_LE_PH:
23462             check_dsp(ctx);
23463             gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
23464             break;
23465         case OPC_PICK_QB:
23466             check_dsp(ctx);
23467             gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23468             break;
23469         case OPC_PICK_PH:
23470             check_dsp(ctx);
23471             gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23472             break;
23473         case OPC_PACKRL_PH:
23474             check_dsp(ctx);
23475             gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
23476             break;
23477         }
23478         break;
23479 #ifdef TARGET_MIPS64
23480     case OPC_CMPU_EQ_OB_DSP:
23481         switch (op2) {
23482         case OPC_CMP_EQ_PW:
23483             check_dsp(ctx);
23484             gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
23485             break;
23486         case OPC_CMP_LT_PW:
23487             check_dsp(ctx);
23488             gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
23489             break;
23490         case OPC_CMP_LE_PW:
23491             check_dsp(ctx);
23492             gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
23493             break;
23494         case OPC_CMP_EQ_QH:
23495             check_dsp(ctx);
23496             gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
23497             break;
23498         case OPC_CMP_LT_QH:
23499             check_dsp(ctx);
23500             gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
23501             break;
23502         case OPC_CMP_LE_QH:
23503             check_dsp(ctx);
23504             gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
23505             break;
23506         case OPC_CMPGDU_EQ_OB:
23507             check_dsp_r2(ctx);
23508             gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23509             break;
23510         case OPC_CMPGDU_LT_OB:
23511             check_dsp_r2(ctx);
23512             gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23513             break;
23514         case OPC_CMPGDU_LE_OB:
23515             check_dsp_r2(ctx);
23516             gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23517             break;
23518         case OPC_CMPGU_EQ_OB:
23519             check_dsp(ctx);
23520             gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
23521             break;
23522         case OPC_CMPGU_LT_OB:
23523             check_dsp(ctx);
23524             gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
23525             break;
23526         case OPC_CMPGU_LE_OB:
23527             check_dsp(ctx);
23528             gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
23529             break;
23530         case OPC_CMPU_EQ_OB:
23531             check_dsp(ctx);
23532             gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
23533             break;
23534         case OPC_CMPU_LT_OB:
23535             check_dsp(ctx);
23536             gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
23537             break;
23538         case OPC_CMPU_LE_OB:
23539             check_dsp(ctx);
23540             gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23541             break;
23542         case OPC_PACKRL_PW:
23543             check_dsp(ctx);
23544             gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23545             break;
23546         case OPC_PICK_OB:
23547             check_dsp(ctx);
23548             gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23549             break;
23550         case OPC_PICK_PW:
23551             check_dsp(ctx);
23552             gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23553             break;
23554         case OPC_PICK_QH:
23555             check_dsp(ctx);
23556             gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23557             break;
23558         }
23559         break;
23560 #endif
23561     }
23562
23563     tcg_temp_free(t1);
23564     tcg_temp_free(v1_t);
23565     tcg_temp_free(v2_t);
23566 }
23567
23568 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23569                                uint32_t op1, int rt, int rs, int sa)
23570 {
23571     TCGv t0;
23572
23573     check_dsp_r2(ctx);
23574
23575     if (rt == 0) {
23576         /* Treat as NOP. */
23577         return;
23578     }
23579
23580     t0 = tcg_temp_new();
23581     gen_load_gpr(t0, rs);
23582
23583     switch (op1) {
23584     case OPC_APPEND_DSP:
23585         switch (MASK_APPEND(ctx->opcode)) {
23586         case OPC_APPEND:
23587             if (sa != 0) {
23588                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23589             }
23590             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23591             break;
23592         case OPC_PREPEND:
23593             if (sa != 0) {
23594                 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
23595                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23596                 tcg_gen_shli_tl(t0, t0, 32 - sa);
23597                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23598             }
23599             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23600             break;
23601         case OPC_BALIGN:
23602             sa &= 3;
23603             if (sa != 0 && sa != 2) {
23604                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23605                 tcg_gen_ext32u_tl(t0, t0);
23606                 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
23607                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23608             }
23609             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23610             break;
23611         default:            /* Invalid */
23612             MIPS_INVAL("MASK APPEND");
23613             generate_exception_end(ctx, EXCP_RI);
23614             break;
23615         }
23616         break;
23617 #ifdef TARGET_MIPS64
23618     case OPC_DAPPEND_DSP:
23619         switch (MASK_DAPPEND(ctx->opcode)) {
23620         case OPC_DAPPEND:
23621             if (sa != 0) {
23622                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
23623             }
23624             break;
23625         case OPC_PREPENDD:
23626             tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23627             tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23628             tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
23629             break;
23630         case OPC_PREPENDW:
23631             if (sa != 0) {
23632                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23633                 tcg_gen_shli_tl(t0, t0, 64 - sa);
23634                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23635             }
23636             break;
23637         case OPC_DBALIGN:
23638             sa &= 7;
23639             if (sa != 0 && sa != 2 && sa != 4) {
23640                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23641                 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23642                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23643             }
23644             break;
23645         default:            /* Invalid */
23646             MIPS_INVAL("MASK DAPPEND");
23647             generate_exception_end(ctx, EXCP_RI);
23648             break;
23649         }
23650         break;
23651 #endif
23652     }
23653     tcg_temp_free(t0);
23654 }
23655
23656 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23657                                 int ret, int v1, int v2, int check_ret)
23658
23659 {
23660     TCGv t0;
23661     TCGv t1;
23662     TCGv v1_t;
23663     TCGv v2_t;
23664     int16_t imm;
23665
23666     if ((ret == 0) && (check_ret == 1)) {
23667         /* Treat as NOP. */
23668         return;
23669     }
23670
23671     t0 = tcg_temp_new();
23672     t1 = tcg_temp_new();
23673     v1_t = tcg_temp_new();
23674     v2_t = tcg_temp_new();
23675
23676     gen_load_gpr(v1_t, v1);
23677     gen_load_gpr(v2_t, v2);
23678
23679     switch (op1) {
23680     case OPC_EXTR_W_DSP:
23681         check_dsp(ctx);
23682         switch (op2) {
23683         case OPC_EXTR_W:
23684             tcg_gen_movi_tl(t0, v2);
23685             tcg_gen_movi_tl(t1, v1);
23686             gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
23687             break;
23688         case OPC_EXTR_R_W:
23689             tcg_gen_movi_tl(t0, v2);
23690             tcg_gen_movi_tl(t1, v1);
23691             gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23692             break;
23693         case OPC_EXTR_RS_W:
23694             tcg_gen_movi_tl(t0, v2);
23695             tcg_gen_movi_tl(t1, v1);
23696             gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23697             break;
23698         case OPC_EXTR_S_H:
23699             tcg_gen_movi_tl(t0, v2);
23700             tcg_gen_movi_tl(t1, v1);
23701             gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23702             break;
23703         case OPC_EXTRV_S_H:
23704             tcg_gen_movi_tl(t0, v2);
23705             gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
23706             break;
23707         case OPC_EXTRV_W:
23708             tcg_gen_movi_tl(t0, v2);
23709             gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23710             break;
23711         case OPC_EXTRV_R_W:
23712             tcg_gen_movi_tl(t0, v2);
23713             gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23714             break;
23715         case OPC_EXTRV_RS_W:
23716             tcg_gen_movi_tl(t0, v2);
23717             gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23718             break;
23719         case OPC_EXTP:
23720             tcg_gen_movi_tl(t0, v2);
23721             tcg_gen_movi_tl(t1, v1);
23722             gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
23723             break;
23724         case OPC_EXTPV:
23725             tcg_gen_movi_tl(t0, v2);
23726             gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
23727             break;
23728         case OPC_EXTPDP:
23729             tcg_gen_movi_tl(t0, v2);
23730             tcg_gen_movi_tl(t1, v1);
23731             gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
23732             break;
23733         case OPC_EXTPDPV:
23734             tcg_gen_movi_tl(t0, v2);
23735             gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23736             break;
23737         case OPC_SHILO:
23738             imm = (ctx->opcode >> 20) & 0x3F;
23739             tcg_gen_movi_tl(t0, ret);
23740             tcg_gen_movi_tl(t1, imm);
23741             gen_helper_shilo(t0, t1, cpu_env);
23742             break;
23743         case OPC_SHILOV:
23744             tcg_gen_movi_tl(t0, ret);
23745             gen_helper_shilo(t0, v1_t, cpu_env);
23746             break;
23747         case OPC_MTHLIP:
23748             tcg_gen_movi_tl(t0, ret);
23749             gen_helper_mthlip(t0, v1_t, cpu_env);
23750             break;
23751         case OPC_WRDSP:
23752             imm = (ctx->opcode >> 11) & 0x3FF;
23753             tcg_gen_movi_tl(t0, imm);
23754             gen_helper_wrdsp(v1_t, t0, cpu_env);
23755             break;
23756         case OPC_RDDSP:
23757             imm = (ctx->opcode >> 16) & 0x03FF;
23758             tcg_gen_movi_tl(t0, imm);
23759             gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
23760             break;
23761         }
23762         break;
23763 #ifdef TARGET_MIPS64
23764     case OPC_DEXTR_W_DSP:
23765         check_dsp(ctx);
23766         switch (op2) {
23767         case OPC_DMTHLIP:
23768             tcg_gen_movi_tl(t0, ret);
23769             gen_helper_dmthlip(v1_t, t0, cpu_env);
23770             break;
23771         case OPC_DSHILO:
23772             {
23773                 int shift = (ctx->opcode >> 19) & 0x7F;
23774                 int ac = (ctx->opcode >> 11) & 0x03;
23775                 tcg_gen_movi_tl(t0, shift);
23776                 tcg_gen_movi_tl(t1, ac);
23777                 gen_helper_dshilo(t0, t1, cpu_env);
23778                 break;
23779             }
23780         case OPC_DSHILOV:
23781             {
23782                 int ac = (ctx->opcode >> 11) & 0x03;
23783                 tcg_gen_movi_tl(t0, ac);
23784                 gen_helper_dshilo(v1_t, t0, cpu_env);
23785                 break;
23786             }
23787         case OPC_DEXTP:
23788             tcg_gen_movi_tl(t0, v2);
23789             tcg_gen_movi_tl(t1, v1);
23790
23791             gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
23792             break;
23793         case OPC_DEXTPV:
23794             tcg_gen_movi_tl(t0, v2);
23795             gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
23796             break;
23797         case OPC_DEXTPDP:
23798             tcg_gen_movi_tl(t0, v2);
23799             tcg_gen_movi_tl(t1, v1);
23800             gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
23801             break;
23802         case OPC_DEXTPDPV:
23803             tcg_gen_movi_tl(t0, v2);
23804             gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23805             break;
23806         case OPC_DEXTR_L:
23807             tcg_gen_movi_tl(t0, v2);
23808             tcg_gen_movi_tl(t1, v1);
23809             gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
23810             break;
23811         case OPC_DEXTR_R_L:
23812             tcg_gen_movi_tl(t0, v2);
23813             tcg_gen_movi_tl(t1, v1);
23814             gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
23815             break;
23816         case OPC_DEXTR_RS_L:
23817             tcg_gen_movi_tl(t0, v2);
23818             tcg_gen_movi_tl(t1, v1);
23819             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
23820             break;
23821         case OPC_DEXTR_W:
23822             tcg_gen_movi_tl(t0, v2);
23823             tcg_gen_movi_tl(t1, v1);
23824             gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
23825             break;
23826         case OPC_DEXTR_R_W:
23827             tcg_gen_movi_tl(t0, v2);
23828             tcg_gen_movi_tl(t1, v1);
23829             gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23830             break;
23831         case OPC_DEXTR_RS_W:
23832             tcg_gen_movi_tl(t0, v2);
23833             tcg_gen_movi_tl(t1, v1);
23834             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23835             break;
23836         case OPC_DEXTR_S_H:
23837             tcg_gen_movi_tl(t0, v2);
23838             tcg_gen_movi_tl(t1, v1);
23839             gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23840             break;
23841         case OPC_DEXTRV_S_H:
23842             tcg_gen_movi_tl(t0, v2);
23843             tcg_gen_movi_tl(t1, v1);
23844             gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23845             break;
23846         case OPC_DEXTRV_L:
23847             tcg_gen_movi_tl(t0, v2);
23848             gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23849             break;
23850         case OPC_DEXTRV_R_L:
23851             tcg_gen_movi_tl(t0, v2);
23852             gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23853             break;
23854         case OPC_DEXTRV_RS_L:
23855             tcg_gen_movi_tl(t0, v2);
23856             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23857             break;
23858         case OPC_DEXTRV_W:
23859             tcg_gen_movi_tl(t0, v2);
23860             gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23861             break;
23862         case OPC_DEXTRV_R_W:
23863             tcg_gen_movi_tl(t0, v2);
23864             gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23865             break;
23866         case OPC_DEXTRV_RS_W:
23867             tcg_gen_movi_tl(t0, v2);
23868             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23869             break;
23870         }
23871         break;
23872 #endif
23873     }
23874
23875     tcg_temp_free(t0);
23876     tcg_temp_free(t1);
23877     tcg_temp_free(v1_t);
23878     tcg_temp_free(v2_t);
23879 }
23880
23881 /* End MIPSDSP functions. */
23882
23883 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
23884 {
23885     int rs, rt, rd, sa;
23886     uint32_t op1, op2;
23887
23888     rs = (ctx->opcode >> 21) & 0x1f;
23889     rt = (ctx->opcode >> 16) & 0x1f;
23890     rd = (ctx->opcode >> 11) & 0x1f;
23891     sa = (ctx->opcode >> 6) & 0x1f;
23892
23893     op1 = MASK_SPECIAL(ctx->opcode);
23894     switch (op1) {
23895     case OPC_LSA:
23896         gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23897         break;
23898     case OPC_MULT:
23899     case OPC_MULTU:
23900     case OPC_DIV:
23901     case OPC_DIVU:
23902         op2 = MASK_R6_MULDIV(ctx->opcode);
23903         switch (op2) {
23904         case R6_OPC_MUL:
23905         case R6_OPC_MUH:
23906         case R6_OPC_MULU:
23907         case R6_OPC_MUHU:
23908         case R6_OPC_DIV:
23909         case R6_OPC_MOD:
23910         case R6_OPC_DIVU:
23911         case R6_OPC_MODU:
23912             gen_r6_muldiv(ctx, op2, rd, rs, rt);
23913             break;
23914         default:
23915             MIPS_INVAL("special_r6 muldiv");
23916             generate_exception_end(ctx, EXCP_RI);
23917             break;
23918         }
23919         break;
23920     case OPC_SELEQZ:
23921     case OPC_SELNEZ:
23922         gen_cond_move(ctx, op1, rd, rs, rt);
23923         break;
23924     case R6_OPC_CLO:
23925     case R6_OPC_CLZ:
23926         if (rt == 0 && sa == 1) {
23927             /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23928                We need additionally to check other fields */
23929             gen_cl(ctx, op1, rd, rs);
23930         } else {
23931             generate_exception_end(ctx, EXCP_RI);
23932         }
23933         break;
23934     case R6_OPC_SDBBP:
23935         if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23936             gen_helper_do_semihosting(cpu_env);
23937         } else {
23938             if (ctx->hflags & MIPS_HFLAG_SBRI) {
23939                 generate_exception_end(ctx, EXCP_RI);
23940             } else {
23941                 generate_exception_end(ctx, EXCP_DBp);
23942             }
23943         }
23944         break;
23945 #if defined(TARGET_MIPS64)
23946     case OPC_DLSA:
23947         check_mips_64(ctx);
23948         gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23949         break;
23950     case R6_OPC_DCLO:
23951     case R6_OPC_DCLZ:
23952         if (rt == 0 && sa == 1) {
23953             /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23954                We need additionally to check other fields */
23955             check_mips_64(ctx);
23956             gen_cl(ctx, op1, rd, rs);
23957         } else {
23958             generate_exception_end(ctx, EXCP_RI);
23959         }
23960         break;
23961     case OPC_DMULT:
23962     case OPC_DMULTU:
23963     case OPC_DDIV:
23964     case OPC_DDIVU:
23965
23966         op2 = MASK_R6_MULDIV(ctx->opcode);
23967         switch (op2) {
23968         case R6_OPC_DMUL:
23969         case R6_OPC_DMUH:
23970         case R6_OPC_DMULU:
23971         case R6_OPC_DMUHU:
23972         case R6_OPC_DDIV:
23973         case R6_OPC_DMOD:
23974         case R6_OPC_DDIVU:
23975         case R6_OPC_DMODU:
23976             check_mips_64(ctx);
23977             gen_r6_muldiv(ctx, op2, rd, rs, rt);
23978             break;
23979         default:
23980             MIPS_INVAL("special_r6 muldiv");
23981             generate_exception_end(ctx, EXCP_RI);
23982             break;
23983         }
23984         break;
23985 #endif
23986     default:            /* Invalid */
23987         MIPS_INVAL("special_r6");
23988         generate_exception_end(ctx, EXCP_RI);
23989         break;
23990     }
23991 }
23992
23993 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
23994 {
23995     int rs = extract32(ctx->opcode, 21, 5);
23996     int rt = extract32(ctx->opcode, 16, 5);
23997     int rd = extract32(ctx->opcode, 11, 5);
23998     uint32_t op1 = MASK_SPECIAL(ctx->opcode);
23999
24000     switch (op1) {
24001     case OPC_MOVN:         /* Conditional move */
24002     case OPC_MOVZ:
24003         gen_cond_move(ctx, op1, rd, rs, rt);
24004         break;
24005     case OPC_MFHI:          /* Move from HI/LO */
24006     case OPC_MFLO:
24007         gen_HILO(ctx, op1, 0, rd);
24008         break;
24009     case OPC_MTHI:
24010     case OPC_MTLO:          /* Move to HI/LO */
24011         gen_HILO(ctx, op1, 0, rs);
24012         break;
24013     case OPC_MULT:
24014     case OPC_MULTU:
24015         gen_mul_txx9(ctx, op1, rd, rs, rt);
24016         break;
24017     case OPC_DIV:
24018     case OPC_DIVU:
24019         gen_muldiv(ctx, op1, 0, rs, rt);
24020         break;
24021 #if defined(TARGET_MIPS64)
24022     case OPC_DMULT:
24023     case OPC_DMULTU:
24024     case OPC_DDIV:
24025     case OPC_DDIVU:
24026         check_insn_opc_user_only(ctx, INSN_R5900);
24027         gen_muldiv(ctx, op1, 0, rs, rt);
24028         break;
24029 #endif
24030     case OPC_JR:
24031         gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
24032         break;
24033     default:            /* Invalid */
24034         MIPS_INVAL("special_tx79");
24035         generate_exception_end(ctx, EXCP_RI);
24036         break;
24037     }
24038 }
24039
24040 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
24041 {
24042     int rs, rt, rd, sa;
24043     uint32_t op1;
24044
24045     rs = (ctx->opcode >> 21) & 0x1f;
24046     rt = (ctx->opcode >> 16) & 0x1f;
24047     rd = (ctx->opcode >> 11) & 0x1f;
24048     sa = (ctx->opcode >> 6) & 0x1f;
24049
24050     op1 = MASK_SPECIAL(ctx->opcode);
24051     switch (op1) {
24052     case OPC_MOVN:         /* Conditional move */
24053     case OPC_MOVZ:
24054         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
24055                    INSN_LOONGSON2E | INSN_LOONGSON2F);
24056         gen_cond_move(ctx, op1, rd, rs, rt);
24057         break;
24058     case OPC_MFHI:          /* Move from HI/LO */
24059     case OPC_MFLO:
24060         gen_HILO(ctx, op1, rs & 3, rd);
24061         break;
24062     case OPC_MTHI:
24063     case OPC_MTLO:          /* Move to HI/LO */
24064         gen_HILO(ctx, op1, rd & 3, rs);
24065         break;
24066     case OPC_MOVCI:
24067         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
24068         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
24069             check_cp1_enabled(ctx);
24070             gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
24071                       (ctx->opcode >> 16) & 1);
24072         } else {
24073             generate_exception_err(ctx, EXCP_CpU, 1);
24074         }
24075         break;
24076     case OPC_MULT:
24077     case OPC_MULTU:
24078         if (sa) {
24079             check_insn(ctx, INSN_VR54XX);
24080             op1 = MASK_MUL_VR54XX(ctx->opcode);
24081             gen_mul_vr54xx(ctx, op1, rd, rs, rt);
24082         } else {
24083             gen_muldiv(ctx, op1, rd & 3, rs, rt);
24084         }
24085         break;
24086     case OPC_DIV:
24087     case OPC_DIVU:
24088         gen_muldiv(ctx, op1, 0, rs, rt);
24089         break;
24090 #if defined(TARGET_MIPS64)
24091     case OPC_DMULT:
24092     case OPC_DMULTU:
24093     case OPC_DDIV:
24094     case OPC_DDIVU:
24095         check_insn(ctx, ISA_MIPS3);
24096         check_mips_64(ctx);
24097         gen_muldiv(ctx, op1, 0, rs, rt);
24098         break;
24099 #endif
24100     case OPC_JR:
24101         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24102         break;
24103     case OPC_SPIM:
24104 #ifdef MIPS_STRICT_STANDARD
24105         MIPS_INVAL("SPIM");
24106         generate_exception_end(ctx, EXCP_RI);
24107 #else
24108         /* Implemented as RI exception for now. */
24109         MIPS_INVAL("spim (unofficial)");
24110         generate_exception_end(ctx, EXCP_RI);
24111 #endif
24112         break;
24113     default:            /* Invalid */
24114         MIPS_INVAL("special_legacy");
24115         generate_exception_end(ctx, EXCP_RI);
24116         break;
24117     }
24118 }
24119
24120 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
24121 {
24122     int rs, rt, rd, sa;
24123     uint32_t op1;
24124
24125     rs = (ctx->opcode >> 21) & 0x1f;
24126     rt = (ctx->opcode >> 16) & 0x1f;
24127     rd = (ctx->opcode >> 11) & 0x1f;
24128     sa = (ctx->opcode >> 6) & 0x1f;
24129
24130     op1 = MASK_SPECIAL(ctx->opcode);
24131     switch (op1) {
24132     case OPC_SLL:          /* Shift with immediate */
24133         if (sa == 5 && rd == 0 &&
24134             rs == 0 && rt == 0) { /* PAUSE */
24135             if ((ctx->insn_flags & ISA_MIPS32R6) &&
24136                 (ctx->hflags & MIPS_HFLAG_BMASK)) {
24137                 generate_exception_end(ctx, EXCP_RI);
24138                 break;
24139             }
24140         }
24141         /* Fallthrough */
24142     case OPC_SRA:
24143         gen_shift_imm(ctx, op1, rd, rt, sa);
24144         break;
24145     case OPC_SRL:
24146         switch ((ctx->opcode >> 21) & 0x1f) {
24147         case 1:
24148             /* rotr is decoded as srl on non-R2 CPUs */
24149             if (ctx->insn_flags & ISA_MIPS32R2) {
24150                 op1 = OPC_ROTR;
24151             }
24152             /* Fallthrough */
24153         case 0:
24154             gen_shift_imm(ctx, op1, rd, rt, sa);
24155             break;
24156         default:
24157             generate_exception_end(ctx, EXCP_RI);
24158             break;
24159         }
24160         break;
24161     case OPC_ADD:
24162     case OPC_ADDU:
24163     case OPC_SUB:
24164     case OPC_SUBU:
24165         gen_arith(ctx, op1, rd, rs, rt);
24166         break;
24167     case OPC_SLLV:         /* Shifts */
24168     case OPC_SRAV:
24169         gen_shift(ctx, op1, rd, rs, rt);
24170         break;
24171     case OPC_SRLV:
24172         switch ((ctx->opcode >> 6) & 0x1f) {
24173         case 1:
24174             /* rotrv is decoded as srlv on non-R2 CPUs */
24175             if (ctx->insn_flags & ISA_MIPS32R2) {
24176                 op1 = OPC_ROTRV;
24177             }
24178             /* Fallthrough */
24179         case 0:
24180             gen_shift(ctx, op1, rd, rs, rt);
24181             break;
24182         default:
24183             generate_exception_end(ctx, EXCP_RI);
24184             break;
24185         }
24186         break;
24187     case OPC_SLT:          /* Set on less than */
24188     case OPC_SLTU:
24189         gen_slt(ctx, op1, rd, rs, rt);
24190         break;
24191     case OPC_AND:          /* Logic*/
24192     case OPC_OR:
24193     case OPC_NOR:
24194     case OPC_XOR:
24195         gen_logic(ctx, op1, rd, rs, rt);
24196         break;
24197     case OPC_JALR:
24198         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24199         break;
24200     case OPC_TGE: /* Traps */
24201     case OPC_TGEU:
24202     case OPC_TLT:
24203     case OPC_TLTU:
24204     case OPC_TEQ:
24205     case OPC_TNE:
24206         check_insn(ctx, ISA_MIPS2);
24207         gen_trap(ctx, op1, rs, rt, -1);
24208         break;
24209     case OPC_LSA: /* OPC_PMON */
24210         if ((ctx->insn_flags & ISA_MIPS32R6) ||
24211             (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24212             decode_opc_special_r6(env, ctx);
24213         } else {
24214             /* Pmon entry point, also R4010 selsl */
24215 #ifdef MIPS_STRICT_STANDARD
24216             MIPS_INVAL("PMON / selsl");
24217             generate_exception_end(ctx, EXCP_RI);
24218 #else
24219             gen_helper_0e0i(pmon, sa);
24220 #endif
24221         }
24222         break;
24223     case OPC_SYSCALL:
24224         generate_exception_end(ctx, EXCP_SYSCALL);
24225         break;
24226     case OPC_BREAK:
24227         generate_exception_end(ctx, EXCP_BREAK);
24228         break;
24229     case OPC_SYNC:
24230         check_insn(ctx, ISA_MIPS2);
24231         gen_sync(extract32(ctx->opcode, 6, 5));
24232         break;
24233
24234 #if defined(TARGET_MIPS64)
24235         /* MIPS64 specific opcodes */
24236     case OPC_DSLL:
24237     case OPC_DSRA:
24238     case OPC_DSLL32:
24239     case OPC_DSRA32:
24240         check_insn(ctx, ISA_MIPS3);
24241         check_mips_64(ctx);
24242         gen_shift_imm(ctx, op1, rd, rt, sa);
24243         break;
24244     case OPC_DSRL:
24245         switch ((ctx->opcode >> 21) & 0x1f) {
24246         case 1:
24247             /* drotr is decoded as dsrl on non-R2 CPUs */
24248             if (ctx->insn_flags & ISA_MIPS32R2) {
24249                 op1 = OPC_DROTR;
24250             }
24251             /* Fallthrough */
24252         case 0:
24253             check_insn(ctx, ISA_MIPS3);
24254             check_mips_64(ctx);
24255             gen_shift_imm(ctx, op1, rd, rt, sa);
24256             break;
24257         default:
24258             generate_exception_end(ctx, EXCP_RI);
24259             break;
24260         }
24261         break;
24262     case OPC_DSRL32:
24263         switch ((ctx->opcode >> 21) & 0x1f) {
24264         case 1:
24265             /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24266             if (ctx->insn_flags & ISA_MIPS32R2) {
24267                 op1 = OPC_DROTR32;
24268             }
24269             /* Fallthrough */
24270         case 0:
24271             check_insn(ctx, ISA_MIPS3);
24272             check_mips_64(ctx);
24273             gen_shift_imm(ctx, op1, rd, rt, sa);
24274             break;
24275         default:
24276             generate_exception_end(ctx, EXCP_RI);
24277             break;
24278         }
24279         break;
24280     case OPC_DADD:
24281     case OPC_DADDU:
24282     case OPC_DSUB:
24283     case OPC_DSUBU:
24284         check_insn(ctx, ISA_MIPS3);
24285         check_mips_64(ctx);
24286         gen_arith(ctx, op1, rd, rs, rt);
24287         break;
24288     case OPC_DSLLV:
24289     case OPC_DSRAV:
24290         check_insn(ctx, ISA_MIPS3);
24291         check_mips_64(ctx);
24292         gen_shift(ctx, op1, rd, rs, rt);
24293         break;
24294     case OPC_DSRLV:
24295         switch ((ctx->opcode >> 6) & 0x1f) {
24296         case 1:
24297             /* drotrv is decoded as dsrlv on non-R2 CPUs */
24298             if (ctx->insn_flags & ISA_MIPS32R2) {
24299                 op1 = OPC_DROTRV;
24300             }
24301             /* Fallthrough */
24302         case 0:
24303             check_insn(ctx, ISA_MIPS3);
24304             check_mips_64(ctx);
24305             gen_shift(ctx, op1, rd, rs, rt);
24306             break;
24307         default:
24308             generate_exception_end(ctx, EXCP_RI);
24309             break;
24310         }
24311         break;
24312     case OPC_DLSA:
24313         if ((ctx->insn_flags & ISA_MIPS32R6) ||
24314             (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24315             decode_opc_special_r6(env, ctx);
24316         }
24317         break;
24318 #endif
24319     default:
24320         if (ctx->insn_flags & ISA_MIPS32R6) {
24321             decode_opc_special_r6(env, ctx);
24322         } else if (ctx->insn_flags & INSN_R5900) {
24323             decode_opc_special_tx79(env, ctx);
24324         } else {
24325             decode_opc_special_legacy(env, ctx);
24326         }
24327     }
24328 }
24329
24330
24331 #if defined(TARGET_MIPS64)
24332
24333 /*
24334  *
24335  *           MMI (MultiMedia Interface) ASE instructions
24336  *           ===========================================
24337  */
24338
24339 /*
24340  *          MMI instructions category: data communication
24341  *          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24342  *
24343  *   PCPYH    PEXCH    PEXTLB   PINTH    PPACB    PEXT5    PREVH
24344  *   PCPYLD   PEXCW    PEXTLH   PINTEH   PPACH    PPAC5    PROT3W
24345  *   PCPYUD   PEXEH    PEXTLW            PPACW
24346  *            PEXEW    PEXTUB
24347  *                     PEXTUH
24348  *                     PEXTUW
24349  */
24350
24351 #endif
24352
24353
24354 #if !defined(TARGET_MIPS64)
24355
24356 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24357 #define MXU_APTN1_A    0
24358 #define MXU_APTN1_S    1
24359
24360 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24361 #define MXU_APTN2_AA    0
24362 #define MXU_APTN2_AS    1
24363 #define MXU_APTN2_SA    2
24364 #define MXU_APTN2_SS    3
24365
24366 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
24367 #define MXU_EPTN2_AA    0
24368 #define MXU_EPTN2_AS    1
24369 #define MXU_EPTN2_SA    2
24370 #define MXU_EPTN2_SS    3
24371
24372 /* MXU operand getting pattern 'optn2' */
24373 #define MXU_OPTN2_PTN0  0
24374 #define MXU_OPTN2_PTN1  1
24375 #define MXU_OPTN2_PTN2  2
24376 #define MXU_OPTN2_PTN3  3
24377 /* alternative naming scheme for 'optn2' */
24378 #define MXU_OPTN2_WW    0
24379 #define MXU_OPTN2_LW    1
24380 #define MXU_OPTN2_HW    2
24381 #define MXU_OPTN2_XW    3
24382
24383 /* MXU operand getting pattern 'optn3' */
24384 #define MXU_OPTN3_PTN0  0
24385 #define MXU_OPTN3_PTN1  1
24386 #define MXU_OPTN3_PTN2  2
24387 #define MXU_OPTN3_PTN3  3
24388 #define MXU_OPTN3_PTN4  4
24389 #define MXU_OPTN3_PTN5  5
24390 #define MXU_OPTN3_PTN6  6
24391 #define MXU_OPTN3_PTN7  7
24392
24393
24394 /*
24395  * S32I2M XRa, rb - Register move from GRF to XRF
24396  */
24397 static void gen_mxu_s32i2m(DisasContext *ctx)
24398 {
24399     TCGv t0;
24400     uint32_t XRa, Rb;
24401
24402     t0 = tcg_temp_new();
24403
24404     XRa = extract32(ctx->opcode, 6, 5);
24405     Rb = extract32(ctx->opcode, 16, 5);
24406
24407     gen_load_gpr(t0, Rb);
24408     if (XRa <= 15) {
24409         gen_store_mxu_gpr(t0, XRa);
24410     } else if (XRa == 16) {
24411         gen_store_mxu_cr(t0);
24412     }
24413
24414     tcg_temp_free(t0);
24415 }
24416
24417 /*
24418  * S32M2I XRa, rb - Register move from XRF to GRF
24419  */
24420 static void gen_mxu_s32m2i(DisasContext *ctx)
24421 {
24422     TCGv t0;
24423     uint32_t XRa, Rb;
24424
24425     t0 = tcg_temp_new();
24426
24427     XRa = extract32(ctx->opcode, 6, 5);
24428     Rb = extract32(ctx->opcode, 16, 5);
24429
24430     if (XRa <= 15) {
24431         gen_load_mxu_gpr(t0, XRa);
24432     } else if (XRa == 16) {
24433         gen_load_mxu_cr(t0);
24434     }
24435
24436     gen_store_gpr(t0, Rb);
24437
24438     tcg_temp_free(t0);
24439 }
24440
24441 /*
24442  * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24443  */
24444 static void gen_mxu_s8ldd(DisasContext *ctx)
24445 {
24446     TCGv t0, t1;
24447     uint32_t XRa, Rb, s8, optn3;
24448
24449     t0 = tcg_temp_new();
24450     t1 = tcg_temp_new();
24451
24452     XRa = extract32(ctx->opcode, 6, 4);
24453     s8 = extract32(ctx->opcode, 10, 8);
24454     optn3 = extract32(ctx->opcode, 18, 3);
24455     Rb = extract32(ctx->opcode, 21, 5);
24456
24457     gen_load_gpr(t0, Rb);
24458     tcg_gen_addi_tl(t0, t0, (int8_t)s8);
24459
24460     switch (optn3) {
24461     /* XRa[7:0] = tmp8 */
24462     case MXU_OPTN3_PTN0:
24463         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24464         gen_load_mxu_gpr(t0, XRa);
24465         tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
24466         break;
24467     /* XRa[15:8] = tmp8 */
24468     case MXU_OPTN3_PTN1:
24469         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24470         gen_load_mxu_gpr(t0, XRa);
24471         tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
24472         break;
24473     /* XRa[23:16] = tmp8 */
24474     case MXU_OPTN3_PTN2:
24475         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24476         gen_load_mxu_gpr(t0, XRa);
24477         tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
24478         break;
24479     /* XRa[31:24] = tmp8 */
24480     case MXU_OPTN3_PTN3:
24481         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24482         gen_load_mxu_gpr(t0, XRa);
24483         tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
24484         break;
24485     /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
24486     case MXU_OPTN3_PTN4:
24487         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24488         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24489         break;
24490     /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
24491     case MXU_OPTN3_PTN5:
24492         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24493         tcg_gen_shli_tl(t1, t1, 8);
24494         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24495         break;
24496     /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
24497     case MXU_OPTN3_PTN6:
24498         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
24499         tcg_gen_mov_tl(t0, t1);
24500         tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
24501         tcg_gen_shli_tl(t1, t1, 16);
24502         tcg_gen_or_tl(t0, t0, t1);
24503         break;
24504     /* XRa = {tmp8, tmp8, tmp8, tmp8} */
24505     case MXU_OPTN3_PTN7:
24506         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24507         tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
24508         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24509         break;
24510     }
24511
24512     gen_store_mxu_gpr(t0, XRa);
24513
24514     tcg_temp_free(t0);
24515     tcg_temp_free(t1);
24516 }
24517
24518 /*
24519  * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
24520  */
24521 static void gen_mxu_d16mul(DisasContext *ctx)
24522 {
24523     TCGv t0, t1, t2, t3;
24524     uint32_t XRa, XRb, XRc, XRd, optn2;
24525
24526     t0 = tcg_temp_new();
24527     t1 = tcg_temp_new();
24528     t2 = tcg_temp_new();
24529     t3 = tcg_temp_new();
24530
24531     XRa = extract32(ctx->opcode, 6, 4);
24532     XRb = extract32(ctx->opcode, 10, 4);
24533     XRc = extract32(ctx->opcode, 14, 4);
24534     XRd = extract32(ctx->opcode, 18, 4);
24535     optn2 = extract32(ctx->opcode, 22, 2);
24536
24537     gen_load_mxu_gpr(t1, XRb);
24538     tcg_gen_sextract_tl(t0, t1, 0, 16);
24539     tcg_gen_sextract_tl(t1, t1, 16, 16);
24540     gen_load_mxu_gpr(t3, XRc);
24541     tcg_gen_sextract_tl(t2, t3, 0, 16);
24542     tcg_gen_sextract_tl(t3, t3, 16, 16);
24543
24544     switch (optn2) {
24545     case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24546         tcg_gen_mul_tl(t3, t1, t3);
24547         tcg_gen_mul_tl(t2, t0, t2);
24548         break;
24549     case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24550         tcg_gen_mul_tl(t3, t0, t3);
24551         tcg_gen_mul_tl(t2, t0, t2);
24552         break;
24553     case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24554         tcg_gen_mul_tl(t3, t1, t3);
24555         tcg_gen_mul_tl(t2, t1, t2);
24556         break;
24557     case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24558         tcg_gen_mul_tl(t3, t0, t3);
24559         tcg_gen_mul_tl(t2, t1, t2);
24560         break;
24561     }
24562     gen_store_mxu_gpr(t3, XRa);
24563     gen_store_mxu_gpr(t2, XRd);
24564
24565     tcg_temp_free(t0);
24566     tcg_temp_free(t1);
24567     tcg_temp_free(t2);
24568     tcg_temp_free(t3);
24569 }
24570
24571 /*
24572  * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
24573  *                                           and accumulate
24574  */
24575 static void gen_mxu_d16mac(DisasContext *ctx)
24576 {
24577     TCGv t0, t1, t2, t3;
24578     uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
24579
24580     t0 = tcg_temp_new();
24581     t1 = tcg_temp_new();
24582     t2 = tcg_temp_new();
24583     t3 = tcg_temp_new();
24584
24585     XRa = extract32(ctx->opcode, 6, 4);
24586     XRb = extract32(ctx->opcode, 10, 4);
24587     XRc = extract32(ctx->opcode, 14, 4);
24588     XRd = extract32(ctx->opcode, 18, 4);
24589     optn2 = extract32(ctx->opcode, 22, 2);
24590     aptn2 = extract32(ctx->opcode, 24, 2);
24591
24592     gen_load_mxu_gpr(t1, XRb);
24593     tcg_gen_sextract_tl(t0, t1, 0, 16);
24594     tcg_gen_sextract_tl(t1, t1, 16, 16);
24595
24596     gen_load_mxu_gpr(t3, XRc);
24597     tcg_gen_sextract_tl(t2, t3, 0, 16);
24598     tcg_gen_sextract_tl(t3, t3, 16, 16);
24599
24600     switch (optn2) {
24601     case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24602         tcg_gen_mul_tl(t3, t1, t3);
24603         tcg_gen_mul_tl(t2, t0, t2);
24604         break;
24605     case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24606         tcg_gen_mul_tl(t3, t0, t3);
24607         tcg_gen_mul_tl(t2, t0, t2);
24608         break;
24609     case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24610         tcg_gen_mul_tl(t3, t1, t3);
24611         tcg_gen_mul_tl(t2, t1, t2);
24612         break;
24613     case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24614         tcg_gen_mul_tl(t3, t0, t3);
24615         tcg_gen_mul_tl(t2, t1, t2);
24616         break;
24617     }
24618     gen_load_mxu_gpr(t0, XRa);
24619     gen_load_mxu_gpr(t1, XRd);
24620
24621     switch (aptn2) {
24622     case MXU_APTN2_AA:
24623         tcg_gen_add_tl(t3, t0, t3);
24624         tcg_gen_add_tl(t2, t1, t2);
24625         break;
24626     case MXU_APTN2_AS:
24627         tcg_gen_add_tl(t3, t0, t3);
24628         tcg_gen_sub_tl(t2, t1, t2);
24629         break;
24630     case MXU_APTN2_SA:
24631         tcg_gen_sub_tl(t3, t0, t3);
24632         tcg_gen_add_tl(t2, t1, t2);
24633         break;
24634     case MXU_APTN2_SS:
24635         tcg_gen_sub_tl(t3, t0, t3);
24636         tcg_gen_sub_tl(t2, t1, t2);
24637         break;
24638     }
24639     gen_store_mxu_gpr(t3, XRa);
24640     gen_store_mxu_gpr(t2, XRd);
24641
24642     tcg_temp_free(t0);
24643     tcg_temp_free(t1);
24644     tcg_temp_free(t2);
24645     tcg_temp_free(t3);
24646 }
24647
24648 /*
24649  * Q8MUL   XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
24650  * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
24651  */
24652 static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
24653 {
24654     TCGv t0, t1, t2, t3, t4, t5, t6, t7;
24655     uint32_t XRa, XRb, XRc, XRd, sel;
24656
24657     t0 = tcg_temp_new();
24658     t1 = tcg_temp_new();
24659     t2 = tcg_temp_new();
24660     t3 = tcg_temp_new();
24661     t4 = tcg_temp_new();
24662     t5 = tcg_temp_new();
24663     t6 = tcg_temp_new();
24664     t7 = tcg_temp_new();
24665
24666     XRa = extract32(ctx->opcode, 6, 4);
24667     XRb = extract32(ctx->opcode, 10, 4);
24668     XRc = extract32(ctx->opcode, 14, 4);
24669     XRd = extract32(ctx->opcode, 18, 4);
24670     sel = extract32(ctx->opcode, 22, 2);
24671
24672     gen_load_mxu_gpr(t3, XRb);
24673     gen_load_mxu_gpr(t7, XRc);
24674
24675     if (sel == 0x2) {
24676         /* Q8MULSU */
24677         tcg_gen_ext8s_tl(t0, t3);
24678         tcg_gen_shri_tl(t3, t3, 8);
24679         tcg_gen_ext8s_tl(t1, t3);
24680         tcg_gen_shri_tl(t3, t3, 8);
24681         tcg_gen_ext8s_tl(t2, t3);
24682         tcg_gen_shri_tl(t3, t3, 8);
24683         tcg_gen_ext8s_tl(t3, t3);
24684     } else {
24685         /* Q8MUL */
24686         tcg_gen_ext8u_tl(t0, t3);
24687         tcg_gen_shri_tl(t3, t3, 8);
24688         tcg_gen_ext8u_tl(t1, t3);
24689         tcg_gen_shri_tl(t3, t3, 8);
24690         tcg_gen_ext8u_tl(t2, t3);
24691         tcg_gen_shri_tl(t3, t3, 8);
24692         tcg_gen_ext8u_tl(t3, t3);
24693     }
24694
24695     tcg_gen_ext8u_tl(t4, t7);
24696     tcg_gen_shri_tl(t7, t7, 8);
24697     tcg_gen_ext8u_tl(t5, t7);
24698     tcg_gen_shri_tl(t7, t7, 8);
24699     tcg_gen_ext8u_tl(t6, t7);
24700     tcg_gen_shri_tl(t7, t7, 8);
24701     tcg_gen_ext8u_tl(t7, t7);
24702
24703     tcg_gen_mul_tl(t0, t0, t4);
24704     tcg_gen_mul_tl(t1, t1, t5);
24705     tcg_gen_mul_tl(t2, t2, t6);
24706     tcg_gen_mul_tl(t3, t3, t7);
24707
24708     tcg_gen_andi_tl(t0, t0, 0xFFFF);
24709     tcg_gen_andi_tl(t1, t1, 0xFFFF);
24710     tcg_gen_andi_tl(t2, t2, 0xFFFF);
24711     tcg_gen_andi_tl(t3, t3, 0xFFFF);
24712
24713     tcg_gen_shli_tl(t1, t1, 16);
24714     tcg_gen_shli_tl(t3, t3, 16);
24715
24716     tcg_gen_or_tl(t0, t0, t1);
24717     tcg_gen_or_tl(t1, t2, t3);
24718
24719     gen_store_mxu_gpr(t0, XRd);
24720     gen_store_mxu_gpr(t1, XRa);
24721
24722     tcg_temp_free(t0);
24723     tcg_temp_free(t1);
24724     tcg_temp_free(t2);
24725     tcg_temp_free(t3);
24726     tcg_temp_free(t4);
24727     tcg_temp_free(t5);
24728     tcg_temp_free(t6);
24729     tcg_temp_free(t7);
24730 }
24731
24732 /*
24733  * S32LDD  XRa, Rb, S12 - Load a word from memory to XRF
24734  * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
24735  */
24736 static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
24737 {
24738     TCGv t0, t1;
24739     uint32_t XRa, Rb, s12, sel;
24740
24741     t0 = tcg_temp_new();
24742     t1 = tcg_temp_new();
24743
24744     XRa = extract32(ctx->opcode, 6, 4);
24745     s12 = extract32(ctx->opcode, 10, 10);
24746     sel = extract32(ctx->opcode, 20, 1);
24747     Rb = extract32(ctx->opcode, 21, 5);
24748
24749     gen_load_gpr(t0, Rb);
24750
24751     tcg_gen_movi_tl(t1, s12);
24752     tcg_gen_shli_tl(t1, t1, 2);
24753     if (s12 & 0x200) {
24754         tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
24755     }
24756     tcg_gen_add_tl(t1, t0, t1);
24757     tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
24758
24759     if (sel == 1) {
24760         /* S32LDDR */
24761         tcg_gen_bswap32_tl(t1, t1);
24762     }
24763     gen_store_mxu_gpr(t1, XRa);
24764
24765     tcg_temp_free(t0);
24766     tcg_temp_free(t1);
24767 }
24768
24769
24770 /*
24771  *                 MXU instruction category: logic
24772  *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24773  *
24774  *               S32NOR    S32AND    S32OR    S32XOR
24775  */
24776
24777 /*
24778  *  S32NOR XRa, XRb, XRc
24779  *    Update XRa with the result of logical bitwise 'nor' operation
24780  *    applied to the content of XRb and XRc.
24781  *
24782  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24783  *  +-----------+---------+-----+-------+-------+-------+-----------+
24784  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
24785  *  +-----------+---------+-----+-------+-------+-------+-----------+
24786  */
24787 static void gen_mxu_S32NOR(DisasContext *ctx)
24788 {
24789     uint32_t pad, XRc, XRb, XRa;
24790
24791     pad = extract32(ctx->opcode, 21, 5);
24792     XRc = extract32(ctx->opcode, 14, 4);
24793     XRb = extract32(ctx->opcode, 10, 4);
24794     XRa = extract32(ctx->opcode,  6, 4);
24795
24796     if (unlikely(pad != 0)) {
24797         /* opcode padding incorrect -> do nothing */
24798     } else if (unlikely(XRa == 0)) {
24799         /* destination is zero register -> do nothing */
24800     } else if (unlikely((XRb == 0) && (XRc == 0))) {
24801         /* both operands zero registers -> just set destination to all 1s */
24802         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
24803     } else if (unlikely(XRb == 0)) {
24804         /* XRb zero register -> just set destination to the negation of XRc */
24805         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24806     } else if (unlikely(XRc == 0)) {
24807         /* XRa zero register -> just set destination to the negation of XRb */
24808         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24809     } else if (unlikely(XRb == XRc)) {
24810         /* both operands same -> just set destination to the negation of XRb */
24811         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24812     } else {
24813         /* the most general case */
24814         tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24815     }
24816 }
24817
24818 /*
24819  *  S32AND XRa, XRb, XRc
24820  *    Update XRa with the result of logical bitwise 'and' operation
24821  *    applied to the content of XRb and XRc.
24822  *
24823  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24824  *  +-----------+---------+-----+-------+-------+-------+-----------+
24825  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
24826  *  +-----------+---------+-----+-------+-------+-------+-----------+
24827  */
24828 static void gen_mxu_S32AND(DisasContext *ctx)
24829 {
24830     uint32_t pad, XRc, XRb, XRa;
24831
24832     pad = extract32(ctx->opcode, 21, 5);
24833     XRc = extract32(ctx->opcode, 14, 4);
24834     XRb = extract32(ctx->opcode, 10, 4);
24835     XRa = extract32(ctx->opcode,  6, 4);
24836
24837     if (unlikely(pad != 0)) {
24838         /* opcode padding incorrect -> do nothing */
24839     } else if (unlikely(XRa == 0)) {
24840         /* destination is zero register -> do nothing */
24841     } else if (unlikely((XRb == 0) || (XRc == 0))) {
24842         /* one of operands zero register -> just set destination to all 0s */
24843         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24844     } else if (unlikely(XRb == XRc)) {
24845         /* both operands same -> just set destination to one of them */
24846         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24847     } else {
24848         /* the most general case */
24849         tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24850     }
24851 }
24852
24853 /*
24854  *  S32OR XRa, XRb, XRc
24855  *    Update XRa with the result of logical bitwise 'or' operation
24856  *    applied to the content of XRb and XRc.
24857  *
24858  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24859  *  +-----------+---------+-----+-------+-------+-------+-----------+
24860  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
24861  *  +-----------+---------+-----+-------+-------+-------+-----------+
24862  */
24863 static void gen_mxu_S32OR(DisasContext *ctx)
24864 {
24865     uint32_t pad, XRc, XRb, XRa;
24866
24867     pad = extract32(ctx->opcode, 21, 5);
24868     XRc = extract32(ctx->opcode, 14, 4);
24869     XRb = extract32(ctx->opcode, 10, 4);
24870     XRa = extract32(ctx->opcode,  6, 4);
24871
24872     if (unlikely(pad != 0)) {
24873         /* opcode padding incorrect -> do nothing */
24874     } else if (unlikely(XRa == 0)) {
24875         /* destination is zero register -> do nothing */
24876     } else if (unlikely((XRb == 0) && (XRc == 0))) {
24877         /* both operands zero registers -> just set destination to all 0s */
24878         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24879     } else if (unlikely(XRb == 0)) {
24880         /* XRb zero register -> just set destination to the content of XRc */
24881         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24882     } else if (unlikely(XRc == 0)) {
24883         /* XRc zero register -> just set destination to the content of XRb */
24884         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24885     } else if (unlikely(XRb == XRc)) {
24886         /* both operands same -> just set destination to one of them */
24887         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24888     } else {
24889         /* the most general case */
24890         tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24891     }
24892 }
24893
24894 /*
24895  *  S32XOR XRa, XRb, XRc
24896  *    Update XRa with the result of logical bitwise 'xor' operation
24897  *    applied to the content of XRb and XRc.
24898  *
24899  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24900  *  +-----------+---------+-----+-------+-------+-------+-----------+
24901  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
24902  *  +-----------+---------+-----+-------+-------+-------+-----------+
24903  */
24904 static void gen_mxu_S32XOR(DisasContext *ctx)
24905 {
24906     uint32_t pad, XRc, XRb, XRa;
24907
24908     pad = extract32(ctx->opcode, 21, 5);
24909     XRc = extract32(ctx->opcode, 14, 4);
24910     XRb = extract32(ctx->opcode, 10, 4);
24911     XRa = extract32(ctx->opcode,  6, 4);
24912
24913     if (unlikely(pad != 0)) {
24914         /* opcode padding incorrect -> do nothing */
24915     } else if (unlikely(XRa == 0)) {
24916         /* destination is zero register -> do nothing */
24917     } else if (unlikely((XRb == 0) && (XRc == 0))) {
24918         /* both operands zero registers -> just set destination to all 0s */
24919         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24920     } else if (unlikely(XRb == 0)) {
24921         /* XRb zero register -> just set destination to the content of XRc */
24922         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24923     } else if (unlikely(XRc == 0)) {
24924         /* XRc zero register -> just set destination to the content of XRb */
24925         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24926     } else if (unlikely(XRb == XRc)) {
24927         /* both operands same -> just set destination to all 0s */
24928         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24929     } else {
24930         /* the most general case */
24931         tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24932     }
24933 }
24934
24935
24936 /*
24937  *                   MXU instruction category max/min
24938  *                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24939  *
24940  *                     S32MAX     D16MAX     Q8MAX
24941  *                     S32MIN     D16MIN     Q8MIN
24942  */
24943
24944 /*
24945  *  S32MAX XRa, XRb, XRc
24946  *    Update XRa with the maximum of signed 32-bit integers contained
24947  *    in XRb and XRc.
24948  *
24949  *  S32MIN XRa, XRb, XRc
24950  *    Update XRa with the minimum of signed 32-bit integers contained
24951  *    in XRb and XRc.
24952  *
24953  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
24954  *  +-----------+---------+-----+-------+-------+-------+-----------+
24955  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
24956  *  +-----------+---------+-----+-------+-------+-------+-----------+
24957  */
24958 static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
24959 {
24960     uint32_t pad, opc, XRc, XRb, XRa;
24961
24962     pad = extract32(ctx->opcode, 21, 5);
24963     opc = extract32(ctx->opcode, 18, 3);
24964     XRc = extract32(ctx->opcode, 14, 4);
24965     XRb = extract32(ctx->opcode, 10, 4);
24966     XRa = extract32(ctx->opcode,  6, 4);
24967
24968     if (unlikely(pad != 0)) {
24969         /* opcode padding incorrect -> do nothing */
24970     } else if (unlikely(XRa == 0)) {
24971         /* destination is zero register -> do nothing */
24972     } else if (unlikely((XRb == 0) && (XRc == 0))) {
24973         /* both operands zero registers -> just set destination to zero */
24974         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24975     } else if (unlikely((XRb == 0) || (XRc == 0))) {
24976         /* exactly one operand is zero register - find which one is not...*/
24977         uint32_t XRx = XRb ? XRb : XRc;
24978         /* ...and do max/min operation with one operand 0 */
24979         if (opc == OPC_MXU_S32MAX) {
24980             tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
24981         } else {
24982             tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
24983         }
24984     } else if (unlikely(XRb == XRc)) {
24985         /* both operands same -> just set destination to one of them */
24986         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24987     } else {
24988         /* the most general case */
24989         if (opc == OPC_MXU_S32MAX) {
24990             tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
24991                                                mxu_gpr[XRc - 1]);
24992         } else {
24993             tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
24994                                                mxu_gpr[XRc - 1]);
24995         }
24996     }
24997 }
24998
24999 /*
25000  *  D16MAX
25001  *    Update XRa with the 16-bit-wise maximums of signed integers
25002  *    contained in XRb and XRc.
25003  *
25004  *  D16MIN
25005  *    Update XRa with the 16-bit-wise minimums of signed integers
25006  *    contained in XRb and XRc.
25007  *
25008  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25009  *  +-----------+---------+-----+-------+-------+-------+-----------+
25010  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
25011  *  +-----------+---------+-----+-------+-------+-------+-----------+
25012  */
25013 static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
25014 {
25015     uint32_t pad, opc, XRc, XRb, XRa;
25016
25017     pad = extract32(ctx->opcode, 21, 5);
25018     opc = extract32(ctx->opcode, 18, 3);
25019     XRc = extract32(ctx->opcode, 14, 4);
25020     XRb = extract32(ctx->opcode, 10, 4);
25021     XRa = extract32(ctx->opcode,  6, 4);
25022
25023     if (unlikely(pad != 0)) {
25024         /* opcode padding incorrect -> do nothing */
25025     } else if (unlikely(XRc == 0)) {
25026         /* destination is zero register -> do nothing */
25027     } else if (unlikely((XRb == 0) && (XRa == 0))) {
25028         /* both operands zero registers -> just set destination to zero */
25029         tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0);
25030     } else if (unlikely((XRb == 0) || (XRa == 0))) {
25031         /* exactly one operand is zero register - find which one is not...*/
25032         uint32_t XRx = XRb ? XRb : XRc;
25033         /* ...and do half-word-wise max/min with one operand 0 */
25034         TCGv_i32 t0 = tcg_temp_new();
25035         TCGv_i32 t1 = tcg_const_i32(0);
25036
25037         /* the left half-word first */
25038         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
25039         if (opc == OPC_MXU_D16MAX) {
25040             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25041         } else {
25042             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25043         }
25044
25045         /* the right half-word */
25046         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
25047         /* move half-words to the leftmost position */
25048         tcg_gen_shli_i32(t0, t0, 16);
25049         /* t0 will be max/min of t0 and t1 */
25050         if (opc == OPC_MXU_D16MAX) {
25051             tcg_gen_smax_i32(t0, t0, t1);
25052         } else {
25053             tcg_gen_smin_i32(t0, t0, t1);
25054         }
25055         /* return resulting half-words to its original position */
25056         tcg_gen_shri_i32(t0, t0, 16);
25057         /* finaly update the destination */
25058         tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25059
25060         tcg_temp_free(t1);
25061         tcg_temp_free(t0);
25062     } else if (unlikely(XRb == XRc)) {
25063         /* both operands same -> just set destination to one of them */
25064         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25065     } else {
25066         /* the most general case */
25067         TCGv_i32 t0 = tcg_temp_new();
25068         TCGv_i32 t1 = tcg_temp_new();
25069
25070         /* the left half-word first */
25071         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
25072         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25073         if (opc == OPC_MXU_D16MAX) {
25074             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25075         } else {
25076             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25077         }
25078
25079         /* the right half-word */
25080         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25081         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
25082         /* move half-words to the leftmost position */
25083         tcg_gen_shli_i32(t0, t0, 16);
25084         tcg_gen_shli_i32(t1, t1, 16);
25085         /* t0 will be max/min of t0 and t1 */
25086         if (opc == OPC_MXU_D16MAX) {
25087             tcg_gen_smax_i32(t0, t0, t1);
25088         } else {
25089             tcg_gen_smin_i32(t0, t0, t1);
25090         }
25091         /* return resulting half-words to its original position */
25092         tcg_gen_shri_i32(t0, t0, 16);
25093         /* finaly update the destination */
25094         tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25095
25096         tcg_temp_free(t1);
25097         tcg_temp_free(t0);
25098     }
25099 }
25100
25101 /*
25102  *  Q8MAX
25103  *    Update XRa with the 8-bit-wise maximums of signed integers
25104  *    contained in XRb and XRc.
25105  *
25106  *  Q8MIN
25107  *    Update XRa with the 8-bit-wise minimums of signed integers
25108  *    contained in XRb and XRc.
25109  *
25110  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25111  *  +-----------+---------+-----+-------+-------+-------+-----------+
25112  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
25113  *  +-----------+---------+-----+-------+-------+-------+-----------+
25114  */
25115 static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
25116 {
25117     uint32_t pad, opc, XRc, XRb, XRa;
25118
25119     pad = extract32(ctx->opcode, 21, 5);
25120     opc = extract32(ctx->opcode, 18, 3);
25121     XRc = extract32(ctx->opcode, 14, 4);
25122     XRb = extract32(ctx->opcode, 10, 4);
25123     XRa = extract32(ctx->opcode,  6, 4);
25124
25125     if (unlikely(pad != 0)) {
25126         /* opcode padding incorrect -> do nothing */
25127     } else if (unlikely(XRa == 0)) {
25128         /* destination is zero register -> do nothing */
25129     } else if (unlikely((XRb == 0) && (XRc == 0))) {
25130         /* both operands zero registers -> just set destination to zero */
25131         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25132     } else if (unlikely((XRb == 0) || (XRc == 0))) {
25133         /* exactly one operand is zero register - make it be the first...*/
25134         uint32_t XRx = XRb ? XRb : XRc;
25135         /* ...and do byte-wise max/min with one operand 0 */
25136         TCGv_i32 t0 = tcg_temp_new();
25137         TCGv_i32 t1 = tcg_const_i32(0);
25138         int32_t i;
25139
25140         /* the leftmost byte (byte 3) first */
25141         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
25142         if (opc == OPC_MXU_Q8MAX) {
25143             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25144         } else {
25145             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25146         }
25147
25148         /* bytes 2, 1, 0 */
25149         for (i = 2; i >= 0; i--) {
25150             /* extract the byte */
25151             tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
25152             /* move the byte to the leftmost position */
25153             tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25154             /* t0 will be max/min of t0 and t1 */
25155             if (opc == OPC_MXU_Q8MAX) {
25156                 tcg_gen_smax_i32(t0, t0, t1);
25157             } else {
25158                 tcg_gen_smin_i32(t0, t0, t1);
25159             }
25160             /* return resulting byte to its original position */
25161             tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25162             /* finaly update the destination */
25163             tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25164         }
25165
25166         tcg_temp_free(t1);
25167         tcg_temp_free(t0);
25168     } else if (unlikely(XRb == XRc)) {
25169         /* both operands same -> just set destination to one of them */
25170         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25171     } else {
25172         /* the most general case */
25173         TCGv_i32 t0 = tcg_temp_new();
25174         TCGv_i32 t1 = tcg_temp_new();
25175         int32_t i;
25176
25177         /* the leftmost bytes (bytes 3) first */
25178         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
25179         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25180         if (opc == OPC_MXU_Q8MAX) {
25181             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25182         } else {
25183             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25184         }
25185
25186         /* bytes 2, 1, 0 */
25187         for (i = 2; i >= 0; i--) {
25188             /* extract corresponding bytes */
25189             tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
25190             tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
25191             /* move the bytes to the leftmost position */
25192             tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25193             tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
25194             /* t0 will be max/min of t0 and t1 */
25195             if (opc == OPC_MXU_Q8MAX) {
25196                 tcg_gen_smax_i32(t0, t0, t1);
25197             } else {
25198                 tcg_gen_smin_i32(t0, t0, t1);
25199             }
25200             /* return resulting byte to its original position */
25201             tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25202             /* finaly update the destination */
25203             tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25204         }
25205
25206         tcg_temp_free(t1);
25207         tcg_temp_free(t0);
25208     }
25209 }
25210
25211
25212 /*
25213  *                 MXU instruction category: align
25214  *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25215  *
25216  *                       S32ALN     S32ALNI
25217  */
25218
25219 /*
25220  *  S32ALNI XRc, XRb, XRa, optn3
25221  *    Arrange bytes from XRb and XRc according to one of five sets of
25222  *    rules determined by optn3, and place the result in XRa.
25223  *
25224  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25225  *  +-----------+-----+---+-----+-------+-------+-------+-----------+
25226  *  |  SPECIAL2 |optn3|0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
25227  *  +-----------+-----+---+-----+-------+-------+-------+-----------+
25228  *
25229  */
25230 static void gen_mxu_S32ALNI(DisasContext *ctx)
25231 {
25232     uint32_t optn3, pad, XRc, XRb, XRa;
25233
25234     optn3 = extract32(ctx->opcode,  23, 3);
25235     pad   = extract32(ctx->opcode,  21, 2);
25236     XRc   = extract32(ctx->opcode, 14, 4);
25237     XRb   = extract32(ctx->opcode, 10, 4);
25238     XRa   = extract32(ctx->opcode,  6, 4);
25239
25240     if (unlikely(pad != 0)) {
25241         /* opcode padding incorrect -> do nothing */
25242     } else if (unlikely(XRa == 0)) {
25243         /* destination is zero register -> do nothing */
25244     } else if (unlikely((XRb == 0) && (XRc == 0))) {
25245         /* both operands zero registers -> just set destination to all 0s */
25246         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25247     } else if (unlikely(XRb == 0)) {
25248         /* XRb zero register -> just appropriatelly shift XRc into XRa */
25249         switch (optn3) {
25250         case MXU_OPTN3_PTN0:
25251             tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25252             break;
25253         case MXU_OPTN3_PTN1:
25254         case MXU_OPTN3_PTN2:
25255         case MXU_OPTN3_PTN3:
25256             tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
25257                              8 * (4 - optn3));
25258             break;
25259         case MXU_OPTN3_PTN4:
25260             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25261             break;
25262         }
25263     } else if (unlikely(XRc == 0)) {
25264         /* XRc zero register -> just appropriatelly shift XRb into XRa */
25265         switch (optn3) {
25266         case MXU_OPTN3_PTN0:
25267             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25268             break;
25269         case MXU_OPTN3_PTN1:
25270         case MXU_OPTN3_PTN2:
25271         case MXU_OPTN3_PTN3:
25272             tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25273             break;
25274         case MXU_OPTN3_PTN4:
25275             tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25276             break;
25277         }
25278     } else if (unlikely(XRb == XRc)) {
25279         /* both operands same -> just rotation or moving from any of them */
25280         switch (optn3) {
25281         case MXU_OPTN3_PTN0:
25282         case MXU_OPTN3_PTN4:
25283             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25284             break;
25285         case MXU_OPTN3_PTN1:
25286         case MXU_OPTN3_PTN2:
25287         case MXU_OPTN3_PTN3:
25288             tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25289             break;
25290         }
25291     } else {
25292         /* the most general case */
25293         switch (optn3) {
25294         case MXU_OPTN3_PTN0:
25295             {
25296                 /*                                         */
25297                 /*         XRb                XRc          */
25298                 /*  +---------------+                      */
25299                 /*  | A   B   C   D |    E   F   G   H     */
25300                 /*  +-------+-------+                      */
25301                 /*          |                              */
25302                 /*         XRa                             */
25303                 /*                                         */
25304
25305                 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25306             }
25307             break;
25308         case MXU_OPTN3_PTN1:
25309             {
25310                 /*                                         */
25311                 /*         XRb                 XRc         */
25312                 /*      +-------------------+              */
25313                 /*    A | B   C   D       E | F   G   H    */
25314                 /*      +---------+---------+              */
25315                 /*                |                        */
25316                 /*               XRa                       */
25317                 /*                                         */
25318
25319                 TCGv_i32 t0 = tcg_temp_new();
25320                 TCGv_i32 t1 = tcg_temp_new();
25321
25322                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
25323                 tcg_gen_shli_i32(t0, t0, 8);
25324
25325                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25326                 tcg_gen_shri_i32(t1, t1, 24);
25327
25328                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25329
25330                 tcg_temp_free(t1);
25331                 tcg_temp_free(t0);
25332             }
25333             break;
25334         case MXU_OPTN3_PTN2:
25335             {
25336                 /*                                         */
25337                 /*         XRb                 XRc         */
25338                 /*          +-------------------+          */
25339                 /*    A   B | C   D       E   F | G   H    */
25340                 /*          +---------+---------+          */
25341                 /*                    |                    */
25342                 /*                   XRa                   */
25343                 /*                                         */
25344
25345                 TCGv_i32 t0 = tcg_temp_new();
25346                 TCGv_i32 t1 = tcg_temp_new();
25347
25348                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25349                 tcg_gen_shli_i32(t0, t0, 16);
25350
25351                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25352                 tcg_gen_shri_i32(t1, t1, 16);
25353
25354                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25355
25356                 tcg_temp_free(t1);
25357                 tcg_temp_free(t0);
25358             }
25359             break;
25360         case MXU_OPTN3_PTN3:
25361             {
25362                 /*                                         */
25363                 /*         XRb                 XRc         */
25364                 /*              +-------------------+      */
25365                 /*    A   B   C | D       E   F   G | H    */
25366                 /*              +---------+---------+      */
25367                 /*                        |                */
25368                 /*                       XRa               */
25369                 /*                                         */
25370
25371                 TCGv_i32 t0 = tcg_temp_new();
25372                 TCGv_i32 t1 = tcg_temp_new();
25373
25374                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
25375                 tcg_gen_shli_i32(t0, t0, 24);
25376
25377                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
25378                 tcg_gen_shri_i32(t1, t1, 8);
25379
25380                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25381
25382                 tcg_temp_free(t1);
25383                 tcg_temp_free(t0);
25384             }
25385             break;
25386         case MXU_OPTN3_PTN4:
25387             {
25388                 /*                                         */
25389                 /*         XRb                 XRc         */
25390                 /*                     +---------------+   */
25391                 /*    A   B   C   D    | E   F   G   H |   */
25392                 /*                     +-------+-------+   */
25393                 /*                             |           */
25394                 /*                            XRa          */
25395                 /*                                         */
25396
25397                 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25398             }
25399             break;
25400         }
25401     }
25402 }
25403
25404
25405 /*
25406  * Decoding engine for MXU
25407  * =======================
25408  */
25409
25410 /*
25411  *
25412  * Decode MXU pool00
25413  *
25414  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25415  *  +-----------+---------+-----+-------+-------+-------+-----------+
25416  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL00|
25417  *  +-----------+---------+-----+-------+-------+-------+-----------+
25418  *
25419  */
25420 static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
25421 {
25422     uint32_t opcode = extract32(ctx->opcode, 18, 3);
25423
25424     switch (opcode) {
25425     case OPC_MXU_S32MAX:
25426     case OPC_MXU_S32MIN:
25427         gen_mxu_S32MAX_S32MIN(ctx);
25428         break;
25429     case OPC_MXU_D16MAX:
25430     case OPC_MXU_D16MIN:
25431         gen_mxu_D16MAX_D16MIN(ctx);
25432         break;
25433     case OPC_MXU_Q8MAX:
25434     case OPC_MXU_Q8MIN:
25435         gen_mxu_Q8MAX_Q8MIN(ctx);
25436         break;
25437     case OPC_MXU_Q8SLT:
25438         /* TODO: Implement emulation of Q8SLT instruction. */
25439         MIPS_INVAL("OPC_MXU_Q8SLT");
25440         generate_exception_end(ctx, EXCP_RI);
25441         break;
25442     case OPC_MXU_Q8SLTU:
25443         /* TODO: Implement emulation of Q8SLTU instruction. */
25444         MIPS_INVAL("OPC_MXU_Q8SLTU");
25445         generate_exception_end(ctx, EXCP_RI);
25446         break;
25447     default:
25448         MIPS_INVAL("decode_opc_mxu");
25449         generate_exception_end(ctx, EXCP_RI);
25450         break;
25451     }
25452 }
25453
25454 /*
25455  *
25456  * Decode MXU pool01
25457  *
25458  *  S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
25459  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25460  *  +-----------+---------+-----+-------+-------+-------+-----------+
25461  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
25462  *  +-----------+---------+-----+-------+-------+-------+-----------+
25463  *
25464  *  Q8ADD:
25465  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25466  *  +-----------+---+-----+-----+-------+-------+-------+-----------+
25467  *  |  SPECIAL2 |en2|0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
25468  *  +-----------+---+-----+-----+-------+-------+-------+-----------+
25469  *
25470  */
25471 static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
25472 {
25473     uint32_t opcode = extract32(ctx->opcode, 18, 3);
25474
25475     switch (opcode) {
25476     case OPC_MXU_S32SLT:
25477         /* TODO: Implement emulation of S32SLT instruction. */
25478         MIPS_INVAL("OPC_MXU_S32SLT");
25479         generate_exception_end(ctx, EXCP_RI);
25480         break;
25481     case OPC_MXU_D16SLT:
25482         /* TODO: Implement emulation of D16SLT instruction. */
25483         MIPS_INVAL("OPC_MXU_D16SLT");
25484         generate_exception_end(ctx, EXCP_RI);
25485         break;
25486     case OPC_MXU_D16AVG:
25487         /* TODO: Implement emulation of D16AVG instruction. */
25488         MIPS_INVAL("OPC_MXU_D16AVG");
25489         generate_exception_end(ctx, EXCP_RI);
25490         break;
25491     case OPC_MXU_D16AVGR:
25492         /* TODO: Implement emulation of D16AVGR instruction. */
25493         MIPS_INVAL("OPC_MXU_D16AVGR");
25494         generate_exception_end(ctx, EXCP_RI);
25495         break;
25496     case OPC_MXU_Q8AVG:
25497         /* TODO: Implement emulation of Q8AVG instruction. */
25498         MIPS_INVAL("OPC_MXU_Q8AVG");
25499         generate_exception_end(ctx, EXCP_RI);
25500         break;
25501     case OPC_MXU_Q8AVGR:
25502         /* TODO: Implement emulation of Q8AVGR instruction. */
25503         MIPS_INVAL("OPC_MXU_Q8AVGR");
25504         generate_exception_end(ctx, EXCP_RI);
25505         break;
25506     case OPC_MXU_Q8ADD:
25507         /* TODO: Implement emulation of Q8ADD instruction. */
25508         MIPS_INVAL("OPC_MXU_Q8ADD");
25509         generate_exception_end(ctx, EXCP_RI);
25510         break;
25511     default:
25512         MIPS_INVAL("decode_opc_mxu");
25513         generate_exception_end(ctx, EXCP_RI);
25514         break;
25515     }
25516 }
25517
25518 /*
25519  *
25520  * Decode MXU pool02
25521  *
25522  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25523  *  +-----------+---------+-----+-------+-------+-------+-----------+
25524  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL02|
25525  *  +-----------+---------+-----+-------+-------+-------+-----------+
25526  *
25527  */
25528 static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
25529 {
25530     uint32_t opcode = extract32(ctx->opcode, 18, 3);
25531
25532     switch (opcode) {
25533     case OPC_MXU_S32CPS:
25534         /* TODO: Implement emulation of S32CPS instruction. */
25535         MIPS_INVAL("OPC_MXU_S32CPS");
25536         generate_exception_end(ctx, EXCP_RI);
25537         break;
25538     case OPC_MXU_D16CPS:
25539         /* TODO: Implement emulation of D16CPS instruction. */
25540         MIPS_INVAL("OPC_MXU_D16CPS");
25541         generate_exception_end(ctx, EXCP_RI);
25542         break;
25543     case OPC_MXU_Q8ABD:
25544         /* TODO: Implement emulation of Q8ABD instruction. */
25545         MIPS_INVAL("OPC_MXU_Q8ABD");
25546         generate_exception_end(ctx, EXCP_RI);
25547         break;
25548     case OPC_MXU_Q16SAT:
25549         /* TODO: Implement emulation of Q16SAT instruction. */
25550         MIPS_INVAL("OPC_MXU_Q16SAT");
25551         generate_exception_end(ctx, EXCP_RI);
25552         break;
25553     default:
25554         MIPS_INVAL("decode_opc_mxu");
25555         generate_exception_end(ctx, EXCP_RI);
25556         break;
25557     }
25558 }
25559
25560 /*
25561  *
25562  * Decode MXU pool03
25563  *
25564  *  D16MULF:
25565  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25566  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25567  *  |  SPECIAL2 |x x|on2|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL03|
25568  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25569  *
25570  *  D16MULE:
25571  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25572  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25573  *  |  SPECIAL2 |x x|on2|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL03|
25574  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25575  *
25576  */
25577 static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
25578 {
25579     uint32_t opcode = extract32(ctx->opcode, 24, 2);
25580
25581     switch (opcode) {
25582     case OPC_MXU_D16MULF:
25583         /* TODO: Implement emulation of D16MULF instruction. */
25584         MIPS_INVAL("OPC_MXU_D16MULF");
25585         generate_exception_end(ctx, EXCP_RI);
25586         break;
25587     case OPC_MXU_D16MULE:
25588         /* TODO: Implement emulation of D16MULE instruction. */
25589         MIPS_INVAL("OPC_MXU_D16MULE");
25590         generate_exception_end(ctx, EXCP_RI);
25591         break;
25592     default:
25593         MIPS_INVAL("decode_opc_mxu");
25594         generate_exception_end(ctx, EXCP_RI);
25595         break;
25596     }
25597 }
25598
25599 /*
25600  *
25601  * Decode MXU pool04
25602  *
25603  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25604  *  +-----------+---------+-+-------------------+-------+-----------+
25605  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL04|
25606  *  +-----------+---------+-+-------------------+-------+-----------+
25607  *
25608  */
25609 static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
25610 {
25611     uint32_t opcode = extract32(ctx->opcode, 20, 1);
25612
25613     switch (opcode) {
25614     case OPC_MXU_S32LDD:
25615     case OPC_MXU_S32LDDR:
25616         gen_mxu_s32ldd_s32lddr(ctx);
25617         break;
25618     default:
25619         MIPS_INVAL("decode_opc_mxu");
25620         generate_exception_end(ctx, EXCP_RI);
25621         break;
25622     }
25623 }
25624
25625 /*
25626  *
25627  * Decode MXU pool05
25628  *
25629  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25630  *  +-----------+---------+-+-------------------+-------+-----------+
25631  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL05|
25632  *  +-----------+---------+-+-------------------+-------+-----------+
25633  *
25634  */
25635 static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
25636 {
25637     uint32_t opcode = extract32(ctx->opcode, 20, 1);
25638
25639     switch (opcode) {
25640     case OPC_MXU_S32STD:
25641         /* TODO: Implement emulation of S32STD instruction. */
25642         MIPS_INVAL("OPC_MXU_S32STD");
25643         generate_exception_end(ctx, EXCP_RI);
25644         break;
25645     case OPC_MXU_S32STDR:
25646         /* TODO: Implement emulation of S32STDR instruction. */
25647         MIPS_INVAL("OPC_MXU_S32STDR");
25648         generate_exception_end(ctx, EXCP_RI);
25649         break;
25650     default:
25651         MIPS_INVAL("decode_opc_mxu");
25652         generate_exception_end(ctx, EXCP_RI);
25653         break;
25654     }
25655 }
25656
25657 /*
25658  *
25659  * Decode MXU pool06
25660  *
25661  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25662  *  +-----------+---------+---------+---+-------+-------+-----------+
25663  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL06|
25664  *  +-----------+---------+---------+---+-------+-------+-----------+
25665  *
25666  */
25667 static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
25668 {
25669     uint32_t opcode = extract32(ctx->opcode, 10, 4);
25670
25671     switch (opcode) {
25672     case OPC_MXU_S32LDDV:
25673         /* TODO: Implement emulation of S32LDDV instruction. */
25674         MIPS_INVAL("OPC_MXU_S32LDDV");
25675         generate_exception_end(ctx, EXCP_RI);
25676         break;
25677     case OPC_MXU_S32LDDVR:
25678         /* TODO: Implement emulation of S32LDDVR instruction. */
25679         MIPS_INVAL("OPC_MXU_S32LDDVR");
25680         generate_exception_end(ctx, EXCP_RI);
25681         break;
25682     default:
25683         MIPS_INVAL("decode_opc_mxu");
25684         generate_exception_end(ctx, EXCP_RI);
25685         break;
25686     }
25687 }
25688
25689 /*
25690  *
25691  * Decode MXU pool07
25692  *
25693  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25694  *  +-----------+---------+---------+---+-------+-------+-----------+
25695  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL07|
25696  *  +-----------+---------+---------+---+-------+-------+-----------+
25697  *
25698  */
25699 static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
25700 {
25701     uint32_t opcode = extract32(ctx->opcode, 10, 4);
25702
25703     switch (opcode) {
25704     case OPC_MXU_S32STDV:
25705         /* TODO: Implement emulation of S32TDV instruction. */
25706         MIPS_INVAL("OPC_MXU_S32TDV");
25707         generate_exception_end(ctx, EXCP_RI);
25708         break;
25709     case OPC_MXU_S32STDVR:
25710         /* TODO: Implement emulation of S32TDVR instruction. */
25711         MIPS_INVAL("OPC_MXU_S32TDVR");
25712         generate_exception_end(ctx, EXCP_RI);
25713         break;
25714     default:
25715         MIPS_INVAL("decode_opc_mxu");
25716         generate_exception_end(ctx, EXCP_RI);
25717         break;
25718     }
25719 }
25720
25721 /*
25722  *
25723  * Decode MXU pool08
25724  *
25725  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25726  *  +-----------+---------+-+-------------------+-------+-----------+
25727  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL08|
25728  *  +-----------+---------+-+-------------------+-------+-----------+
25729  *
25730 */
25731 static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
25732 {
25733     uint32_t opcode = extract32(ctx->opcode, 20, 1);
25734
25735     switch (opcode) {
25736     case OPC_MXU_S32LDI:
25737         /* TODO: Implement emulation of S32LDI instruction. */
25738         MIPS_INVAL("OPC_MXU_S32LDI");
25739         generate_exception_end(ctx, EXCP_RI);
25740         break;
25741     case OPC_MXU_S32LDIR:
25742         /* TODO: Implement emulation of S32LDIR instruction. */
25743         MIPS_INVAL("OPC_MXU_S32LDIR");
25744         generate_exception_end(ctx, EXCP_RI);
25745         break;
25746     default:
25747         MIPS_INVAL("decode_opc_mxu");
25748         generate_exception_end(ctx, EXCP_RI);
25749         break;
25750     }
25751 }
25752
25753 /*
25754  *
25755  * Decode MXU pool09
25756  *
25757  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25758  *  +-----------+---------+-+-------------------+-------+-----------+
25759  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL09|
25760  *  +-----------+---------+-+-------------------+-------+-----------+
25761  *
25762  */
25763 static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
25764 {
25765     uint32_t opcode = extract32(ctx->opcode, 5, 0);
25766
25767     switch (opcode) {
25768     case OPC_MXU_S32SDI:
25769         /* TODO: Implement emulation of S32SDI instruction. */
25770         MIPS_INVAL("OPC_MXU_S32SDI");
25771         generate_exception_end(ctx, EXCP_RI);
25772         break;
25773     case OPC_MXU_S32SDIR:
25774         /* TODO: Implement emulation of S32SDIR instruction. */
25775         MIPS_INVAL("OPC_MXU_S32SDIR");
25776         generate_exception_end(ctx, EXCP_RI);
25777         break;
25778     default:
25779         MIPS_INVAL("decode_opc_mxu");
25780         generate_exception_end(ctx, EXCP_RI);
25781         break;
25782     }
25783 }
25784
25785 /*
25786  *
25787  * Decode MXU pool10
25788  *
25789  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25790  *  +-----------+---------+---------+---+-------+-------+-----------+
25791  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL10|
25792  *  +-----------+---------+---------+---+-------+-------+-----------+
25793  *
25794  */
25795 static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
25796 {
25797     uint32_t opcode = extract32(ctx->opcode, 5, 0);
25798
25799     switch (opcode) {
25800     case OPC_MXU_S32LDIV:
25801         /* TODO: Implement emulation of S32LDIV instruction. */
25802         MIPS_INVAL("OPC_MXU_S32LDIV");
25803         generate_exception_end(ctx, EXCP_RI);
25804         break;
25805     case OPC_MXU_S32LDIVR:
25806         /* TODO: Implement emulation of S32LDIVR instruction. */
25807         MIPS_INVAL("OPC_MXU_S32LDIVR");
25808         generate_exception_end(ctx, EXCP_RI);
25809         break;
25810     default:
25811         MIPS_INVAL("decode_opc_mxu");
25812         generate_exception_end(ctx, EXCP_RI);
25813         break;
25814     }
25815 }
25816
25817 /*
25818  *
25819  * Decode MXU pool11
25820  *
25821  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25822  *  +-----------+---------+---------+---+-------+-------+-----------+
25823  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL11|
25824  *  +-----------+---------+---------+---+-------+-------+-----------+
25825  *
25826  */
25827 static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
25828 {
25829     uint32_t opcode = extract32(ctx->opcode, 10, 4);
25830
25831     switch (opcode) {
25832     case OPC_MXU_S32SDIV:
25833         /* TODO: Implement emulation of S32SDIV instruction. */
25834         MIPS_INVAL("OPC_MXU_S32SDIV");
25835         generate_exception_end(ctx, EXCP_RI);
25836         break;
25837     case OPC_MXU_S32SDIVR:
25838         /* TODO: Implement emulation of S32SDIVR instruction. */
25839         MIPS_INVAL("OPC_MXU_S32SDIVR");
25840         generate_exception_end(ctx, EXCP_RI);
25841         break;
25842     default:
25843         MIPS_INVAL("decode_opc_mxu");
25844         generate_exception_end(ctx, EXCP_RI);
25845         break;
25846     }
25847 }
25848
25849 /*
25850  *
25851  * Decode MXU pool12
25852  *
25853  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25854  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25855  *  |  SPECIAL2 |an2|x x|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL12|
25856  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25857  *
25858  */
25859 static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
25860 {
25861     uint32_t opcode = extract32(ctx->opcode, 22, 2);
25862
25863     switch (opcode) {
25864     case OPC_MXU_D32ACC:
25865         /* TODO: Implement emulation of D32ACC instruction. */
25866         MIPS_INVAL("OPC_MXU_D32ACC");
25867         generate_exception_end(ctx, EXCP_RI);
25868         break;
25869     case OPC_MXU_D32ACCM:
25870         /* TODO: Implement emulation of D32ACCM instruction. */
25871         MIPS_INVAL("OPC_MXU_D32ACCM");
25872         generate_exception_end(ctx, EXCP_RI);
25873         break;
25874     case OPC_MXU_D32ASUM:
25875         /* TODO: Implement emulation of D32ASUM instruction. */
25876         MIPS_INVAL("OPC_MXU_D32ASUM");
25877         generate_exception_end(ctx, EXCP_RI);
25878         break;
25879     default:
25880         MIPS_INVAL("decode_opc_mxu");
25881         generate_exception_end(ctx, EXCP_RI);
25882         break;
25883     }
25884 }
25885
25886 /*
25887  *
25888  * Decode MXU pool13
25889  *
25890  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25891  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25892  *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL13|
25893  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25894  *
25895  */
25896 static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
25897 {
25898     uint32_t opcode = extract32(ctx->opcode, 22, 2);
25899
25900     switch (opcode) {
25901     case OPC_MXU_Q16ACC:
25902         /* TODO: Implement emulation of Q16ACC instruction. */
25903         MIPS_INVAL("OPC_MXU_Q16ACC");
25904         generate_exception_end(ctx, EXCP_RI);
25905         break;
25906     case OPC_MXU_Q16ACCM:
25907         /* TODO: Implement emulation of Q16ACCM instruction. */
25908         MIPS_INVAL("OPC_MXU_Q16ACCM");
25909         generate_exception_end(ctx, EXCP_RI);
25910         break;
25911     case OPC_MXU_Q16ASUM:
25912         /* TODO: Implement emulation of Q16ASUM instruction. */
25913         MIPS_INVAL("OPC_MXU_Q16ASUM");
25914         generate_exception_end(ctx, EXCP_RI);
25915         break;
25916     default:
25917         MIPS_INVAL("decode_opc_mxu");
25918         generate_exception_end(ctx, EXCP_RI);
25919         break;
25920     }
25921 }
25922
25923 /*
25924  *
25925  * Decode MXU pool14
25926  *
25927  *  Q8ADDE, Q8ACCE:
25928  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25929  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25930  *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL14|
25931  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25932  *
25933  *  D8SUM, D8SUMC:
25934  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25935  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25936  *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL14|
25937  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25938  *
25939  */
25940 static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
25941 {
25942     uint32_t opcode = extract32(ctx->opcode, 22, 2);
25943
25944     switch (opcode) {
25945     case OPC_MXU_Q8ADDE:
25946         /* TODO: Implement emulation of Q8ADDE instruction. */
25947         MIPS_INVAL("OPC_MXU_Q8ADDE");
25948         generate_exception_end(ctx, EXCP_RI);
25949         break;
25950     case OPC_MXU_D8SUM:
25951         /* TODO: Implement emulation of D8SUM instruction. */
25952         MIPS_INVAL("OPC_MXU_D8SUM");
25953         generate_exception_end(ctx, EXCP_RI);
25954         break;
25955     case OPC_MXU_D8SUMC:
25956         /* TODO: Implement emulation of D8SUMC instruction. */
25957         MIPS_INVAL("OPC_MXU_D8SUMC");
25958         generate_exception_end(ctx, EXCP_RI);
25959         break;
25960     default:
25961         MIPS_INVAL("decode_opc_mxu");
25962         generate_exception_end(ctx, EXCP_RI);
25963         break;
25964     }
25965 }
25966
25967 /*
25968  *
25969  * Decode MXU pool15
25970  *
25971  *  S32MUL, S32MULU, S32EXTRV:
25972  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25973  *  +-----------+---------+---------+---+-------+-------+-----------+
25974  *  |  SPECIAL2 |    rs   |    rt   |x x|  XRd  |  XRa  |MXU__POOL15|
25975  *  +-----------+---------+---------+---+-------+-------+-----------+
25976  *
25977  *  S32EXTR:
25978  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
25979  *  +-----------+---------+---------+---+-------+-------+-----------+
25980  *  |  SPECIAL2 |    rb   |   sft5  |x x|  XRd  |  XRa  |MXU__POOL15|
25981  *  +-----------+---------+---------+---+-------+-------+-----------+
25982  *
25983  */
25984 static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
25985 {
25986     uint32_t opcode = extract32(ctx->opcode, 14, 2);
25987
25988     switch (opcode) {
25989     case OPC_MXU_S32MUL:
25990         /* TODO: Implement emulation of S32MUL instruction. */
25991         MIPS_INVAL("OPC_MXU_S32MUL");
25992         generate_exception_end(ctx, EXCP_RI);
25993         break;
25994     case OPC_MXU_S32MULU:
25995         /* TODO: Implement emulation of S32MULU instruction. */
25996         MIPS_INVAL("OPC_MXU_S32MULU");
25997         generate_exception_end(ctx, EXCP_RI);
25998         break;
25999     case OPC_MXU_S32EXTR:
26000         /* TODO: Implement emulation of S32EXTR instruction. */
26001         MIPS_INVAL("OPC_MXU_S32EXTR");
26002         generate_exception_end(ctx, EXCP_RI);
26003         break;
26004     case OPC_MXU_S32EXTRV:
26005         /* TODO: Implement emulation of S32EXTRV instruction. */
26006         MIPS_INVAL("OPC_MXU_S32EXTRV");
26007         generate_exception_end(ctx, EXCP_RI);
26008         break;
26009     default:
26010         MIPS_INVAL("decode_opc_mxu");
26011         generate_exception_end(ctx, EXCP_RI);
26012         break;
26013     }
26014 }
26015
26016 /*
26017  *
26018  * Decode MXU pool16
26019  *
26020  *  D32SARW:
26021  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26022  *  +-----------+---------+-----+-------+-------+-------+-----------+
26023  *  |  SPECIAL2 |    rb   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26024  *  +-----------+---------+-----+-------+-------+-------+-----------+
26025  *
26026  *  S32ALN:
26027  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26028  *  +-----------+---------+-----+-------+-------+-------+-----------+
26029  *  |  SPECIAL2 |    rs   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26030  *  +-----------+---------+-----+-------+-------+-------+-----------+
26031  *
26032  *  S32ALNI:
26033  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26034  *  +-----------+-----+---+-----+-------+-------+-------+-----------+
26035  *  |  SPECIAL2 |  s3 |0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26036  *  +-----------+-----+---+-----+-------+-------+-------+-----------+
26037  *
26038  *  S32LUI:
26039  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26040  *  +-----------+-----+---+-----+-------+---------------+-----------+
26041  *  |  SPECIAL2 |optn3|0 0|x x x|  XRc  |       s8      |MXU__POOL16|
26042  *  +-----------+-----+---+-----+-------+---------------+-----------+
26043  *
26044  *  S32NOR, S32AND, S32OR, S32XOR:
26045  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26046  *  +-----------+---------+-----+-------+-------+-------+-----------+
26047  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26048  *  +-----------+---------+-----+-------+-------+-------+-----------+
26049  *
26050  */
26051 static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
26052 {
26053     uint32_t opcode = extract32(ctx->opcode, 18, 3);
26054
26055     switch (opcode) {
26056     case OPC_MXU_D32SARW:
26057         /* TODO: Implement emulation of D32SARW instruction. */
26058         MIPS_INVAL("OPC_MXU_D32SARW");
26059         generate_exception_end(ctx, EXCP_RI);
26060         break;
26061     case OPC_MXU_S32ALN:
26062         /* TODO: Implement emulation of S32ALN instruction. */
26063         MIPS_INVAL("OPC_MXU_S32ALN");
26064         generate_exception_end(ctx, EXCP_RI);
26065         break;
26066     case OPC_MXU_S32ALNI:
26067         gen_mxu_S32ALNI(ctx);
26068         break;
26069     case OPC_MXU_S32LUI:
26070         /* TODO: Implement emulation of S32LUI instruction. */
26071         MIPS_INVAL("OPC_MXU_S32LUI");
26072         generate_exception_end(ctx, EXCP_RI);
26073         break;
26074     case OPC_MXU_S32NOR:
26075         gen_mxu_S32NOR(ctx);
26076         break;
26077     case OPC_MXU_S32AND:
26078         gen_mxu_S32AND(ctx);
26079         break;
26080     case OPC_MXU_S32OR:
26081         gen_mxu_S32OR(ctx);
26082         break;
26083     case OPC_MXU_S32XOR:
26084         gen_mxu_S32XOR(ctx);
26085         break;
26086     default:
26087         MIPS_INVAL("decode_opc_mxu");
26088         generate_exception_end(ctx, EXCP_RI);
26089         break;
26090     }
26091 }
26092
26093 /*
26094  *
26095  * Decode MXU pool17
26096  *
26097  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26098  *  +-----------+---------+---------+---+---------+-----+-----------+
26099  *  |  SPECIAL2 |    rs   |    rt   |0 0|    rd   |x x x|MXU__POOL15|
26100  *  +-----------+---------+---------+---+---------+-----+-----------+
26101  *
26102  */
26103 static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
26104 {
26105     uint32_t opcode = extract32(ctx->opcode, 6, 2);
26106
26107     switch (opcode) {
26108     case OPC_MXU_LXW:
26109         /* TODO: Implement emulation of LXW instruction. */
26110         MIPS_INVAL("OPC_MXU_LXW");
26111         generate_exception_end(ctx, EXCP_RI);
26112         break;
26113     case OPC_MXU_LXH:
26114         /* TODO: Implement emulation of LXH instruction. */
26115         MIPS_INVAL("OPC_MXU_LXH");
26116         generate_exception_end(ctx, EXCP_RI);
26117         break;
26118     case OPC_MXU_LXHU:
26119         /* TODO: Implement emulation of LXHU instruction. */
26120         MIPS_INVAL("OPC_MXU_LXHU");
26121         generate_exception_end(ctx, EXCP_RI);
26122         break;
26123     case OPC_MXU_LXB:
26124         /* TODO: Implement emulation of LXB instruction. */
26125         MIPS_INVAL("OPC_MXU_LXB");
26126         generate_exception_end(ctx, EXCP_RI);
26127         break;
26128     case OPC_MXU_LXBU:
26129         /* TODO: Implement emulation of LXBU instruction. */
26130         MIPS_INVAL("OPC_MXU_LXBU");
26131         generate_exception_end(ctx, EXCP_RI);
26132         break;
26133     default:
26134         MIPS_INVAL("decode_opc_mxu");
26135         generate_exception_end(ctx, EXCP_RI);
26136         break;
26137     }
26138 }
26139 /*
26140  *
26141  * Decode MXU pool18
26142  *
26143  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26144  *  +-----------+---------+-----+-------+-------+-------+-----------+
26145  *  |  SPECIAL2 |    rb   |x x x|  XRd  |  XRa  |0 0 0 0|MXU__POOL18|
26146  *  +-----------+---------+-----+-------+-------+-------+-----------+
26147  *
26148  */
26149 static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
26150 {
26151     uint32_t opcode = extract32(ctx->opcode, 18, 3);
26152
26153     switch (opcode) {
26154     case OPC_MXU_D32SLLV:
26155         /* TODO: Implement emulation of D32SLLV instruction. */
26156         MIPS_INVAL("OPC_MXU_D32SLLV");
26157         generate_exception_end(ctx, EXCP_RI);
26158         break;
26159     case OPC_MXU_D32SLRV:
26160         /* TODO: Implement emulation of D32SLRV instruction. */
26161         MIPS_INVAL("OPC_MXU_D32SLRV");
26162         generate_exception_end(ctx, EXCP_RI);
26163         break;
26164     case OPC_MXU_D32SARV:
26165         /* TODO: Implement emulation of D32SARV instruction. */
26166         MIPS_INVAL("OPC_MXU_D32SARV");
26167         generate_exception_end(ctx, EXCP_RI);
26168         break;
26169     case OPC_MXU_Q16SLLV:
26170         /* TODO: Implement emulation of Q16SLLV instruction. */
26171         MIPS_INVAL("OPC_MXU_Q16SLLV");
26172         generate_exception_end(ctx, EXCP_RI);
26173         break;
26174     case OPC_MXU_Q16SLRV:
26175         /* TODO: Implement emulation of Q16SLRV instruction. */
26176         MIPS_INVAL("OPC_MXU_Q16SLRV");
26177         generate_exception_end(ctx, EXCP_RI);
26178         break;
26179     case OPC_MXU_Q16SARV:
26180         /* TODO: Implement emulation of Q16SARV instruction. */
26181         MIPS_INVAL("OPC_MXU_Q16SARV");
26182         generate_exception_end(ctx, EXCP_RI);
26183         break;
26184     default:
26185         MIPS_INVAL("decode_opc_mxu");
26186         generate_exception_end(ctx, EXCP_RI);
26187         break;
26188     }
26189 }
26190
26191 /*
26192  *
26193  * Decode MXU pool19
26194  *
26195  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26196  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26197  *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL19|
26198  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26199  *
26200  */
26201 static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
26202 {
26203     uint32_t opcode = extract32(ctx->opcode, 22, 2);
26204
26205     switch (opcode) {
26206     case OPC_MXU_Q8MUL:
26207     case OPC_MXU_Q8MULSU:
26208         gen_mxu_q8mul_q8mulsu(ctx);
26209         break;
26210     default:
26211         MIPS_INVAL("decode_opc_mxu");
26212         generate_exception_end(ctx, EXCP_RI);
26213         break;
26214     }
26215 }
26216
26217 /*
26218  *
26219  * Decode MXU pool20
26220  *
26221  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26222  *  +-----------+---------+-----+-------+-------+-------+-----------+
26223  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL20|
26224  *  +-----------+---------+-----+-------+-------+-------+-----------+
26225  *
26226  */
26227 static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
26228 {
26229     uint32_t opcode = extract32(ctx->opcode, 18, 3);
26230
26231     switch (opcode) {
26232     case OPC_MXU_Q8MOVZ:
26233         /* TODO: Implement emulation of Q8MOVZ instruction. */
26234         MIPS_INVAL("OPC_MXU_Q8MOVZ");
26235         generate_exception_end(ctx, EXCP_RI);
26236         break;
26237     case OPC_MXU_Q8MOVN:
26238         /* TODO: Implement emulation of Q8MOVN instruction. */
26239         MIPS_INVAL("OPC_MXU_Q8MOVN");
26240         generate_exception_end(ctx, EXCP_RI);
26241         break;
26242     case OPC_MXU_D16MOVZ:
26243         /* TODO: Implement emulation of D16MOVZ instruction. */
26244         MIPS_INVAL("OPC_MXU_D16MOVZ");
26245         generate_exception_end(ctx, EXCP_RI);
26246         break;
26247     case OPC_MXU_D16MOVN:
26248         /* TODO: Implement emulation of D16MOVN instruction. */
26249         MIPS_INVAL("OPC_MXU_D16MOVN");
26250         generate_exception_end(ctx, EXCP_RI);
26251         break;
26252     case OPC_MXU_S32MOVZ:
26253         /* TODO: Implement emulation of S32MOVZ instruction. */
26254         MIPS_INVAL("OPC_MXU_S32MOVZ");
26255         generate_exception_end(ctx, EXCP_RI);
26256         break;
26257     case OPC_MXU_S32MOVN:
26258         /* TODO: Implement emulation of S32MOVN instruction. */
26259         MIPS_INVAL("OPC_MXU_S32MOVN");
26260         generate_exception_end(ctx, EXCP_RI);
26261         break;
26262     default:
26263         MIPS_INVAL("decode_opc_mxu");
26264         generate_exception_end(ctx, EXCP_RI);
26265         break;
26266     }
26267 }
26268
26269 /*
26270  *
26271  * Decode MXU pool21
26272  *
26273  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26274  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26275  *  |  SPECIAL2 |an2|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL21|
26276  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26277  *
26278  */
26279 static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx)
26280 {
26281     uint32_t opcode = extract32(ctx->opcode, 22, 2);
26282
26283     switch (opcode) {
26284     case OPC_MXU_Q8MAC:
26285         /* TODO: Implement emulation of Q8MAC instruction. */
26286         MIPS_INVAL("OPC_MXU_Q8MAC");
26287         generate_exception_end(ctx, EXCP_RI);
26288         break;
26289     case OPC_MXU_Q8MACSU:
26290         /* TODO: Implement emulation of Q8MACSU instruction. */
26291         MIPS_INVAL("OPC_MXU_Q8MACSU");
26292         generate_exception_end(ctx, EXCP_RI);
26293         break;
26294     default:
26295         MIPS_INVAL("decode_opc_mxu");
26296         generate_exception_end(ctx, EXCP_RI);
26297         break;
26298     }
26299 }
26300
26301
26302 /*
26303  * Main MXU decoding function
26304  *
26305  *   1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
26306  *  +-----------+---------------------------------------+-----------+
26307  *  |  SPECIAL2 |                                       |x x x x x x|
26308  *  +-----------+---------------------------------------+-----------+
26309  *
26310  */
26311 static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
26312 {
26313     /*
26314      * TODO: Investigate necessity of including handling of
26315      * CLZ, CLO, SDBB in this function, as they belong to
26316      * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
26317      */
26318     uint32_t opcode = extract32(ctx->opcode, 0, 6);
26319
26320     if (opcode == OPC__MXU_MUL) {
26321         uint32_t  rs, rt, rd, op1;
26322
26323         rs = extract32(ctx->opcode, 21, 5);
26324         rt = extract32(ctx->opcode, 16, 5);
26325         rd = extract32(ctx->opcode, 11, 5);
26326         op1 = MASK_SPECIAL2(ctx->opcode);
26327
26328         gen_arith(ctx, op1, rd, rs, rt);
26329
26330         return;
26331     }
26332
26333     if (opcode == OPC_MXU_S32M2I) {
26334         gen_mxu_s32m2i(ctx);
26335         return;
26336     }
26337
26338     if (opcode == OPC_MXU_S32I2M) {
26339         gen_mxu_s32i2m(ctx);
26340         return;
26341     }
26342
26343     {
26344         TCGv t_mxu_cr = tcg_temp_new();
26345         TCGLabel *l_exit = gen_new_label();
26346
26347         gen_load_mxu_cr(t_mxu_cr);
26348         tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
26349         tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
26350
26351         switch (opcode) {
26352         case OPC_MXU_S32MADD:
26353             /* TODO: Implement emulation of S32MADD instruction. */
26354             MIPS_INVAL("OPC_MXU_S32MADD");
26355             generate_exception_end(ctx, EXCP_RI);
26356             break;
26357         case OPC_MXU_S32MADDU:
26358             /* TODO: Implement emulation of S32MADDU instruction. */
26359             MIPS_INVAL("OPC_MXU_S32MADDU");
26360             generate_exception_end(ctx, EXCP_RI);
26361             break;
26362         case OPC_MXU__POOL00:
26363             decode_opc_mxu__pool00(env, ctx);
26364             break;
26365         case OPC_MXU_S32MSUB:
26366             /* TODO: Implement emulation of S32MSUB instruction. */
26367             MIPS_INVAL("OPC_MXU_S32MSUB");
26368             generate_exception_end(ctx, EXCP_RI);
26369             break;
26370         case OPC_MXU_S32MSUBU:
26371             /* TODO: Implement emulation of S32MSUBU instruction. */
26372             MIPS_INVAL("OPC_MXU_S32MSUBU");
26373             generate_exception_end(ctx, EXCP_RI);
26374             break;
26375         case OPC_MXU__POOL01:
26376             decode_opc_mxu__pool01(env, ctx);
26377             break;
26378         case OPC_MXU__POOL02:
26379             decode_opc_mxu__pool02(env, ctx);
26380             break;
26381         case OPC_MXU_D16MUL:
26382             gen_mxu_d16mul(ctx);
26383             break;
26384         case OPC_MXU__POOL03:
26385             decode_opc_mxu__pool03(env, ctx);
26386             break;
26387         case OPC_MXU_D16MAC:
26388             gen_mxu_d16mac(ctx);
26389             break;
26390         case OPC_MXU_D16MACF:
26391             /* TODO: Implement emulation of D16MACF instruction. */
26392             MIPS_INVAL("OPC_MXU_D16MACF");
26393             generate_exception_end(ctx, EXCP_RI);
26394             break;
26395         case OPC_MXU_D16MADL:
26396             /* TODO: Implement emulation of D16MADL instruction. */
26397             MIPS_INVAL("OPC_MXU_D16MADL");
26398             generate_exception_end(ctx, EXCP_RI);
26399             break;
26400         case OPC_MXU_S16MAD:
26401             /* TODO: Implement emulation of S16MAD instruction. */
26402             MIPS_INVAL("OPC_MXU_S16MAD");
26403             generate_exception_end(ctx, EXCP_RI);
26404             break;
26405         case OPC_MXU_Q16ADD:
26406             /* TODO: Implement emulation of Q16ADD instruction. */
26407             MIPS_INVAL("OPC_MXU_Q16ADD");
26408             generate_exception_end(ctx, EXCP_RI);
26409             break;
26410         case OPC_MXU_D16MACE:
26411             /* TODO: Implement emulation of D16MACE instruction. */
26412             MIPS_INVAL("OPC_MXU_D16MACE");
26413             generate_exception_end(ctx, EXCP_RI);
26414             break;
26415         case OPC_MXU__POOL04:
26416             decode_opc_mxu__pool04(env, ctx);
26417             break;
26418         case OPC_MXU__POOL05:
26419             decode_opc_mxu__pool05(env, ctx);
26420             break;
26421         case OPC_MXU__POOL06:
26422             decode_opc_mxu__pool06(env, ctx);
26423             break;
26424         case OPC_MXU__POOL07:
26425             decode_opc_mxu__pool07(env, ctx);
26426             break;
26427         case OPC_MXU__POOL08:
26428             decode_opc_mxu__pool08(env, ctx);
26429             break;
26430         case OPC_MXU__POOL09:
26431             decode_opc_mxu__pool09(env, ctx);
26432             break;
26433         case OPC_MXU__POOL10:
26434             decode_opc_mxu__pool10(env, ctx);
26435             break;
26436         case OPC_MXU__POOL11:
26437             decode_opc_mxu__pool11(env, ctx);
26438             break;
26439         case OPC_MXU_D32ADD:
26440             /* TODO: Implement emulation of D32ADD instruction. */
26441             MIPS_INVAL("OPC_MXU_D32ADD");
26442             generate_exception_end(ctx, EXCP_RI);
26443             break;
26444         case OPC_MXU__POOL12:
26445             decode_opc_mxu__pool12(env, ctx);
26446             break;
26447         case OPC_MXU__POOL13:
26448             decode_opc_mxu__pool13(env, ctx);
26449             break;
26450         case OPC_MXU__POOL14:
26451             decode_opc_mxu__pool14(env, ctx);
26452             break;
26453         case OPC_MXU_Q8ACCE:
26454             /* TODO: Implement emulation of Q8ACCE instruction. */
26455             MIPS_INVAL("OPC_MXU_Q8ACCE");
26456             generate_exception_end(ctx, EXCP_RI);
26457             break;
26458         case OPC_MXU_S8LDD:
26459             gen_mxu_s8ldd(ctx);
26460             break;
26461         case OPC_MXU_S8STD:
26462             /* TODO: Implement emulation of S8STD instruction. */
26463             MIPS_INVAL("OPC_MXU_S8STD");
26464             generate_exception_end(ctx, EXCP_RI);
26465             break;
26466         case OPC_MXU_S8LDI:
26467             /* TODO: Implement emulation of S8LDI instruction. */
26468             MIPS_INVAL("OPC_MXU_S8LDI");
26469             generate_exception_end(ctx, EXCP_RI);
26470             break;
26471         case OPC_MXU_S8SDI:
26472             /* TODO: Implement emulation of S8SDI instruction. */
26473             MIPS_INVAL("OPC_MXU_S8SDI");
26474             generate_exception_end(ctx, EXCP_RI);
26475             break;
26476         case OPC_MXU__POOL15:
26477             decode_opc_mxu__pool15(env, ctx);
26478             break;
26479         case OPC_MXU__POOL16:
26480             decode_opc_mxu__pool16(env, ctx);
26481             break;
26482         case OPC_MXU__POOL17:
26483             decode_opc_mxu__pool17(env, ctx);
26484             break;
26485         case OPC_MXU_S16LDD:
26486             /* TODO: Implement emulation of S16LDD instruction. */
26487             MIPS_INVAL("OPC_MXU_S16LDD");
26488             generate_exception_end(ctx, EXCP_RI);
26489             break;
26490         case OPC_MXU_S16STD:
26491             /* TODO: Implement emulation of S16STD instruction. */
26492             MIPS_INVAL("OPC_MXU_S16STD");
26493             generate_exception_end(ctx, EXCP_RI);
26494             break;
26495         case OPC_MXU_S16LDI:
26496             /* TODO: Implement emulation of S16LDI instruction. */
26497             MIPS_INVAL("OPC_MXU_S16LDI");
26498             generate_exception_end(ctx, EXCP_RI);
26499             break;
26500         case OPC_MXU_S16SDI:
26501             /* TODO: Implement emulation of S16SDI instruction. */
26502             MIPS_INVAL("OPC_MXU_S16SDI");
26503             generate_exception_end(ctx, EXCP_RI);
26504             break;
26505         case OPC_MXU_D32SLL:
26506             /* TODO: Implement emulation of D32SLL instruction. */
26507             MIPS_INVAL("OPC_MXU_D32SLL");
26508             generate_exception_end(ctx, EXCP_RI);
26509             break;
26510         case OPC_MXU_D32SLR:
26511             /* TODO: Implement emulation of D32SLR instruction. */
26512             MIPS_INVAL("OPC_MXU_D32SLR");
26513             generate_exception_end(ctx, EXCP_RI);
26514             break;
26515         case OPC_MXU_D32SARL:
26516             /* TODO: Implement emulation of D32SARL instruction. */
26517             MIPS_INVAL("OPC_MXU_D32SARL");
26518             generate_exception_end(ctx, EXCP_RI);
26519             break;
26520         case OPC_MXU_D32SAR:
26521             /* TODO: Implement emulation of D32SAR instruction. */
26522             MIPS_INVAL("OPC_MXU_D32SAR");
26523             generate_exception_end(ctx, EXCP_RI);
26524             break;
26525         case OPC_MXU_Q16SLL:
26526             /* TODO: Implement emulation of Q16SLL instruction. */
26527             MIPS_INVAL("OPC_MXU_Q16SLL");
26528             generate_exception_end(ctx, EXCP_RI);
26529             break;
26530         case OPC_MXU_Q16SLR:
26531             /* TODO: Implement emulation of Q16SLR instruction. */
26532             MIPS_INVAL("OPC_MXU_Q16SLR");
26533             generate_exception_end(ctx, EXCP_RI);
26534             break;
26535         case OPC_MXU__POOL18:
26536             decode_opc_mxu__pool18(env, ctx);
26537             break;
26538         case OPC_MXU_Q16SAR:
26539             /* TODO: Implement emulation of Q16SAR instruction. */
26540             MIPS_INVAL("OPC_MXU_Q16SAR");
26541             generate_exception_end(ctx, EXCP_RI);
26542             break;
26543         case OPC_MXU__POOL19:
26544             decode_opc_mxu__pool19(env, ctx);
26545             break;
26546         case OPC_MXU__POOL20:
26547             decode_opc_mxu__pool20(env, ctx);
26548             break;
26549         case OPC_MXU__POOL21:
26550             decode_opc_mxu__pool21(env, ctx);
26551             break;
26552         case OPC_MXU_Q16SCOP:
26553             /* TODO: Implement emulation of Q16SCOP instruction. */
26554             MIPS_INVAL("OPC_MXU_Q16SCOP");
26555             generate_exception_end(ctx, EXCP_RI);
26556             break;
26557         case OPC_MXU_Q8MADL:
26558             /* TODO: Implement emulation of Q8MADL instruction. */
26559             MIPS_INVAL("OPC_MXU_Q8MADL");
26560             generate_exception_end(ctx, EXCP_RI);
26561             break;
26562         case OPC_MXU_S32SFL:
26563             /* TODO: Implement emulation of S32SFL instruction. */
26564             MIPS_INVAL("OPC_MXU_S32SFL");
26565             generate_exception_end(ctx, EXCP_RI);
26566             break;
26567         case OPC_MXU_Q8SAD:
26568             /* TODO: Implement emulation of Q8SAD instruction. */
26569             MIPS_INVAL("OPC_MXU_Q8SAD");
26570             generate_exception_end(ctx, EXCP_RI);
26571             break;
26572         default:
26573             MIPS_INVAL("decode_opc_mxu");
26574             generate_exception_end(ctx, EXCP_RI);
26575         }
26576
26577         gen_set_label(l_exit);
26578         tcg_temp_free(t_mxu_cr);
26579     }
26580 }
26581
26582 #endif /* !defined(TARGET_MIPS64) */
26583
26584
26585 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
26586 {
26587     int rs, rt, rd;
26588     uint32_t op1;
26589
26590     check_insn_opc_removed(ctx, ISA_MIPS32R6);
26591
26592     rs = (ctx->opcode >> 21) & 0x1f;
26593     rt = (ctx->opcode >> 16) & 0x1f;
26594     rd = (ctx->opcode >> 11) & 0x1f;
26595
26596     op1 = MASK_SPECIAL2(ctx->opcode);
26597     switch (op1) {
26598     case OPC_MADD: /* Multiply and add/sub */
26599     case OPC_MADDU:
26600     case OPC_MSUB:
26601     case OPC_MSUBU:
26602         check_insn(ctx, ISA_MIPS32);
26603         gen_muldiv(ctx, op1, rd & 3, rs, rt);
26604         break;
26605     case OPC_MUL:
26606         gen_arith(ctx, op1, rd, rs, rt);
26607         break;
26608     case OPC_DIV_G_2F:
26609     case OPC_DIVU_G_2F:
26610     case OPC_MULT_G_2F:
26611     case OPC_MULTU_G_2F:
26612     case OPC_MOD_G_2F:
26613     case OPC_MODU_G_2F:
26614         check_insn(ctx, INSN_LOONGSON2F);
26615         gen_loongson_integer(ctx, op1, rd, rs, rt);
26616         break;
26617     case OPC_CLO:
26618     case OPC_CLZ:
26619         check_insn(ctx, ISA_MIPS32);
26620         gen_cl(ctx, op1, rd, rs);
26621         break;
26622     case OPC_SDBBP:
26623         if (is_uhi(extract32(ctx->opcode, 6, 20))) {
26624             gen_helper_do_semihosting(cpu_env);
26625         } else {
26626             /* XXX: not clear which exception should be raised
26627              *      when in debug mode...
26628              */
26629             check_insn(ctx, ISA_MIPS32);
26630             generate_exception_end(ctx, EXCP_DBp);
26631         }
26632         break;
26633 #if defined(TARGET_MIPS64)
26634     case OPC_DCLO:
26635     case OPC_DCLZ:
26636         check_insn(ctx, ISA_MIPS64);
26637         check_mips_64(ctx);
26638         gen_cl(ctx, op1, rd, rs);
26639         break;
26640     case OPC_DMULT_G_2F:
26641     case OPC_DMULTU_G_2F:
26642     case OPC_DDIV_G_2F:
26643     case OPC_DDIVU_G_2F:
26644     case OPC_DMOD_G_2F:
26645     case OPC_DMODU_G_2F:
26646         check_insn(ctx, INSN_LOONGSON2F);
26647         gen_loongson_integer(ctx, op1, rd, rs, rt);
26648         break;
26649 #endif
26650     default:            /* Invalid */
26651         MIPS_INVAL("special2_legacy");
26652         generate_exception_end(ctx, EXCP_RI);
26653         break;
26654     }
26655 }
26656
26657 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
26658 {
26659     int rs, rt, rd, sa;
26660     uint32_t op1, op2;
26661     int16_t imm;
26662
26663     rs = (ctx->opcode >> 21) & 0x1f;
26664     rt = (ctx->opcode >> 16) & 0x1f;
26665     rd = (ctx->opcode >> 11) & 0x1f;
26666     sa = (ctx->opcode >> 6) & 0x1f;
26667     imm = (int16_t)ctx->opcode >> 7;
26668
26669     op1 = MASK_SPECIAL3(ctx->opcode);
26670     switch (op1) {
26671     case R6_OPC_PREF:
26672         if (rt >= 24) {
26673             /* hint codes 24-31 are reserved and signal RI */
26674             generate_exception_end(ctx, EXCP_RI);
26675         }
26676         /* Treat as NOP. */
26677         break;
26678     case R6_OPC_CACHE:
26679         check_cp0_enabled(ctx);
26680         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
26681             gen_cache_operation(ctx, rt, rs, imm);
26682         }
26683         break;
26684     case R6_OPC_SC:
26685         gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
26686         break;
26687     case R6_OPC_LL:
26688         gen_ld(ctx, op1, rt, rs, imm);
26689         break;
26690     case OPC_BSHFL:
26691         {
26692             if (rd == 0) {
26693                 /* Treat as NOP. */
26694                 break;
26695             }
26696             op2 = MASK_BSHFL(ctx->opcode);
26697             switch (op2) {
26698             case OPC_ALIGN:
26699             case OPC_ALIGN_1:
26700             case OPC_ALIGN_2:
26701             case OPC_ALIGN_3:
26702                 gen_align(ctx, 32, rd, rs, rt, sa & 3);
26703                 break;
26704             case OPC_BITSWAP:
26705                 gen_bitswap(ctx, op2, rd, rt);
26706                 break;
26707             }
26708         }
26709         break;
26710 #if defined(TARGET_MIPS64)
26711     case R6_OPC_SCD:
26712         gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
26713         break;
26714     case R6_OPC_LLD:
26715         gen_ld(ctx, op1, rt, rs, imm);
26716         break;
26717     case OPC_DBSHFL:
26718         check_mips_64(ctx);
26719         {
26720             if (rd == 0) {
26721                 /* Treat as NOP. */
26722                 break;
26723             }
26724             op2 = MASK_DBSHFL(ctx->opcode);
26725             switch (op2) {
26726             case OPC_DALIGN:
26727             case OPC_DALIGN_1:
26728             case OPC_DALIGN_2:
26729             case OPC_DALIGN_3:
26730             case OPC_DALIGN_4:
26731             case OPC_DALIGN_5:
26732             case OPC_DALIGN_6:
26733             case OPC_DALIGN_7:
26734                 gen_align(ctx, 64, rd, rs, rt, sa & 7);
26735                 break;
26736             case OPC_DBITSWAP:
26737                 gen_bitswap(ctx, op2, rd, rt);
26738                 break;
26739             }
26740
26741         }
26742         break;
26743 #endif
26744     default:            /* Invalid */
26745         MIPS_INVAL("special3_r6");
26746         generate_exception_end(ctx, EXCP_RI);
26747         break;
26748     }
26749 }
26750
26751 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
26752 {
26753     int rs, rt, rd;
26754     uint32_t op1, op2;
26755
26756     rs = (ctx->opcode >> 21) & 0x1f;
26757     rt = (ctx->opcode >> 16) & 0x1f;
26758     rd = (ctx->opcode >> 11) & 0x1f;
26759
26760     op1 = MASK_SPECIAL3(ctx->opcode);
26761     switch (op1) {
26762     case OPC_DIV_G_2E:
26763     case OPC_DIVU_G_2E:
26764     case OPC_MOD_G_2E:
26765     case OPC_MODU_G_2E:
26766     case OPC_MULT_G_2E:
26767     case OPC_MULTU_G_2E:
26768         /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
26769          * the same mask and op1. */
26770         if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
26771             op2 = MASK_ADDUH_QB(ctx->opcode);
26772             switch (op2) {
26773             case OPC_ADDUH_QB:
26774             case OPC_ADDUH_R_QB:
26775             case OPC_ADDQH_PH:
26776             case OPC_ADDQH_R_PH:
26777             case OPC_ADDQH_W:
26778             case OPC_ADDQH_R_W:
26779             case OPC_SUBUH_QB:
26780             case OPC_SUBUH_R_QB:
26781             case OPC_SUBQH_PH:
26782             case OPC_SUBQH_R_PH:
26783             case OPC_SUBQH_W:
26784             case OPC_SUBQH_R_W:
26785                 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26786                 break;
26787             case OPC_MUL_PH:
26788             case OPC_MUL_S_PH:
26789             case OPC_MULQ_S_W:
26790             case OPC_MULQ_RS_W:
26791                 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
26792                 break;
26793             default:
26794                 MIPS_INVAL("MASK ADDUH.QB");
26795                 generate_exception_end(ctx, EXCP_RI);
26796                 break;
26797             }
26798         } else if (ctx->insn_flags & INSN_LOONGSON2E) {
26799             gen_loongson_integer(ctx, op1, rd, rs, rt);
26800         } else {
26801             generate_exception_end(ctx, EXCP_RI);
26802         }
26803         break;
26804     case OPC_LX_DSP:
26805         op2 = MASK_LX(ctx->opcode);
26806         switch (op2) {
26807 #if defined(TARGET_MIPS64)
26808         case OPC_LDX:
26809 #endif
26810         case OPC_LBUX:
26811         case OPC_LHX:
26812         case OPC_LWX:
26813             gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
26814             break;
26815         default:            /* Invalid */
26816             MIPS_INVAL("MASK LX");
26817             generate_exception_end(ctx, EXCP_RI);
26818             break;
26819         }
26820         break;
26821     case OPC_ABSQ_S_PH_DSP:
26822         op2 = MASK_ABSQ_S_PH(ctx->opcode);
26823         switch (op2) {
26824         case OPC_ABSQ_S_QB:
26825         case OPC_ABSQ_S_PH:
26826         case OPC_ABSQ_S_W:
26827         case OPC_PRECEQ_W_PHL:
26828         case OPC_PRECEQ_W_PHR:
26829         case OPC_PRECEQU_PH_QBL:
26830         case OPC_PRECEQU_PH_QBR:
26831         case OPC_PRECEQU_PH_QBLA:
26832         case OPC_PRECEQU_PH_QBRA:
26833         case OPC_PRECEU_PH_QBL:
26834         case OPC_PRECEU_PH_QBR:
26835         case OPC_PRECEU_PH_QBLA:
26836         case OPC_PRECEU_PH_QBRA:
26837             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26838             break;
26839         case OPC_BITREV:
26840         case OPC_REPL_QB:
26841         case OPC_REPLV_QB:
26842         case OPC_REPL_PH:
26843         case OPC_REPLV_PH:
26844             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
26845             break;
26846         default:
26847             MIPS_INVAL("MASK ABSQ_S.PH");
26848             generate_exception_end(ctx, EXCP_RI);
26849             break;
26850         }
26851         break;
26852     case OPC_ADDU_QB_DSP:
26853         op2 = MASK_ADDU_QB(ctx->opcode);
26854         switch (op2) {
26855         case OPC_ADDQ_PH:
26856         case OPC_ADDQ_S_PH:
26857         case OPC_ADDQ_S_W:
26858         case OPC_ADDU_QB:
26859         case OPC_ADDU_S_QB:
26860         case OPC_ADDU_PH:
26861         case OPC_ADDU_S_PH:
26862         case OPC_SUBQ_PH:
26863         case OPC_SUBQ_S_PH:
26864         case OPC_SUBQ_S_W:
26865         case OPC_SUBU_QB:
26866         case OPC_SUBU_S_QB:
26867         case OPC_SUBU_PH:
26868         case OPC_SUBU_S_PH:
26869         case OPC_ADDSC:
26870         case OPC_ADDWC:
26871         case OPC_MODSUB:
26872         case OPC_RADDU_W_QB:
26873             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26874             break;
26875         case OPC_MULEU_S_PH_QBL:
26876         case OPC_MULEU_S_PH_QBR:
26877         case OPC_MULQ_RS_PH:
26878         case OPC_MULEQ_S_W_PHL:
26879         case OPC_MULEQ_S_W_PHR:
26880         case OPC_MULQ_S_PH:
26881             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
26882             break;
26883         default:            /* Invalid */
26884             MIPS_INVAL("MASK ADDU.QB");
26885             generate_exception_end(ctx, EXCP_RI);
26886             break;
26887
26888         }
26889         break;
26890     case OPC_CMPU_EQ_QB_DSP:
26891         op2 = MASK_CMPU_EQ_QB(ctx->opcode);
26892         switch (op2) {
26893         case OPC_PRECR_SRA_PH_W:
26894         case OPC_PRECR_SRA_R_PH_W:
26895             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
26896             break;
26897         case OPC_PRECR_QB_PH:
26898         case OPC_PRECRQ_QB_PH:
26899         case OPC_PRECRQ_PH_W:
26900         case OPC_PRECRQ_RS_PH_W:
26901         case OPC_PRECRQU_S_QB_PH:
26902             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26903             break;
26904         case OPC_CMPU_EQ_QB:
26905         case OPC_CMPU_LT_QB:
26906         case OPC_CMPU_LE_QB:
26907         case OPC_CMP_EQ_PH:
26908         case OPC_CMP_LT_PH:
26909         case OPC_CMP_LE_PH:
26910             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
26911             break;
26912         case OPC_CMPGU_EQ_QB:
26913         case OPC_CMPGU_LT_QB:
26914         case OPC_CMPGU_LE_QB:
26915         case OPC_CMPGDU_EQ_QB:
26916         case OPC_CMPGDU_LT_QB:
26917         case OPC_CMPGDU_LE_QB:
26918         case OPC_PICK_QB:
26919         case OPC_PICK_PH:
26920         case OPC_PACKRL_PH:
26921             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
26922             break;
26923         default:            /* Invalid */
26924             MIPS_INVAL("MASK CMPU.EQ.QB");
26925             generate_exception_end(ctx, EXCP_RI);
26926             break;
26927         }
26928         break;
26929     case OPC_SHLL_QB_DSP:
26930         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
26931         break;
26932     case OPC_DPA_W_PH_DSP:
26933         op2 = MASK_DPA_W_PH(ctx->opcode);
26934         switch (op2) {
26935         case OPC_DPAU_H_QBL:
26936         case OPC_DPAU_H_QBR:
26937         case OPC_DPSU_H_QBL:
26938         case OPC_DPSU_H_QBR:
26939         case OPC_DPA_W_PH:
26940         case OPC_DPAX_W_PH:
26941         case OPC_DPAQ_S_W_PH:
26942         case OPC_DPAQX_S_W_PH:
26943         case OPC_DPAQX_SA_W_PH:
26944         case OPC_DPS_W_PH:
26945         case OPC_DPSX_W_PH:
26946         case OPC_DPSQ_S_W_PH:
26947         case OPC_DPSQX_S_W_PH:
26948         case OPC_DPSQX_SA_W_PH:
26949         case OPC_MULSAQ_S_W_PH:
26950         case OPC_DPAQ_SA_L_W:
26951         case OPC_DPSQ_SA_L_W:
26952         case OPC_MAQ_S_W_PHL:
26953         case OPC_MAQ_S_W_PHR:
26954         case OPC_MAQ_SA_W_PHL:
26955         case OPC_MAQ_SA_W_PHR:
26956         case OPC_MULSA_W_PH:
26957             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26958             break;
26959         default:            /* Invalid */
26960             MIPS_INVAL("MASK DPAW.PH");
26961             generate_exception_end(ctx, EXCP_RI);
26962             break;
26963         }
26964         break;
26965     case OPC_INSV_DSP:
26966         op2 = MASK_INSV(ctx->opcode);
26967         switch (op2) {
26968         case OPC_INSV:
26969             check_dsp(ctx);
26970             {
26971                 TCGv t0, t1;
26972
26973                 if (rt == 0) {
26974                     break;
26975                 }
26976
26977                 t0 = tcg_temp_new();
26978                 t1 = tcg_temp_new();
26979
26980                 gen_load_gpr(t0, rt);
26981                 gen_load_gpr(t1, rs);
26982
26983                 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
26984
26985                 tcg_temp_free(t0);
26986                 tcg_temp_free(t1);
26987                 break;
26988             }
26989         default:            /* Invalid */
26990             MIPS_INVAL("MASK INSV");
26991             generate_exception_end(ctx, EXCP_RI);
26992             break;
26993         }
26994         break;
26995     case OPC_APPEND_DSP:
26996         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
26997         break;
26998     case OPC_EXTR_W_DSP:
26999         op2 = MASK_EXTR_W(ctx->opcode);
27000         switch (op2) {
27001         case OPC_EXTR_W:
27002         case OPC_EXTR_R_W:
27003         case OPC_EXTR_RS_W:
27004         case OPC_EXTR_S_H:
27005         case OPC_EXTRV_S_H:
27006         case OPC_EXTRV_W:
27007         case OPC_EXTRV_R_W:
27008         case OPC_EXTRV_RS_W:
27009         case OPC_EXTP:
27010         case OPC_EXTPV:
27011         case OPC_EXTPDP:
27012         case OPC_EXTPDPV:
27013             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27014             break;
27015         case OPC_RDDSP:
27016             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
27017             break;
27018         case OPC_SHILO:
27019         case OPC_SHILOV:
27020         case OPC_MTHLIP:
27021         case OPC_WRDSP:
27022             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27023             break;
27024         default:            /* Invalid */
27025             MIPS_INVAL("MASK EXTR.W");
27026             generate_exception_end(ctx, EXCP_RI);
27027             break;
27028         }
27029         break;
27030 #if defined(TARGET_MIPS64)
27031     case OPC_DDIV_G_2E:
27032     case OPC_DDIVU_G_2E:
27033     case OPC_DMULT_G_2E:
27034     case OPC_DMULTU_G_2E:
27035     case OPC_DMOD_G_2E:
27036     case OPC_DMODU_G_2E:
27037         check_insn(ctx, INSN_LOONGSON2E);
27038         gen_loongson_integer(ctx, op1, rd, rs, rt);
27039         break;
27040     case OPC_ABSQ_S_QH_DSP:
27041         op2 = MASK_ABSQ_S_QH(ctx->opcode);
27042         switch (op2) {
27043         case OPC_PRECEQ_L_PWL:
27044         case OPC_PRECEQ_L_PWR:
27045         case OPC_PRECEQ_PW_QHL:
27046         case OPC_PRECEQ_PW_QHR:
27047         case OPC_PRECEQ_PW_QHLA:
27048         case OPC_PRECEQ_PW_QHRA:
27049         case OPC_PRECEQU_QH_OBL:
27050         case OPC_PRECEQU_QH_OBR:
27051         case OPC_PRECEQU_QH_OBLA:
27052         case OPC_PRECEQU_QH_OBRA:
27053         case OPC_PRECEU_QH_OBL:
27054         case OPC_PRECEU_QH_OBR:
27055         case OPC_PRECEU_QH_OBLA:
27056         case OPC_PRECEU_QH_OBRA:
27057         case OPC_ABSQ_S_OB:
27058         case OPC_ABSQ_S_PW:
27059         case OPC_ABSQ_S_QH:
27060             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27061             break;
27062         case OPC_REPL_OB:
27063         case OPC_REPL_PW:
27064         case OPC_REPL_QH:
27065         case OPC_REPLV_OB:
27066         case OPC_REPLV_PW:
27067         case OPC_REPLV_QH:
27068             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
27069             break;
27070         default:            /* Invalid */
27071             MIPS_INVAL("MASK ABSQ_S.QH");
27072             generate_exception_end(ctx, EXCP_RI);
27073             break;
27074         }
27075         break;
27076     case OPC_ADDU_OB_DSP:
27077         op2 = MASK_ADDU_OB(ctx->opcode);
27078         switch (op2) {
27079         case OPC_RADDU_L_OB:
27080         case OPC_SUBQ_PW:
27081         case OPC_SUBQ_S_PW:
27082         case OPC_SUBQ_QH:
27083         case OPC_SUBQ_S_QH:
27084         case OPC_SUBU_OB:
27085         case OPC_SUBU_S_OB:
27086         case OPC_SUBU_QH:
27087         case OPC_SUBU_S_QH:
27088         case OPC_SUBUH_OB:
27089         case OPC_SUBUH_R_OB:
27090         case OPC_ADDQ_PW:
27091         case OPC_ADDQ_S_PW:
27092         case OPC_ADDQ_QH:
27093         case OPC_ADDQ_S_QH:
27094         case OPC_ADDU_OB:
27095         case OPC_ADDU_S_OB:
27096         case OPC_ADDU_QH:
27097         case OPC_ADDU_S_QH:
27098         case OPC_ADDUH_OB:
27099         case OPC_ADDUH_R_OB:
27100             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27101             break;
27102         case OPC_MULEQ_S_PW_QHL:
27103         case OPC_MULEQ_S_PW_QHR:
27104         case OPC_MULEU_S_QH_OBL:
27105         case OPC_MULEU_S_QH_OBR:
27106         case OPC_MULQ_RS_QH:
27107             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27108             break;
27109         default:            /* Invalid */
27110             MIPS_INVAL("MASK ADDU.OB");
27111             generate_exception_end(ctx, EXCP_RI);
27112             break;
27113         }
27114         break;
27115     case OPC_CMPU_EQ_OB_DSP:
27116         op2 = MASK_CMPU_EQ_OB(ctx->opcode);
27117         switch (op2) {
27118         case OPC_PRECR_SRA_QH_PW:
27119         case OPC_PRECR_SRA_R_QH_PW:
27120             /* Return value is rt. */
27121             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
27122             break;
27123         case OPC_PRECR_OB_QH:
27124         case OPC_PRECRQ_OB_QH:
27125         case OPC_PRECRQ_PW_L:
27126         case OPC_PRECRQ_QH_PW:
27127         case OPC_PRECRQ_RS_QH_PW:
27128         case OPC_PRECRQU_S_OB_QH:
27129             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27130             break;
27131         case OPC_CMPU_EQ_OB:
27132         case OPC_CMPU_LT_OB:
27133         case OPC_CMPU_LE_OB:
27134         case OPC_CMP_EQ_QH:
27135         case OPC_CMP_LT_QH:
27136         case OPC_CMP_LE_QH:
27137         case OPC_CMP_EQ_PW:
27138         case OPC_CMP_LT_PW:
27139         case OPC_CMP_LE_PW:
27140             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
27141             break;
27142         case OPC_CMPGDU_EQ_OB:
27143         case OPC_CMPGDU_LT_OB:
27144         case OPC_CMPGDU_LE_OB:
27145         case OPC_CMPGU_EQ_OB:
27146         case OPC_CMPGU_LT_OB:
27147         case OPC_CMPGU_LE_OB:
27148         case OPC_PACKRL_PW:
27149         case OPC_PICK_OB:
27150         case OPC_PICK_PW:
27151         case OPC_PICK_QH:
27152             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
27153             break;
27154         default:            /* Invalid */
27155             MIPS_INVAL("MASK CMPU_EQ.OB");
27156             generate_exception_end(ctx, EXCP_RI);
27157             break;
27158         }
27159         break;
27160     case OPC_DAPPEND_DSP:
27161         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27162         break;
27163     case OPC_DEXTR_W_DSP:
27164         op2 = MASK_DEXTR_W(ctx->opcode);
27165         switch (op2) {
27166         case OPC_DEXTP:
27167         case OPC_DEXTPDP:
27168         case OPC_DEXTPDPV:
27169         case OPC_DEXTPV:
27170         case OPC_DEXTR_L:
27171         case OPC_DEXTR_R_L:
27172         case OPC_DEXTR_RS_L:
27173         case OPC_DEXTR_W:
27174         case OPC_DEXTR_R_W:
27175         case OPC_DEXTR_RS_W:
27176         case OPC_DEXTR_S_H:
27177         case OPC_DEXTRV_L:
27178         case OPC_DEXTRV_R_L:
27179         case OPC_DEXTRV_RS_L:
27180         case OPC_DEXTRV_S_H:
27181         case OPC_DEXTRV_W:
27182         case OPC_DEXTRV_R_W:
27183         case OPC_DEXTRV_RS_W:
27184             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27185             break;
27186         case OPC_DMTHLIP:
27187         case OPC_DSHILO:
27188         case OPC_DSHILOV:
27189             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27190             break;
27191         default:            /* Invalid */
27192             MIPS_INVAL("MASK EXTR.W");
27193             generate_exception_end(ctx, EXCP_RI);
27194             break;
27195         }
27196         break;
27197     case OPC_DPAQ_W_QH_DSP:
27198         op2 = MASK_DPAQ_W_QH(ctx->opcode);
27199         switch (op2) {
27200         case OPC_DPAU_H_OBL:
27201         case OPC_DPAU_H_OBR:
27202         case OPC_DPSU_H_OBL:
27203         case OPC_DPSU_H_OBR:
27204         case OPC_DPA_W_QH:
27205         case OPC_DPAQ_S_W_QH:
27206         case OPC_DPS_W_QH:
27207         case OPC_DPSQ_S_W_QH:
27208         case OPC_MULSAQ_S_W_QH:
27209         case OPC_DPAQ_SA_L_PW:
27210         case OPC_DPSQ_SA_L_PW:
27211         case OPC_MULSAQ_S_L_PW:
27212             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27213             break;
27214         case OPC_MAQ_S_W_QHLL:
27215         case OPC_MAQ_S_W_QHLR:
27216         case OPC_MAQ_S_W_QHRL:
27217         case OPC_MAQ_S_W_QHRR:
27218         case OPC_MAQ_SA_W_QHLL:
27219         case OPC_MAQ_SA_W_QHLR:
27220         case OPC_MAQ_SA_W_QHRL:
27221         case OPC_MAQ_SA_W_QHRR:
27222         case OPC_MAQ_S_L_PWL:
27223         case OPC_MAQ_S_L_PWR:
27224         case OPC_DMADD:
27225         case OPC_DMADDU:
27226         case OPC_DMSUB:
27227         case OPC_DMSUBU:
27228             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27229             break;
27230         default:            /* Invalid */
27231             MIPS_INVAL("MASK DPAQ.W.QH");
27232             generate_exception_end(ctx, EXCP_RI);
27233             break;
27234         }
27235         break;
27236     case OPC_DINSV_DSP:
27237         op2 = MASK_INSV(ctx->opcode);
27238         switch (op2) {
27239         case OPC_DINSV:
27240         {
27241             TCGv t0, t1;
27242
27243             if (rt == 0) {
27244                 break;
27245             }
27246             check_dsp(ctx);
27247
27248             t0 = tcg_temp_new();
27249             t1 = tcg_temp_new();
27250
27251             gen_load_gpr(t0, rt);
27252             gen_load_gpr(t1, rs);
27253
27254             gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
27255
27256             tcg_temp_free(t0);
27257             tcg_temp_free(t1);
27258             break;
27259         }
27260         default:            /* Invalid */
27261             MIPS_INVAL("MASK DINSV");
27262             generate_exception_end(ctx, EXCP_RI);
27263             break;
27264         }
27265         break;
27266     case OPC_SHLL_OB_DSP:
27267         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27268         break;
27269 #endif
27270     default:            /* Invalid */
27271         MIPS_INVAL("special3_legacy");
27272         generate_exception_end(ctx, EXCP_RI);
27273         break;
27274     }
27275 }
27276
27277
27278 #if defined(TARGET_MIPS64)
27279
27280 static void decode_mmi0(CPUMIPSState *env, DisasContext *ctx)
27281 {
27282     uint32_t opc = MASK_MMI0(ctx->opcode);
27283
27284     switch (opc) {
27285     case MMI_OPC_0_PADDW:     /* TODO: MMI_OPC_0_PADDW */
27286     case MMI_OPC_0_PSUBW:     /* TODO: MMI_OPC_0_PSUBW */
27287     case MMI_OPC_0_PCGTW:     /* TODO: MMI_OPC_0_PCGTW */
27288     case MMI_OPC_0_PMAXW:     /* TODO: MMI_OPC_0_PMAXW */
27289     case MMI_OPC_0_PADDH:     /* TODO: MMI_OPC_0_PADDH */
27290     case MMI_OPC_0_PSUBH:     /* TODO: MMI_OPC_0_PSUBH */
27291     case MMI_OPC_0_PCGTH:     /* TODO: MMI_OPC_0_PCGTH */
27292     case MMI_OPC_0_PMAXH:     /* TODO: MMI_OPC_0_PMAXH */
27293     case MMI_OPC_0_PADDB:     /* TODO: MMI_OPC_0_PADDB */
27294     case MMI_OPC_0_PSUBB:     /* TODO: MMI_OPC_0_PSUBB */
27295     case MMI_OPC_0_PCGTB:     /* TODO: MMI_OPC_0_PCGTB */
27296     case MMI_OPC_0_PADDSW:    /* TODO: MMI_OPC_0_PADDSW */
27297     case MMI_OPC_0_PSUBSW:    /* TODO: MMI_OPC_0_PSUBSW */
27298     case MMI_OPC_0_PEXTLW:    /* TODO: MMI_OPC_0_PEXTLW */
27299     case MMI_OPC_0_PPACW:     /* TODO: MMI_OPC_0_PPACW */
27300     case MMI_OPC_0_PADDSH:    /* TODO: MMI_OPC_0_PADDSH */
27301     case MMI_OPC_0_PSUBSH:    /* TODO: MMI_OPC_0_PSUBSH */
27302     case MMI_OPC_0_PEXTLH:    /* TODO: MMI_OPC_0_PEXTLH */
27303     case MMI_OPC_0_PPACH:     /* TODO: MMI_OPC_0_PPACH */
27304     case MMI_OPC_0_PADDSB:    /* TODO: MMI_OPC_0_PADDSB */
27305     case MMI_OPC_0_PSUBSB:    /* TODO: MMI_OPC_0_PSUBSB */
27306     case MMI_OPC_0_PEXTLB:    /* TODO: MMI_OPC_0_PEXTLB */
27307     case MMI_OPC_0_PPACB:     /* TODO: MMI_OPC_0_PPACB */
27308     case MMI_OPC_0_PEXT5:     /* TODO: MMI_OPC_0_PEXT5 */
27309     case MMI_OPC_0_PPAC5:     /* TODO: MMI_OPC_0_PPAC5 */
27310         generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI0 */
27311         break;
27312     default:
27313         MIPS_INVAL("TX79 MMI class MMI0");
27314         generate_exception_end(ctx, EXCP_RI);
27315         break;
27316     }
27317 }
27318
27319 static void decode_mmi1(CPUMIPSState *env, DisasContext *ctx)
27320 {
27321     uint32_t opc = MASK_MMI1(ctx->opcode);
27322
27323     switch (opc) {
27324     case MMI_OPC_1_PABSW:     /* TODO: MMI_OPC_1_PABSW */
27325     case MMI_OPC_1_PCEQW:     /* TODO: MMI_OPC_1_PCEQW */
27326     case MMI_OPC_1_PMINW:     /* TODO: MMI_OPC_1_PMINW */
27327     case MMI_OPC_1_PADSBH:    /* TODO: MMI_OPC_1_PADSBH */
27328     case MMI_OPC_1_PABSH:     /* TODO: MMI_OPC_1_PABSH */
27329     case MMI_OPC_1_PCEQH:     /* TODO: MMI_OPC_1_PCEQH */
27330     case MMI_OPC_1_PMINH:     /* TODO: MMI_OPC_1_PMINH */
27331     case MMI_OPC_1_PCEQB:     /* TODO: MMI_OPC_1_PCEQB */
27332     case MMI_OPC_1_PADDUW:    /* TODO: MMI_OPC_1_PADDUW */
27333     case MMI_OPC_1_PSUBUW:    /* TODO: MMI_OPC_1_PSUBUW */
27334     case MMI_OPC_1_PEXTUW:    /* TODO: MMI_OPC_1_PEXTUW */
27335     case MMI_OPC_1_PADDUH:    /* TODO: MMI_OPC_1_PADDUH */
27336     case MMI_OPC_1_PSUBUH:    /* TODO: MMI_OPC_1_PSUBUH */
27337     case MMI_OPC_1_PEXTUH:    /* TODO: MMI_OPC_1_PEXTUH */
27338     case MMI_OPC_1_PADDUB:    /* TODO: MMI_OPC_1_PADDUB */
27339     case MMI_OPC_1_PSUBUB:    /* TODO: MMI_OPC_1_PSUBUB */
27340     case MMI_OPC_1_PEXTUB:    /* TODO: MMI_OPC_1_PEXTUB */
27341     case MMI_OPC_1_QFSRV:     /* TODO: MMI_OPC_1_QFSRV */
27342         generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI1 */
27343         break;
27344     default:
27345         MIPS_INVAL("TX79 MMI class MMI1");
27346         generate_exception_end(ctx, EXCP_RI);
27347         break;
27348     }
27349 }
27350
27351 static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
27352 {
27353     uint32_t opc = MASK_MMI2(ctx->opcode);
27354
27355     switch (opc) {
27356     case MMI_OPC_2_PMADDW:    /* TODO: MMI_OPC_2_PMADDW */
27357     case MMI_OPC_2_PSLLVW:    /* TODO: MMI_OPC_2_PSLLVW */
27358     case MMI_OPC_2_PSRLVW:    /* TODO: MMI_OPC_2_PSRLVW */
27359     case MMI_OPC_2_PMSUBW:    /* TODO: MMI_OPC_2_PMSUBW */
27360     case MMI_OPC_2_PMFHI:     /* TODO: MMI_OPC_2_PMFHI */
27361     case MMI_OPC_2_PMFLO:     /* TODO: MMI_OPC_2_PMFLO */
27362     case MMI_OPC_2_PINTH:     /* TODO: MMI_OPC_2_PINTH */
27363     case MMI_OPC_2_PMULTW:    /* TODO: MMI_OPC_2_PMULTW */
27364     case MMI_OPC_2_PDIVW:     /* TODO: MMI_OPC_2_PDIVW */
27365     case MMI_OPC_2_PCPYLD:    /* TODO: MMI_OPC_2_PCPYLD */
27366     case MMI_OPC_2_PMADDH:    /* TODO: MMI_OPC_2_PMADDH */
27367     case MMI_OPC_2_PHMADH:    /* TODO: MMI_OPC_2_PHMADH */
27368     case MMI_OPC_2_PAND:      /* TODO: MMI_OPC_2_PAND */
27369     case MMI_OPC_2_PXOR:      /* TODO: MMI_OPC_2_PXOR */
27370     case MMI_OPC_2_PMSUBH:    /* TODO: MMI_OPC_2_PMSUBH */
27371     case MMI_OPC_2_PHMSBH:    /* TODO: MMI_OPC_2_PHMSBH */
27372     case MMI_OPC_2_PEXEH:     /* TODO: MMI_OPC_2_PEXEH */
27373     case MMI_OPC_2_PREVH:     /* TODO: MMI_OPC_2_PREVH */
27374     case MMI_OPC_2_PMULTH:    /* TODO: MMI_OPC_2_PMULTH */
27375     case MMI_OPC_2_PDIVBW:    /* TODO: MMI_OPC_2_PDIVBW */
27376     case MMI_OPC_2_PEXEW:     /* TODO: MMI_OPC_2_PEXEW */
27377     case MMI_OPC_2_PROT3W:    /* TODO: MMI_OPC_2_PROT3W */
27378         generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI2 */
27379         break;
27380     default:
27381         MIPS_INVAL("TX79 MMI class MMI2");
27382         generate_exception_end(ctx, EXCP_RI);
27383         break;
27384     }
27385 }
27386
27387 static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx)
27388 {
27389     uint32_t opc = MASK_MMI3(ctx->opcode);
27390
27391     switch (opc) {
27392     case MMI_OPC_3_PMADDUW:    /* TODO: MMI_OPC_3_PMADDUW */
27393     case MMI_OPC_3_PSRAVW:     /* TODO: MMI_OPC_3_PSRAVW */
27394     case MMI_OPC_3_PMTHI:      /* TODO: MMI_OPC_3_PMTHI */
27395     case MMI_OPC_3_PMTLO:      /* TODO: MMI_OPC_3_PMTLO */
27396     case MMI_OPC_3_PINTEH:     /* TODO: MMI_OPC_3_PINTEH */
27397     case MMI_OPC_3_PMULTUW:    /* TODO: MMI_OPC_3_PMULTUW */
27398     case MMI_OPC_3_PDIVUW:     /* TODO: MMI_OPC_3_PDIVUW */
27399     case MMI_OPC_3_PCPYUD:     /* TODO: MMI_OPC_3_PCPYUD */
27400     case MMI_OPC_3_POR:        /* TODO: MMI_OPC_3_POR */
27401     case MMI_OPC_3_PNOR:       /* TODO: MMI_OPC_3_PNOR */
27402     case MMI_OPC_3_PEXCH:      /* TODO: MMI_OPC_3_PEXCH */
27403     case MMI_OPC_3_PCPYH:      /* TODO: MMI_OPC_3_PCPYH */
27404     case MMI_OPC_3_PEXCW:      /* TODO: MMI_OPC_3_PEXCW */
27405         generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI3 */
27406         break;
27407     default:
27408         MIPS_INVAL("TX79 MMI class MMI3");
27409         generate_exception_end(ctx, EXCP_RI);
27410         break;
27411     }
27412 }
27413
27414 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
27415 {
27416     uint32_t opc = MASK_MMI(ctx->opcode);
27417     int rs = extract32(ctx->opcode, 21, 5);
27418     int rt = extract32(ctx->opcode, 16, 5);
27419     int rd = extract32(ctx->opcode, 11, 5);
27420
27421     switch (opc) {
27422     case MMI_OPC_CLASS_MMI0:
27423         decode_mmi0(env, ctx);
27424         break;
27425     case MMI_OPC_CLASS_MMI1:
27426         decode_mmi1(env, ctx);
27427         break;
27428     case MMI_OPC_CLASS_MMI2:
27429         decode_mmi2(env, ctx);
27430         break;
27431     case MMI_OPC_CLASS_MMI3:
27432         decode_mmi3(env, ctx);
27433         break;
27434     case MMI_OPC_MULT1:
27435     case MMI_OPC_MULTU1:
27436     case MMI_OPC_MADD:
27437     case MMI_OPC_MADDU:
27438     case MMI_OPC_MADD1:
27439     case MMI_OPC_MADDU1:
27440         gen_mul_txx9(ctx, opc, rd, rs, rt);
27441         break;
27442     case MMI_OPC_DIV1:
27443     case MMI_OPC_DIVU1:
27444         gen_div1_tx79(ctx, opc, rs, rt);
27445         break;
27446     case MMI_OPC_MTLO1:
27447     case MMI_OPC_MTHI1:
27448         gen_HILO1_tx79(ctx, opc, rs);
27449         break;
27450     case MMI_OPC_MFLO1:
27451     case MMI_OPC_MFHI1:
27452         gen_HILO1_tx79(ctx, opc, rd);
27453         break;
27454     case MMI_OPC_PLZCW:         /* TODO: MMI_OPC_PLZCW */
27455     case MMI_OPC_PMFHL:         /* TODO: MMI_OPC_PMFHL */
27456     case MMI_OPC_PMTHL:         /* TODO: MMI_OPC_PMTHL */
27457     case MMI_OPC_PSLLH:         /* TODO: MMI_OPC_PSLLH */
27458     case MMI_OPC_PSRLH:         /* TODO: MMI_OPC_PSRLH */
27459     case MMI_OPC_PSRAH:         /* TODO: MMI_OPC_PSRAH */
27460     case MMI_OPC_PSLLW:         /* TODO: MMI_OPC_PSLLW */
27461     case MMI_OPC_PSRLW:         /* TODO: MMI_OPC_PSRLW */
27462     case MMI_OPC_PSRAW:         /* TODO: MMI_OPC_PSRAW */
27463         generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_CLASS_MMI */
27464         break;
27465     default:
27466         MIPS_INVAL("TX79 MMI class");
27467         generate_exception_end(ctx, EXCP_RI);
27468         break;
27469     }
27470 }
27471
27472 static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx)
27473 {
27474     generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_LQ */
27475 }
27476
27477 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
27478 {
27479     generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_SQ */
27480 }
27481
27482 /*
27483  * The TX79-specific instruction Store Quadword
27484  *
27485  * +--------+-------+-------+------------------------+
27486  * | 011111 |  base |   rt  |           offset       | SQ
27487  * +--------+-------+-------+------------------------+
27488  *      6       5       5                 16
27489  *
27490  * has the same opcode as the Read Hardware Register instruction
27491  *
27492  * +--------+-------+-------+-------+-------+--------+
27493  * | 011111 | 00000 |   rt  |   rd  | 00000 | 111011 | RDHWR
27494  * +--------+-------+-------+-------+-------+--------+
27495  *      6       5       5       5       5        6
27496  *
27497  * that is required, trapped and emulated by the Linux kernel. However, all
27498  * RDHWR encodings yield address error exceptions on the TX79 since the SQ
27499  * offset is odd. Therefore all valid SQ instructions can execute normally.
27500  * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
27501  * between SQ and RDHWR, as the Linux kernel does.
27502  */
27503 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
27504 {
27505     int base = extract32(ctx->opcode, 21, 5);
27506     int rt = extract32(ctx->opcode, 16, 5);
27507     int offset = extract32(ctx->opcode, 0, 16);
27508
27509 #ifdef CONFIG_USER_ONLY
27510     uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
27511     uint32_t op2 = extract32(ctx->opcode, 6, 5);
27512
27513     if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
27514         int rd = extract32(ctx->opcode, 11, 5);
27515
27516         gen_rdhwr(ctx, rt, rd, 0);
27517         return;
27518     }
27519 #endif
27520
27521     gen_mmi_sq(ctx, base, rt, offset);
27522 }
27523
27524 #endif
27525
27526 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
27527 {
27528     int rs, rt, rd, sa;
27529     uint32_t op1, op2;
27530     int16_t imm;
27531
27532     rs = (ctx->opcode >> 21) & 0x1f;
27533     rt = (ctx->opcode >> 16) & 0x1f;
27534     rd = (ctx->opcode >> 11) & 0x1f;
27535     sa = (ctx->opcode >> 6) & 0x1f;
27536     imm = sextract32(ctx->opcode, 7, 9);
27537
27538     op1 = MASK_SPECIAL3(ctx->opcode);
27539
27540     /*
27541      * EVA loads and stores overlap Loongson 2E instructions decoded by
27542      * decode_opc_special3_legacy(), so be careful to allow their decoding when
27543      * EVA is absent.
27544      */
27545     if (ctx->eva) {
27546         switch (op1) {
27547         case OPC_LWLE:
27548         case OPC_LWRE:
27549             check_insn_opc_removed(ctx, ISA_MIPS32R6);
27550             /* fall through */
27551         case OPC_LBUE:
27552         case OPC_LHUE:
27553         case OPC_LBE:
27554         case OPC_LHE:
27555         case OPC_LLE:
27556         case OPC_LWE:
27557             check_cp0_enabled(ctx);
27558             gen_ld(ctx, op1, rt, rs, imm);
27559             return;
27560         case OPC_SWLE:
27561         case OPC_SWRE:
27562             check_insn_opc_removed(ctx, ISA_MIPS32R6);
27563             /* fall through */
27564         case OPC_SBE:
27565         case OPC_SHE:
27566         case OPC_SWE:
27567             check_cp0_enabled(ctx);
27568             gen_st(ctx, op1, rt, rs, imm);
27569             return;
27570         case OPC_SCE:
27571             check_cp0_enabled(ctx);
27572             gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
27573             return;
27574         case OPC_CACHEE:
27575             check_cp0_enabled(ctx);
27576             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
27577                 gen_cache_operation(ctx, rt, rs, imm);
27578             }
27579             /* Treat as NOP. */
27580             return;
27581         case OPC_PREFE:
27582             check_cp0_enabled(ctx);
27583             /* Treat as NOP. */
27584             return;
27585         }
27586     }
27587
27588     switch (op1) {
27589     case OPC_EXT:
27590     case OPC_INS:
27591         check_insn(ctx, ISA_MIPS32R2);
27592         gen_bitops(ctx, op1, rt, rs, sa, rd);
27593         break;
27594     case OPC_BSHFL:
27595         op2 = MASK_BSHFL(ctx->opcode);
27596         switch (op2) {
27597         case OPC_ALIGN:
27598         case OPC_ALIGN_1:
27599         case OPC_ALIGN_2:
27600         case OPC_ALIGN_3:
27601         case OPC_BITSWAP:
27602             check_insn(ctx, ISA_MIPS32R6);
27603             decode_opc_special3_r6(env, ctx);
27604             break;
27605         default:
27606             check_insn(ctx, ISA_MIPS32R2);
27607             gen_bshfl(ctx, op2, rt, rd);
27608             break;
27609         }
27610         break;
27611 #if defined(TARGET_MIPS64)
27612     case OPC_DEXTM:
27613     case OPC_DEXTU:
27614     case OPC_DEXT:
27615     case OPC_DINSM:
27616     case OPC_DINSU:
27617     case OPC_DINS:
27618         check_insn(ctx, ISA_MIPS64R2);
27619         check_mips_64(ctx);
27620         gen_bitops(ctx, op1, rt, rs, sa, rd);
27621         break;
27622     case OPC_DBSHFL:
27623         op2 = MASK_DBSHFL(ctx->opcode);
27624         switch (op2) {
27625         case OPC_DALIGN:
27626         case OPC_DALIGN_1:
27627         case OPC_DALIGN_2:
27628         case OPC_DALIGN_3:
27629         case OPC_DALIGN_4:
27630         case OPC_DALIGN_5:
27631         case OPC_DALIGN_6:
27632         case OPC_DALIGN_7:
27633         case OPC_DBITSWAP:
27634             check_insn(ctx, ISA_MIPS32R6);
27635             decode_opc_special3_r6(env, ctx);
27636             break;
27637         default:
27638             check_insn(ctx, ISA_MIPS64R2);
27639             check_mips_64(ctx);
27640             op2 = MASK_DBSHFL(ctx->opcode);
27641             gen_bshfl(ctx, op2, rt, rd);
27642             break;
27643         }
27644         break;
27645 #endif
27646     case OPC_RDHWR:
27647         gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
27648         break;
27649     case OPC_FORK:
27650         check_mt(ctx);
27651         {
27652             TCGv t0 = tcg_temp_new();
27653             TCGv t1 = tcg_temp_new();
27654
27655             gen_load_gpr(t0, rt);
27656             gen_load_gpr(t1, rs);
27657             gen_helper_fork(t0, t1);
27658             tcg_temp_free(t0);
27659             tcg_temp_free(t1);
27660         }
27661         break;
27662     case OPC_YIELD:
27663         check_mt(ctx);
27664         {
27665             TCGv t0 = tcg_temp_new();
27666
27667             gen_load_gpr(t0, rs);
27668             gen_helper_yield(t0, cpu_env, t0);
27669             gen_store_gpr(t0, rd);
27670             tcg_temp_free(t0);
27671         }
27672         break;
27673     default:
27674         if (ctx->insn_flags & ISA_MIPS32R6) {
27675             decode_opc_special3_r6(env, ctx);
27676         } else {
27677             decode_opc_special3_legacy(env, ctx);
27678         }
27679     }
27680 }
27681
27682 /* MIPS SIMD Architecture (MSA)  */
27683 static inline int check_msa_access(DisasContext *ctx)
27684 {
27685     if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
27686                  !(ctx->hflags & MIPS_HFLAG_F64))) {
27687         generate_exception_end(ctx, EXCP_RI);
27688         return 0;
27689     }
27690
27691     if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
27692         if (ctx->insn_flags & ASE_MSA) {
27693             generate_exception_end(ctx, EXCP_MSADIS);
27694             return 0;
27695         } else {
27696             generate_exception_end(ctx, EXCP_RI);
27697             return 0;
27698         }
27699     }
27700     return 1;
27701 }
27702
27703 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
27704 {
27705     /* generates tcg ops to check if any element is 0 */
27706     /* Note this function only works with MSA_WRLEN = 128 */
27707     uint64_t eval_zero_or_big = 0;
27708     uint64_t eval_big = 0;
27709     TCGv_i64 t0 = tcg_temp_new_i64();
27710     TCGv_i64 t1 = tcg_temp_new_i64();
27711     switch (df) {
27712     case DF_BYTE:
27713         eval_zero_or_big = 0x0101010101010101ULL;
27714         eval_big = 0x8080808080808080ULL;
27715         break;
27716     case DF_HALF:
27717         eval_zero_or_big = 0x0001000100010001ULL;
27718         eval_big = 0x8000800080008000ULL;
27719         break;
27720     case DF_WORD:
27721         eval_zero_or_big = 0x0000000100000001ULL;
27722         eval_big = 0x8000000080000000ULL;
27723         break;
27724     case DF_DOUBLE:
27725         eval_zero_or_big = 0x0000000000000001ULL;
27726         eval_big = 0x8000000000000000ULL;
27727         break;
27728     }
27729     tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
27730     tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
27731     tcg_gen_andi_i64(t0, t0, eval_big);
27732     tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
27733     tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
27734     tcg_gen_andi_i64(t1, t1, eval_big);
27735     tcg_gen_or_i64(t0, t0, t1);
27736     /* if all bits are zero then all elements are not zero */
27737     /* if some bit is non-zero then some element is zero */
27738     tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
27739     tcg_gen_trunc_i64_tl(tresult, t0);
27740     tcg_temp_free_i64(t0);
27741     tcg_temp_free_i64(t1);
27742 }
27743
27744 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
27745 {
27746     uint8_t df = (ctx->opcode >> 21) & 0x3;
27747     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27748     int64_t s16 = (int16_t)ctx->opcode;
27749
27750     check_msa_access(ctx);
27751
27752     if (ctx->hflags & MIPS_HFLAG_BMASK) {
27753         generate_exception_end(ctx, EXCP_RI);
27754         return;
27755     }
27756     switch (op1) {
27757     case OPC_BZ_V:
27758     case OPC_BNZ_V:
27759         {
27760             TCGv_i64 t0 = tcg_temp_new_i64();
27761             tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
27762             tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
27763                     TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
27764             tcg_gen_trunc_i64_tl(bcond, t0);
27765             tcg_temp_free_i64(t0);
27766         }
27767         break;
27768     case OPC_BZ_B:
27769     case OPC_BZ_H:
27770     case OPC_BZ_W:
27771     case OPC_BZ_D:
27772         gen_check_zero_element(bcond, df, wt);
27773         break;
27774     case OPC_BNZ_B:
27775     case OPC_BNZ_H:
27776     case OPC_BNZ_W:
27777     case OPC_BNZ_D:
27778         gen_check_zero_element(bcond, df, wt);
27779         tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
27780         break;
27781     }
27782
27783     ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
27784
27785     ctx->hflags |= MIPS_HFLAG_BC;
27786     ctx->hflags |= MIPS_HFLAG_BDS32;
27787 }
27788
27789 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
27790 {
27791 #define MASK_MSA_I8(op)    (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
27792     uint8_t i8 = (ctx->opcode >> 16) & 0xff;
27793     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27794     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27795
27796     TCGv_i32 twd = tcg_const_i32(wd);
27797     TCGv_i32 tws = tcg_const_i32(ws);
27798     TCGv_i32 ti8 = tcg_const_i32(i8);
27799
27800     switch (MASK_MSA_I8(ctx->opcode)) {
27801     case OPC_ANDI_B:
27802         gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
27803         break;
27804     case OPC_ORI_B:
27805         gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
27806         break;
27807     case OPC_NORI_B:
27808         gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
27809         break;
27810     case OPC_XORI_B:
27811         gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
27812         break;
27813     case OPC_BMNZI_B:
27814         gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
27815         break;
27816     case OPC_BMZI_B:
27817         gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
27818         break;
27819     case OPC_BSELI_B:
27820         gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
27821         break;
27822     case OPC_SHF_B:
27823     case OPC_SHF_H:
27824     case OPC_SHF_W:
27825         {
27826             uint8_t df = (ctx->opcode >> 24) & 0x3;
27827             if (df == DF_DOUBLE) {
27828                 generate_exception_end(ctx, EXCP_RI);
27829             } else {
27830                 TCGv_i32 tdf = tcg_const_i32(df);
27831                 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
27832                 tcg_temp_free_i32(tdf);
27833             }
27834         }
27835         break;
27836     default:
27837         MIPS_INVAL("MSA instruction");
27838         generate_exception_end(ctx, EXCP_RI);
27839         break;
27840     }
27841
27842     tcg_temp_free_i32(twd);
27843     tcg_temp_free_i32(tws);
27844     tcg_temp_free_i32(ti8);
27845 }
27846
27847 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
27848 {
27849 #define MASK_MSA_I5(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27850     uint8_t df = (ctx->opcode >> 21) & 0x3;
27851     int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
27852     uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
27853     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27854     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27855
27856     TCGv_i32 tdf = tcg_const_i32(df);
27857     TCGv_i32 twd = tcg_const_i32(wd);
27858     TCGv_i32 tws = tcg_const_i32(ws);
27859     TCGv_i32 timm = tcg_temp_new_i32();
27860     tcg_gen_movi_i32(timm, u5);
27861
27862     switch (MASK_MSA_I5(ctx->opcode)) {
27863     case OPC_ADDVI_df:
27864         gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
27865         break;
27866     case OPC_SUBVI_df:
27867         gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
27868         break;
27869     case OPC_MAXI_S_df:
27870         tcg_gen_movi_i32(timm, s5);
27871         gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
27872         break;
27873     case OPC_MAXI_U_df:
27874         gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
27875         break;
27876     case OPC_MINI_S_df:
27877         tcg_gen_movi_i32(timm, s5);
27878         gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
27879         break;
27880     case OPC_MINI_U_df:
27881         gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
27882         break;
27883     case OPC_CEQI_df:
27884         tcg_gen_movi_i32(timm, s5);
27885         gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
27886         break;
27887     case OPC_CLTI_S_df:
27888         tcg_gen_movi_i32(timm, s5);
27889         gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
27890         break;
27891     case OPC_CLTI_U_df:
27892         gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
27893         break;
27894     case OPC_CLEI_S_df:
27895         tcg_gen_movi_i32(timm, s5);
27896         gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
27897         break;
27898     case OPC_CLEI_U_df:
27899         gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
27900         break;
27901     case OPC_LDI_df:
27902         {
27903             int32_t s10 = sextract32(ctx->opcode, 11, 10);
27904             tcg_gen_movi_i32(timm, s10);
27905             gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
27906         }
27907         break;
27908     default:
27909         MIPS_INVAL("MSA instruction");
27910         generate_exception_end(ctx, EXCP_RI);
27911         break;
27912     }
27913
27914     tcg_temp_free_i32(tdf);
27915     tcg_temp_free_i32(twd);
27916     tcg_temp_free_i32(tws);
27917     tcg_temp_free_i32(timm);
27918 }
27919
27920 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
27921 {
27922 #define MASK_MSA_BIT(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27923     uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
27924     uint32_t df = 0, m = 0;
27925     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27926     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27927
27928     TCGv_i32 tdf;
27929     TCGv_i32 tm;
27930     TCGv_i32 twd;
27931     TCGv_i32 tws;
27932
27933     if ((dfm & 0x40) == 0x00) {
27934         m = dfm & 0x3f;
27935         df = DF_DOUBLE;
27936     } else if ((dfm & 0x60) == 0x40) {
27937         m = dfm & 0x1f;
27938         df = DF_WORD;
27939     } else if ((dfm & 0x70) == 0x60) {
27940         m = dfm & 0x0f;
27941         df = DF_HALF;
27942     } else if ((dfm & 0x78) == 0x70) {
27943         m = dfm & 0x7;
27944         df = DF_BYTE;
27945     } else {
27946         generate_exception_end(ctx, EXCP_RI);
27947         return;
27948     }
27949
27950     tdf = tcg_const_i32(df);
27951     tm  = tcg_const_i32(m);
27952     twd = tcg_const_i32(wd);
27953     tws = tcg_const_i32(ws);
27954
27955     switch (MASK_MSA_BIT(ctx->opcode)) {
27956     case OPC_SLLI_df:
27957         gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
27958         break;
27959     case OPC_SRAI_df:
27960         gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
27961         break;
27962     case OPC_SRLI_df:
27963         gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
27964         break;
27965     case OPC_BCLRI_df:
27966         gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
27967         break;
27968     case OPC_BSETI_df:
27969         gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
27970         break;
27971     case OPC_BNEGI_df:
27972         gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
27973         break;
27974     case OPC_BINSLI_df:
27975         gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
27976         break;
27977     case OPC_BINSRI_df:
27978         gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
27979         break;
27980     case OPC_SAT_S_df:
27981         gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
27982         break;
27983     case OPC_SAT_U_df:
27984         gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
27985         break;
27986     case OPC_SRARI_df:
27987         gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
27988         break;
27989     case OPC_SRLRI_df:
27990         gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
27991         break;
27992     default:
27993         MIPS_INVAL("MSA instruction");
27994         generate_exception_end(ctx, EXCP_RI);
27995         break;
27996     }
27997
27998     tcg_temp_free_i32(tdf);
27999     tcg_temp_free_i32(tm);
28000     tcg_temp_free_i32(twd);
28001     tcg_temp_free_i32(tws);
28002 }
28003
28004 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
28005 {
28006 #define MASK_MSA_3R(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28007     uint8_t df = (ctx->opcode >> 21) & 0x3;
28008     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28009     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28010     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28011
28012     TCGv_i32 tdf = tcg_const_i32(df);
28013     TCGv_i32 twd = tcg_const_i32(wd);
28014     TCGv_i32 tws = tcg_const_i32(ws);
28015     TCGv_i32 twt = tcg_const_i32(wt);
28016
28017     switch (MASK_MSA_3R(ctx->opcode)) {
28018     case OPC_SLL_df:
28019         gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
28020         break;
28021     case OPC_ADDV_df:
28022         gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
28023         break;
28024     case OPC_CEQ_df:
28025         gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
28026         break;
28027     case OPC_ADD_A_df:
28028         gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
28029         break;
28030     case OPC_SUBS_S_df:
28031         gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
28032         break;
28033     case OPC_MULV_df:
28034         gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
28035         break;
28036     case OPC_SLD_df:
28037         gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
28038         break;
28039     case OPC_VSHF_df:
28040         gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
28041         break;
28042     case OPC_SRA_df:
28043         gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
28044         break;
28045     case OPC_SUBV_df:
28046         gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
28047         break;
28048     case OPC_ADDS_A_df:
28049         gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
28050         break;
28051     case OPC_SUBS_U_df:
28052         gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
28053         break;
28054     case OPC_MADDV_df:
28055         gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
28056         break;
28057     case OPC_SPLAT_df:
28058         gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
28059         break;
28060     case OPC_SRAR_df:
28061         gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
28062         break;
28063     case OPC_SRL_df:
28064         gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
28065         break;
28066     case OPC_MAX_S_df:
28067         gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
28068         break;
28069     case OPC_CLT_S_df:
28070         gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
28071         break;
28072     case OPC_ADDS_S_df:
28073         gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
28074         break;
28075     case OPC_SUBSUS_U_df:
28076         gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
28077         break;
28078     case OPC_MSUBV_df:
28079         gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
28080         break;
28081     case OPC_PCKEV_df:
28082         gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
28083         break;
28084     case OPC_SRLR_df:
28085         gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
28086         break;
28087     case OPC_BCLR_df:
28088         gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
28089         break;
28090     case OPC_MAX_U_df:
28091         gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
28092         break;
28093     case OPC_CLT_U_df:
28094         gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
28095         break;
28096     case OPC_ADDS_U_df:
28097         gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
28098         break;
28099     case OPC_SUBSUU_S_df:
28100         gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
28101         break;
28102     case OPC_PCKOD_df:
28103         gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
28104         break;
28105     case OPC_BSET_df:
28106         gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
28107         break;
28108     case OPC_MIN_S_df:
28109         gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
28110         break;
28111     case OPC_CLE_S_df:
28112         gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
28113         break;
28114     case OPC_AVE_S_df:
28115         gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
28116         break;
28117     case OPC_ASUB_S_df:
28118         gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
28119         break;
28120     case OPC_DIV_S_df:
28121         gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
28122         break;
28123     case OPC_ILVL_df:
28124         gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
28125         break;
28126     case OPC_BNEG_df:
28127         gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
28128         break;
28129     case OPC_MIN_U_df:
28130         gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
28131         break;
28132     case OPC_CLE_U_df:
28133         gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
28134         break;
28135     case OPC_AVE_U_df:
28136         gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
28137         break;
28138     case OPC_ASUB_U_df:
28139         gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
28140         break;
28141     case OPC_DIV_U_df:
28142         gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
28143         break;
28144     case OPC_ILVR_df:
28145         gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
28146         break;
28147     case OPC_BINSL_df:
28148         gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
28149         break;
28150     case OPC_MAX_A_df:
28151         gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
28152         break;
28153     case OPC_AVER_S_df:
28154         gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
28155         break;
28156     case OPC_MOD_S_df:
28157         gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
28158         break;
28159     case OPC_ILVEV_df:
28160         gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
28161         break;
28162     case OPC_BINSR_df:
28163         gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
28164         break;
28165     case OPC_MIN_A_df:
28166         gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
28167         break;
28168     case OPC_AVER_U_df:
28169         gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
28170         break;
28171     case OPC_MOD_U_df:
28172         gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
28173         break;
28174     case OPC_ILVOD_df:
28175         gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
28176         break;
28177
28178     case OPC_DOTP_S_df:
28179     case OPC_DOTP_U_df:
28180     case OPC_DPADD_S_df:
28181     case OPC_DPADD_U_df:
28182     case OPC_DPSUB_S_df:
28183     case OPC_HADD_S_df:
28184     case OPC_DPSUB_U_df:
28185     case OPC_HADD_U_df:
28186     case OPC_HSUB_S_df:
28187     case OPC_HSUB_U_df:
28188         if (df == DF_BYTE) {
28189             generate_exception_end(ctx, EXCP_RI);
28190             break;
28191         }
28192         switch (MASK_MSA_3R(ctx->opcode)) {
28193         case OPC_DOTP_S_df:
28194             gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
28195             break;
28196         case OPC_DOTP_U_df:
28197             gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
28198             break;
28199         case OPC_DPADD_S_df:
28200             gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
28201             break;
28202         case OPC_DPADD_U_df:
28203             gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
28204             break;
28205         case OPC_DPSUB_S_df:
28206             gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
28207             break;
28208         case OPC_HADD_S_df:
28209             gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
28210             break;
28211         case OPC_DPSUB_U_df:
28212             gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
28213             break;
28214         case OPC_HADD_U_df:
28215             gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
28216             break;
28217         case OPC_HSUB_S_df:
28218             gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
28219             break;
28220         case OPC_HSUB_U_df:
28221             gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
28222             break;
28223         }
28224         break;
28225     default:
28226         MIPS_INVAL("MSA instruction");
28227         generate_exception_end(ctx, EXCP_RI);
28228         break;
28229     }
28230     tcg_temp_free_i32(twd);
28231     tcg_temp_free_i32(tws);
28232     tcg_temp_free_i32(twt);
28233     tcg_temp_free_i32(tdf);
28234 }
28235
28236 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
28237 {
28238 #define MASK_MSA_ELM_DF3E(op)   (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
28239     uint8_t source = (ctx->opcode >> 11) & 0x1f;
28240     uint8_t dest = (ctx->opcode >> 6) & 0x1f;
28241     TCGv telm = tcg_temp_new();
28242     TCGv_i32 tsr = tcg_const_i32(source);
28243     TCGv_i32 tdt = tcg_const_i32(dest);
28244
28245     switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
28246     case OPC_CTCMSA:
28247         gen_load_gpr(telm, source);
28248         gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
28249         break;
28250     case OPC_CFCMSA:
28251         gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
28252         gen_store_gpr(telm, dest);
28253         break;
28254     case OPC_MOVE_V:
28255         gen_helper_msa_move_v(cpu_env, tdt, tsr);
28256         break;
28257     default:
28258         MIPS_INVAL("MSA instruction");
28259         generate_exception_end(ctx, EXCP_RI);
28260         break;
28261     }
28262
28263     tcg_temp_free(telm);
28264     tcg_temp_free_i32(tdt);
28265     tcg_temp_free_i32(tsr);
28266 }
28267
28268 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
28269         uint32_t n)
28270 {
28271 #define MASK_MSA_ELM(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28272     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28273     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28274
28275     TCGv_i32 tws = tcg_const_i32(ws);
28276     TCGv_i32 twd = tcg_const_i32(wd);
28277     TCGv_i32 tn  = tcg_const_i32(n);
28278     TCGv_i32 tdf = tcg_const_i32(df);
28279
28280     switch (MASK_MSA_ELM(ctx->opcode)) {
28281     case OPC_SLDI_df:
28282         gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
28283         break;
28284     case OPC_SPLATI_df:
28285         gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
28286         break;
28287     case OPC_INSVE_df:
28288         gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
28289         break;
28290     case OPC_COPY_S_df:
28291     case OPC_COPY_U_df:
28292     case OPC_INSERT_df:
28293 #if !defined(TARGET_MIPS64)
28294         /* Double format valid only for MIPS64 */
28295         if (df == DF_DOUBLE) {
28296             generate_exception_end(ctx, EXCP_RI);
28297             break;
28298         }
28299 #endif
28300         switch (MASK_MSA_ELM(ctx->opcode)) {
28301         case OPC_COPY_S_df:
28302             if (likely(wd != 0)) {
28303                 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
28304             }
28305             break;
28306         case OPC_COPY_U_df:
28307             if (likely(wd != 0)) {
28308                 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
28309             }
28310             break;
28311         case OPC_INSERT_df:
28312             gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
28313             break;
28314         }
28315         break;
28316     default:
28317         MIPS_INVAL("MSA instruction");
28318         generate_exception_end(ctx, EXCP_RI);
28319     }
28320     tcg_temp_free_i32(twd);
28321     tcg_temp_free_i32(tws);
28322     tcg_temp_free_i32(tn);
28323     tcg_temp_free_i32(tdf);
28324 }
28325
28326 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
28327 {
28328     uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
28329     uint32_t df = 0, n = 0;
28330
28331     if ((dfn & 0x30) == 0x00) {
28332         n = dfn & 0x0f;
28333         df = DF_BYTE;
28334     } else if ((dfn & 0x38) == 0x20) {
28335         n = dfn & 0x07;
28336         df = DF_HALF;
28337     } else if ((dfn & 0x3c) == 0x30) {
28338         n = dfn & 0x03;
28339         df = DF_WORD;
28340     } else if ((dfn & 0x3e) == 0x38) {
28341         n = dfn & 0x01;
28342         df = DF_DOUBLE;
28343     } else if (dfn == 0x3E) {
28344         /* CTCMSA, CFCMSA, MOVE.V */
28345         gen_msa_elm_3e(env, ctx);
28346         return;
28347     } else {
28348         generate_exception_end(ctx, EXCP_RI);
28349         return;
28350     }
28351
28352     gen_msa_elm_df(env, ctx, df, n);
28353 }
28354
28355 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
28356 {
28357 #define MASK_MSA_3RF(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28358     uint8_t df = (ctx->opcode >> 21) & 0x1;
28359     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28360     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28361     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28362
28363     TCGv_i32 twd = tcg_const_i32(wd);
28364     TCGv_i32 tws = tcg_const_i32(ws);
28365     TCGv_i32 twt = tcg_const_i32(wt);
28366     TCGv_i32 tdf = tcg_temp_new_i32();
28367
28368     /* adjust df value for floating-point instruction */
28369     tcg_gen_movi_i32(tdf, df + 2);
28370
28371     switch (MASK_MSA_3RF(ctx->opcode)) {
28372     case OPC_FCAF_df:
28373         gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
28374         break;
28375     case OPC_FADD_df:
28376         gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
28377         break;
28378     case OPC_FCUN_df:
28379         gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
28380         break;
28381     case OPC_FSUB_df:
28382         gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
28383         break;
28384     case OPC_FCOR_df:
28385         gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
28386         break;
28387     case OPC_FCEQ_df:
28388         gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
28389         break;
28390     case OPC_FMUL_df:
28391         gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
28392         break;
28393     case OPC_FCUNE_df:
28394         gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
28395         break;
28396     case OPC_FCUEQ_df:
28397         gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
28398         break;
28399     case OPC_FDIV_df:
28400         gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
28401         break;
28402     case OPC_FCNE_df:
28403         gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
28404         break;
28405     case OPC_FCLT_df:
28406         gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
28407         break;
28408     case OPC_FMADD_df:
28409         gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
28410         break;
28411     case OPC_MUL_Q_df:
28412         tcg_gen_movi_i32(tdf, df + 1);
28413         gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
28414         break;
28415     case OPC_FCULT_df:
28416         gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
28417         break;
28418     case OPC_FMSUB_df:
28419         gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
28420         break;
28421     case OPC_MADD_Q_df:
28422         tcg_gen_movi_i32(tdf, df + 1);
28423         gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
28424         break;
28425     case OPC_FCLE_df:
28426         gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
28427         break;
28428     case OPC_MSUB_Q_df:
28429         tcg_gen_movi_i32(tdf, df + 1);
28430         gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
28431         break;
28432     case OPC_FCULE_df:
28433         gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
28434         break;
28435     case OPC_FEXP2_df:
28436         gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
28437         break;
28438     case OPC_FSAF_df:
28439         gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
28440         break;
28441     case OPC_FEXDO_df:
28442         gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
28443         break;
28444     case OPC_FSUN_df:
28445         gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
28446         break;
28447     case OPC_FSOR_df:
28448         gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
28449         break;
28450     case OPC_FSEQ_df:
28451         gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
28452         break;
28453     case OPC_FTQ_df:
28454         gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
28455         break;
28456     case OPC_FSUNE_df:
28457         gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
28458         break;
28459     case OPC_FSUEQ_df:
28460         gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
28461         break;
28462     case OPC_FSNE_df:
28463         gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
28464         break;
28465     case OPC_FSLT_df:
28466         gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
28467         break;
28468     case OPC_FMIN_df:
28469         gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
28470         break;
28471     case OPC_MULR_Q_df:
28472         tcg_gen_movi_i32(tdf, df + 1);
28473         gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
28474         break;
28475     case OPC_FSULT_df:
28476         gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
28477         break;
28478     case OPC_FMIN_A_df:
28479         gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
28480         break;
28481     case OPC_MADDR_Q_df:
28482         tcg_gen_movi_i32(tdf, df + 1);
28483         gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
28484         break;
28485     case OPC_FSLE_df:
28486         gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
28487         break;
28488     case OPC_FMAX_df:
28489         gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
28490         break;
28491     case OPC_MSUBR_Q_df:
28492         tcg_gen_movi_i32(tdf, df + 1);
28493         gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
28494         break;
28495     case OPC_FSULE_df:
28496         gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
28497         break;
28498     case OPC_FMAX_A_df:
28499         gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
28500         break;
28501     default:
28502         MIPS_INVAL("MSA instruction");
28503         generate_exception_end(ctx, EXCP_RI);
28504         break;
28505     }
28506
28507     tcg_temp_free_i32(twd);
28508     tcg_temp_free_i32(tws);
28509     tcg_temp_free_i32(twt);
28510     tcg_temp_free_i32(tdf);
28511 }
28512
28513 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
28514 {
28515 #define MASK_MSA_2R(op)     (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28516                             (op & (0x7 << 18)))
28517     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28518     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28519     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28520     uint8_t df = (ctx->opcode >> 16) & 0x3;
28521     TCGv_i32 twd = tcg_const_i32(wd);
28522     TCGv_i32 tws = tcg_const_i32(ws);
28523     TCGv_i32 twt = tcg_const_i32(wt);
28524     TCGv_i32 tdf = tcg_const_i32(df);
28525
28526     switch (MASK_MSA_2R(ctx->opcode)) {
28527     case OPC_FILL_df:
28528 #if !defined(TARGET_MIPS64)
28529         /* Double format valid only for MIPS64 */
28530         if (df == DF_DOUBLE) {
28531             generate_exception_end(ctx, EXCP_RI);
28532             break;
28533         }
28534 #endif
28535         gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
28536         break;
28537     case OPC_PCNT_df:
28538         gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
28539         break;
28540     case OPC_NLOC_df:
28541         gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
28542         break;
28543     case OPC_NLZC_df:
28544         gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
28545         break;
28546     default:
28547         MIPS_INVAL("MSA instruction");
28548         generate_exception_end(ctx, EXCP_RI);
28549         break;
28550     }
28551
28552     tcg_temp_free_i32(twd);
28553     tcg_temp_free_i32(tws);
28554     tcg_temp_free_i32(twt);
28555     tcg_temp_free_i32(tdf);
28556 }
28557
28558 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
28559 {
28560 #define MASK_MSA_2RF(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28561                             (op & (0xf << 17)))
28562     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28563     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28564     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28565     uint8_t df = (ctx->opcode >> 16) & 0x1;
28566     TCGv_i32 twd = tcg_const_i32(wd);
28567     TCGv_i32 tws = tcg_const_i32(ws);
28568     TCGv_i32 twt = tcg_const_i32(wt);
28569     /* adjust df value for floating-point instruction */
28570     TCGv_i32 tdf = tcg_const_i32(df + 2);
28571
28572     switch (MASK_MSA_2RF(ctx->opcode)) {
28573     case OPC_FCLASS_df:
28574         gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
28575         break;
28576     case OPC_FTRUNC_S_df:
28577         gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
28578         break;
28579     case OPC_FTRUNC_U_df:
28580         gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
28581         break;
28582     case OPC_FSQRT_df:
28583         gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
28584         break;
28585     case OPC_FRSQRT_df:
28586         gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
28587         break;
28588     case OPC_FRCP_df:
28589         gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
28590         break;
28591     case OPC_FRINT_df:
28592         gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
28593         break;
28594     case OPC_FLOG2_df:
28595         gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
28596         break;
28597     case OPC_FEXUPL_df:
28598         gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
28599         break;
28600     case OPC_FEXUPR_df:
28601         gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
28602         break;
28603     case OPC_FFQL_df:
28604         gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
28605         break;
28606     case OPC_FFQR_df:
28607         gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
28608         break;
28609     case OPC_FTINT_S_df:
28610         gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
28611         break;
28612     case OPC_FTINT_U_df:
28613         gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
28614         break;
28615     case OPC_FFINT_S_df:
28616         gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
28617         break;
28618     case OPC_FFINT_U_df:
28619         gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
28620         break;
28621     }
28622
28623     tcg_temp_free_i32(twd);
28624     tcg_temp_free_i32(tws);
28625     tcg_temp_free_i32(twt);
28626     tcg_temp_free_i32(tdf);
28627 }
28628
28629 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
28630 {
28631 #define MASK_MSA_VEC(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
28632     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28633     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28634     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28635     TCGv_i32 twd = tcg_const_i32(wd);
28636     TCGv_i32 tws = tcg_const_i32(ws);
28637     TCGv_i32 twt = tcg_const_i32(wt);
28638
28639     switch (MASK_MSA_VEC(ctx->opcode)) {
28640     case OPC_AND_V:
28641         gen_helper_msa_and_v(cpu_env, twd, tws, twt);
28642         break;
28643     case OPC_OR_V:
28644         gen_helper_msa_or_v(cpu_env, twd, tws, twt);
28645         break;
28646     case OPC_NOR_V:
28647         gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
28648         break;
28649     case OPC_XOR_V:
28650         gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
28651         break;
28652     case OPC_BMNZ_V:
28653         gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
28654         break;
28655     case OPC_BMZ_V:
28656         gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
28657         break;
28658     case OPC_BSEL_V:
28659         gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
28660         break;
28661     default:
28662         MIPS_INVAL("MSA instruction");
28663         generate_exception_end(ctx, EXCP_RI);
28664         break;
28665     }
28666
28667     tcg_temp_free_i32(twd);
28668     tcg_temp_free_i32(tws);
28669     tcg_temp_free_i32(twt);
28670 }
28671
28672 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
28673 {
28674     switch (MASK_MSA_VEC(ctx->opcode)) {
28675     case OPC_AND_V:
28676     case OPC_OR_V:
28677     case OPC_NOR_V:
28678     case OPC_XOR_V:
28679     case OPC_BMNZ_V:
28680     case OPC_BMZ_V:
28681     case OPC_BSEL_V:
28682         gen_msa_vec_v(env, ctx);
28683         break;
28684     case OPC_MSA_2R:
28685         gen_msa_2r(env, ctx);
28686         break;
28687     case OPC_MSA_2RF:
28688         gen_msa_2rf(env, ctx);
28689         break;
28690     default:
28691         MIPS_INVAL("MSA instruction");
28692         generate_exception_end(ctx, EXCP_RI);
28693         break;
28694     }
28695 }
28696
28697 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
28698 {
28699     uint32_t opcode = ctx->opcode;
28700     check_insn(ctx, ASE_MSA);
28701     check_msa_access(ctx);
28702
28703     switch (MASK_MSA_MINOR(opcode)) {
28704     case OPC_MSA_I8_00:
28705     case OPC_MSA_I8_01:
28706     case OPC_MSA_I8_02:
28707         gen_msa_i8(env, ctx);
28708         break;
28709     case OPC_MSA_I5_06:
28710     case OPC_MSA_I5_07:
28711         gen_msa_i5(env, ctx);
28712         break;
28713     case OPC_MSA_BIT_09:
28714     case OPC_MSA_BIT_0A:
28715         gen_msa_bit(env, ctx);
28716         break;
28717     case OPC_MSA_3R_0D:
28718     case OPC_MSA_3R_0E:
28719     case OPC_MSA_3R_0F:
28720     case OPC_MSA_3R_10:
28721     case OPC_MSA_3R_11:
28722     case OPC_MSA_3R_12:
28723     case OPC_MSA_3R_13:
28724     case OPC_MSA_3R_14:
28725     case OPC_MSA_3R_15:
28726         gen_msa_3r(env, ctx);
28727         break;
28728     case OPC_MSA_ELM:
28729         gen_msa_elm(env, ctx);
28730         break;
28731     case OPC_MSA_3RF_1A:
28732     case OPC_MSA_3RF_1B:
28733     case OPC_MSA_3RF_1C:
28734         gen_msa_3rf(env, ctx);
28735         break;
28736     case OPC_MSA_VEC:
28737         gen_msa_vec(env, ctx);
28738         break;
28739     case OPC_LD_B:
28740     case OPC_LD_H:
28741     case OPC_LD_W:
28742     case OPC_LD_D:
28743     case OPC_ST_B:
28744     case OPC_ST_H:
28745     case OPC_ST_W:
28746     case OPC_ST_D:
28747         {
28748             int32_t s10 = sextract32(ctx->opcode, 16, 10);
28749             uint8_t rs = (ctx->opcode >> 11) & 0x1f;
28750             uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28751             uint8_t df = (ctx->opcode >> 0) & 0x3;
28752
28753             TCGv_i32 twd = tcg_const_i32(wd);
28754             TCGv taddr = tcg_temp_new();
28755             gen_base_offset_addr(ctx, taddr, rs, s10 << df);
28756
28757             switch (MASK_MSA_MINOR(opcode)) {
28758             case OPC_LD_B:
28759                 gen_helper_msa_ld_b(cpu_env, twd, taddr);
28760                 break;
28761             case OPC_LD_H:
28762                 gen_helper_msa_ld_h(cpu_env, twd, taddr);
28763                 break;
28764             case OPC_LD_W:
28765                 gen_helper_msa_ld_w(cpu_env, twd, taddr);
28766                 break;
28767             case OPC_LD_D:
28768                 gen_helper_msa_ld_d(cpu_env, twd, taddr);
28769                 break;
28770             case OPC_ST_B:
28771                 gen_helper_msa_st_b(cpu_env, twd, taddr);
28772                 break;
28773             case OPC_ST_H:
28774                 gen_helper_msa_st_h(cpu_env, twd, taddr);
28775                 break;
28776             case OPC_ST_W:
28777                 gen_helper_msa_st_w(cpu_env, twd, taddr);
28778                 break;
28779             case OPC_ST_D:
28780                 gen_helper_msa_st_d(cpu_env, twd, taddr);
28781                 break;
28782             }
28783
28784             tcg_temp_free_i32(twd);
28785             tcg_temp_free(taddr);
28786         }
28787         break;
28788     default:
28789         MIPS_INVAL("MSA instruction");
28790         generate_exception_end(ctx, EXCP_RI);
28791         break;
28792     }
28793
28794 }
28795
28796 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
28797 {
28798     int32_t offset;
28799     int rs, rt, rd, sa;
28800     uint32_t op, op1;
28801     int16_t imm;
28802
28803     /* make sure instructions are on a word boundary */
28804     if (ctx->base.pc_next & 0x3) {
28805         env->CP0_BadVAddr = ctx->base.pc_next;
28806         generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
28807         return;
28808     }
28809
28810     /* Handle blikely not taken case */
28811     if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
28812         TCGLabel *l1 = gen_new_label();
28813
28814         tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
28815         tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
28816         gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
28817         gen_set_label(l1);
28818     }
28819
28820     op = MASK_OP_MAJOR(ctx->opcode);
28821     rs = (ctx->opcode >> 21) & 0x1f;
28822     rt = (ctx->opcode >> 16) & 0x1f;
28823     rd = (ctx->opcode >> 11) & 0x1f;
28824     sa = (ctx->opcode >> 6) & 0x1f;
28825     imm = (int16_t)ctx->opcode;
28826     switch (op) {
28827     case OPC_SPECIAL:
28828         decode_opc_special(env, ctx);
28829         break;
28830     case OPC_SPECIAL2:
28831 #if defined(TARGET_MIPS64)
28832         if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
28833             decode_mmi(env, ctx);
28834 #else
28835         if (ctx->insn_flags & ASE_MXU) {
28836             decode_opc_mxu(env, ctx);
28837 #endif
28838         } else {
28839             decode_opc_special2_legacy(env, ctx);
28840         }
28841         break;
28842     case OPC_SPECIAL3:
28843 #if defined(TARGET_MIPS64)
28844         if (ctx->insn_flags & INSN_R5900) {
28845             decode_mmi_sq(env, ctx);    /* MMI_OPC_SQ */
28846         } else {
28847             decode_opc_special3(env, ctx);
28848         }
28849 #else
28850         decode_opc_special3(env, ctx);
28851 #endif
28852         break;
28853     case OPC_REGIMM:
28854         op1 = MASK_REGIMM(ctx->opcode);
28855         switch (op1) {
28856         case OPC_BLTZL: /* REGIMM branches */
28857         case OPC_BGEZL:
28858         case OPC_BLTZALL:
28859         case OPC_BGEZALL:
28860             check_insn(ctx, ISA_MIPS2);
28861             check_insn_opc_removed(ctx, ISA_MIPS32R6);
28862             /* Fallthrough */
28863         case OPC_BLTZ:
28864         case OPC_BGEZ:
28865             gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
28866             break;
28867         case OPC_BLTZAL:
28868         case OPC_BGEZAL:
28869             if (ctx->insn_flags & ISA_MIPS32R6) {
28870                 if (rs == 0) {
28871                     /* OPC_NAL, OPC_BAL */
28872                     gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
28873                 } else {
28874                     generate_exception_end(ctx, EXCP_RI);
28875                 }
28876             } else {
28877                 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
28878             }
28879             break;
28880         case OPC_TGEI: /* REGIMM traps */
28881         case OPC_TGEIU:
28882         case OPC_TLTI:
28883         case OPC_TLTIU:
28884         case OPC_TEQI:
28885
28886         case OPC_TNEI:
28887             check_insn(ctx, ISA_MIPS2);
28888             check_insn_opc_removed(ctx, ISA_MIPS32R6);
28889             gen_trap(ctx, op1, rs, -1, imm);
28890             break;
28891         case OPC_SIGRIE:
28892             check_insn(ctx, ISA_MIPS32R6);
28893             generate_exception_end(ctx, EXCP_RI);
28894             break;
28895         case OPC_SYNCI:
28896             check_insn(ctx, ISA_MIPS32R2);
28897             /* Break the TB to be able to sync copied instructions
28898                immediately */
28899             ctx->base.is_jmp = DISAS_STOP;
28900             break;
28901         case OPC_BPOSGE32:    /* MIPS DSP branch */
28902 #if defined(TARGET_MIPS64)
28903         case OPC_BPOSGE64:
28904 #endif
28905             check_dsp(ctx);
28906             gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
28907             break;
28908 #if defined(TARGET_MIPS64)
28909         case OPC_DAHI:
28910             check_insn(ctx, ISA_MIPS32R6);
28911             check_mips_64(ctx);
28912             if (rs != 0) {
28913                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
28914             }
28915             break;
28916         case OPC_DATI:
28917             check_insn(ctx, ISA_MIPS32R6);
28918             check_mips_64(ctx);
28919             if (rs != 0) {
28920                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
28921             }
28922             break;
28923 #endif
28924         default:            /* Invalid */
28925             MIPS_INVAL("regimm");
28926             generate_exception_end(ctx, EXCP_RI);
28927             break;
28928         }
28929         break;
28930     case OPC_CP0:
28931         check_cp0_enabled(ctx);
28932         op1 = MASK_CP0(ctx->opcode);
28933         switch (op1) {
28934         case OPC_MFC0:
28935         case OPC_MTC0:
28936         case OPC_MFTR:
28937         case OPC_MTTR:
28938         case OPC_MFHC0:
28939         case OPC_MTHC0:
28940 #if defined(TARGET_MIPS64)
28941         case OPC_DMFC0:
28942         case OPC_DMTC0:
28943 #endif
28944 #ifndef CONFIG_USER_ONLY
28945             gen_cp0(env, ctx, op1, rt, rd);
28946 #endif /* !CONFIG_USER_ONLY */
28947             break;
28948         case OPC_C0:
28949         case OPC_C0_1:
28950         case OPC_C0_2:
28951         case OPC_C0_3:
28952         case OPC_C0_4:
28953         case OPC_C0_5:
28954         case OPC_C0_6:
28955         case OPC_C0_7:
28956         case OPC_C0_8:
28957         case OPC_C0_9:
28958         case OPC_C0_A:
28959         case OPC_C0_B:
28960         case OPC_C0_C:
28961         case OPC_C0_D:
28962         case OPC_C0_E:
28963         case OPC_C0_F:
28964 #ifndef CONFIG_USER_ONLY
28965             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
28966 #endif /* !CONFIG_USER_ONLY */
28967             break;
28968         case OPC_MFMC0:
28969 #ifndef CONFIG_USER_ONLY
28970             {
28971                 uint32_t op2;
28972                 TCGv t0 = tcg_temp_new();
28973
28974                 op2 = MASK_MFMC0(ctx->opcode);
28975                 switch (op2) {
28976                 case OPC_DMT:
28977                     check_cp0_mt(ctx);
28978                     gen_helper_dmt(t0);
28979                     gen_store_gpr(t0, rt);
28980                     break;
28981                 case OPC_EMT:
28982                     check_cp0_mt(ctx);
28983                     gen_helper_emt(t0);
28984                     gen_store_gpr(t0, rt);
28985                     break;
28986                 case OPC_DVPE:
28987                     check_cp0_mt(ctx);
28988                     gen_helper_dvpe(t0, cpu_env);
28989                     gen_store_gpr(t0, rt);
28990                     break;
28991                 case OPC_EVPE:
28992                     check_cp0_mt(ctx);
28993                     gen_helper_evpe(t0, cpu_env);
28994                     gen_store_gpr(t0, rt);
28995                     break;
28996                 case OPC_DVP:
28997                     check_insn(ctx, ISA_MIPS32R6);
28998                     if (ctx->vp) {
28999                         gen_helper_dvp(t0, cpu_env);
29000                         gen_store_gpr(t0, rt);
29001                     }
29002                     break;
29003                 case OPC_EVP:
29004                     check_insn(ctx, ISA_MIPS32R6);
29005                     if (ctx->vp) {
29006                         gen_helper_evp(t0, cpu_env);
29007                         gen_store_gpr(t0, rt);
29008                     }
29009                     break;
29010                 case OPC_DI:
29011                     check_insn(ctx, ISA_MIPS32R2);
29012                     save_cpu_state(ctx, 1);
29013                     gen_helper_di(t0, cpu_env);
29014                     gen_store_gpr(t0, rt);
29015                     /* Stop translation as we may have switched
29016                        the execution mode.  */
29017                     ctx->base.is_jmp = DISAS_STOP;
29018                     break;
29019                 case OPC_EI:
29020                     check_insn(ctx, ISA_MIPS32R2);
29021                     save_cpu_state(ctx, 1);
29022                     gen_helper_ei(t0, cpu_env);
29023                     gen_store_gpr(t0, rt);
29024                     /* DISAS_STOP isn't sufficient, we need to ensure we break
29025                        out of translated code to check for pending interrupts */
29026                     gen_save_pc(ctx->base.pc_next + 4);
29027                     ctx->base.is_jmp = DISAS_EXIT;
29028                     break;
29029                 default:            /* Invalid */
29030                     MIPS_INVAL("mfmc0");
29031                     generate_exception_end(ctx, EXCP_RI);
29032                     break;
29033                 }
29034                 tcg_temp_free(t0);
29035             }
29036 #endif /* !CONFIG_USER_ONLY */
29037             break;
29038         case OPC_RDPGPR:
29039             check_insn(ctx, ISA_MIPS32R2);
29040             gen_load_srsgpr(rt, rd);
29041             break;
29042         case OPC_WRPGPR:
29043             check_insn(ctx, ISA_MIPS32R2);
29044             gen_store_srsgpr(rt, rd);
29045             break;
29046         default:
29047             MIPS_INVAL("cp0");
29048             generate_exception_end(ctx, EXCP_RI);
29049             break;
29050         }
29051         break;
29052     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
29053         if (ctx->insn_flags & ISA_MIPS32R6) {
29054             /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
29055             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29056         } else {
29057             /* OPC_ADDI */
29058             /* Arithmetic with immediate opcode */
29059             gen_arith_imm(ctx, op, rt, rs, imm);
29060         }
29061         break;
29062     case OPC_ADDIU:
29063          gen_arith_imm(ctx, op, rt, rs, imm);
29064          break;
29065     case OPC_SLTI: /* Set on less than with immediate opcode */
29066     case OPC_SLTIU:
29067          gen_slt_imm(ctx, op, rt, rs, imm);
29068          break;
29069     case OPC_ANDI: /* Arithmetic with immediate opcode */
29070     case OPC_LUI: /* OPC_AUI */
29071     case OPC_ORI:
29072     case OPC_XORI:
29073          gen_logic_imm(ctx, op, rt, rs, imm);
29074          break;
29075     case OPC_J: /* Jump */
29076     case OPC_JAL:
29077          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
29078          gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
29079          break;
29080     /* Branch */
29081     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
29082         if (ctx->insn_flags & ISA_MIPS32R6) {
29083             if (rt == 0) {
29084                 generate_exception_end(ctx, EXCP_RI);
29085                 break;
29086             }
29087             /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
29088             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29089         } else {
29090             /* OPC_BLEZL */
29091             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29092         }
29093         break;
29094     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
29095         if (ctx->insn_flags & ISA_MIPS32R6) {
29096             if (rt == 0) {
29097                 generate_exception_end(ctx, EXCP_RI);
29098                 break;
29099             }
29100             /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
29101             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29102         } else {
29103             /* OPC_BGTZL */
29104             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29105         }
29106         break;
29107     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
29108         if (rt == 0) {
29109             /* OPC_BLEZ */
29110             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29111         } else {
29112             check_insn(ctx, ISA_MIPS32R6);
29113             /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
29114             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29115         }
29116         break;
29117     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
29118         if (rt == 0) {
29119             /* OPC_BGTZ */
29120             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29121         } else {
29122             check_insn(ctx, ISA_MIPS32R6);
29123             /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
29124             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29125         }
29126         break;
29127     case OPC_BEQL:
29128     case OPC_BNEL:
29129         check_insn(ctx, ISA_MIPS2);
29130          check_insn_opc_removed(ctx, ISA_MIPS32R6);
29131         /* Fallthrough */
29132     case OPC_BEQ:
29133     case OPC_BNE:
29134          gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29135          break;
29136     case OPC_LL: /* Load and stores */
29137         check_insn(ctx, ISA_MIPS2);
29138         if (ctx->insn_flags & INSN_R5900) {
29139             check_insn_opc_user_only(ctx, INSN_R5900);
29140         }
29141         /* Fallthrough */
29142     case OPC_LWL:
29143     case OPC_LWR:
29144         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29145          /* Fallthrough */
29146     case OPC_LB:
29147     case OPC_LH:
29148     case OPC_LW:
29149     case OPC_LWPC:
29150     case OPC_LBU:
29151     case OPC_LHU:
29152          gen_ld(ctx, op, rt, rs, imm);
29153          break;
29154     case OPC_SWL:
29155     case OPC_SWR:
29156         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29157         /* fall through */
29158     case OPC_SB:
29159     case OPC_SH:
29160     case OPC_SW:
29161          gen_st(ctx, op, rt, rs, imm);
29162          break;
29163     case OPC_SC:
29164         check_insn(ctx, ISA_MIPS2);
29165          check_insn_opc_removed(ctx, ISA_MIPS32R6);
29166         if (ctx->insn_flags & INSN_R5900) {
29167             check_insn_opc_user_only(ctx, INSN_R5900);
29168         }
29169         gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
29170         break;
29171     case OPC_CACHE:
29172         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29173         check_cp0_enabled(ctx);
29174         check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
29175         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
29176             gen_cache_operation(ctx, rt, rs, imm);
29177         }
29178         /* Treat as NOP. */
29179         break;
29180     case OPC_PREF:
29181         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29182         if (ctx->insn_flags & INSN_R5900) {
29183             /* Treat as NOP. */
29184         } else {
29185             check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
29186             /* Treat as NOP. */
29187         }
29188         break;
29189
29190     /* Floating point (COP1). */
29191     case OPC_LWC1:
29192     case OPC_LDC1:
29193     case OPC_SWC1:
29194     case OPC_SDC1:
29195         gen_cop1_ldst(ctx, op, rt, rs, imm);
29196         break;
29197
29198     case OPC_CP1:
29199         op1 = MASK_CP1(ctx->opcode);
29200
29201         switch (op1) {
29202         case OPC_MFHC1:
29203         case OPC_MTHC1:
29204             check_cp1_enabled(ctx);
29205             check_insn(ctx, ISA_MIPS32R2);
29206             /* fall through */
29207         case OPC_MFC1:
29208         case OPC_CFC1:
29209         case OPC_MTC1:
29210         case OPC_CTC1:
29211             check_cp1_enabled(ctx);
29212             gen_cp1(ctx, op1, rt, rd);
29213             break;
29214 #if defined(TARGET_MIPS64)
29215         case OPC_DMFC1:
29216         case OPC_DMTC1:
29217             check_cp1_enabled(ctx);
29218             check_insn(ctx, ISA_MIPS3);
29219             check_mips_64(ctx);
29220             gen_cp1(ctx, op1, rt, rd);
29221             break;
29222 #endif
29223         case OPC_BC1EQZ: /* OPC_BC1ANY2 */
29224             check_cp1_enabled(ctx);
29225             if (ctx->insn_flags & ISA_MIPS32R6) {
29226                 /* OPC_BC1EQZ */
29227                 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
29228                                        rt, imm << 2, 4);
29229             } else {
29230                 /* OPC_BC1ANY2 */
29231                 check_cop1x(ctx);
29232                 check_insn(ctx, ASE_MIPS3D);
29233                 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29234                                     (rt >> 2) & 0x7, imm << 2);
29235             }
29236             break;
29237         case OPC_BC1NEZ:
29238             check_cp1_enabled(ctx);
29239             check_insn(ctx, ISA_MIPS32R6);
29240             gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
29241                                    rt, imm << 2, 4);
29242             break;
29243         case OPC_BC1ANY4:
29244             check_cp1_enabled(ctx);
29245             check_insn_opc_removed(ctx, ISA_MIPS32R6);
29246             check_cop1x(ctx);
29247             check_insn(ctx, ASE_MIPS3D);
29248             /* fall through */
29249         case OPC_BC1:
29250             check_cp1_enabled(ctx);
29251             check_insn_opc_removed(ctx, ISA_MIPS32R6);
29252             gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29253                                 (rt >> 2) & 0x7, imm << 2);
29254             break;
29255         case OPC_PS_FMT:
29256             check_ps(ctx);
29257             /* fall through */
29258         case OPC_S_FMT:
29259         case OPC_D_FMT:
29260             check_cp1_enabled(ctx);
29261             gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29262                        (imm >> 8) & 0x7);
29263             break;
29264         case OPC_W_FMT:
29265         case OPC_L_FMT:
29266         {
29267             int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
29268             check_cp1_enabled(ctx);
29269             if (ctx->insn_flags & ISA_MIPS32R6) {
29270                 switch (r6_op) {
29271                 case R6_OPC_CMP_AF_S:
29272                 case R6_OPC_CMP_UN_S:
29273                 case R6_OPC_CMP_EQ_S:
29274                 case R6_OPC_CMP_UEQ_S:
29275                 case R6_OPC_CMP_LT_S:
29276                 case R6_OPC_CMP_ULT_S:
29277                 case R6_OPC_CMP_LE_S:
29278                 case R6_OPC_CMP_ULE_S:
29279                 case R6_OPC_CMP_SAF_S:
29280                 case R6_OPC_CMP_SUN_S:
29281                 case R6_OPC_CMP_SEQ_S:
29282                 case R6_OPC_CMP_SEUQ_S:
29283                 case R6_OPC_CMP_SLT_S:
29284                 case R6_OPC_CMP_SULT_S:
29285                 case R6_OPC_CMP_SLE_S:
29286                 case R6_OPC_CMP_SULE_S:
29287                 case R6_OPC_CMP_OR_S:
29288                 case R6_OPC_CMP_UNE_S:
29289                 case R6_OPC_CMP_NE_S:
29290                 case R6_OPC_CMP_SOR_S:
29291                 case R6_OPC_CMP_SUNE_S:
29292                 case R6_OPC_CMP_SNE_S:
29293                     gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29294                     break;
29295                 case R6_OPC_CMP_AF_D:
29296                 case R6_OPC_CMP_UN_D:
29297                 case R6_OPC_CMP_EQ_D:
29298                 case R6_OPC_CMP_UEQ_D:
29299                 case R6_OPC_CMP_LT_D:
29300                 case R6_OPC_CMP_ULT_D:
29301                 case R6_OPC_CMP_LE_D:
29302                 case R6_OPC_CMP_ULE_D:
29303                 case R6_OPC_CMP_SAF_D:
29304                 case R6_OPC_CMP_SUN_D:
29305                 case R6_OPC_CMP_SEQ_D:
29306                 case R6_OPC_CMP_SEUQ_D:
29307                 case R6_OPC_CMP_SLT_D:
29308                 case R6_OPC_CMP_SULT_D:
29309                 case R6_OPC_CMP_SLE_D:
29310                 case R6_OPC_CMP_SULE_D:
29311                 case R6_OPC_CMP_OR_D:
29312                 case R6_OPC_CMP_UNE_D:
29313                 case R6_OPC_CMP_NE_D:
29314                 case R6_OPC_CMP_SOR_D:
29315                 case R6_OPC_CMP_SUNE_D:
29316                 case R6_OPC_CMP_SNE_D:
29317                     gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29318                     break;
29319                 default:
29320                     gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
29321                                rt, rd, sa, (imm >> 8) & 0x7);
29322
29323                     break;
29324                 }
29325             } else {
29326                 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29327                            (imm >> 8) & 0x7);
29328             }
29329             break;
29330         }
29331         case OPC_BZ_V:
29332         case OPC_BNZ_V:
29333         case OPC_BZ_B:
29334         case OPC_BZ_H:
29335         case OPC_BZ_W:
29336         case OPC_BZ_D:
29337         case OPC_BNZ_B:
29338         case OPC_BNZ_H:
29339         case OPC_BNZ_W:
29340         case OPC_BNZ_D:
29341             check_insn(ctx, ASE_MSA);
29342             gen_msa_branch(env, ctx, op1);
29343             break;
29344         default:
29345             MIPS_INVAL("cp1");
29346             generate_exception_end(ctx, EXCP_RI);
29347             break;
29348         }
29349         break;
29350
29351     /* Compact branches [R6] and COP2 [non-R6] */
29352     case OPC_BC: /* OPC_LWC2 */
29353     case OPC_BALC: /* OPC_SWC2 */
29354         if (ctx->insn_flags & ISA_MIPS32R6) {
29355             /* OPC_BC, OPC_BALC */
29356             gen_compute_compact_branch(ctx, op, 0, 0,
29357                                        sextract32(ctx->opcode << 2, 0, 28));
29358         } else {
29359             /* OPC_LWC2, OPC_SWC2 */
29360             /* COP2: Not implemented. */
29361             generate_exception_err(ctx, EXCP_CpU, 2);
29362         }
29363         break;
29364     case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
29365     case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
29366         if (ctx->insn_flags & ISA_MIPS32R6) {
29367             if (rs != 0) {
29368                 /* OPC_BEQZC, OPC_BNEZC */
29369                 gen_compute_compact_branch(ctx, op, rs, 0,
29370                                            sextract32(ctx->opcode << 2, 0, 23));
29371             } else {
29372                 /* OPC_JIC, OPC_JIALC */
29373                 gen_compute_compact_branch(ctx, op, 0, rt, imm);
29374             }
29375         } else {
29376             /* OPC_LWC2, OPC_SWC2 */
29377             /* COP2: Not implemented. */
29378             generate_exception_err(ctx, EXCP_CpU, 2);
29379         }
29380         break;
29381     case OPC_CP2:
29382         check_insn(ctx, INSN_LOONGSON2F);
29383         /* Note that these instructions use different fields.  */
29384         gen_loongson_multimedia(ctx, sa, rd, rt);
29385         break;
29386
29387     case OPC_CP3:
29388         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29389         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
29390             check_cp1_enabled(ctx);
29391             op1 = MASK_CP3(ctx->opcode);
29392             switch (op1) {
29393             case OPC_LUXC1:
29394             case OPC_SUXC1:
29395                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29396                 /* Fallthrough */
29397             case OPC_LWXC1:
29398             case OPC_LDXC1:
29399             case OPC_SWXC1:
29400             case OPC_SDXC1:
29401                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29402                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
29403                 break;
29404             case OPC_PREFX:
29405                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29406                 /* Treat as NOP. */
29407                 break;
29408             case OPC_ALNV_PS:
29409                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29410                 /* Fallthrough */
29411             case OPC_MADD_S:
29412             case OPC_MADD_D:
29413             case OPC_MADD_PS:
29414             case OPC_MSUB_S:
29415             case OPC_MSUB_D:
29416             case OPC_MSUB_PS:
29417             case OPC_NMADD_S:
29418             case OPC_NMADD_D:
29419             case OPC_NMADD_PS:
29420             case OPC_NMSUB_S:
29421             case OPC_NMSUB_D:
29422             case OPC_NMSUB_PS:
29423                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29424                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
29425                 break;
29426             default:
29427                 MIPS_INVAL("cp3");
29428                 generate_exception_end(ctx, EXCP_RI);
29429                 break;
29430             }
29431         } else {
29432             generate_exception_err(ctx, EXCP_CpU, 1);
29433         }
29434         break;
29435
29436 #if defined(TARGET_MIPS64)
29437     /* MIPS64 opcodes */
29438     case OPC_LLD:
29439         if (ctx->insn_flags & INSN_R5900) {
29440             check_insn_opc_user_only(ctx, INSN_R5900);
29441         }
29442         /* fall through */
29443     case OPC_LDL:
29444     case OPC_LDR:
29445         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29446         /* fall through */
29447     case OPC_LWU:
29448     case OPC_LD:
29449         check_insn(ctx, ISA_MIPS3);
29450         check_mips_64(ctx);
29451         gen_ld(ctx, op, rt, rs, imm);
29452         break;
29453     case OPC_SDL:
29454     case OPC_SDR:
29455         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29456         /* fall through */
29457     case OPC_SD:
29458         check_insn(ctx, ISA_MIPS3);
29459         check_mips_64(ctx);
29460         gen_st(ctx, op, rt, rs, imm);
29461         break;
29462     case OPC_SCD:
29463         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29464         check_insn(ctx, ISA_MIPS3);
29465         if (ctx->insn_flags & INSN_R5900) {
29466             check_insn_opc_user_only(ctx, INSN_R5900);
29467         }
29468         check_mips_64(ctx);
29469         gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
29470         break;
29471     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
29472         if (ctx->insn_flags & ISA_MIPS32R6) {
29473             /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
29474             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29475         } else {
29476             /* OPC_DADDI */
29477             check_insn(ctx, ISA_MIPS3);
29478             check_mips_64(ctx);
29479             gen_arith_imm(ctx, op, rt, rs, imm);
29480         }
29481         break;
29482     case OPC_DADDIU:
29483         check_insn(ctx, ISA_MIPS3);
29484         check_mips_64(ctx);
29485         gen_arith_imm(ctx, op, rt, rs, imm);
29486         break;
29487 #else
29488     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
29489         if (ctx->insn_flags & ISA_MIPS32R6) {
29490             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29491         } else {
29492             MIPS_INVAL("major opcode");
29493             generate_exception_end(ctx, EXCP_RI);
29494         }
29495         break;
29496 #endif
29497     case OPC_DAUI: /* OPC_JALX */
29498         if (ctx->insn_flags & ISA_MIPS32R6) {
29499 #if defined(TARGET_MIPS64)
29500             /* OPC_DAUI */
29501             check_mips_64(ctx);
29502             if (rs == 0) {
29503                 generate_exception(ctx, EXCP_RI);
29504             } else if (rt != 0) {
29505                 TCGv t0 = tcg_temp_new();
29506                 gen_load_gpr(t0, rs);
29507                 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
29508                 tcg_temp_free(t0);
29509             }
29510 #else
29511             generate_exception_end(ctx, EXCP_RI);
29512             MIPS_INVAL("major opcode");
29513 #endif
29514         } else {
29515             /* OPC_JALX */
29516             check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
29517             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
29518             gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
29519         }
29520         break;
29521     case OPC_MSA: /* OPC_MDMX */
29522         if (ctx->insn_flags & INSN_R5900) {
29523 #if defined(TARGET_MIPS64)
29524             gen_mmi_lq(env, ctx);    /* MMI_OPC_LQ */
29525 #endif
29526         } else {
29527             /* MDMX: Not implemented. */
29528             gen_msa(env, ctx);
29529         }
29530         break;
29531     case OPC_PCREL:
29532         check_insn(ctx, ISA_MIPS32R6);
29533         gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
29534         break;
29535     default:            /* Invalid */
29536         MIPS_INVAL("major opcode");
29537         generate_exception_end(ctx, EXCP_RI);
29538         break;
29539     }
29540 }
29541
29542 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
29543 {
29544     DisasContext *ctx = container_of(dcbase, DisasContext, base);
29545     CPUMIPSState *env = cs->env_ptr;
29546
29547     ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
29548     ctx->saved_pc = -1;
29549     ctx->insn_flags = env->insn_flags;
29550     ctx->CP0_Config1 = env->CP0_Config1;
29551     ctx->CP0_Config2 = env->CP0_Config2;
29552     ctx->CP0_Config3 = env->CP0_Config3;
29553     ctx->CP0_Config5 = env->CP0_Config5;
29554     ctx->btarget = 0;
29555     ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
29556     ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
29557     ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
29558     ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
29559     ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
29560     ctx->PAMask = env->PAMask;
29561     ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
29562     ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
29563     ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
29564     ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
29565     ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
29566     /* Restore delay slot state from the tb context.  */
29567     ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
29568     ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
29569     ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
29570              (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
29571     ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
29572     ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
29573     ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
29574     ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
29575     restore_cpu_state(env, ctx);
29576 #ifdef CONFIG_USER_ONLY
29577         ctx->mem_idx = MIPS_HFLAG_UM;
29578 #else
29579         ctx->mem_idx = hflags_mmu_index(ctx->hflags);
29580 #endif
29581     ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
29582                                   MO_UNALN : MO_ALIGN;
29583
29584     LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
29585               ctx->hflags);
29586 }
29587
29588 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
29589 {
29590 }
29591
29592 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
29593 {
29594     DisasContext *ctx = container_of(dcbase, DisasContext, base);
29595
29596     tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
29597                        ctx->btarget);
29598 }
29599
29600 static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
29601                                      const CPUBreakpoint *bp)
29602 {
29603     DisasContext *ctx = container_of(dcbase, DisasContext, base);
29604
29605     save_cpu_state(ctx, 1);
29606     ctx->base.is_jmp = DISAS_NORETURN;
29607     gen_helper_raise_exception_debug(cpu_env);
29608     /* The address covered by the breakpoint must be included in
29609        [tb->pc, tb->pc + tb->size) in order to for it to be
29610        properly cleared -- thus we increment the PC here so that
29611        the logic setting tb->size below does the right thing.  */
29612     ctx->base.pc_next += 4;
29613     return true;
29614 }
29615
29616 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
29617 {
29618     CPUMIPSState *env = cs->env_ptr;
29619     DisasContext *ctx = container_of(dcbase, DisasContext, base);
29620     int insn_bytes;
29621     int is_slot;
29622
29623     is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
29624     if (ctx->insn_flags & ISA_NANOMIPS32) {
29625         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29626         insn_bytes = decode_nanomips_opc(env, ctx);
29627     } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
29628         ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
29629         insn_bytes = 4;
29630         decode_opc(env, ctx);
29631     } else if (ctx->insn_flags & ASE_MICROMIPS) {
29632         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29633         insn_bytes = decode_micromips_opc(env, ctx);
29634     } else if (ctx->insn_flags & ASE_MIPS16) {
29635         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29636         insn_bytes = decode_mips16_opc(env, ctx);
29637     } else {
29638         generate_exception_end(ctx, EXCP_RI);
29639         g_assert(ctx->base.is_jmp == DISAS_NORETURN);
29640         return;
29641     }
29642
29643     if (ctx->hflags & MIPS_HFLAG_BMASK) {
29644         if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
29645                              MIPS_HFLAG_FBNSLOT))) {
29646             /* force to generate branch as there is neither delay nor
29647                forbidden slot */
29648             is_slot = 1;
29649         }
29650         if ((ctx->hflags & MIPS_HFLAG_M16) &&
29651             (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
29652             /* Force to generate branch as microMIPS R6 doesn't restrict
29653                branches in the forbidden slot. */
29654             is_slot = 1;
29655         }
29656     }
29657     if (is_slot) {
29658         gen_branch(ctx, insn_bytes);
29659     }
29660     ctx->base.pc_next += insn_bytes;
29661
29662     if (ctx->base.is_jmp != DISAS_NEXT) {
29663         return;
29664     }
29665     /* Execute a branch and its delay slot as a single instruction.
29666        This is what GDB expects and is consistent with what the
29667        hardware does (e.g. if a delay slot instruction faults, the
29668        reported PC is the PC of the branch).  */
29669     if (ctx->base.singlestep_enabled &&
29670         (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
29671         ctx->base.is_jmp = DISAS_TOO_MANY;
29672     }
29673     if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
29674         ctx->base.is_jmp = DISAS_TOO_MANY;
29675     }
29676 }
29677
29678 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
29679 {
29680     DisasContext *ctx = container_of(dcbase, DisasContext, base);
29681
29682     if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
29683         save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
29684         gen_helper_raise_exception_debug(cpu_env);
29685     } else {
29686         switch (ctx->base.is_jmp) {
29687         case DISAS_STOP:
29688             gen_save_pc(ctx->base.pc_next);
29689             tcg_gen_lookup_and_goto_ptr();
29690             break;
29691         case DISAS_NEXT:
29692         case DISAS_TOO_MANY:
29693             save_cpu_state(ctx, 0);
29694             gen_goto_tb(ctx, 0, ctx->base.pc_next);
29695             break;
29696         case DISAS_EXIT:
29697             tcg_gen_exit_tb(NULL, 0);
29698             break;
29699         case DISAS_NORETURN:
29700             break;
29701         default:
29702             g_assert_not_reached();
29703         }
29704     }
29705 }
29706
29707 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
29708 {
29709     qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
29710     log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
29711 }
29712
29713 static const TranslatorOps mips_tr_ops = {
29714     .init_disas_context = mips_tr_init_disas_context,
29715     .tb_start           = mips_tr_tb_start,
29716     .insn_start         = mips_tr_insn_start,
29717     .breakpoint_check   = mips_tr_breakpoint_check,
29718     .translate_insn     = mips_tr_translate_insn,
29719     .tb_stop            = mips_tr_tb_stop,
29720     .disas_log          = mips_tr_disas_log,
29721 };
29722
29723 void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
29724 {
29725     DisasContext ctx;
29726
29727     translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
29728 }
29729
29730 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
29731                            int flags)
29732 {
29733     int i;
29734     int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
29735
29736 #define printfpr(fp)                                                    \
29737     do {                                                                \
29738         if (is_fpu64)                                                   \
29739             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
29740                         " fd:%13g fs:%13g psu: %13g\n",                 \
29741                         (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
29742                         (double)(fp)->fd,                               \
29743                         (double)(fp)->fs[FP_ENDIAN_IDX],                \
29744                         (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
29745         else {                                                          \
29746             fpr_t tmp;                                                  \
29747             tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
29748             tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
29749             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
29750                         " fd:%13g fs:%13g psu:%13g\n",                  \
29751                         tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
29752                         (double)tmp.fd,                                 \
29753                         (double)tmp.fs[FP_ENDIAN_IDX],                  \
29754                         (double)tmp.fs[!FP_ENDIAN_IDX]);                \
29755         }                                                               \
29756     } while(0)
29757
29758
29759     fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
29760                 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
29761                 get_float_exception_flags(&env->active_fpu.fp_status));
29762     for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
29763         fpu_fprintf(f, "%3s: ", fregnames[i]);
29764         printfpr(&env->active_fpu.fpr[i]);
29765     }
29766
29767 #undef printfpr
29768 }
29769
29770 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
29771                          int flags)
29772 {
29773     MIPSCPU *cpu = MIPS_CPU(cs);
29774     CPUMIPSState *env = &cpu->env;
29775     int i;
29776
29777     cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
29778                 " LO=0x" TARGET_FMT_lx " ds %04x "
29779                 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
29780                 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
29781                 env->hflags, env->btarget, env->bcond);
29782     for (i = 0; i < 32; i++) {
29783         if ((i & 3) == 0)
29784             cpu_fprintf(f, "GPR%02d:", i);
29785         cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
29786         if ((i & 3) == 3)
29787             cpu_fprintf(f, "\n");
29788     }
29789
29790     cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
29791                 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
29792     cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
29793                 PRIx64 "\n",
29794                 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
29795     cpu_fprintf(f, "    Config2 0x%08x Config3 0x%08x\n",
29796                 env->CP0_Config2, env->CP0_Config3);
29797     cpu_fprintf(f, "    Config4 0x%08x Config5 0x%08x\n",
29798                 env->CP0_Config4, env->CP0_Config5);
29799     if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
29800         fpu_dump_state(env, f, cpu_fprintf, flags);
29801     }
29802 }
29803
29804 void mips_tcg_init(void)
29805 {
29806     int i;
29807
29808     cpu_gpr[0] = NULL;
29809     for (i = 1; i < 32; i++)
29810         cpu_gpr[i] = tcg_global_mem_new(cpu_env,
29811                                         offsetof(CPUMIPSState, active_tc.gpr[i]),
29812                                         regnames[i]);
29813
29814     for (i = 0; i < 32; i++) {
29815         int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
29816         msa_wr_d[i * 2] =
29817                 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
29818         /* The scalar floating-point unit (FPU) registers are mapped on
29819          * the MSA vector registers. */
29820         fpu_f64[i] = msa_wr_d[i * 2];
29821         off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
29822         msa_wr_d[i * 2 + 1] =
29823                 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
29824     }
29825
29826     cpu_PC = tcg_global_mem_new(cpu_env,
29827                                 offsetof(CPUMIPSState, active_tc.PC), "PC");
29828     for (i = 0; i < MIPS_DSP_ACC; i++) {
29829         cpu_HI[i] = tcg_global_mem_new(cpu_env,
29830                                        offsetof(CPUMIPSState, active_tc.HI[i]),
29831                                        regnames_HI[i]);
29832         cpu_LO[i] = tcg_global_mem_new(cpu_env,
29833                                        offsetof(CPUMIPSState, active_tc.LO[i]),
29834                                        regnames_LO[i]);
29835     }
29836     cpu_dspctrl = tcg_global_mem_new(cpu_env,
29837                                      offsetof(CPUMIPSState, active_tc.DSPControl),
29838                                      "DSPControl");
29839     bcond = tcg_global_mem_new(cpu_env,
29840                                offsetof(CPUMIPSState, bcond), "bcond");
29841     btarget = tcg_global_mem_new(cpu_env,
29842                                  offsetof(CPUMIPSState, btarget), "btarget");
29843     hflags = tcg_global_mem_new_i32(cpu_env,
29844                                     offsetof(CPUMIPSState, hflags), "hflags");
29845
29846     fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
29847                                       offsetof(CPUMIPSState, active_fpu.fcr0),
29848                                       "fcr0");
29849     fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
29850                                        offsetof(CPUMIPSState, active_fpu.fcr31),
29851                                        "fcr31");
29852     cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
29853                                     "lladdr");
29854     cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
29855                                    "llval");
29856
29857 #if defined(TARGET_MIPS64)
29858     cpu_mmr[0] = NULL;
29859     for (i = 1; i < 32; i++) {
29860         cpu_mmr[i] = tcg_global_mem_new_i64(cpu_env,
29861                                             offsetof(CPUMIPSState,
29862                                                      active_tc.mmr[i]),
29863                                             regnames[i]);
29864     }
29865 #endif
29866
29867 #if !defined(TARGET_MIPS64)
29868     for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
29869         mxu_gpr[i] = tcg_global_mem_new(cpu_env,
29870                                         offsetof(CPUMIPSState,
29871                                                  active_tc.mxu_gpr[i]),
29872                                         mxuregnames[i]);
29873     }
29874
29875     mxu_CR = tcg_global_mem_new(cpu_env,
29876                                 offsetof(CPUMIPSState, active_tc.mxu_cr),
29877                                 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
29878 #endif
29879 }
29880
29881 #include "translate_init.inc.c"
29882
29883 void cpu_mips_realize_env(CPUMIPSState *env)
29884 {
29885     env->exception_base = (int32_t)0xBFC00000;
29886
29887 #ifndef CONFIG_USER_ONLY
29888     mmu_init(env, env->cpu_model);
29889 #endif
29890     fpu_init(env, env->cpu_model);
29891     mvp_init(env, env->cpu_model);
29892 }
29893
29894 bool cpu_supports_cps_smp(const char *cpu_type)
29895 {
29896     const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
29897     return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
29898 }
29899
29900 bool cpu_supports_isa(const char *cpu_type, uint64_t isa)
29901 {
29902     const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
29903     return (mcc->cpu_def->insn_flags & isa) != 0;
29904 }
29905
29906 void cpu_set_exception_base(int vp_index, target_ulong address)
29907 {
29908     MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
29909     vp->env.exception_base = address;
29910 }
29911
29912 void cpu_state_reset(CPUMIPSState *env)
29913 {
29914     MIPSCPU *cpu = mips_env_get_cpu(env);
29915     CPUState *cs = CPU(cpu);
29916
29917     /* Reset registers to their default values */
29918     env->CP0_PRid = env->cpu_model->CP0_PRid;
29919     env->CP0_Config0 = env->cpu_model->CP0_Config0;
29920 #ifdef TARGET_WORDS_BIGENDIAN
29921     env->CP0_Config0 |= (1 << CP0C0_BE);
29922 #endif
29923     env->CP0_Config1 = env->cpu_model->CP0_Config1;
29924     env->CP0_Config2 = env->cpu_model->CP0_Config2;
29925     env->CP0_Config3 = env->cpu_model->CP0_Config3;
29926     env->CP0_Config4 = env->cpu_model->CP0_Config4;
29927     env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
29928     env->CP0_Config5 = env->cpu_model->CP0_Config5;
29929     env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
29930     env->CP0_Config6 = env->cpu_model->CP0_Config6;
29931     env->CP0_Config7 = env->cpu_model->CP0_Config7;
29932     env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
29933                                  << env->cpu_model->CP0_LLAddr_shift;
29934     env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
29935     env->SYNCI_Step = env->cpu_model->SYNCI_Step;
29936     env->CCRes = env->cpu_model->CCRes;
29937     env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
29938     env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
29939     env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
29940     env->current_tc = 0;
29941     env->SEGBITS = env->cpu_model->SEGBITS;
29942     env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
29943 #if defined(TARGET_MIPS64)
29944     if (env->cpu_model->insn_flags & ISA_MIPS3) {
29945         env->SEGMask |= 3ULL << 62;
29946     }
29947 #endif
29948     env->PABITS = env->cpu_model->PABITS;
29949     env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
29950     env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
29951     env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
29952     env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
29953     env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
29954     env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
29955     env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
29956     env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
29957     env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
29958     env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
29959     env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
29960     env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
29961     env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
29962     env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
29963     env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
29964     env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
29965     env->msair = env->cpu_model->MSAIR;
29966     env->insn_flags = env->cpu_model->insn_flags;
29967
29968 #if defined(CONFIG_USER_ONLY)
29969     env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
29970 # ifdef TARGET_MIPS64
29971     /* Enable 64-bit register mode.  */
29972     env->CP0_Status |= (1 << CP0St_PX);
29973 # endif
29974 # ifdef TARGET_ABI_MIPSN64
29975     /* Enable 64-bit address mode.  */
29976     env->CP0_Status |= (1 << CP0St_UX);
29977 # endif
29978     /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
29979        hardware registers.  */
29980     env->CP0_HWREna |= 0x0000000F;
29981     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
29982         env->CP0_Status |= (1 << CP0St_CU1);
29983     }
29984     if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
29985         env->CP0_Status |= (1 << CP0St_MX);
29986     }
29987 # if defined(TARGET_MIPS64)
29988     /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
29989     if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
29990         (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
29991         env->CP0_Status |= (1 << CP0St_FR);
29992     }
29993 # endif
29994 #else
29995     if (env->hflags & MIPS_HFLAG_BMASK) {
29996         /* If the exception was raised from a delay slot,
29997            come back to the jump.  */
29998         env->CP0_ErrorEPC = (env->active_tc.PC
29999                              - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
30000     } else {
30001         env->CP0_ErrorEPC = env->active_tc.PC;
30002     }
30003     env->active_tc.PC = env->exception_base;
30004     env->CP0_Random = env->tlb->nb_tlb - 1;
30005     env->tlb->tlb_in_use = env->tlb->nb_tlb;
30006     env->CP0_Wired = 0;
30007     env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
30008     env->CP0_EBase = (cs->cpu_index & 0x3FF);
30009     if (mips_um_ksegs_enabled()) {
30010         env->CP0_EBase |= 0x40000000;
30011     } else {
30012         env->CP0_EBase |= (int32_t)0x80000000;
30013     }
30014     if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
30015         env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
30016     }
30017     env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
30018                                  0x3ff : 0xff;
30019     env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
30020     /* vectored interrupts not implemented, timer on int 7,
30021        no performance counters. */
30022     env->CP0_IntCtl = 0xe0000000;
30023     {
30024         int i;
30025
30026         for (i = 0; i < 7; i++) {
30027             env->CP0_WatchLo[i] = 0;
30028             env->CP0_WatchHi[i] = 0x80000000;
30029         }
30030         env->CP0_WatchLo[7] = 0;
30031         env->CP0_WatchHi[7] = 0;
30032     }
30033     /* Count register increments in debug mode, EJTAG version 1 */
30034     env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
30035
30036     cpu_mips_store_count(env, 1);
30037
30038     if (env->CP0_Config3 & (1 << CP0C3_MT)) {
30039         int i;
30040
30041         /* Only TC0 on VPE 0 starts as active.  */
30042         for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
30043             env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
30044             env->tcs[i].CP0_TCHalt = 1;
30045         }
30046         env->active_tc.CP0_TCHalt = 1;
30047         cs->halted = 1;
30048
30049         if (cs->cpu_index == 0) {
30050             /* VPE0 starts up enabled.  */
30051             env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
30052             env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
30053
30054             /* TC0 starts up unhalted.  */
30055             cs->halted = 0;
30056             env->active_tc.CP0_TCHalt = 0;
30057             env->tcs[0].CP0_TCHalt = 0;
30058             /* With thread 0 active.  */
30059             env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
30060             env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
30061         }
30062     }
30063
30064     /*
30065      * Configure default legacy segmentation control. We use this regardless of
30066      * whether segmentation control is presented to the guest.
30067      */
30068     /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
30069     env->CP0_SegCtl0 =   (CP0SC_AM_MK << CP0SC_AM);
30070     /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
30071     env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
30072     /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
30073     env->CP0_SegCtl1 =   (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
30074                          (2 << CP0SC_C);
30075     /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
30076     env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
30077                          (3 << CP0SC_C)) << 16;
30078     /* USeg (seg4 0x40000000..0x7FFFFFFF) */
30079     env->CP0_SegCtl2 =   (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30080                          (1 << CP0SC_EU) | (2 << CP0SC_C);
30081     /* USeg (seg5 0x00000000..0x3FFFFFFF) */
30082     env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30083                          (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
30084     /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
30085     env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
30086 #endif
30087     if ((env->insn_flags & ISA_MIPS32R6) &&
30088         (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
30089         /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
30090         env->CP0_Status |= (1 << CP0St_FR);
30091     }
30092
30093     if (env->insn_flags & ISA_MIPS32R6) {
30094         /* PTW  =  1 */
30095         env->CP0_PWSize = 0x40;
30096         /* GDI  = 12 */
30097         /* UDI  = 12 */
30098         /* MDI  = 12 */
30099         /* PRI  = 12 */
30100         /* PTEI =  2 */
30101         env->CP0_PWField = 0x0C30C302;
30102     } else {
30103         /* GDI  =  0 */
30104         /* UDI  =  0 */
30105         /* MDI  =  0 */
30106         /* PRI  =  0 */
30107         /* PTEI =  2 */
30108         env->CP0_PWField = 0x02;
30109     }
30110
30111     if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
30112         /*  microMIPS on reset when Config3.ISA is 3 */
30113         env->hflags |= MIPS_HFLAG_M16;
30114     }
30115
30116     /* MSA */
30117     if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
30118         msa_reset(env);
30119     }
30120
30121     compute_hflags(env);
30122     restore_fp_status(env);
30123     restore_pamask(env);
30124     cs->exception_index = EXCP_NONE;
30125
30126     if (semihosting_get_argc()) {
30127         /* UHI interface can be used to obtain argc and argv */
30128         env->active_tc.gpr[4] = -1;
30129     }
30130 }
30131
30132 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
30133                           target_ulong *data)
30134 {
30135     env->active_tc.PC = data[0];
30136     env->hflags &= ~MIPS_HFLAG_BMASK;
30137     env->hflags |= data[1];
30138     switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
30139     case MIPS_HFLAG_BR:
30140         break;
30141     case MIPS_HFLAG_BC:
30142     case MIPS_HFLAG_BL:
30143     case MIPS_HFLAG_B:
30144         env->btarget = data[2];
30145         break;
30146     }
30147 }
This page took 1.657545 seconds and 4 git commands to generate.