]> Git Repo - qemu.git/blob - target/mips/translate.c
Merge remote-tracking branch 'remotes/xtensa/tags/20190122-xtensa' into staging
[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_i32 hflags;
2454 static TCGv_i32 fpu_fcr0, fpu_fcr31;
2455 static TCGv_i64 fpu_f64[32];
2456 static TCGv_i64 msa_wr_d[64];
2457
2458 #if defined(TARGET_MIPS64)
2459 /* Upper halves of R5900's 128-bit registers: MMRs (multimedia registers) */
2460 static TCGv_i64 cpu_mmr[32];
2461 #endif
2462
2463 #if !defined(TARGET_MIPS64)
2464 /* MXU registers */
2465 static TCGv mxu_gpr[NUMBER_OF_MXU_REGISTERS - 1];
2466 static TCGv mxu_CR;
2467 #endif
2468
2469 #include "exec/gen-icount.h"
2470
2471 #define gen_helper_0e0i(name, arg) do {                           \
2472     TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
2473     gen_helper_##name(cpu_env, helper_tmp);                       \
2474     tcg_temp_free_i32(helper_tmp);                                \
2475     } while(0)
2476
2477 #define gen_helper_0e1i(name, arg1, arg2) do {                    \
2478     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
2479     gen_helper_##name(cpu_env, arg1, helper_tmp);                 \
2480     tcg_temp_free_i32(helper_tmp);                                \
2481     } while(0)
2482
2483 #define gen_helper_1e0i(name, ret, arg1) do {                     \
2484     TCGv_i32 helper_tmp = tcg_const_i32(arg1);                    \
2485     gen_helper_##name(ret, cpu_env, helper_tmp);                  \
2486     tcg_temp_free_i32(helper_tmp);                                \
2487     } while(0)
2488
2489 #define gen_helper_1e1i(name, ret, arg1, arg2) do {               \
2490     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
2491     gen_helper_##name(ret, cpu_env, arg1, helper_tmp);            \
2492     tcg_temp_free_i32(helper_tmp);                                \
2493     } while(0)
2494
2495 #define gen_helper_0e2i(name, arg1, arg2, arg3) do {              \
2496     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
2497     gen_helper_##name(cpu_env, arg1, arg2, helper_tmp);           \
2498     tcg_temp_free_i32(helper_tmp);                                \
2499     } while(0)
2500
2501 #define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do {         \
2502     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
2503     gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp);      \
2504     tcg_temp_free_i32(helper_tmp);                                \
2505     } while(0)
2506
2507 #define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do {        \
2508     TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
2509     gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp);     \
2510     tcg_temp_free_i32(helper_tmp);                                \
2511     } while(0)
2512
2513 typedef struct DisasContext {
2514     DisasContextBase base;
2515     target_ulong saved_pc;
2516     target_ulong page_start;
2517     uint32_t opcode;
2518     uint64_t insn_flags;
2519     int32_t CP0_Config1;
2520     int32_t CP0_Config2;
2521     int32_t CP0_Config3;
2522     int32_t CP0_Config5;
2523     /* Routine used to access memory */
2524     int mem_idx;
2525     TCGMemOp default_tcg_memop_mask;
2526     uint32_t hflags, saved_hflags;
2527     target_ulong btarget;
2528     bool ulri;
2529     int kscrexist;
2530     bool rxi;
2531     int ie;
2532     bool bi;
2533     bool bp;
2534     uint64_t PAMask;
2535     bool mvh;
2536     bool eva;
2537     bool sc;
2538     int CP0_LLAddr_shift;
2539     bool ps;
2540     bool vp;
2541     bool cmgcr;
2542     bool mrp;
2543     bool nan2008;
2544     bool abs2008;
2545     bool saar;
2546 } DisasContext;
2547
2548 #define DISAS_STOP       DISAS_TARGET_0
2549 #define DISAS_EXIT       DISAS_TARGET_1
2550
2551 static const char * const regnames[] = {
2552     "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
2553     "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
2554     "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
2555     "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
2556 };
2557
2558 static const char * const regnames_HI[] = {
2559     "HI0", "HI1", "HI2", "HI3",
2560 };
2561
2562 static const char * const regnames_LO[] = {
2563     "LO0", "LO1", "LO2", "LO3",
2564 };
2565
2566 static const char * const fregnames[] = {
2567     "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
2568     "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
2569     "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
2570     "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
2571 };
2572
2573 static const char * const msaregnames[] = {
2574     "w0.d0",  "w0.d1",  "w1.d0",  "w1.d1",
2575     "w2.d0",  "w2.d1",  "w3.d0",  "w3.d1",
2576     "w4.d0",  "w4.d1",  "w5.d0",  "w5.d1",
2577     "w6.d0",  "w6.d1",  "w7.d0",  "w7.d1",
2578     "w8.d0",  "w8.d1",  "w9.d0",  "w9.d1",
2579     "w10.d0", "w10.d1", "w11.d0", "w11.d1",
2580     "w12.d0", "w12.d1", "w13.d0", "w13.d1",
2581     "w14.d0", "w14.d1", "w15.d0", "w15.d1",
2582     "w16.d0", "w16.d1", "w17.d0", "w17.d1",
2583     "w18.d0", "w18.d1", "w19.d0", "w19.d1",
2584     "w20.d0", "w20.d1", "w21.d0", "w21.d1",
2585     "w22.d0", "w22.d1", "w23.d0", "w23.d1",
2586     "w24.d0", "w24.d1", "w25.d0", "w25.d1",
2587     "w26.d0", "w26.d1", "w27.d0", "w27.d1",
2588     "w28.d0", "w28.d1", "w29.d0", "w29.d1",
2589     "w30.d0", "w30.d1", "w31.d0", "w31.d1",
2590 };
2591
2592 #if !defined(TARGET_MIPS64)
2593 static const char * const mxuregnames[] = {
2594     "XR1",  "XR2",  "XR3",  "XR4",  "XR5",  "XR6",  "XR7",  "XR8",
2595     "XR9",  "XR10", "XR11", "XR12", "XR13", "XR14", "XR15", "MXU_CR",
2596 };
2597 #endif
2598
2599 #define LOG_DISAS(...)                                                        \
2600     do {                                                                      \
2601         if (MIPS_DEBUG_DISAS) {                                               \
2602             qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
2603         }                                                                     \
2604     } while (0)
2605
2606 #define MIPS_INVAL(op)                                                        \
2607     do {                                                                      \
2608         if (MIPS_DEBUG_DISAS) {                                               \
2609             qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
2610                           TARGET_FMT_lx ": %08x Invalid %s %03x %03x %03x\n", \
2611                           ctx->base.pc_next, ctx->opcode, op,                 \
2612                           ctx->opcode >> 26, ctx->opcode & 0x3F,              \
2613                           ((ctx->opcode >> 16) & 0x1F));                      \
2614         }                                                                     \
2615     } while (0)
2616
2617 /* General purpose registers moves. */
2618 static inline void gen_load_gpr (TCGv t, int reg)
2619 {
2620     if (reg == 0)
2621         tcg_gen_movi_tl(t, 0);
2622     else
2623         tcg_gen_mov_tl(t, cpu_gpr[reg]);
2624 }
2625
2626 static inline void gen_store_gpr (TCGv t, int reg)
2627 {
2628     if (reg != 0)
2629         tcg_gen_mov_tl(cpu_gpr[reg], t);
2630 }
2631
2632 /* Moves to/from shadow registers. */
2633 static inline void gen_load_srsgpr (int from, int to)
2634 {
2635     TCGv t0 = tcg_temp_new();
2636
2637     if (from == 0)
2638         tcg_gen_movi_tl(t0, 0);
2639     else {
2640         TCGv_i32 t2 = tcg_temp_new_i32();
2641         TCGv_ptr addr = tcg_temp_new_ptr();
2642
2643         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2644         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2645         tcg_gen_andi_i32(t2, t2, 0xf);
2646         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2647         tcg_gen_ext_i32_ptr(addr, t2);
2648         tcg_gen_add_ptr(addr, cpu_env, addr);
2649
2650         tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
2651         tcg_temp_free_ptr(addr);
2652         tcg_temp_free_i32(t2);
2653     }
2654     gen_store_gpr(t0, to);
2655     tcg_temp_free(t0);
2656 }
2657
2658 static inline void gen_store_srsgpr (int from, int to)
2659 {
2660     if (to != 0) {
2661         TCGv t0 = tcg_temp_new();
2662         TCGv_i32 t2 = tcg_temp_new_i32();
2663         TCGv_ptr addr = tcg_temp_new_ptr();
2664
2665         gen_load_gpr(t0, from);
2666         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
2667         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
2668         tcg_gen_andi_i32(t2, t2, 0xf);
2669         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
2670         tcg_gen_ext_i32_ptr(addr, t2);
2671         tcg_gen_add_ptr(addr, cpu_env, addr);
2672
2673         tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
2674         tcg_temp_free_ptr(addr);
2675         tcg_temp_free_i32(t2);
2676         tcg_temp_free(t0);
2677     }
2678 }
2679
2680 #if !defined(TARGET_MIPS64)
2681 /* MXU General purpose registers moves. */
2682 static inline void gen_load_mxu_gpr(TCGv t, unsigned int reg)
2683 {
2684     if (reg == 0) {
2685         tcg_gen_movi_tl(t, 0);
2686     } else if (reg <= 15) {
2687         tcg_gen_mov_tl(t, mxu_gpr[reg - 1]);
2688     }
2689 }
2690
2691 static inline void gen_store_mxu_gpr(TCGv t, unsigned int reg)
2692 {
2693     if (reg > 0 && reg <= 15) {
2694         tcg_gen_mov_tl(mxu_gpr[reg - 1], t);
2695     }
2696 }
2697
2698 /* MXU control register moves. */
2699 static inline void gen_load_mxu_cr(TCGv t)
2700 {
2701     tcg_gen_mov_tl(t, mxu_CR);
2702 }
2703
2704 static inline void gen_store_mxu_cr(TCGv t)
2705 {
2706     /* TODO: Add handling of RW rules for MXU_CR. */
2707     tcg_gen_mov_tl(mxu_CR, t);
2708 }
2709 #endif
2710
2711
2712 /* Tests */
2713 static inline void gen_save_pc(target_ulong pc)
2714 {
2715     tcg_gen_movi_tl(cpu_PC, pc);
2716 }
2717
2718 static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
2719 {
2720     LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
2721     if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
2722         gen_save_pc(ctx->base.pc_next);
2723         ctx->saved_pc = ctx->base.pc_next;
2724     }
2725     if (ctx->hflags != ctx->saved_hflags) {
2726         tcg_gen_movi_i32(hflags, ctx->hflags);
2727         ctx->saved_hflags = ctx->hflags;
2728         switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2729         case MIPS_HFLAG_BR:
2730             break;
2731         case MIPS_HFLAG_BC:
2732         case MIPS_HFLAG_BL:
2733         case MIPS_HFLAG_B:
2734             tcg_gen_movi_tl(btarget, ctx->btarget);
2735             break;
2736         }
2737     }
2738 }
2739
2740 static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
2741 {
2742     ctx->saved_hflags = ctx->hflags;
2743     switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
2744     case MIPS_HFLAG_BR:
2745         break;
2746     case MIPS_HFLAG_BC:
2747     case MIPS_HFLAG_BL:
2748     case MIPS_HFLAG_B:
2749         ctx->btarget = env->btarget;
2750         break;
2751     }
2752 }
2753
2754 static inline void generate_exception_err(DisasContext *ctx, int excp, int err)
2755 {
2756     TCGv_i32 texcp = tcg_const_i32(excp);
2757     TCGv_i32 terr = tcg_const_i32(err);
2758     save_cpu_state(ctx, 1);
2759     gen_helper_raise_exception_err(cpu_env, texcp, terr);
2760     tcg_temp_free_i32(terr);
2761     tcg_temp_free_i32(texcp);
2762     ctx->base.is_jmp = DISAS_NORETURN;
2763 }
2764
2765 static inline void generate_exception(DisasContext *ctx, int excp)
2766 {
2767     gen_helper_0e0i(raise_exception, excp);
2768 }
2769
2770 static inline void generate_exception_end(DisasContext *ctx, int excp)
2771 {
2772     generate_exception_err(ctx, excp, 0);
2773 }
2774
2775 /* Floating point register moves. */
2776 static void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2777 {
2778     if (ctx->hflags & MIPS_HFLAG_FRE) {
2779         generate_exception(ctx, EXCP_RI);
2780     }
2781     tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
2782 }
2783
2784 static void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
2785 {
2786     TCGv_i64 t64;
2787     if (ctx->hflags & MIPS_HFLAG_FRE) {
2788         generate_exception(ctx, EXCP_RI);
2789     }
2790     t64 = tcg_temp_new_i64();
2791     tcg_gen_extu_i32_i64(t64, t);
2792     tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
2793     tcg_temp_free_i64(t64);
2794 }
2795
2796 static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2797 {
2798     if (ctx->hflags & MIPS_HFLAG_F64) {
2799         tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
2800     } else {
2801         gen_load_fpr32(ctx, t, reg | 1);
2802     }
2803 }
2804
2805 static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
2806 {
2807     if (ctx->hflags & MIPS_HFLAG_F64) {
2808         TCGv_i64 t64 = tcg_temp_new_i64();
2809         tcg_gen_extu_i32_i64(t64, t);
2810         tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
2811         tcg_temp_free_i64(t64);
2812     } else {
2813         gen_store_fpr32(ctx, t, reg | 1);
2814     }
2815 }
2816
2817 static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2818 {
2819     if (ctx->hflags & MIPS_HFLAG_F64) {
2820         tcg_gen_mov_i64(t, fpu_f64[reg]);
2821     } else {
2822         tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
2823     }
2824 }
2825
2826 static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
2827 {
2828     if (ctx->hflags & MIPS_HFLAG_F64) {
2829         tcg_gen_mov_i64(fpu_f64[reg], t);
2830     } else {
2831         TCGv_i64 t0;
2832         tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
2833         t0 = tcg_temp_new_i64();
2834         tcg_gen_shri_i64(t0, t, 32);
2835         tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
2836         tcg_temp_free_i64(t0);
2837     }
2838 }
2839
2840 static inline int get_fp_bit (int cc)
2841 {
2842     if (cc)
2843         return 24 + cc;
2844     else
2845         return 23;
2846 }
2847
2848 /* Addresses computation */
2849 static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
2850 {
2851     tcg_gen_add_tl(ret, arg0, arg1);
2852
2853 #if defined(TARGET_MIPS64)
2854     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2855         tcg_gen_ext32s_i64(ret, ret);
2856     }
2857 #endif
2858 }
2859
2860 static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
2861                                     target_long ofs)
2862 {
2863     tcg_gen_addi_tl(ret, base, ofs);
2864
2865 #if defined(TARGET_MIPS64)
2866     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2867         tcg_gen_ext32s_i64(ret, ret);
2868     }
2869 #endif
2870 }
2871
2872 /* Addresses computation (translation time) */
2873 static target_long addr_add(DisasContext *ctx, target_long base,
2874                             target_long offset)
2875 {
2876     target_long sum = base + offset;
2877
2878 #if defined(TARGET_MIPS64)
2879     if (ctx->hflags & MIPS_HFLAG_AWRAP) {
2880         sum = (int32_t)sum;
2881     }
2882 #endif
2883     return sum;
2884 }
2885
2886 /* Sign-extract the low 32-bits to a target_long.  */
2887 static inline void gen_move_low32(TCGv ret, TCGv_i64 arg)
2888 {
2889 #if defined(TARGET_MIPS64)
2890     tcg_gen_ext32s_i64(ret, arg);
2891 #else
2892     tcg_gen_extrl_i64_i32(ret, arg);
2893 #endif
2894 }
2895
2896 /* Sign-extract the high 32-bits to a target_long.  */
2897 static inline void gen_move_high32(TCGv ret, TCGv_i64 arg)
2898 {
2899 #if defined(TARGET_MIPS64)
2900     tcg_gen_sari_i64(ret, arg, 32);
2901 #else
2902     tcg_gen_extrh_i64_i32(ret, arg);
2903 #endif
2904 }
2905
2906 static inline void check_cp0_enabled(DisasContext *ctx)
2907 {
2908     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
2909         generate_exception_err(ctx, EXCP_CpU, 0);
2910 }
2911
2912 static inline void check_cp1_enabled(DisasContext *ctx)
2913 {
2914     if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
2915         generate_exception_err(ctx, EXCP_CpU, 1);
2916 }
2917
2918 /* Verify that the processor is running with COP1X instructions enabled.
2919    This is associated with the nabla symbol in the MIPS32 and MIPS64
2920    opcode tables.  */
2921
2922 static inline void check_cop1x(DisasContext *ctx)
2923 {
2924     if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
2925         generate_exception_end(ctx, EXCP_RI);
2926 }
2927
2928 /* Verify that the processor is running with 64-bit floating-point
2929    operations enabled.  */
2930
2931 static inline void check_cp1_64bitmode(DisasContext *ctx)
2932 {
2933     if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
2934         generate_exception_end(ctx, EXCP_RI);
2935 }
2936
2937 /*
2938  * Verify if floating point register is valid; an operation is not defined
2939  * if bit 0 of any register specification is set and the FR bit in the
2940  * Status register equals zero, since the register numbers specify an
2941  * even-odd pair of adjacent coprocessor general registers. When the FR bit
2942  * in the Status register equals one, both even and odd register numbers
2943  * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
2944  *
2945  * Multiple 64 bit wide registers can be checked by calling
2946  * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
2947  */
2948 static inline void check_cp1_registers(DisasContext *ctx, int regs)
2949 {
2950     if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
2951         generate_exception_end(ctx, EXCP_RI);
2952 }
2953
2954 /* Verify that the processor is running with DSP instructions enabled.
2955    This is enabled by CP0 Status register MX(24) bit.
2956  */
2957
2958 static inline void check_dsp(DisasContext *ctx)
2959 {
2960     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
2961         if (ctx->insn_flags & ASE_DSP) {
2962             generate_exception_end(ctx, EXCP_DSPDIS);
2963         } else {
2964             generate_exception_end(ctx, EXCP_RI);
2965         }
2966     }
2967 }
2968
2969 static inline void check_dsp_r2(DisasContext *ctx)
2970 {
2971     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
2972         if (ctx->insn_flags & ASE_DSP) {
2973             generate_exception_end(ctx, EXCP_DSPDIS);
2974         } else {
2975             generate_exception_end(ctx, EXCP_RI);
2976         }
2977     }
2978 }
2979
2980 static inline void check_dsp_r3(DisasContext *ctx)
2981 {
2982     if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
2983         if (ctx->insn_flags & ASE_DSP) {
2984             generate_exception_end(ctx, EXCP_DSPDIS);
2985         } else {
2986             generate_exception_end(ctx, EXCP_RI);
2987         }
2988     }
2989 }
2990
2991 /* This code generates a "reserved instruction" exception if the
2992    CPU does not support the instruction set corresponding to flags. */
2993 static inline void check_insn(DisasContext *ctx, uint64_t flags)
2994 {
2995     if (unlikely(!(ctx->insn_flags & flags))) {
2996         generate_exception_end(ctx, EXCP_RI);
2997     }
2998 }
2999
3000 /* This code generates a "reserved instruction" exception if the
3001    CPU has corresponding flag set which indicates that the instruction
3002    has been removed. */
3003 static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
3004 {
3005     if (unlikely(ctx->insn_flags & flags)) {
3006         generate_exception_end(ctx, EXCP_RI);
3007     }
3008 }
3009
3010 /*
3011  * The Linux kernel traps certain reserved instruction exceptions to
3012  * emulate the corresponding instructions. QEMU is the kernel in user
3013  * mode, so those traps are emulated by accepting the instructions.
3014  *
3015  * A reserved instruction exception is generated for flagged CPUs if
3016  * QEMU runs in system mode.
3017  */
3018 static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
3019 {
3020 #ifndef CONFIG_USER_ONLY
3021     check_insn_opc_removed(ctx, flags);
3022 #endif
3023 }
3024
3025 /* This code generates a "reserved instruction" exception if the
3026    CPU does not support 64-bit paired-single (PS) floating point data type */
3027 static inline void check_ps(DisasContext *ctx)
3028 {
3029     if (unlikely(!ctx->ps)) {
3030         generate_exception(ctx, EXCP_RI);
3031     }
3032     check_cp1_64bitmode(ctx);
3033 }
3034
3035 #ifdef TARGET_MIPS64
3036 /* This code generates a "reserved instruction" exception if 64-bit
3037    instructions are not enabled. */
3038 static inline void check_mips_64(DisasContext *ctx)
3039 {
3040     if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
3041         generate_exception_end(ctx, EXCP_RI);
3042 }
3043 #endif
3044
3045 #ifndef CONFIG_USER_ONLY
3046 static inline void check_mvh(DisasContext *ctx)
3047 {
3048     if (unlikely(!ctx->mvh)) {
3049         generate_exception(ctx, EXCP_RI);
3050     }
3051 }
3052 #endif
3053
3054 /*
3055  * This code generates a "reserved instruction" exception if the
3056  * Config5 XNP bit is set.
3057  */
3058 static inline void check_xnp(DisasContext *ctx)
3059 {
3060     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
3061         generate_exception_end(ctx, EXCP_RI);
3062     }
3063 }
3064
3065 #ifndef CONFIG_USER_ONLY
3066 /*
3067  * This code generates a "reserved instruction" exception if the
3068  * Config3 PW bit is NOT set.
3069  */
3070 static inline void check_pw(DisasContext *ctx)
3071 {
3072     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
3073         generate_exception_end(ctx, EXCP_RI);
3074     }
3075 }
3076 #endif
3077
3078 /*
3079  * This code generates a "reserved instruction" exception if the
3080  * Config3 MT bit is NOT set.
3081  */
3082 static inline void check_mt(DisasContext *ctx)
3083 {
3084     if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3085         generate_exception_end(ctx, EXCP_RI);
3086     }
3087 }
3088
3089 #ifndef CONFIG_USER_ONLY
3090 /*
3091  * This code generates a "coprocessor unusable" exception if CP0 is not
3092  * available, and, if that is not the case, generates a "reserved instruction"
3093  * exception if the Config5 MT bit is NOT set. This is needed for availability
3094  * control of some of MT ASE instructions.
3095  */
3096 static inline void check_cp0_mt(DisasContext *ctx)
3097 {
3098     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
3099         generate_exception_err(ctx, EXCP_CpU, 0);
3100     } else {
3101         if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
3102             generate_exception_err(ctx, EXCP_RI, 0);
3103         }
3104     }
3105 }
3106 #endif
3107
3108 /*
3109  * This code generates a "reserved instruction" exception if the
3110  * Config5 NMS bit is set.
3111  */
3112 static inline void check_nms(DisasContext *ctx)
3113 {
3114     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
3115         generate_exception_end(ctx, EXCP_RI);
3116     }
3117 }
3118
3119 /*
3120  * This code generates a "reserved instruction" exception if the
3121  * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
3122  * Config2 TL, and Config5 L2C are unset.
3123  */
3124 static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
3125 {
3126     if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
3127         !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
3128         !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
3129         !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
3130         !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
3131         !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))
3132     {
3133         generate_exception_end(ctx, EXCP_RI);
3134     }
3135 }
3136
3137 /*
3138  * This code generates a "reserved instruction" exception if the
3139  * Config5 EVA bit is NOT set.
3140  */
3141 static inline void check_eva(DisasContext *ctx)
3142 {
3143     if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
3144         generate_exception_end(ctx, EXCP_RI);
3145     }
3146 }
3147
3148
3149 /* Define small wrappers for gen_load_fpr* so that we have a uniform
3150    calling interface for 32 and 64-bit FPRs.  No sense in changing
3151    all callers for gen_load_fpr32 when we need the CTX parameter for
3152    this one use.  */
3153 #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
3154 #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
3155 #define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
3156 static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
3157                                                int ft, int fs, int cc)        \
3158 {                                                                             \
3159     TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
3160     TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
3161     switch (ifmt) {                                                           \
3162     case FMT_PS:                                                              \
3163         check_ps(ctx);                                                        \
3164         break;                                                                \
3165     case FMT_D:                                                               \
3166         if (abs) {                                                            \
3167             check_cop1x(ctx);                                                 \
3168         }                                                                     \
3169         check_cp1_registers(ctx, fs | ft);                                    \
3170         break;                                                                \
3171     case FMT_S:                                                               \
3172         if (abs) {                                                            \
3173             check_cop1x(ctx);                                                 \
3174         }                                                                     \
3175         break;                                                                \
3176     }                                                                         \
3177     gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
3178     gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
3179     switch (n) {                                                              \
3180     case  0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
3181     case  1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
3182     case  2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
3183     case  3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
3184     case  4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
3185     case  5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
3186     case  6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
3187     case  7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
3188     case  8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
3189     case  9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
3190     case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
3191     case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
3192     case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
3193     case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
3194     case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
3195     case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
3196     default: abort();                                                         \
3197     }                                                                         \
3198     tcg_temp_free_i##bits (fp0);                                              \
3199     tcg_temp_free_i##bits (fp1);                                              \
3200 }
3201
3202 FOP_CONDS(, 0, d, FMT_D, 64)
3203 FOP_CONDS(abs, 1, d, FMT_D, 64)
3204 FOP_CONDS(, 0, s, FMT_S, 32)
3205 FOP_CONDS(abs, 1, s, FMT_S, 32)
3206 FOP_CONDS(, 0, ps, FMT_PS, 64)
3207 FOP_CONDS(abs, 1, ps, FMT_PS, 64)
3208 #undef FOP_CONDS
3209
3210 #define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
3211 static inline void gen_r6_cmp_ ## fmt(DisasContext * ctx, int n,        \
3212                                       int ft, int fs, int fd)           \
3213 {                                                                       \
3214     TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
3215     TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
3216     if (ifmt == FMT_D) {                                                \
3217         check_cp1_registers(ctx, fs | ft | fd);                         \
3218     }                                                                   \
3219     gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
3220     gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
3221     switch (n) {                                                        \
3222     case  0:                                                            \
3223         gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
3224         break;                                                          \
3225     case  1:                                                            \
3226         gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
3227         break;                                                          \
3228     case  2:                                                            \
3229         gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
3230         break;                                                          \
3231     case  3:                                                            \
3232         gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
3233         break;                                                          \
3234     case  4:                                                            \
3235         gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
3236         break;                                                          \
3237     case  5:                                                            \
3238         gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
3239         break;                                                          \
3240     case  6:                                                            \
3241         gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
3242         break;                                                          \
3243     case  7:                                                            \
3244         gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
3245         break;                                                          \
3246     case  8:                                                            \
3247         gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
3248         break;                                                          \
3249     case  9:                                                            \
3250         gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
3251         break;                                                          \
3252     case 10:                                                            \
3253         gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
3254         break;                                                          \
3255     case 11:                                                            \
3256         gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
3257         break;                                                          \
3258     case 12:                                                            \
3259         gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
3260         break;                                                          \
3261     case 13:                                                            \
3262         gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
3263         break;                                                          \
3264     case 14:                                                            \
3265         gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
3266         break;                                                          \
3267     case 15:                                                            \
3268         gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
3269         break;                                                          \
3270     case 17:                                                            \
3271         gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
3272         break;                                                          \
3273     case 18:                                                            \
3274         gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
3275         break;                                                          \
3276     case 19:                                                            \
3277         gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
3278         break;                                                          \
3279     case 25:                                                            \
3280         gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
3281         break;                                                          \
3282     case 26:                                                            \
3283         gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
3284         break;                                                          \
3285     case 27:                                                            \
3286         gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
3287         break;                                                          \
3288     default:                                                            \
3289         abort();                                                        \
3290     }                                                                   \
3291     STORE;                                                              \
3292     tcg_temp_free_i ## bits (fp0);                                      \
3293     tcg_temp_free_i ## bits (fp1);                                      \
3294 }
3295
3296 FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
3297 FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
3298 #undef FOP_CONDNS
3299 #undef gen_ldcmp_fpr32
3300 #undef gen_ldcmp_fpr64
3301
3302 /* load/store instructions. */
3303 #ifdef CONFIG_USER_ONLY
3304 #define OP_LD_ATOMIC(insn,fname)                                           \
3305 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
3306                                 DisasContext *ctx)                         \
3307 {                                                                          \
3308     TCGv t0 = tcg_temp_new();                                              \
3309     tcg_gen_mov_tl(t0, arg1);                                              \
3310     tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
3311     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                \
3312     tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));                \
3313     tcg_temp_free(t0);                                                     \
3314 }
3315 #else
3316 #define OP_LD_ATOMIC(insn,fname)                                           \
3317 static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
3318                                 DisasContext *ctx)                         \
3319 {                                                                          \
3320     gen_helper_1e1i(insn, ret, arg1, mem_idx);                             \
3321 }
3322 #endif
3323 OP_LD_ATOMIC(ll,ld32s);
3324 #if defined(TARGET_MIPS64)
3325 OP_LD_ATOMIC(lld,ld64);
3326 #endif
3327 #undef OP_LD_ATOMIC
3328
3329 #ifdef CONFIG_USER_ONLY
3330 #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
3331 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx,   \
3332                                 DisasContext *ctx)                           \
3333 {                                                                            \
3334     TCGv t0 = tcg_temp_new();                                                \
3335     TCGLabel *l1 = gen_new_label();                                          \
3336     TCGLabel *l2 = gen_new_label();                                          \
3337                                                                              \
3338     tcg_gen_andi_tl(t0, arg2, almask);                                       \
3339     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
3340     tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));          \
3341     generate_exception(ctx, EXCP_AdES);                                      \
3342     gen_set_label(l1);                                                       \
3343     tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                  \
3344     tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
3345     tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
3346     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg));                   \
3347     tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval));              \
3348     generate_exception_end(ctx, EXCP_SC);                                    \
3349     gen_set_label(l2);                                                       \
3350     tcg_gen_movi_tl(t0, 0);                                                  \
3351     gen_store_gpr(t0, rt);                                                   \
3352     tcg_temp_free(t0);                                                       \
3353 }
3354 #else
3355 #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
3356 static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, int mem_idx,   \
3357                                 DisasContext *ctx)                           \
3358 {                                                                            \
3359     TCGv t0 = tcg_temp_new();                                                \
3360     gen_helper_1e2i(insn, t0, arg1, arg2, mem_idx);                          \
3361     gen_store_gpr(t0, rt);                                                   \
3362     tcg_temp_free(t0);                                                       \
3363 }
3364 #endif
3365 OP_ST_ATOMIC(sc,st32,ld32s,0x3);
3366 #if defined(TARGET_MIPS64)
3367 OP_ST_ATOMIC(scd,st64,ld64,0x7);
3368 #endif
3369 #undef OP_ST_ATOMIC
3370
3371 static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
3372                                   int base, int offset)
3373 {
3374     if (base == 0) {
3375         tcg_gen_movi_tl(addr, offset);
3376     } else if (offset == 0) {
3377         gen_load_gpr(addr, base);
3378     } else {
3379         tcg_gen_movi_tl(addr, offset);
3380         gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
3381     }
3382 }
3383
3384 static target_ulong pc_relative_pc (DisasContext *ctx)
3385 {
3386     target_ulong pc = ctx->base.pc_next;
3387
3388     if (ctx->hflags & MIPS_HFLAG_BMASK) {
3389         int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
3390
3391         pc -= branch_bytes;
3392     }
3393
3394     pc &= ~(target_ulong)3;
3395     return pc;
3396 }
3397
3398 /* Load */
3399 static void gen_ld(DisasContext *ctx, uint32_t opc,
3400                    int rt, int base, int offset)
3401 {
3402     TCGv t0, t1, t2;
3403     int mem_idx = ctx->mem_idx;
3404
3405     if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
3406         /* Loongson CPU uses a load to zero register for prefetch.
3407            We emulate it as a NOP. On other CPU we must perform the
3408            actual memory access. */
3409         return;
3410     }
3411
3412     t0 = tcg_temp_new();
3413     gen_base_offset_addr(ctx, t0, base, offset);
3414
3415     switch (opc) {
3416 #if defined(TARGET_MIPS64)
3417     case OPC_LWU:
3418         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
3419                            ctx->default_tcg_memop_mask);
3420         gen_store_gpr(t0, rt);
3421         break;
3422     case OPC_LD:
3423         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
3424                            ctx->default_tcg_memop_mask);
3425         gen_store_gpr(t0, rt);
3426         break;
3427     case OPC_LLD:
3428     case R6_OPC_LLD:
3429         op_ld_lld(t0, t0, mem_idx, ctx);
3430         gen_store_gpr(t0, rt);
3431         break;
3432     case OPC_LDL:
3433         t1 = tcg_temp_new();
3434         /* Do a byte access to possibly trigger a page
3435            fault with the unaligned address.  */
3436         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3437         tcg_gen_andi_tl(t1, t0, 7);
3438 #ifndef TARGET_WORDS_BIGENDIAN
3439         tcg_gen_xori_tl(t1, t1, 7);
3440 #endif
3441         tcg_gen_shli_tl(t1, t1, 3);
3442         tcg_gen_andi_tl(t0, t0, ~7);
3443         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3444         tcg_gen_shl_tl(t0, t0, t1);
3445         t2 = tcg_const_tl(-1);
3446         tcg_gen_shl_tl(t2, t2, t1);
3447         gen_load_gpr(t1, rt);
3448         tcg_gen_andc_tl(t1, t1, t2);
3449         tcg_temp_free(t2);
3450         tcg_gen_or_tl(t0, t0, t1);
3451         tcg_temp_free(t1);
3452         gen_store_gpr(t0, rt);
3453         break;
3454     case OPC_LDR:
3455         t1 = tcg_temp_new();
3456         /* Do a byte access to possibly trigger a page
3457            fault with the unaligned address.  */
3458         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3459         tcg_gen_andi_tl(t1, t0, 7);
3460 #ifdef TARGET_WORDS_BIGENDIAN
3461         tcg_gen_xori_tl(t1, t1, 7);
3462 #endif
3463         tcg_gen_shli_tl(t1, t1, 3);
3464         tcg_gen_andi_tl(t0, t0, ~7);
3465         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3466         tcg_gen_shr_tl(t0, t0, t1);
3467         tcg_gen_xori_tl(t1, t1, 63);
3468         t2 = tcg_const_tl(0xfffffffffffffffeull);
3469         tcg_gen_shl_tl(t2, t2, t1);
3470         gen_load_gpr(t1, rt);
3471         tcg_gen_and_tl(t1, t1, t2);
3472         tcg_temp_free(t2);
3473         tcg_gen_or_tl(t0, t0, t1);
3474         tcg_temp_free(t1);
3475         gen_store_gpr(t0, rt);
3476         break;
3477     case OPC_LDPC:
3478         t1 = tcg_const_tl(pc_relative_pc(ctx));
3479         gen_op_addr_add(ctx, t0, t0, t1);
3480         tcg_temp_free(t1);
3481         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
3482         gen_store_gpr(t0, rt);
3483         break;
3484 #endif
3485     case OPC_LWPC:
3486         t1 = tcg_const_tl(pc_relative_pc(ctx));
3487         gen_op_addr_add(ctx, t0, t0, t1);
3488         tcg_temp_free(t1);
3489         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
3490         gen_store_gpr(t0, rt);
3491         break;
3492     case OPC_LWE:
3493         mem_idx = MIPS_HFLAG_UM;
3494         /* fall through */
3495     case OPC_LW:
3496         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
3497                            ctx->default_tcg_memop_mask);
3498         gen_store_gpr(t0, rt);
3499         break;
3500     case OPC_LHE:
3501         mem_idx = MIPS_HFLAG_UM;
3502         /* fall through */
3503     case OPC_LH:
3504         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
3505                            ctx->default_tcg_memop_mask);
3506         gen_store_gpr(t0, rt);
3507         break;
3508     case OPC_LHUE:
3509         mem_idx = MIPS_HFLAG_UM;
3510         /* fall through */
3511     case OPC_LHU:
3512         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
3513                            ctx->default_tcg_memop_mask);
3514         gen_store_gpr(t0, rt);
3515         break;
3516     case OPC_LBE:
3517         mem_idx = MIPS_HFLAG_UM;
3518         /* fall through */
3519     case OPC_LB:
3520         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
3521         gen_store_gpr(t0, rt);
3522         break;
3523     case OPC_LBUE:
3524         mem_idx = MIPS_HFLAG_UM;
3525         /* fall through */
3526     case OPC_LBU:
3527         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
3528         gen_store_gpr(t0, rt);
3529         break;
3530     case OPC_LWLE:
3531         mem_idx = MIPS_HFLAG_UM;
3532         /* fall through */
3533     case OPC_LWL:
3534         t1 = tcg_temp_new();
3535         /* Do a byte access to possibly trigger a page
3536            fault with the unaligned address.  */
3537         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3538         tcg_gen_andi_tl(t1, t0, 3);
3539 #ifndef TARGET_WORDS_BIGENDIAN
3540         tcg_gen_xori_tl(t1, t1, 3);
3541 #endif
3542         tcg_gen_shli_tl(t1, t1, 3);
3543         tcg_gen_andi_tl(t0, t0, ~3);
3544         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3545         tcg_gen_shl_tl(t0, t0, t1);
3546         t2 = tcg_const_tl(-1);
3547         tcg_gen_shl_tl(t2, t2, t1);
3548         gen_load_gpr(t1, rt);
3549         tcg_gen_andc_tl(t1, t1, t2);
3550         tcg_temp_free(t2);
3551         tcg_gen_or_tl(t0, t0, t1);
3552         tcg_temp_free(t1);
3553         tcg_gen_ext32s_tl(t0, t0);
3554         gen_store_gpr(t0, rt);
3555         break;
3556     case OPC_LWRE:
3557         mem_idx = MIPS_HFLAG_UM;
3558         /* fall through */
3559     case OPC_LWR:
3560         t1 = tcg_temp_new();
3561         /* Do a byte access to possibly trigger a page
3562            fault with the unaligned address.  */
3563         tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
3564         tcg_gen_andi_tl(t1, t0, 3);
3565 #ifdef TARGET_WORDS_BIGENDIAN
3566         tcg_gen_xori_tl(t1, t1, 3);
3567 #endif
3568         tcg_gen_shli_tl(t1, t1, 3);
3569         tcg_gen_andi_tl(t0, t0, ~3);
3570         tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
3571         tcg_gen_shr_tl(t0, t0, t1);
3572         tcg_gen_xori_tl(t1, t1, 31);
3573         t2 = tcg_const_tl(0xfffffffeull);
3574         tcg_gen_shl_tl(t2, t2, t1);
3575         gen_load_gpr(t1, rt);
3576         tcg_gen_and_tl(t1, t1, t2);
3577         tcg_temp_free(t2);
3578         tcg_gen_or_tl(t0, t0, t1);
3579         tcg_temp_free(t1);
3580         tcg_gen_ext32s_tl(t0, t0);
3581         gen_store_gpr(t0, rt);
3582         break;
3583     case OPC_LLE:
3584         mem_idx = MIPS_HFLAG_UM;
3585         /* fall through */
3586     case OPC_LL:
3587     case R6_OPC_LL:
3588         op_ld_ll(t0, t0, mem_idx, ctx);
3589         gen_store_gpr(t0, rt);
3590         break;
3591     }
3592     tcg_temp_free(t0);
3593 }
3594
3595 static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
3596                     uint32_t reg1, uint32_t reg2)
3597 {
3598     TCGv taddr = tcg_temp_new();
3599     TCGv_i64 tval = tcg_temp_new_i64();
3600     TCGv tmp1 = tcg_temp_new();
3601     TCGv tmp2 = tcg_temp_new();
3602
3603     gen_base_offset_addr(ctx, taddr, base, offset);
3604     tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
3605 #ifdef TARGET_WORDS_BIGENDIAN
3606     tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
3607 #else
3608     tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
3609 #endif
3610     gen_store_gpr(tmp1, reg1);
3611     tcg_temp_free(tmp1);
3612     gen_store_gpr(tmp2, reg2);
3613     tcg_temp_free(tmp2);
3614     tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3615     tcg_temp_free_i64(tval);
3616     tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
3617     tcg_temp_free(taddr);
3618 }
3619
3620 /* Store */
3621 static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
3622                     int base, int offset)
3623 {
3624     TCGv t0 = tcg_temp_new();
3625     TCGv t1 = tcg_temp_new();
3626     int mem_idx = ctx->mem_idx;
3627
3628     gen_base_offset_addr(ctx, t0, base, offset);
3629     gen_load_gpr(t1, rt);
3630     switch (opc) {
3631 #if defined(TARGET_MIPS64)
3632     case OPC_SD:
3633         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
3634                            ctx->default_tcg_memop_mask);
3635         break;
3636     case OPC_SDL:
3637         gen_helper_0e2i(sdl, t1, t0, mem_idx);
3638         break;
3639     case OPC_SDR:
3640         gen_helper_0e2i(sdr, t1, t0, mem_idx);
3641         break;
3642 #endif
3643     case OPC_SWE:
3644         mem_idx = MIPS_HFLAG_UM;
3645         /* fall through */
3646     case OPC_SW:
3647         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
3648                            ctx->default_tcg_memop_mask);
3649         break;
3650     case OPC_SHE:
3651         mem_idx = MIPS_HFLAG_UM;
3652         /* fall through */
3653     case OPC_SH:
3654         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
3655                            ctx->default_tcg_memop_mask);
3656         break;
3657     case OPC_SBE:
3658         mem_idx = MIPS_HFLAG_UM;
3659         /* fall through */
3660     case OPC_SB:
3661         tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
3662         break;
3663     case OPC_SWLE:
3664         mem_idx = MIPS_HFLAG_UM;
3665         /* fall through */
3666     case OPC_SWL:
3667         gen_helper_0e2i(swl, t1, t0, mem_idx);
3668         break;
3669     case OPC_SWRE:
3670         mem_idx = MIPS_HFLAG_UM;
3671         /* fall through */
3672     case OPC_SWR:
3673         gen_helper_0e2i(swr, t1, t0, mem_idx);
3674         break;
3675     }
3676     tcg_temp_free(t0);
3677     tcg_temp_free(t1);
3678 }
3679
3680
3681 /* Store conditional */
3682 static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
3683                          int base, int16_t offset)
3684 {
3685     TCGv t0, t1;
3686     int mem_idx = ctx->mem_idx;
3687
3688 #ifdef CONFIG_USER_ONLY
3689     t0 = tcg_temp_local_new();
3690     t1 = tcg_temp_local_new();
3691 #else
3692     t0 = tcg_temp_new();
3693     t1 = tcg_temp_new();
3694 #endif
3695     gen_base_offset_addr(ctx, t0, base, offset);
3696     gen_load_gpr(t1, rt);
3697     switch (opc) {
3698 #if defined(TARGET_MIPS64)
3699     case OPC_SCD:
3700     case R6_OPC_SCD:
3701         op_st_scd(t1, t0, rt, mem_idx, ctx);
3702         break;
3703 #endif
3704     case OPC_SCE:
3705         mem_idx = MIPS_HFLAG_UM;
3706         /* fall through */
3707     case OPC_SC:
3708     case R6_OPC_SC:
3709         op_st_sc(t1, t0, rt, mem_idx, ctx);
3710         break;
3711     }
3712     tcg_temp_free(t1);
3713     tcg_temp_free(t0);
3714 }
3715
3716 static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
3717                     uint32_t reg1, uint32_t reg2)
3718 {
3719     TCGv taddr = tcg_temp_local_new();
3720     TCGv lladdr = tcg_temp_local_new();
3721     TCGv_i64 tval = tcg_temp_new_i64();
3722     TCGv_i64 llval = tcg_temp_new_i64();
3723     TCGv_i64 val = tcg_temp_new_i64();
3724     TCGv tmp1 = tcg_temp_new();
3725     TCGv tmp2 = tcg_temp_new();
3726     TCGLabel *lab_fail = gen_new_label();
3727     TCGLabel *lab_done = gen_new_label();
3728
3729     gen_base_offset_addr(ctx, taddr, base, offset);
3730
3731     tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3732     tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
3733
3734     gen_load_gpr(tmp1, reg1);
3735     gen_load_gpr(tmp2, reg2);
3736
3737 #ifdef TARGET_WORDS_BIGENDIAN
3738     tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
3739 #else
3740     tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
3741 #endif
3742
3743     tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
3744     tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
3745                                ctx->mem_idx, MO_64);
3746     if (reg1 != 0) {
3747         tcg_gen_movi_tl(cpu_gpr[reg1], 1);
3748     }
3749     tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
3750
3751     gen_set_label(lab_fail);
3752
3753     if (reg1 != 0) {
3754         tcg_gen_movi_tl(cpu_gpr[reg1], 0);
3755     }
3756     gen_set_label(lab_done);
3757     tcg_gen_movi_tl(lladdr, -1);
3758     tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
3759 }
3760
3761 /* Load and store */
3762 static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
3763                           TCGv t0)
3764 {
3765     /* Don't do NOP if destination is zero: we must perform the actual
3766        memory access. */
3767     switch (opc) {
3768     case OPC_LWC1:
3769         {
3770             TCGv_i32 fp0 = tcg_temp_new_i32();
3771             tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
3772                                 ctx->default_tcg_memop_mask);
3773             gen_store_fpr32(ctx, fp0, ft);
3774             tcg_temp_free_i32(fp0);
3775         }
3776         break;
3777     case OPC_SWC1:
3778         {
3779             TCGv_i32 fp0 = tcg_temp_new_i32();
3780             gen_load_fpr32(ctx, fp0, ft);
3781             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
3782                                 ctx->default_tcg_memop_mask);
3783             tcg_temp_free_i32(fp0);
3784         }
3785         break;
3786     case OPC_LDC1:
3787         {
3788             TCGv_i64 fp0 = tcg_temp_new_i64();
3789             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3790                                 ctx->default_tcg_memop_mask);
3791             gen_store_fpr64(ctx, fp0, ft);
3792             tcg_temp_free_i64(fp0);
3793         }
3794         break;
3795     case OPC_SDC1:
3796         {
3797             TCGv_i64 fp0 = tcg_temp_new_i64();
3798             gen_load_fpr64(ctx, fp0, ft);
3799             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
3800                                 ctx->default_tcg_memop_mask);
3801             tcg_temp_free_i64(fp0);
3802         }
3803         break;
3804     default:
3805         MIPS_INVAL("flt_ldst");
3806         generate_exception_end(ctx, EXCP_RI);
3807         break;
3808     }
3809 }
3810
3811 static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
3812                           int rs, int16_t imm)
3813 {
3814     TCGv t0 = tcg_temp_new();
3815
3816     if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
3817         check_cp1_enabled(ctx);
3818         switch (op) {
3819         case OPC_LDC1:
3820         case OPC_SDC1:
3821             check_insn(ctx, ISA_MIPS2);
3822             /* Fallthrough */
3823         default:
3824             gen_base_offset_addr(ctx, t0, rs, imm);
3825             gen_flt_ldst(ctx, op, rt, t0);
3826         }
3827     } else {
3828         generate_exception_err(ctx, EXCP_CpU, 1);
3829     }
3830     tcg_temp_free(t0);
3831 }
3832
3833 /* Arithmetic with immediate operand */
3834 static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
3835                           int rt, int rs, int imm)
3836 {
3837     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3838
3839     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
3840         /* If no destination, treat it as a NOP.
3841            For addi, we must generate the overflow exception when needed. */
3842         return;
3843     }
3844     switch (opc) {
3845     case OPC_ADDI:
3846         {
3847             TCGv t0 = tcg_temp_local_new();
3848             TCGv t1 = tcg_temp_new();
3849             TCGv t2 = tcg_temp_new();
3850             TCGLabel *l1 = gen_new_label();
3851
3852             gen_load_gpr(t1, rs);
3853             tcg_gen_addi_tl(t0, t1, uimm);
3854             tcg_gen_ext32s_tl(t0, t0);
3855
3856             tcg_gen_xori_tl(t1, t1, ~uimm);
3857             tcg_gen_xori_tl(t2, t0, uimm);
3858             tcg_gen_and_tl(t1, t1, t2);
3859             tcg_temp_free(t2);
3860             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3861             tcg_temp_free(t1);
3862             /* operands of same sign, result different sign */
3863             generate_exception(ctx, EXCP_OVERFLOW);
3864             gen_set_label(l1);
3865             tcg_gen_ext32s_tl(t0, t0);
3866             gen_store_gpr(t0, rt);
3867             tcg_temp_free(t0);
3868         }
3869         break;
3870     case OPC_ADDIU:
3871         if (rs != 0) {
3872             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3873             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3874         } else {
3875             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3876         }
3877         break;
3878 #if defined(TARGET_MIPS64)
3879     case OPC_DADDI:
3880         {
3881             TCGv t0 = tcg_temp_local_new();
3882             TCGv t1 = tcg_temp_new();
3883             TCGv t2 = tcg_temp_new();
3884             TCGLabel *l1 = gen_new_label();
3885
3886             gen_load_gpr(t1, rs);
3887             tcg_gen_addi_tl(t0, t1, uimm);
3888
3889             tcg_gen_xori_tl(t1, t1, ~uimm);
3890             tcg_gen_xori_tl(t2, t0, uimm);
3891             tcg_gen_and_tl(t1, t1, t2);
3892             tcg_temp_free(t2);
3893             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
3894             tcg_temp_free(t1);
3895             /* operands of same sign, result different sign */
3896             generate_exception(ctx, EXCP_OVERFLOW);
3897             gen_set_label(l1);
3898             gen_store_gpr(t0, rt);
3899             tcg_temp_free(t0);
3900         }
3901         break;
3902     case OPC_DADDIU:
3903         if (rs != 0) {
3904             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3905         } else {
3906             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3907         }
3908         break;
3909 #endif
3910     }
3911 }
3912
3913 /* Logic with immediate operand */
3914 static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
3915                           int rt, int rs, int16_t imm)
3916 {
3917     target_ulong uimm;
3918
3919     if (rt == 0) {
3920         /* If no destination, treat it as a NOP. */
3921         return;
3922     }
3923     uimm = (uint16_t)imm;
3924     switch (opc) {
3925     case OPC_ANDI:
3926         if (likely(rs != 0))
3927             tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3928         else
3929             tcg_gen_movi_tl(cpu_gpr[rt], 0);
3930         break;
3931     case OPC_ORI:
3932         if (rs != 0)
3933             tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3934         else
3935             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3936         break;
3937     case OPC_XORI:
3938         if (likely(rs != 0))
3939             tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
3940         else
3941             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
3942         break;
3943     case OPC_LUI:
3944         if (rs != 0 && (ctx->insn_flags & ISA_MIPS32R6)) {
3945             /* OPC_AUI */
3946             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
3947             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
3948         } else {
3949             tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
3950         }
3951         break;
3952
3953     default:
3954         break;
3955     }
3956 }
3957
3958 /* Set on less than with immediate operand */
3959 static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
3960                         int rt, int rs, int16_t imm)
3961 {
3962     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
3963     TCGv t0;
3964
3965     if (rt == 0) {
3966         /* If no destination, treat it as a NOP. */
3967         return;
3968     }
3969     t0 = tcg_temp_new();
3970     gen_load_gpr(t0, rs);
3971     switch (opc) {
3972     case OPC_SLTI:
3973         tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
3974         break;
3975     case OPC_SLTIU:
3976         tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
3977         break;
3978     }
3979     tcg_temp_free(t0);
3980 }
3981
3982 /* Shifts with immediate operand */
3983 static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
3984                           int rt, int rs, int16_t imm)
3985 {
3986     target_ulong uimm = ((uint16_t)imm) & 0x1f;
3987     TCGv t0;
3988
3989     if (rt == 0) {
3990         /* If no destination, treat it as a NOP. */
3991         return;
3992     }
3993
3994     t0 = tcg_temp_new();
3995     gen_load_gpr(t0, rs);
3996     switch (opc) {
3997     case OPC_SLL:
3998         tcg_gen_shli_tl(t0, t0, uimm);
3999         tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4000         break;
4001     case OPC_SRA:
4002         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
4003         break;
4004     case OPC_SRL:
4005         if (uimm != 0) {
4006             tcg_gen_ext32u_tl(t0, t0);
4007             tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
4008         } else {
4009             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4010         }
4011         break;
4012     case OPC_ROTR:
4013         if (uimm != 0) {
4014             TCGv_i32 t1 = tcg_temp_new_i32();
4015
4016             tcg_gen_trunc_tl_i32(t1, t0);
4017             tcg_gen_rotri_i32(t1, t1, uimm);
4018             tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
4019             tcg_temp_free_i32(t1);
4020         } else {
4021             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
4022         }
4023         break;
4024 #if defined(TARGET_MIPS64)
4025     case OPC_DSLL:
4026         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
4027         break;
4028     case OPC_DSRA:
4029         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
4030         break;
4031     case OPC_DSRL:
4032         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
4033         break;
4034     case OPC_DROTR:
4035         if (uimm != 0) {
4036             tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
4037         } else {
4038             tcg_gen_mov_tl(cpu_gpr[rt], t0);
4039         }
4040         break;
4041     case OPC_DSLL32:
4042         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
4043         break;
4044     case OPC_DSRA32:
4045         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
4046         break;
4047     case OPC_DSRL32:
4048         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
4049         break;
4050     case OPC_DROTR32:
4051         tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
4052         break;
4053 #endif
4054     }
4055     tcg_temp_free(t0);
4056 }
4057
4058 /* Arithmetic */
4059 static void gen_arith(DisasContext *ctx, uint32_t opc,
4060                       int rd, int rs, int rt)
4061 {
4062     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
4063        && opc != OPC_DADD && opc != OPC_DSUB) {
4064         /* If no destination, treat it as a NOP.
4065            For add & sub, we must generate the overflow exception when needed. */
4066         return;
4067     }
4068
4069     switch (opc) {
4070     case OPC_ADD:
4071         {
4072             TCGv t0 = tcg_temp_local_new();
4073             TCGv t1 = tcg_temp_new();
4074             TCGv t2 = tcg_temp_new();
4075             TCGLabel *l1 = gen_new_label();
4076
4077             gen_load_gpr(t1, rs);
4078             gen_load_gpr(t2, rt);
4079             tcg_gen_add_tl(t0, t1, t2);
4080             tcg_gen_ext32s_tl(t0, t0);
4081             tcg_gen_xor_tl(t1, t1, t2);
4082             tcg_gen_xor_tl(t2, t0, t2);
4083             tcg_gen_andc_tl(t1, t2, t1);
4084             tcg_temp_free(t2);
4085             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4086             tcg_temp_free(t1);
4087             /* operands of same sign, result different sign */
4088             generate_exception(ctx, EXCP_OVERFLOW);
4089             gen_set_label(l1);
4090             gen_store_gpr(t0, rd);
4091             tcg_temp_free(t0);
4092         }
4093         break;
4094     case OPC_ADDU:
4095         if (rs != 0 && rt != 0) {
4096             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4097             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4098         } else if (rs == 0 && rt != 0) {
4099             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4100         } else if (rs != 0 && rt == 0) {
4101             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4102         } else {
4103             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4104         }
4105         break;
4106     case OPC_SUB:
4107         {
4108             TCGv t0 = tcg_temp_local_new();
4109             TCGv t1 = tcg_temp_new();
4110             TCGv t2 = tcg_temp_new();
4111             TCGLabel *l1 = gen_new_label();
4112
4113             gen_load_gpr(t1, rs);
4114             gen_load_gpr(t2, rt);
4115             tcg_gen_sub_tl(t0, t1, t2);
4116             tcg_gen_ext32s_tl(t0, t0);
4117             tcg_gen_xor_tl(t2, t1, t2);
4118             tcg_gen_xor_tl(t1, t0, t1);
4119             tcg_gen_and_tl(t1, t1, t2);
4120             tcg_temp_free(t2);
4121             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4122             tcg_temp_free(t1);
4123             /* operands of different sign, first operand and result different sign */
4124             generate_exception(ctx, EXCP_OVERFLOW);
4125             gen_set_label(l1);
4126             gen_store_gpr(t0, rd);
4127             tcg_temp_free(t0);
4128         }
4129         break;
4130     case OPC_SUBU:
4131         if (rs != 0 && rt != 0) {
4132             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4133             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4134         } else if (rs == 0 && rt != 0) {
4135             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4136             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4137         } else if (rs != 0 && rt == 0) {
4138             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4139         } else {
4140             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4141         }
4142         break;
4143 #if defined(TARGET_MIPS64)
4144     case OPC_DADD:
4145         {
4146             TCGv t0 = tcg_temp_local_new();
4147             TCGv t1 = tcg_temp_new();
4148             TCGv t2 = tcg_temp_new();
4149             TCGLabel *l1 = gen_new_label();
4150
4151             gen_load_gpr(t1, rs);
4152             gen_load_gpr(t2, rt);
4153             tcg_gen_add_tl(t0, t1, t2);
4154             tcg_gen_xor_tl(t1, t1, t2);
4155             tcg_gen_xor_tl(t2, t0, t2);
4156             tcg_gen_andc_tl(t1, t2, t1);
4157             tcg_temp_free(t2);
4158             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4159             tcg_temp_free(t1);
4160             /* operands of same sign, result different sign */
4161             generate_exception(ctx, EXCP_OVERFLOW);
4162             gen_set_label(l1);
4163             gen_store_gpr(t0, rd);
4164             tcg_temp_free(t0);
4165         }
4166         break;
4167     case OPC_DADDU:
4168         if (rs != 0 && rt != 0) {
4169             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4170         } else if (rs == 0 && rt != 0) {
4171             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4172         } else if (rs != 0 && rt == 0) {
4173             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4174         } else {
4175             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4176         }
4177         break;
4178     case OPC_DSUB:
4179         {
4180             TCGv t0 = tcg_temp_local_new();
4181             TCGv t1 = tcg_temp_new();
4182             TCGv t2 = tcg_temp_new();
4183             TCGLabel *l1 = gen_new_label();
4184
4185             gen_load_gpr(t1, rs);
4186             gen_load_gpr(t2, rt);
4187             tcg_gen_sub_tl(t0, t1, t2);
4188             tcg_gen_xor_tl(t2, t1, t2);
4189             tcg_gen_xor_tl(t1, t0, t1);
4190             tcg_gen_and_tl(t1, t1, t2);
4191             tcg_temp_free(t2);
4192             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
4193             tcg_temp_free(t1);
4194             /* operands of different sign, first operand and result different sign */
4195             generate_exception(ctx, EXCP_OVERFLOW);
4196             gen_set_label(l1);
4197             gen_store_gpr(t0, rd);
4198             tcg_temp_free(t0);
4199         }
4200         break;
4201     case OPC_DSUBU:
4202         if (rs != 0 && rt != 0) {
4203             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4204         } else if (rs == 0 && rt != 0) {
4205             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
4206         } else if (rs != 0 && rt == 0) {
4207             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4208         } else {
4209             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4210         }
4211         break;
4212 #endif
4213     case OPC_MUL:
4214         if (likely(rs != 0 && rt != 0)) {
4215             tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4216             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4217         } else {
4218             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4219         }
4220         break;
4221     }
4222 }
4223
4224 /* Conditional move */
4225 static void gen_cond_move(DisasContext *ctx, uint32_t opc,
4226                           int rd, int rs, int rt)
4227 {
4228     TCGv t0, t1, t2;
4229
4230     if (rd == 0) {
4231         /* If no destination, treat it as a NOP. */
4232         return;
4233     }
4234
4235     t0 = tcg_temp_new();
4236     gen_load_gpr(t0, rt);
4237     t1 = tcg_const_tl(0);
4238     t2 = tcg_temp_new();
4239     gen_load_gpr(t2, rs);
4240     switch (opc) {
4241     case OPC_MOVN:
4242         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4243         break;
4244     case OPC_MOVZ:
4245         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
4246         break;
4247     case OPC_SELNEZ:
4248         tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
4249         break;
4250     case OPC_SELEQZ:
4251         tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
4252         break;
4253     }
4254     tcg_temp_free(t2);
4255     tcg_temp_free(t1);
4256     tcg_temp_free(t0);
4257 }
4258
4259 /* Logic */
4260 static void gen_logic(DisasContext *ctx, uint32_t opc,
4261                       int rd, int rs, int rt)
4262 {
4263     if (rd == 0) {
4264         /* If no destination, treat it as a NOP. */
4265         return;
4266     }
4267
4268     switch (opc) {
4269     case OPC_AND:
4270         if (likely(rs != 0 && rt != 0)) {
4271             tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4272         } else {
4273             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4274         }
4275         break;
4276     case OPC_NOR:
4277         if (rs != 0 && rt != 0) {
4278             tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4279         } else if (rs == 0 && rt != 0) {
4280             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
4281         } else if (rs != 0 && rt == 0) {
4282             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
4283         } else {
4284             tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
4285         }
4286         break;
4287     case OPC_OR:
4288         if (likely(rs != 0 && rt != 0)) {
4289             tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4290         } else if (rs == 0 && rt != 0) {
4291             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4292         } else if (rs != 0 && rt == 0) {
4293             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4294         } else {
4295             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4296         }
4297         break;
4298     case OPC_XOR:
4299         if (likely(rs != 0 && rt != 0)) {
4300             tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
4301         } else if (rs == 0 && rt != 0) {
4302             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
4303         } else if (rs != 0 && rt == 0) {
4304             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
4305         } else {
4306             tcg_gen_movi_tl(cpu_gpr[rd], 0);
4307         }
4308         break;
4309     }
4310 }
4311
4312 /* Set on lower than */
4313 static void gen_slt(DisasContext *ctx, uint32_t opc,
4314                     int rd, int rs, int rt)
4315 {
4316     TCGv t0, t1;
4317
4318     if (rd == 0) {
4319         /* If no destination, treat it as a NOP. */
4320         return;
4321     }
4322
4323     t0 = tcg_temp_new();
4324     t1 = tcg_temp_new();
4325     gen_load_gpr(t0, rs);
4326     gen_load_gpr(t1, rt);
4327     switch (opc) {
4328     case OPC_SLT:
4329         tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
4330         break;
4331     case OPC_SLTU:
4332         tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
4333         break;
4334     }
4335     tcg_temp_free(t0);
4336     tcg_temp_free(t1);
4337 }
4338
4339 /* Shifts */
4340 static void gen_shift(DisasContext *ctx, uint32_t opc,
4341                       int rd, int rs, int rt)
4342 {
4343     TCGv t0, t1;
4344
4345     if (rd == 0) {
4346         /* If no destination, treat it as a NOP.
4347            For add & sub, we must generate the overflow exception when needed. */
4348         return;
4349     }
4350
4351     t0 = tcg_temp_new();
4352     t1 = tcg_temp_new();
4353     gen_load_gpr(t0, rs);
4354     gen_load_gpr(t1, rt);
4355     switch (opc) {
4356     case OPC_SLLV:
4357         tcg_gen_andi_tl(t0, t0, 0x1f);
4358         tcg_gen_shl_tl(t0, t1, t0);
4359         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4360         break;
4361     case OPC_SRAV:
4362         tcg_gen_andi_tl(t0, t0, 0x1f);
4363         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4364         break;
4365     case OPC_SRLV:
4366         tcg_gen_ext32u_tl(t1, t1);
4367         tcg_gen_andi_tl(t0, t0, 0x1f);
4368         tcg_gen_shr_tl(t0, t1, t0);
4369         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
4370         break;
4371     case OPC_ROTRV:
4372         {
4373             TCGv_i32 t2 = tcg_temp_new_i32();
4374             TCGv_i32 t3 = tcg_temp_new_i32();
4375
4376             tcg_gen_trunc_tl_i32(t2, t0);
4377             tcg_gen_trunc_tl_i32(t3, t1);
4378             tcg_gen_andi_i32(t2, t2, 0x1f);
4379             tcg_gen_rotr_i32(t2, t3, t2);
4380             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4381             tcg_temp_free_i32(t2);
4382             tcg_temp_free_i32(t3);
4383         }
4384         break;
4385 #if defined(TARGET_MIPS64)
4386     case OPC_DSLLV:
4387         tcg_gen_andi_tl(t0, t0, 0x3f);
4388         tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
4389         break;
4390     case OPC_DSRAV:
4391         tcg_gen_andi_tl(t0, t0, 0x3f);
4392         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
4393         break;
4394     case OPC_DSRLV:
4395         tcg_gen_andi_tl(t0, t0, 0x3f);
4396         tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
4397         break;
4398     case OPC_DROTRV:
4399         tcg_gen_andi_tl(t0, t0, 0x3f);
4400         tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
4401         break;
4402 #endif
4403     }
4404     tcg_temp_free(t0);
4405     tcg_temp_free(t1);
4406 }
4407
4408 /* Copy GPR to and from TX79 HI1/LO1 register. */
4409 static void gen_HILO1_tx79(DisasContext *ctx, uint32_t opc, int reg)
4410 {
4411     if (reg == 0 && (opc == MMI_OPC_MFHI1 || opc == MMI_OPC_MFLO1)) {
4412         /* Treat as NOP. */
4413         return;
4414     }
4415
4416     switch (opc) {
4417     case MMI_OPC_MFHI1:
4418         tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[1]);
4419         break;
4420     case MMI_OPC_MFLO1:
4421         tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[1]);
4422         break;
4423     case MMI_OPC_MTHI1:
4424         if (reg != 0) {
4425             tcg_gen_mov_tl(cpu_HI[1], cpu_gpr[reg]);
4426         } else {
4427             tcg_gen_movi_tl(cpu_HI[1], 0);
4428         }
4429         break;
4430     case MMI_OPC_MTLO1:
4431         if (reg != 0) {
4432             tcg_gen_mov_tl(cpu_LO[1], cpu_gpr[reg]);
4433         } else {
4434             tcg_gen_movi_tl(cpu_LO[1], 0);
4435         }
4436         break;
4437     default:
4438         MIPS_INVAL("mfthilo1 TX79");
4439         generate_exception_end(ctx, EXCP_RI);
4440         break;
4441     }
4442 }
4443
4444 /* Arithmetic on HI/LO registers */
4445 static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
4446 {
4447     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
4448         /* Treat as NOP. */
4449         return;
4450     }
4451
4452     if (acc != 0) {
4453         check_dsp(ctx);
4454     }
4455
4456     switch (opc) {
4457     case OPC_MFHI:
4458 #if defined(TARGET_MIPS64)
4459         if (acc != 0) {
4460             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
4461         } else
4462 #endif
4463         {
4464             tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
4465         }
4466         break;
4467     case OPC_MFLO:
4468 #if defined(TARGET_MIPS64)
4469         if (acc != 0) {
4470             tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
4471         } else
4472 #endif
4473         {
4474             tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
4475         }
4476         break;
4477     case OPC_MTHI:
4478         if (reg != 0) {
4479 #if defined(TARGET_MIPS64)
4480             if (acc != 0) {
4481                 tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
4482             } else
4483 #endif
4484             {
4485                 tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
4486             }
4487         } else {
4488             tcg_gen_movi_tl(cpu_HI[acc], 0);
4489         }
4490         break;
4491     case OPC_MTLO:
4492         if (reg != 0) {
4493 #if defined(TARGET_MIPS64)
4494             if (acc != 0) {
4495                 tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
4496             } else
4497 #endif
4498             {
4499                 tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
4500             }
4501         } else {
4502             tcg_gen_movi_tl(cpu_LO[acc], 0);
4503         }
4504         break;
4505     }
4506 }
4507
4508 static inline void gen_r6_ld(target_long addr, int reg, int memidx,
4509                              TCGMemOp memop)
4510 {
4511     TCGv t0 = tcg_const_tl(addr);
4512     tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
4513     gen_store_gpr(t0, reg);
4514     tcg_temp_free(t0);
4515 }
4516
4517 static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
4518                              int rs)
4519 {
4520     target_long offset;
4521     target_long addr;
4522
4523     switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
4524     case OPC_ADDIUPC:
4525         if (rs != 0) {
4526             offset = sextract32(ctx->opcode << 2, 0, 21);
4527             addr = addr_add(ctx, pc, offset);
4528             tcg_gen_movi_tl(cpu_gpr[rs], addr);
4529         }
4530         break;
4531     case R6_OPC_LWPC:
4532         offset = sextract32(ctx->opcode << 2, 0, 21);
4533         addr = addr_add(ctx, pc, offset);
4534         gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
4535         break;
4536 #if defined(TARGET_MIPS64)
4537     case OPC_LWUPC:
4538         check_mips_64(ctx);
4539         offset = sextract32(ctx->opcode << 2, 0, 21);
4540         addr = addr_add(ctx, pc, offset);
4541         gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
4542         break;
4543 #endif
4544     default:
4545         switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
4546         case OPC_AUIPC:
4547             if (rs != 0) {
4548                 offset = sextract32(ctx->opcode, 0, 16) << 16;
4549                 addr = addr_add(ctx, pc, offset);
4550                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4551             }
4552             break;
4553         case OPC_ALUIPC:
4554             if (rs != 0) {
4555                 offset = sextract32(ctx->opcode, 0, 16) << 16;
4556                 addr = ~0xFFFF & addr_add(ctx, pc, offset);
4557                 tcg_gen_movi_tl(cpu_gpr[rs], addr);
4558             }
4559             break;
4560 #if defined(TARGET_MIPS64)
4561         case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
4562         case R6_OPC_LDPC + (1 << 16):
4563         case R6_OPC_LDPC + (2 << 16):
4564         case R6_OPC_LDPC + (3 << 16):
4565             check_mips_64(ctx);
4566             offset = sextract32(ctx->opcode << 3, 0, 21);
4567             addr = addr_add(ctx, (pc & ~0x7), offset);
4568             gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
4569             break;
4570 #endif
4571         default:
4572             MIPS_INVAL("OPC_PCREL");
4573             generate_exception_end(ctx, EXCP_RI);
4574             break;
4575         }
4576         break;
4577     }
4578 }
4579
4580 static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
4581 {
4582     TCGv t0, t1;
4583
4584     if (rd == 0) {
4585         /* Treat as NOP. */
4586         return;
4587     }
4588
4589     t0 = tcg_temp_new();
4590     t1 = tcg_temp_new();
4591
4592     gen_load_gpr(t0, rs);
4593     gen_load_gpr(t1, rt);
4594
4595     switch (opc) {
4596     case R6_OPC_DIV:
4597         {
4598             TCGv t2 = tcg_temp_new();
4599             TCGv t3 = tcg_temp_new();
4600             tcg_gen_ext32s_tl(t0, t0);
4601             tcg_gen_ext32s_tl(t1, t1);
4602             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4603             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4604             tcg_gen_and_tl(t2, t2, t3);
4605             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4606             tcg_gen_or_tl(t2, t2, t3);
4607             tcg_gen_movi_tl(t3, 0);
4608             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4609             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4610             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4611             tcg_temp_free(t3);
4612             tcg_temp_free(t2);
4613         }
4614         break;
4615     case R6_OPC_MOD:
4616         {
4617             TCGv t2 = tcg_temp_new();
4618             TCGv t3 = tcg_temp_new();
4619             tcg_gen_ext32s_tl(t0, t0);
4620             tcg_gen_ext32s_tl(t1, t1);
4621             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4622             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4623             tcg_gen_and_tl(t2, t2, t3);
4624             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4625             tcg_gen_or_tl(t2, t2, t3);
4626             tcg_gen_movi_tl(t3, 0);
4627             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4628             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4629             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4630             tcg_temp_free(t3);
4631             tcg_temp_free(t2);
4632         }
4633         break;
4634     case R6_OPC_DIVU:
4635         {
4636             TCGv t2 = tcg_const_tl(0);
4637             TCGv t3 = tcg_const_tl(1);
4638             tcg_gen_ext32u_tl(t0, t0);
4639             tcg_gen_ext32u_tl(t1, t1);
4640             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4641             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4642             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4643             tcg_temp_free(t3);
4644             tcg_temp_free(t2);
4645         }
4646         break;
4647     case R6_OPC_MODU:
4648         {
4649             TCGv t2 = tcg_const_tl(0);
4650             TCGv t3 = tcg_const_tl(1);
4651             tcg_gen_ext32u_tl(t0, t0);
4652             tcg_gen_ext32u_tl(t1, t1);
4653             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4654             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4655             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4656             tcg_temp_free(t3);
4657             tcg_temp_free(t2);
4658         }
4659         break;
4660     case R6_OPC_MUL:
4661         {
4662             TCGv_i32 t2 = tcg_temp_new_i32();
4663             TCGv_i32 t3 = tcg_temp_new_i32();
4664             tcg_gen_trunc_tl_i32(t2, t0);
4665             tcg_gen_trunc_tl_i32(t3, t1);
4666             tcg_gen_mul_i32(t2, t2, t3);
4667             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4668             tcg_temp_free_i32(t2);
4669             tcg_temp_free_i32(t3);
4670         }
4671         break;
4672     case R6_OPC_MUH:
4673         {
4674             TCGv_i32 t2 = tcg_temp_new_i32();
4675             TCGv_i32 t3 = tcg_temp_new_i32();
4676             tcg_gen_trunc_tl_i32(t2, t0);
4677             tcg_gen_trunc_tl_i32(t3, t1);
4678             tcg_gen_muls2_i32(t2, t3, t2, t3);
4679             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4680             tcg_temp_free_i32(t2);
4681             tcg_temp_free_i32(t3);
4682         }
4683         break;
4684     case R6_OPC_MULU:
4685         {
4686             TCGv_i32 t2 = tcg_temp_new_i32();
4687             TCGv_i32 t3 = tcg_temp_new_i32();
4688             tcg_gen_trunc_tl_i32(t2, t0);
4689             tcg_gen_trunc_tl_i32(t3, t1);
4690             tcg_gen_mul_i32(t2, t2, t3);
4691             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
4692             tcg_temp_free_i32(t2);
4693             tcg_temp_free_i32(t3);
4694         }
4695         break;
4696     case R6_OPC_MUHU:
4697         {
4698             TCGv_i32 t2 = tcg_temp_new_i32();
4699             TCGv_i32 t3 = tcg_temp_new_i32();
4700             tcg_gen_trunc_tl_i32(t2, t0);
4701             tcg_gen_trunc_tl_i32(t3, t1);
4702             tcg_gen_mulu2_i32(t2, t3, t2, t3);
4703             tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
4704             tcg_temp_free_i32(t2);
4705             tcg_temp_free_i32(t3);
4706         }
4707         break;
4708 #if defined(TARGET_MIPS64)
4709     case R6_OPC_DDIV:
4710         {
4711             TCGv t2 = tcg_temp_new();
4712             TCGv t3 = tcg_temp_new();
4713             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4714             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4715             tcg_gen_and_tl(t2, t2, t3);
4716             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4717             tcg_gen_or_tl(t2, t2, t3);
4718             tcg_gen_movi_tl(t3, 0);
4719             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4720             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4721             tcg_temp_free(t3);
4722             tcg_temp_free(t2);
4723         }
4724         break;
4725     case R6_OPC_DMOD:
4726         {
4727             TCGv t2 = tcg_temp_new();
4728             TCGv t3 = tcg_temp_new();
4729             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4730             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4731             tcg_gen_and_tl(t2, t2, t3);
4732             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4733             tcg_gen_or_tl(t2, t2, t3);
4734             tcg_gen_movi_tl(t3, 0);
4735             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4736             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4737             tcg_temp_free(t3);
4738             tcg_temp_free(t2);
4739         }
4740         break;
4741     case R6_OPC_DDIVU:
4742         {
4743             TCGv t2 = tcg_const_tl(0);
4744             TCGv t3 = tcg_const_tl(1);
4745             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4746             tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
4747             tcg_temp_free(t3);
4748             tcg_temp_free(t2);
4749         }
4750         break;
4751     case R6_OPC_DMODU:
4752         {
4753             TCGv t2 = tcg_const_tl(0);
4754             TCGv t3 = tcg_const_tl(1);
4755             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4756             tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
4757             tcg_temp_free(t3);
4758             tcg_temp_free(t2);
4759         }
4760         break;
4761     case R6_OPC_DMUL:
4762         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4763         break;
4764     case R6_OPC_DMUH:
4765         {
4766             TCGv t2 = tcg_temp_new();
4767             tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
4768             tcg_temp_free(t2);
4769         }
4770         break;
4771     case R6_OPC_DMULU:
4772         tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
4773         break;
4774     case R6_OPC_DMUHU:
4775         {
4776             TCGv t2 = tcg_temp_new();
4777             tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
4778             tcg_temp_free(t2);
4779         }
4780         break;
4781 #endif
4782     default:
4783         MIPS_INVAL("r6 mul/div");
4784         generate_exception_end(ctx, EXCP_RI);
4785         goto out;
4786     }
4787  out:
4788     tcg_temp_free(t0);
4789     tcg_temp_free(t1);
4790 }
4791
4792 static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
4793 {
4794     TCGv t0, t1;
4795
4796     t0 = tcg_temp_new();
4797     t1 = tcg_temp_new();
4798
4799     gen_load_gpr(t0, rs);
4800     gen_load_gpr(t1, rt);
4801
4802     switch (opc) {
4803     case MMI_OPC_DIV1:
4804         {
4805             TCGv t2 = tcg_temp_new();
4806             TCGv t3 = tcg_temp_new();
4807             tcg_gen_ext32s_tl(t0, t0);
4808             tcg_gen_ext32s_tl(t1, t1);
4809             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4810             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4811             tcg_gen_and_tl(t2, t2, t3);
4812             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4813             tcg_gen_or_tl(t2, t2, t3);
4814             tcg_gen_movi_tl(t3, 0);
4815             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4816             tcg_gen_div_tl(cpu_LO[1], t0, t1);
4817             tcg_gen_rem_tl(cpu_HI[1], t0, t1);
4818             tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4819             tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4820             tcg_temp_free(t3);
4821             tcg_temp_free(t2);
4822         }
4823         break;
4824     case MMI_OPC_DIVU1:
4825         {
4826             TCGv t2 = tcg_const_tl(0);
4827             TCGv t3 = tcg_const_tl(1);
4828             tcg_gen_ext32u_tl(t0, t0);
4829             tcg_gen_ext32u_tl(t1, t1);
4830             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4831             tcg_gen_divu_tl(cpu_LO[1], t0, t1);
4832             tcg_gen_remu_tl(cpu_HI[1], t0, t1);
4833             tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
4834             tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
4835             tcg_temp_free(t3);
4836             tcg_temp_free(t2);
4837         }
4838         break;
4839     default:
4840         MIPS_INVAL("div1 TX79");
4841         generate_exception_end(ctx, EXCP_RI);
4842         goto out;
4843     }
4844  out:
4845     tcg_temp_free(t0);
4846     tcg_temp_free(t1);
4847 }
4848
4849 static void gen_muldiv(DisasContext *ctx, uint32_t opc,
4850                        int acc, int rs, int rt)
4851 {
4852     TCGv t0, t1;
4853
4854     t0 = tcg_temp_new();
4855     t1 = tcg_temp_new();
4856
4857     gen_load_gpr(t0, rs);
4858     gen_load_gpr(t1, rt);
4859
4860     if (acc != 0) {
4861         check_dsp(ctx);
4862     }
4863
4864     switch (opc) {
4865     case OPC_DIV:
4866         {
4867             TCGv t2 = tcg_temp_new();
4868             TCGv t3 = tcg_temp_new();
4869             tcg_gen_ext32s_tl(t0, t0);
4870             tcg_gen_ext32s_tl(t1, t1);
4871             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
4872             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
4873             tcg_gen_and_tl(t2, t2, t3);
4874             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4875             tcg_gen_or_tl(t2, t2, t3);
4876             tcg_gen_movi_tl(t3, 0);
4877             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4878             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4879             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4880             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4881             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4882             tcg_temp_free(t3);
4883             tcg_temp_free(t2);
4884         }
4885         break;
4886     case OPC_DIVU:
4887         {
4888             TCGv t2 = tcg_const_tl(0);
4889             TCGv t3 = tcg_const_tl(1);
4890             tcg_gen_ext32u_tl(t0, t0);
4891             tcg_gen_ext32u_tl(t1, t1);
4892             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4893             tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
4894             tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
4895             tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
4896             tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
4897             tcg_temp_free(t3);
4898             tcg_temp_free(t2);
4899         }
4900         break;
4901     case OPC_MULT:
4902         {
4903             TCGv_i32 t2 = tcg_temp_new_i32();
4904             TCGv_i32 t3 = tcg_temp_new_i32();
4905             tcg_gen_trunc_tl_i32(t2, t0);
4906             tcg_gen_trunc_tl_i32(t3, t1);
4907             tcg_gen_muls2_i32(t2, t3, t2, t3);
4908             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4909             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4910             tcg_temp_free_i32(t2);
4911             tcg_temp_free_i32(t3);
4912         }
4913         break;
4914     case OPC_MULTU:
4915         {
4916             TCGv_i32 t2 = tcg_temp_new_i32();
4917             TCGv_i32 t3 = tcg_temp_new_i32();
4918             tcg_gen_trunc_tl_i32(t2, t0);
4919             tcg_gen_trunc_tl_i32(t3, t1);
4920             tcg_gen_mulu2_i32(t2, t3, t2, t3);
4921             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
4922             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
4923             tcg_temp_free_i32(t2);
4924             tcg_temp_free_i32(t3);
4925         }
4926         break;
4927 #if defined(TARGET_MIPS64)
4928     case OPC_DDIV:
4929         {
4930             TCGv t2 = tcg_temp_new();
4931             TCGv t3 = tcg_temp_new();
4932             tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
4933             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
4934             tcg_gen_and_tl(t2, t2, t3);
4935             tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
4936             tcg_gen_or_tl(t2, t2, t3);
4937             tcg_gen_movi_tl(t3, 0);
4938             tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
4939             tcg_gen_div_tl(cpu_LO[acc], t0, t1);
4940             tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
4941             tcg_temp_free(t3);
4942             tcg_temp_free(t2);
4943         }
4944         break;
4945     case OPC_DDIVU:
4946         {
4947             TCGv t2 = tcg_const_tl(0);
4948             TCGv t3 = tcg_const_tl(1);
4949             tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
4950             tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
4951             tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
4952             tcg_temp_free(t3);
4953             tcg_temp_free(t2);
4954         }
4955         break;
4956     case OPC_DMULT:
4957         tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4958         break;
4959     case OPC_DMULTU:
4960         tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
4961         break;
4962 #endif
4963     case OPC_MADD:
4964         {
4965             TCGv_i64 t2 = tcg_temp_new_i64();
4966             TCGv_i64 t3 = tcg_temp_new_i64();
4967
4968             tcg_gen_ext_tl_i64(t2, t0);
4969             tcg_gen_ext_tl_i64(t3, t1);
4970             tcg_gen_mul_i64(t2, t2, t3);
4971             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4972             tcg_gen_add_i64(t2, t2, t3);
4973             tcg_temp_free_i64(t3);
4974             gen_move_low32(cpu_LO[acc], t2);
4975             gen_move_high32(cpu_HI[acc], t2);
4976             tcg_temp_free_i64(t2);
4977         }
4978         break;
4979     case OPC_MADDU:
4980         {
4981             TCGv_i64 t2 = tcg_temp_new_i64();
4982             TCGv_i64 t3 = tcg_temp_new_i64();
4983
4984             tcg_gen_ext32u_tl(t0, t0);
4985             tcg_gen_ext32u_tl(t1, t1);
4986             tcg_gen_extu_tl_i64(t2, t0);
4987             tcg_gen_extu_tl_i64(t3, t1);
4988             tcg_gen_mul_i64(t2, t2, t3);
4989             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
4990             tcg_gen_add_i64(t2, t2, t3);
4991             tcg_temp_free_i64(t3);
4992             gen_move_low32(cpu_LO[acc], t2);
4993             gen_move_high32(cpu_HI[acc], t2);
4994             tcg_temp_free_i64(t2);
4995         }
4996         break;
4997     case OPC_MSUB:
4998         {
4999             TCGv_i64 t2 = tcg_temp_new_i64();
5000             TCGv_i64 t3 = tcg_temp_new_i64();
5001
5002             tcg_gen_ext_tl_i64(t2, t0);
5003             tcg_gen_ext_tl_i64(t3, t1);
5004             tcg_gen_mul_i64(t2, t2, t3);
5005             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5006             tcg_gen_sub_i64(t2, t3, t2);
5007             tcg_temp_free_i64(t3);
5008             gen_move_low32(cpu_LO[acc], t2);
5009             gen_move_high32(cpu_HI[acc], t2);
5010             tcg_temp_free_i64(t2);
5011         }
5012         break;
5013     case OPC_MSUBU:
5014         {
5015             TCGv_i64 t2 = tcg_temp_new_i64();
5016             TCGv_i64 t3 = tcg_temp_new_i64();
5017
5018             tcg_gen_ext32u_tl(t0, t0);
5019             tcg_gen_ext32u_tl(t1, t1);
5020             tcg_gen_extu_tl_i64(t2, t0);
5021             tcg_gen_extu_tl_i64(t3, t1);
5022             tcg_gen_mul_i64(t2, t2, t3);
5023             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5024             tcg_gen_sub_i64(t2, t3, t2);
5025             tcg_temp_free_i64(t3);
5026             gen_move_low32(cpu_LO[acc], t2);
5027             gen_move_high32(cpu_HI[acc], t2);
5028             tcg_temp_free_i64(t2);
5029         }
5030         break;
5031     default:
5032         MIPS_INVAL("mul/div");
5033         generate_exception_end(ctx, EXCP_RI);
5034         goto out;
5035     }
5036  out:
5037     tcg_temp_free(t0);
5038     tcg_temp_free(t1);
5039 }
5040
5041 /*
5042  * These MULT[U] and MADD[U] instructions implemented in for example
5043  * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
5044  * architectures are special three-operand variants with the syntax
5045  *
5046  *     MULT[U][1] rd, rs, rt
5047  *
5048  * such that
5049  *
5050  *     (rd, LO, HI) <- rs * rt
5051  *
5052  * and
5053  *
5054  *     MADD[U][1] rd, rs, rt
5055  *
5056  * such that
5057  *
5058  *     (rd, LO, HI) <- (LO, HI) + rs * rt
5059  *
5060  * where the low-order 32-bits of the result is placed into both the
5061  * GPR rd and the special register LO. The high-order 32-bits of the
5062  * result is placed into the special register HI.
5063  *
5064  * If the GPR rd is omitted in assembly language, it is taken to be 0,
5065  * which is the zero register that always reads as 0.
5066  */
5067 static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
5068                          int rd, int rs, int rt)
5069 {
5070     TCGv t0 = tcg_temp_new();
5071     TCGv t1 = tcg_temp_new();
5072     int acc = 0;
5073
5074     gen_load_gpr(t0, rs);
5075     gen_load_gpr(t1, rt);
5076
5077     switch (opc) {
5078     case MMI_OPC_MULT1:
5079         acc = 1;
5080         /* Fall through */
5081     case OPC_MULT:
5082         {
5083             TCGv_i32 t2 = tcg_temp_new_i32();
5084             TCGv_i32 t3 = tcg_temp_new_i32();
5085             tcg_gen_trunc_tl_i32(t2, t0);
5086             tcg_gen_trunc_tl_i32(t3, t1);
5087             tcg_gen_muls2_i32(t2, t3, t2, t3);
5088             if (rd) {
5089                 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5090             }
5091             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5092             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5093             tcg_temp_free_i32(t2);
5094             tcg_temp_free_i32(t3);
5095         }
5096         break;
5097     case MMI_OPC_MULTU1:
5098         acc = 1;
5099         /* Fall through */
5100     case OPC_MULTU:
5101         {
5102             TCGv_i32 t2 = tcg_temp_new_i32();
5103             TCGv_i32 t3 = tcg_temp_new_i32();
5104             tcg_gen_trunc_tl_i32(t2, t0);
5105             tcg_gen_trunc_tl_i32(t3, t1);
5106             tcg_gen_mulu2_i32(t2, t3, t2, t3);
5107             if (rd) {
5108                 tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
5109             }
5110             tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
5111             tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
5112             tcg_temp_free_i32(t2);
5113             tcg_temp_free_i32(t3);
5114         }
5115         break;
5116     case MMI_OPC_MADD1:
5117         acc = 1;
5118         /* Fall through */
5119     case MMI_OPC_MADD:
5120         {
5121             TCGv_i64 t2 = tcg_temp_new_i64();
5122             TCGv_i64 t3 = tcg_temp_new_i64();
5123
5124             tcg_gen_ext_tl_i64(t2, t0);
5125             tcg_gen_ext_tl_i64(t3, t1);
5126             tcg_gen_mul_i64(t2, t2, t3);
5127             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5128             tcg_gen_add_i64(t2, t2, t3);
5129             tcg_temp_free_i64(t3);
5130             gen_move_low32(cpu_LO[acc], t2);
5131             gen_move_high32(cpu_HI[acc], t2);
5132             if (rd) {
5133                 gen_move_low32(cpu_gpr[rd], t2);
5134             }
5135             tcg_temp_free_i64(t2);
5136         }
5137         break;
5138     case MMI_OPC_MADDU1:
5139         acc = 1;
5140         /* Fall through */
5141     case MMI_OPC_MADDU:
5142         {
5143             TCGv_i64 t2 = tcg_temp_new_i64();
5144             TCGv_i64 t3 = tcg_temp_new_i64();
5145
5146             tcg_gen_ext32u_tl(t0, t0);
5147             tcg_gen_ext32u_tl(t1, t1);
5148             tcg_gen_extu_tl_i64(t2, t0);
5149             tcg_gen_extu_tl_i64(t3, t1);
5150             tcg_gen_mul_i64(t2, t2, t3);
5151             tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
5152             tcg_gen_add_i64(t2, t2, t3);
5153             tcg_temp_free_i64(t3);
5154             gen_move_low32(cpu_LO[acc], t2);
5155             gen_move_high32(cpu_HI[acc], t2);
5156             if (rd) {
5157                 gen_move_low32(cpu_gpr[rd], t2);
5158             }
5159             tcg_temp_free_i64(t2);
5160         }
5161         break;
5162     default:
5163         MIPS_INVAL("mul/madd TXx9");
5164         generate_exception_end(ctx, EXCP_RI);
5165         goto out;
5166     }
5167
5168  out:
5169     tcg_temp_free(t0);
5170     tcg_temp_free(t1);
5171 }
5172
5173 static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
5174                             int rd, int rs, int rt)
5175 {
5176     TCGv t0 = tcg_temp_new();
5177     TCGv t1 = tcg_temp_new();
5178
5179     gen_load_gpr(t0, rs);
5180     gen_load_gpr(t1, rt);
5181
5182     switch (opc) {
5183     case OPC_VR54XX_MULS:
5184         gen_helper_muls(t0, cpu_env, t0, t1);
5185         break;
5186     case OPC_VR54XX_MULSU:
5187         gen_helper_mulsu(t0, cpu_env, t0, t1);
5188         break;
5189     case OPC_VR54XX_MACC:
5190         gen_helper_macc(t0, cpu_env, t0, t1);
5191         break;
5192     case OPC_VR54XX_MACCU:
5193         gen_helper_maccu(t0, cpu_env, t0, t1);
5194         break;
5195     case OPC_VR54XX_MSAC:
5196         gen_helper_msac(t0, cpu_env, t0, t1);
5197         break;
5198     case OPC_VR54XX_MSACU:
5199         gen_helper_msacu(t0, cpu_env, t0, t1);
5200         break;
5201     case OPC_VR54XX_MULHI:
5202         gen_helper_mulhi(t0, cpu_env, t0, t1);
5203         break;
5204     case OPC_VR54XX_MULHIU:
5205         gen_helper_mulhiu(t0, cpu_env, t0, t1);
5206         break;
5207     case OPC_VR54XX_MULSHI:
5208         gen_helper_mulshi(t0, cpu_env, t0, t1);
5209         break;
5210     case OPC_VR54XX_MULSHIU:
5211         gen_helper_mulshiu(t0, cpu_env, t0, t1);
5212         break;
5213     case OPC_VR54XX_MACCHI:
5214         gen_helper_macchi(t0, cpu_env, t0, t1);
5215         break;
5216     case OPC_VR54XX_MACCHIU:
5217         gen_helper_macchiu(t0, cpu_env, t0, t1);
5218         break;
5219     case OPC_VR54XX_MSACHI:
5220         gen_helper_msachi(t0, cpu_env, t0, t1);
5221         break;
5222     case OPC_VR54XX_MSACHIU:
5223         gen_helper_msachiu(t0, cpu_env, t0, t1);
5224         break;
5225     default:
5226         MIPS_INVAL("mul vr54xx");
5227         generate_exception_end(ctx, EXCP_RI);
5228         goto out;
5229     }
5230     gen_store_gpr(t0, rd);
5231
5232  out:
5233     tcg_temp_free(t0);
5234     tcg_temp_free(t1);
5235 }
5236
5237 static void gen_cl (DisasContext *ctx, uint32_t opc,
5238                     int rd, int rs)
5239 {
5240     TCGv t0;
5241
5242     if (rd == 0) {
5243         /* Treat as NOP. */
5244         return;
5245     }
5246     t0 = cpu_gpr[rd];
5247     gen_load_gpr(t0, rs);
5248
5249     switch (opc) {
5250     case OPC_CLO:
5251     case R6_OPC_CLO:
5252 #if defined(TARGET_MIPS64)
5253     case OPC_DCLO:
5254     case R6_OPC_DCLO:
5255 #endif
5256         tcg_gen_not_tl(t0, t0);
5257         break;
5258     }
5259
5260     switch (opc) {
5261     case OPC_CLO:
5262     case R6_OPC_CLO:
5263     case OPC_CLZ:
5264     case R6_OPC_CLZ:
5265         tcg_gen_ext32u_tl(t0, t0);
5266         tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
5267         tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
5268         break;
5269 #if defined(TARGET_MIPS64)
5270     case OPC_DCLO:
5271     case R6_OPC_DCLO:
5272     case OPC_DCLZ:
5273     case R6_OPC_DCLZ:
5274         tcg_gen_clzi_i64(t0, t0, 64);
5275         break;
5276 #endif
5277     }
5278 }
5279
5280 /* Godson integer instructions */
5281 static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
5282                                  int rd, int rs, int rt)
5283 {
5284     TCGv t0, t1;
5285
5286     if (rd == 0) {
5287         /* Treat as NOP. */
5288         return;
5289     }
5290
5291     switch (opc) {
5292     case OPC_MULT_G_2E:
5293     case OPC_MULT_G_2F:
5294     case OPC_MULTU_G_2E:
5295     case OPC_MULTU_G_2F:
5296 #if defined(TARGET_MIPS64)
5297     case OPC_DMULT_G_2E:
5298     case OPC_DMULT_G_2F:
5299     case OPC_DMULTU_G_2E:
5300     case OPC_DMULTU_G_2F:
5301 #endif
5302         t0 = tcg_temp_new();
5303         t1 = tcg_temp_new();
5304         break;
5305     default:
5306         t0 = tcg_temp_local_new();
5307         t1 = tcg_temp_local_new();
5308         break;
5309     }
5310
5311     gen_load_gpr(t0, rs);
5312     gen_load_gpr(t1, rt);
5313
5314     switch (opc) {
5315     case OPC_MULT_G_2E:
5316     case OPC_MULT_G_2F:
5317         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5318         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5319         break;
5320     case OPC_MULTU_G_2E:
5321     case OPC_MULTU_G_2F:
5322         tcg_gen_ext32u_tl(t0, t0);
5323         tcg_gen_ext32u_tl(t1, t1);
5324         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5325         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5326         break;
5327     case OPC_DIV_G_2E:
5328     case OPC_DIV_G_2F:
5329         {
5330             TCGLabel *l1 = gen_new_label();
5331             TCGLabel *l2 = gen_new_label();
5332             TCGLabel *l3 = gen_new_label();
5333             tcg_gen_ext32s_tl(t0, t0);
5334             tcg_gen_ext32s_tl(t1, t1);
5335             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5336             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5337             tcg_gen_br(l3);
5338             gen_set_label(l1);
5339             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5340             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5341             tcg_gen_mov_tl(cpu_gpr[rd], t0);
5342             tcg_gen_br(l3);
5343             gen_set_label(l2);
5344             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5345             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5346             gen_set_label(l3);
5347         }
5348         break;
5349     case OPC_DIVU_G_2E:
5350     case OPC_DIVU_G_2F:
5351         {
5352             TCGLabel *l1 = gen_new_label();
5353             TCGLabel *l2 = gen_new_label();
5354             tcg_gen_ext32u_tl(t0, t0);
5355             tcg_gen_ext32u_tl(t1, t1);
5356             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5357             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5358             tcg_gen_br(l2);
5359             gen_set_label(l1);
5360             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5361             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5362             gen_set_label(l2);
5363         }
5364         break;
5365     case OPC_MOD_G_2E:
5366     case OPC_MOD_G_2F:
5367         {
5368             TCGLabel *l1 = gen_new_label();
5369             TCGLabel *l2 = gen_new_label();
5370             TCGLabel *l3 = gen_new_label();
5371             tcg_gen_ext32u_tl(t0, t0);
5372             tcg_gen_ext32u_tl(t1, t1);
5373             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5374             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
5375             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
5376             gen_set_label(l1);
5377             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5378             tcg_gen_br(l3);
5379             gen_set_label(l2);
5380             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5381             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5382             gen_set_label(l3);
5383         }
5384         break;
5385     case OPC_MODU_G_2E:
5386     case OPC_MODU_G_2F:
5387         {
5388             TCGLabel *l1 = gen_new_label();
5389             TCGLabel *l2 = gen_new_label();
5390             tcg_gen_ext32u_tl(t0, t0);
5391             tcg_gen_ext32u_tl(t1, t1);
5392             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5393             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5394             tcg_gen_br(l2);
5395             gen_set_label(l1);
5396             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5397             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
5398             gen_set_label(l2);
5399         }
5400         break;
5401 #if defined(TARGET_MIPS64)
5402     case OPC_DMULT_G_2E:
5403     case OPC_DMULT_G_2F:
5404         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5405         break;
5406     case OPC_DMULTU_G_2E:
5407     case OPC_DMULTU_G_2F:
5408         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
5409         break;
5410     case OPC_DDIV_G_2E:
5411     case OPC_DDIV_G_2F:
5412         {
5413             TCGLabel *l1 = gen_new_label();
5414             TCGLabel *l2 = gen_new_label();
5415             TCGLabel *l3 = gen_new_label();
5416             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5417             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5418             tcg_gen_br(l3);
5419             gen_set_label(l1);
5420             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5421             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5422             tcg_gen_mov_tl(cpu_gpr[rd], t0);
5423             tcg_gen_br(l3);
5424             gen_set_label(l2);
5425             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
5426             gen_set_label(l3);
5427         }
5428         break;
5429     case OPC_DDIVU_G_2E:
5430     case OPC_DDIVU_G_2F:
5431         {
5432             TCGLabel *l1 = gen_new_label();
5433             TCGLabel *l2 = gen_new_label();
5434             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5435             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5436             tcg_gen_br(l2);
5437             gen_set_label(l1);
5438             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
5439             gen_set_label(l2);
5440         }
5441         break;
5442     case OPC_DMOD_G_2E:
5443     case OPC_DMOD_G_2F:
5444         {
5445             TCGLabel *l1 = gen_new_label();
5446             TCGLabel *l2 = gen_new_label();
5447             TCGLabel *l3 = gen_new_label();
5448             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
5449             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
5450             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
5451             gen_set_label(l1);
5452             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5453             tcg_gen_br(l3);
5454             gen_set_label(l2);
5455             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
5456             gen_set_label(l3);
5457         }
5458         break;
5459     case OPC_DMODU_G_2E:
5460     case OPC_DMODU_G_2F:
5461         {
5462             TCGLabel *l1 = gen_new_label();
5463             TCGLabel *l2 = gen_new_label();
5464             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
5465             tcg_gen_movi_tl(cpu_gpr[rd], 0);
5466             tcg_gen_br(l2);
5467             gen_set_label(l1);
5468             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
5469             gen_set_label(l2);
5470         }
5471         break;
5472 #endif
5473     }
5474
5475     tcg_temp_free(t0);
5476     tcg_temp_free(t1);
5477 }
5478
5479 /* Loongson multimedia instructions */
5480 static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
5481 {
5482     uint32_t opc, shift_max;
5483     TCGv_i64 t0, t1;
5484
5485     opc = MASK_LMI(ctx->opcode);
5486     switch (opc) {
5487     case OPC_ADD_CP2:
5488     case OPC_SUB_CP2:
5489     case OPC_DADD_CP2:
5490     case OPC_DSUB_CP2:
5491         t0 = tcg_temp_local_new_i64();
5492         t1 = tcg_temp_local_new_i64();
5493         break;
5494     default:
5495         t0 = tcg_temp_new_i64();
5496         t1 = tcg_temp_new_i64();
5497         break;
5498     }
5499
5500     check_cp1_enabled(ctx);
5501     gen_load_fpr64(ctx, t0, rs);
5502     gen_load_fpr64(ctx, t1, rt);
5503
5504 #define LMI_HELPER(UP, LO) \
5505     case OPC_##UP: gen_helper_##LO(t0, t0, t1); break
5506 #define LMI_HELPER_1(UP, LO) \
5507     case OPC_##UP: gen_helper_##LO(t0, t0); break
5508 #define LMI_DIRECT(UP, LO, OP) \
5509     case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); break
5510
5511     switch (opc) {
5512     LMI_HELPER(PADDSH, paddsh);
5513     LMI_HELPER(PADDUSH, paddush);
5514     LMI_HELPER(PADDH, paddh);
5515     LMI_HELPER(PADDW, paddw);
5516     LMI_HELPER(PADDSB, paddsb);
5517     LMI_HELPER(PADDUSB, paddusb);
5518     LMI_HELPER(PADDB, paddb);
5519
5520     LMI_HELPER(PSUBSH, psubsh);
5521     LMI_HELPER(PSUBUSH, psubush);
5522     LMI_HELPER(PSUBH, psubh);
5523     LMI_HELPER(PSUBW, psubw);
5524     LMI_HELPER(PSUBSB, psubsb);
5525     LMI_HELPER(PSUBUSB, psubusb);
5526     LMI_HELPER(PSUBB, psubb);
5527
5528     LMI_HELPER(PSHUFH, pshufh);
5529     LMI_HELPER(PACKSSWH, packsswh);
5530     LMI_HELPER(PACKSSHB, packsshb);
5531     LMI_HELPER(PACKUSHB, packushb);
5532
5533     LMI_HELPER(PUNPCKLHW, punpcklhw);
5534     LMI_HELPER(PUNPCKHHW, punpckhhw);
5535     LMI_HELPER(PUNPCKLBH, punpcklbh);
5536     LMI_HELPER(PUNPCKHBH, punpckhbh);
5537     LMI_HELPER(PUNPCKLWD, punpcklwd);
5538     LMI_HELPER(PUNPCKHWD, punpckhwd);
5539
5540     LMI_HELPER(PAVGH, pavgh);
5541     LMI_HELPER(PAVGB, pavgb);
5542     LMI_HELPER(PMAXSH, pmaxsh);
5543     LMI_HELPER(PMINSH, pminsh);
5544     LMI_HELPER(PMAXUB, pmaxub);
5545     LMI_HELPER(PMINUB, pminub);
5546
5547     LMI_HELPER(PCMPEQW, pcmpeqw);
5548     LMI_HELPER(PCMPGTW, pcmpgtw);
5549     LMI_HELPER(PCMPEQH, pcmpeqh);
5550     LMI_HELPER(PCMPGTH, pcmpgth);
5551     LMI_HELPER(PCMPEQB, pcmpeqb);
5552     LMI_HELPER(PCMPGTB, pcmpgtb);
5553
5554     LMI_HELPER(PSLLW, psllw);
5555     LMI_HELPER(PSLLH, psllh);
5556     LMI_HELPER(PSRLW, psrlw);
5557     LMI_HELPER(PSRLH, psrlh);
5558     LMI_HELPER(PSRAW, psraw);
5559     LMI_HELPER(PSRAH, psrah);
5560
5561     LMI_HELPER(PMULLH, pmullh);
5562     LMI_HELPER(PMULHH, pmulhh);
5563     LMI_HELPER(PMULHUH, pmulhuh);
5564     LMI_HELPER(PMADDHW, pmaddhw);
5565
5566     LMI_HELPER(PASUBUB, pasubub);
5567     LMI_HELPER_1(BIADD, biadd);
5568     LMI_HELPER_1(PMOVMSKB, pmovmskb);
5569
5570     LMI_DIRECT(PADDD, paddd, add);
5571     LMI_DIRECT(PSUBD, psubd, sub);
5572     LMI_DIRECT(XOR_CP2, xor, xor);
5573     LMI_DIRECT(NOR_CP2, nor, nor);
5574     LMI_DIRECT(AND_CP2, and, and);
5575     LMI_DIRECT(OR_CP2, or, or);
5576
5577     case OPC_PANDN:
5578         tcg_gen_andc_i64(t0, t1, t0);
5579         break;
5580
5581     case OPC_PINSRH_0:
5582         tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
5583         break;
5584     case OPC_PINSRH_1:
5585         tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
5586         break;
5587     case OPC_PINSRH_2:
5588         tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
5589         break;
5590     case OPC_PINSRH_3:
5591         tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
5592         break;
5593
5594     case OPC_PEXTRH:
5595         tcg_gen_andi_i64(t1, t1, 3);
5596         tcg_gen_shli_i64(t1, t1, 4);
5597         tcg_gen_shr_i64(t0, t0, t1);
5598         tcg_gen_ext16u_i64(t0, t0);
5599         break;
5600
5601     case OPC_ADDU_CP2:
5602         tcg_gen_add_i64(t0, t0, t1);
5603         tcg_gen_ext32s_i64(t0, t0);
5604         break;
5605     case OPC_SUBU_CP2:
5606         tcg_gen_sub_i64(t0, t0, t1);
5607         tcg_gen_ext32s_i64(t0, t0);
5608         break;
5609
5610     case OPC_SLL_CP2:
5611         shift_max = 32;
5612         goto do_shift;
5613     case OPC_SRL_CP2:
5614         shift_max = 32;
5615         goto do_shift;
5616     case OPC_SRA_CP2:
5617         shift_max = 32;
5618         goto do_shift;
5619     case OPC_DSLL_CP2:
5620         shift_max = 64;
5621         goto do_shift;
5622     case OPC_DSRL_CP2:
5623         shift_max = 64;
5624         goto do_shift;
5625     case OPC_DSRA_CP2:
5626         shift_max = 64;
5627         goto do_shift;
5628     do_shift:
5629         /* Make sure shift count isn't TCG undefined behaviour.  */
5630         tcg_gen_andi_i64(t1, t1, shift_max - 1);
5631
5632         switch (opc) {
5633         case OPC_SLL_CP2:
5634         case OPC_DSLL_CP2:
5635             tcg_gen_shl_i64(t0, t0, t1);
5636             break;
5637         case OPC_SRA_CP2:
5638         case OPC_DSRA_CP2:
5639             /* Since SRA is UndefinedResult without sign-extended inputs,
5640                we can treat SRA and DSRA the same.  */
5641             tcg_gen_sar_i64(t0, t0, t1);
5642             break;
5643         case OPC_SRL_CP2:
5644             /* We want to shift in zeros for SRL; zero-extend first.  */
5645             tcg_gen_ext32u_i64(t0, t0);
5646             /* FALLTHRU */
5647         case OPC_DSRL_CP2:
5648             tcg_gen_shr_i64(t0, t0, t1);
5649             break;
5650         }
5651
5652         if (shift_max == 32) {
5653             tcg_gen_ext32s_i64(t0, t0);
5654         }
5655
5656         /* Shifts larger than MAX produce zero.  */
5657         tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
5658         tcg_gen_neg_i64(t1, t1);
5659         tcg_gen_and_i64(t0, t0, t1);
5660         break;
5661
5662     case OPC_ADD_CP2:
5663     case OPC_DADD_CP2:
5664         {
5665             TCGv_i64 t2 = tcg_temp_new_i64();
5666             TCGLabel *lab = gen_new_label();
5667
5668             tcg_gen_mov_i64(t2, t0);
5669             tcg_gen_add_i64(t0, t1, t2);
5670             if (opc == OPC_ADD_CP2) {
5671                 tcg_gen_ext32s_i64(t0, t0);
5672             }
5673             tcg_gen_xor_i64(t1, t1, t2);
5674             tcg_gen_xor_i64(t2, t2, t0);
5675             tcg_gen_andc_i64(t1, t2, t1);
5676             tcg_temp_free_i64(t2);
5677             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5678             generate_exception(ctx, EXCP_OVERFLOW);
5679             gen_set_label(lab);
5680             break;
5681         }
5682
5683     case OPC_SUB_CP2:
5684     case OPC_DSUB_CP2:
5685         {
5686             TCGv_i64 t2 = tcg_temp_new_i64();
5687             TCGLabel *lab = gen_new_label();
5688
5689             tcg_gen_mov_i64(t2, t0);
5690             tcg_gen_sub_i64(t0, t1, t2);
5691             if (opc == OPC_SUB_CP2) {
5692                 tcg_gen_ext32s_i64(t0, t0);
5693             }
5694             tcg_gen_xor_i64(t1, t1, t2);
5695             tcg_gen_xor_i64(t2, t2, t0);
5696             tcg_gen_and_i64(t1, t1, t2);
5697             tcg_temp_free_i64(t2);
5698             tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
5699             generate_exception(ctx, EXCP_OVERFLOW);
5700             gen_set_label(lab);
5701             break;
5702         }
5703
5704     case OPC_PMULUW:
5705         tcg_gen_ext32u_i64(t0, t0);
5706         tcg_gen_ext32u_i64(t1, t1);
5707         tcg_gen_mul_i64(t0, t0, t1);
5708         break;
5709
5710     case OPC_SEQU_CP2:
5711     case OPC_SEQ_CP2:
5712     case OPC_SLTU_CP2:
5713     case OPC_SLT_CP2:
5714     case OPC_SLEU_CP2:
5715     case OPC_SLE_CP2:
5716         /* ??? Document is unclear: Set FCC[CC].  Does that mean the
5717            FD field is the CC field?  */
5718     default:
5719         MIPS_INVAL("loongson_cp2");
5720         generate_exception_end(ctx, EXCP_RI);
5721         return;
5722     }
5723
5724 #undef LMI_HELPER
5725 #undef LMI_DIRECT
5726
5727     gen_store_fpr64(ctx, t0, rd);
5728
5729     tcg_temp_free_i64(t0);
5730     tcg_temp_free_i64(t1);
5731 }
5732
5733 /* Traps */
5734 static void gen_trap (DisasContext *ctx, uint32_t opc,
5735                       int rs, int rt, int16_t imm)
5736 {
5737     int cond;
5738     TCGv t0 = tcg_temp_new();
5739     TCGv t1 = tcg_temp_new();
5740
5741     cond = 0;
5742     /* Load needed operands */
5743     switch (opc) {
5744     case OPC_TEQ:
5745     case OPC_TGE:
5746     case OPC_TGEU:
5747     case OPC_TLT:
5748     case OPC_TLTU:
5749     case OPC_TNE:
5750         /* Compare two registers */
5751         if (rs != rt) {
5752             gen_load_gpr(t0, rs);
5753             gen_load_gpr(t1, rt);
5754             cond = 1;
5755         }
5756         break;
5757     case OPC_TEQI:
5758     case OPC_TGEI:
5759     case OPC_TGEIU:
5760     case OPC_TLTI:
5761     case OPC_TLTIU:
5762     case OPC_TNEI:
5763         /* Compare register to immediate */
5764         if (rs != 0 || imm != 0) {
5765             gen_load_gpr(t0, rs);
5766             tcg_gen_movi_tl(t1, (int32_t)imm);
5767             cond = 1;
5768         }
5769         break;
5770     }
5771     if (cond == 0) {
5772         switch (opc) {
5773         case OPC_TEQ:   /* rs == rs */
5774         case OPC_TEQI:  /* r0 == 0  */
5775         case OPC_TGE:   /* rs >= rs */
5776         case OPC_TGEI:  /* r0 >= 0  */
5777         case OPC_TGEU:  /* rs >= rs unsigned */
5778         case OPC_TGEIU: /* r0 >= 0  unsigned */
5779             /* Always trap */
5780             generate_exception_end(ctx, EXCP_TRAP);
5781             break;
5782         case OPC_TLT:   /* rs < rs           */
5783         case OPC_TLTI:  /* r0 < 0            */
5784         case OPC_TLTU:  /* rs < rs unsigned  */
5785         case OPC_TLTIU: /* r0 < 0  unsigned  */
5786         case OPC_TNE:   /* rs != rs          */
5787         case OPC_TNEI:  /* r0 != 0           */
5788             /* Never trap: treat as NOP. */
5789             break;
5790         }
5791     } else {
5792         TCGLabel *l1 = gen_new_label();
5793
5794         switch (opc) {
5795         case OPC_TEQ:
5796         case OPC_TEQI:
5797             tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
5798             break;
5799         case OPC_TGE:
5800         case OPC_TGEI:
5801             tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
5802             break;
5803         case OPC_TGEU:
5804         case OPC_TGEIU:
5805             tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
5806             break;
5807         case OPC_TLT:
5808         case OPC_TLTI:
5809             tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5810             break;
5811         case OPC_TLTU:
5812         case OPC_TLTIU:
5813             tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5814             break;
5815         case OPC_TNE:
5816         case OPC_TNEI:
5817             tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
5818             break;
5819         }
5820         generate_exception(ctx, EXCP_TRAP);
5821         gen_set_label(l1);
5822     }
5823     tcg_temp_free(t0);
5824     tcg_temp_free(t1);
5825 }
5826
5827 static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5828 {
5829     if (unlikely(ctx->base.singlestep_enabled)) {
5830         return false;
5831     }
5832
5833 #ifndef CONFIG_USER_ONLY
5834     return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
5835 #else
5836     return true;
5837 #endif
5838 }
5839
5840 static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
5841 {
5842     if (use_goto_tb(ctx, dest)) {
5843         tcg_gen_goto_tb(n);
5844         gen_save_pc(dest);
5845         tcg_gen_exit_tb(ctx->base.tb, n);
5846     } else {
5847         gen_save_pc(dest);
5848         if (ctx->base.singlestep_enabled) {
5849             save_cpu_state(ctx, 0);
5850             gen_helper_raise_exception_debug(cpu_env);
5851         }
5852         tcg_gen_lookup_and_goto_ptr();
5853     }
5854 }
5855
5856 /* Branches (before delay slot) */
5857 static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
5858                                 int insn_bytes,
5859                                 int rs, int rt, int32_t offset,
5860                                 int delayslot_size)
5861 {
5862     target_ulong btgt = -1;
5863     int blink = 0;
5864     int bcond_compute = 0;
5865     TCGv t0 = tcg_temp_new();
5866     TCGv t1 = tcg_temp_new();
5867
5868     if (ctx->hflags & MIPS_HFLAG_BMASK) {
5869 #ifdef MIPS_DEBUG_DISAS
5870         LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5871                   TARGET_FMT_lx "\n", ctx->base.pc_next);
5872 #endif
5873         generate_exception_end(ctx, EXCP_RI);
5874         goto out;
5875     }
5876
5877     /* Load needed operands */
5878     switch (opc) {
5879     case OPC_BEQ:
5880     case OPC_BEQL:
5881     case OPC_BNE:
5882     case OPC_BNEL:
5883         /* Compare two registers */
5884         if (rs != rt) {
5885             gen_load_gpr(t0, rs);
5886             gen_load_gpr(t1, rt);
5887             bcond_compute = 1;
5888         }
5889         btgt = ctx->base.pc_next + insn_bytes + offset;
5890         break;
5891     case OPC_BGEZ:
5892     case OPC_BGEZAL:
5893     case OPC_BGEZALL:
5894     case OPC_BGEZL:
5895     case OPC_BGTZ:
5896     case OPC_BGTZL:
5897     case OPC_BLEZ:
5898     case OPC_BLEZL:
5899     case OPC_BLTZ:
5900     case OPC_BLTZAL:
5901     case OPC_BLTZALL:
5902     case OPC_BLTZL:
5903         /* Compare to zero */
5904         if (rs != 0) {
5905             gen_load_gpr(t0, rs);
5906             bcond_compute = 1;
5907         }
5908         btgt = ctx->base.pc_next + insn_bytes + offset;
5909         break;
5910     case OPC_BPOSGE32:
5911 #if defined(TARGET_MIPS64)
5912     case OPC_BPOSGE64:
5913         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5914 #else
5915         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5916 #endif
5917         bcond_compute = 1;
5918         btgt = ctx->base.pc_next + insn_bytes + offset;
5919         break;
5920     case OPC_J:
5921     case OPC_JAL:
5922     case OPC_JALX:
5923         /* Jump to immediate */
5924         btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5925             (uint32_t)offset;
5926         break;
5927     case OPC_JR:
5928     case OPC_JALR:
5929         /* Jump to register */
5930         if (offset != 0 && offset != 16) {
5931             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5932                others are reserved. */
5933             MIPS_INVAL("jump hint");
5934             generate_exception_end(ctx, EXCP_RI);
5935             goto out;
5936         }
5937         gen_load_gpr(btarget, rs);
5938         break;
5939     default:
5940         MIPS_INVAL("branch/jump");
5941         generate_exception_end(ctx, EXCP_RI);
5942         goto out;
5943     }
5944     if (bcond_compute == 0) {
5945         /* No condition to be computed */
5946         switch (opc) {
5947         case OPC_BEQ:     /* rx == rx        */
5948         case OPC_BEQL:    /* rx == rx likely */
5949         case OPC_BGEZ:    /* 0 >= 0          */
5950         case OPC_BGEZL:   /* 0 >= 0 likely   */
5951         case OPC_BLEZ:    /* 0 <= 0          */
5952         case OPC_BLEZL:   /* 0 <= 0 likely   */
5953             /* Always take */
5954             ctx->hflags |= MIPS_HFLAG_B;
5955             break;
5956         case OPC_BGEZAL:  /* 0 >= 0          */
5957         case OPC_BGEZALL: /* 0 >= 0 likely   */
5958             /* Always take and link */
5959             blink = 31;
5960             ctx->hflags |= MIPS_HFLAG_B;
5961             break;
5962         case OPC_BNE:     /* rx != rx        */
5963         case OPC_BGTZ:    /* 0 > 0           */
5964         case OPC_BLTZ:    /* 0 < 0           */
5965             /* Treat as NOP. */
5966             goto out;
5967         case OPC_BLTZAL:  /* 0 < 0           */
5968             /* Handle as an unconditional branch to get correct delay
5969                slot checking.  */
5970             blink = 31;
5971             btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
5972             ctx->hflags |= MIPS_HFLAG_B;
5973             break;
5974         case OPC_BLTZALL: /* 0 < 0 likely */
5975             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5976             /* Skip the instruction in the delay slot */
5977             ctx->base.pc_next += 4;
5978             goto out;
5979         case OPC_BNEL:    /* rx != rx likely */
5980         case OPC_BGTZL:   /* 0 > 0 likely */
5981         case OPC_BLTZL:   /* 0 < 0 likely */
5982             /* Skip the instruction in the delay slot */
5983             ctx->base.pc_next += 4;
5984             goto out;
5985         case OPC_J:
5986             ctx->hflags |= MIPS_HFLAG_B;
5987             break;
5988         case OPC_JALX:
5989             ctx->hflags |= MIPS_HFLAG_BX;
5990             /* Fallthrough */
5991         case OPC_JAL:
5992             blink = 31;
5993             ctx->hflags |= MIPS_HFLAG_B;
5994             break;
5995         case OPC_JR:
5996             ctx->hflags |= MIPS_HFLAG_BR;
5997             break;
5998         case OPC_JALR:
5999             blink = rt;
6000             ctx->hflags |= MIPS_HFLAG_BR;
6001             break;
6002         default:
6003             MIPS_INVAL("branch/jump");
6004             generate_exception_end(ctx, EXCP_RI);
6005             goto out;
6006         }
6007     } else {
6008         switch (opc) {
6009         case OPC_BEQ:
6010             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6011             goto not_likely;
6012         case OPC_BEQL:
6013             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6014             goto likely;
6015         case OPC_BNE:
6016             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6017             goto not_likely;
6018         case OPC_BNEL:
6019             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6020             goto likely;
6021         case OPC_BGEZ:
6022             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6023             goto not_likely;
6024         case OPC_BGEZL:
6025             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6026             goto likely;
6027         case OPC_BGEZAL:
6028             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6029             blink = 31;
6030             goto not_likely;
6031         case OPC_BGEZALL:
6032             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6033             blink = 31;
6034             goto likely;
6035         case OPC_BGTZ:
6036             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6037             goto not_likely;
6038         case OPC_BGTZL:
6039             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
6040             goto likely;
6041         case OPC_BLEZ:
6042             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6043             goto not_likely;
6044         case OPC_BLEZL:
6045             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
6046             goto likely;
6047         case OPC_BLTZ:
6048             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6049             goto not_likely;
6050         case OPC_BLTZL:
6051             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6052             goto likely;
6053         case OPC_BPOSGE32:
6054             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6055             goto not_likely;
6056 #if defined(TARGET_MIPS64)
6057         case OPC_BPOSGE64:
6058             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
6059             goto not_likely;
6060 #endif
6061         case OPC_BLTZAL:
6062             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6063             blink = 31;
6064         not_likely:
6065             ctx->hflags |= MIPS_HFLAG_BC;
6066             break;
6067         case OPC_BLTZALL:
6068             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
6069             blink = 31;
6070         likely:
6071             ctx->hflags |= MIPS_HFLAG_BL;
6072             break;
6073         default:
6074             MIPS_INVAL("conditional branch/jump");
6075             generate_exception_end(ctx, EXCP_RI);
6076             goto out;
6077         }
6078     }
6079
6080     ctx->btarget = btgt;
6081
6082     switch (delayslot_size) {
6083     case 2:
6084         ctx->hflags |= MIPS_HFLAG_BDS16;
6085         break;
6086     case 4:
6087         ctx->hflags |= MIPS_HFLAG_BDS32;
6088         break;
6089     }
6090
6091     if (blink > 0) {
6092         int post_delay = insn_bytes + delayslot_size;
6093         int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
6094
6095         tcg_gen_movi_tl(cpu_gpr[blink],
6096                         ctx->base.pc_next + post_delay + lowbit);
6097     }
6098
6099  out:
6100     if (insn_bytes == 2)
6101         ctx->hflags |= MIPS_HFLAG_B16;
6102     tcg_temp_free(t0);
6103     tcg_temp_free(t1);
6104 }
6105
6106
6107 /* nanoMIPS Branches */
6108 static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
6109                                 int insn_bytes,
6110                                 int rs, int rt, int32_t offset)
6111 {
6112     target_ulong btgt = -1;
6113     int bcond_compute = 0;
6114     TCGv t0 = tcg_temp_new();
6115     TCGv t1 = tcg_temp_new();
6116
6117     /* Load needed operands */
6118     switch (opc) {
6119     case OPC_BEQ:
6120     case OPC_BNE:
6121         /* Compare two registers */
6122         if (rs != rt) {
6123             gen_load_gpr(t0, rs);
6124             gen_load_gpr(t1, rt);
6125             bcond_compute = 1;
6126         }
6127         btgt = ctx->base.pc_next + insn_bytes + offset;
6128         break;
6129     case OPC_BGEZAL:
6130         /* Compare to zero */
6131         if (rs != 0) {
6132             gen_load_gpr(t0, rs);
6133             bcond_compute = 1;
6134         }
6135         btgt = ctx->base.pc_next + insn_bytes + offset;
6136         break;
6137     case OPC_BPOSGE32:
6138         tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
6139         bcond_compute = 1;
6140         btgt = ctx->base.pc_next + insn_bytes + offset;
6141         break;
6142     case OPC_JR:
6143     case OPC_JALR:
6144         /* Jump to register */
6145         if (offset != 0 && offset != 16) {
6146             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
6147                others are reserved. */
6148             MIPS_INVAL("jump hint");
6149             generate_exception_end(ctx, EXCP_RI);
6150             goto out;
6151         }
6152         gen_load_gpr(btarget, rs);
6153         break;
6154     default:
6155         MIPS_INVAL("branch/jump");
6156         generate_exception_end(ctx, EXCP_RI);
6157         goto out;
6158     }
6159     if (bcond_compute == 0) {
6160         /* No condition to be computed */
6161         switch (opc) {
6162         case OPC_BEQ:     /* rx == rx        */
6163             /* Always take */
6164             ctx->hflags |= MIPS_HFLAG_B;
6165             break;
6166         case OPC_BGEZAL:  /* 0 >= 0          */
6167             /* Always take and link */
6168             tcg_gen_movi_tl(cpu_gpr[31],
6169                             ctx->base.pc_next + insn_bytes);
6170             ctx->hflags |= MIPS_HFLAG_B;
6171             break;
6172         case OPC_BNE:     /* rx != rx        */
6173             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
6174             /* Skip the instruction in the delay slot */
6175             ctx->base.pc_next += 4;
6176             goto out;
6177         case OPC_JR:
6178             ctx->hflags |= MIPS_HFLAG_BR;
6179             break;
6180         case OPC_JALR:
6181             if (rt > 0) {
6182                 tcg_gen_movi_tl(cpu_gpr[rt],
6183                                 ctx->base.pc_next + insn_bytes);
6184             }
6185             ctx->hflags |= MIPS_HFLAG_BR;
6186             break;
6187         default:
6188             MIPS_INVAL("branch/jump");
6189             generate_exception_end(ctx, EXCP_RI);
6190             goto out;
6191         }
6192     } else {
6193         switch (opc) {
6194         case OPC_BEQ:
6195             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
6196             goto not_likely;
6197         case OPC_BNE:
6198             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
6199             goto not_likely;
6200         case OPC_BGEZAL:
6201             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
6202             tcg_gen_movi_tl(cpu_gpr[31],
6203                             ctx->base.pc_next + insn_bytes);
6204             goto not_likely;
6205         case OPC_BPOSGE32:
6206             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
6207         not_likely:
6208             ctx->hflags |= MIPS_HFLAG_BC;
6209             break;
6210         default:
6211             MIPS_INVAL("conditional branch/jump");
6212             generate_exception_end(ctx, EXCP_RI);
6213             goto out;
6214         }
6215     }
6216
6217     ctx->btarget = btgt;
6218
6219  out:
6220     if (insn_bytes == 2) {
6221         ctx->hflags |= MIPS_HFLAG_B16;
6222     }
6223     tcg_temp_free(t0);
6224     tcg_temp_free(t1);
6225 }
6226
6227
6228 /* special3 bitfield operations */
6229 static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
6230                         int rs, int lsb, int msb)
6231 {
6232     TCGv t0 = tcg_temp_new();
6233     TCGv t1 = tcg_temp_new();
6234
6235     gen_load_gpr(t1, rs);
6236     switch (opc) {
6237     case OPC_EXT:
6238         if (lsb + msb > 31) {
6239             goto fail;
6240         }
6241         if (msb != 31) {
6242             tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6243         } else {
6244             /* The two checks together imply that lsb == 0,
6245                so this is a simple sign-extension.  */
6246             tcg_gen_ext32s_tl(t0, t1);
6247         }
6248         break;
6249 #if defined(TARGET_MIPS64)
6250     case OPC_DEXTU:
6251         lsb += 32;
6252         goto do_dext;
6253     case OPC_DEXTM:
6254         msb += 32;
6255         goto do_dext;
6256     case OPC_DEXT:
6257     do_dext:
6258         if (lsb + msb > 63) {
6259             goto fail;
6260         }
6261         tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
6262         break;
6263 #endif
6264     case OPC_INS:
6265         if (lsb > msb) {
6266             goto fail;
6267         }
6268         gen_load_gpr(t0, rt);
6269         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6270         tcg_gen_ext32s_tl(t0, t0);
6271         break;
6272 #if defined(TARGET_MIPS64)
6273     case OPC_DINSU:
6274         lsb += 32;
6275         /* FALLTHRU */
6276     case OPC_DINSM:
6277         msb += 32;
6278         /* FALLTHRU */
6279     case OPC_DINS:
6280         if (lsb > msb) {
6281             goto fail;
6282         }
6283         gen_load_gpr(t0, rt);
6284         tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
6285         break;
6286 #endif
6287     default:
6288 fail:
6289         MIPS_INVAL("bitops");
6290         generate_exception_end(ctx, EXCP_RI);
6291         tcg_temp_free(t0);
6292         tcg_temp_free(t1);
6293         return;
6294     }
6295     gen_store_gpr(t0, rt);
6296     tcg_temp_free(t0);
6297     tcg_temp_free(t1);
6298 }
6299
6300 static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
6301 {
6302     TCGv t0;
6303
6304     if (rd == 0) {
6305         /* If no destination, treat it as a NOP. */
6306         return;
6307     }
6308
6309     t0 = tcg_temp_new();
6310     gen_load_gpr(t0, rt);
6311     switch (op2) {
6312     case OPC_WSBH:
6313         {
6314             TCGv t1 = tcg_temp_new();
6315             TCGv t2 = tcg_const_tl(0x00FF00FF);
6316
6317             tcg_gen_shri_tl(t1, t0, 8);
6318             tcg_gen_and_tl(t1, t1, t2);
6319             tcg_gen_and_tl(t0, t0, t2);
6320             tcg_gen_shli_tl(t0, t0, 8);
6321             tcg_gen_or_tl(t0, t0, t1);
6322             tcg_temp_free(t2);
6323             tcg_temp_free(t1);
6324             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6325         }
6326         break;
6327     case OPC_SEB:
6328         tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
6329         break;
6330     case OPC_SEH:
6331         tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
6332         break;
6333 #if defined(TARGET_MIPS64)
6334     case OPC_DSBH:
6335         {
6336             TCGv t1 = tcg_temp_new();
6337             TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
6338
6339             tcg_gen_shri_tl(t1, t0, 8);
6340             tcg_gen_and_tl(t1, t1, t2);
6341             tcg_gen_and_tl(t0, t0, t2);
6342             tcg_gen_shli_tl(t0, t0, 8);
6343             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6344             tcg_temp_free(t2);
6345             tcg_temp_free(t1);
6346         }
6347         break;
6348     case OPC_DSHD:
6349         {
6350             TCGv t1 = tcg_temp_new();
6351             TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
6352
6353             tcg_gen_shri_tl(t1, t0, 16);
6354             tcg_gen_and_tl(t1, t1, t2);
6355             tcg_gen_and_tl(t0, t0, t2);
6356             tcg_gen_shli_tl(t0, t0, 16);
6357             tcg_gen_or_tl(t0, t0, t1);
6358             tcg_gen_shri_tl(t1, t0, 32);
6359             tcg_gen_shli_tl(t0, t0, 32);
6360             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
6361             tcg_temp_free(t2);
6362             tcg_temp_free(t1);
6363         }
6364         break;
6365 #endif
6366     default:
6367         MIPS_INVAL("bsfhl");
6368         generate_exception_end(ctx, EXCP_RI);
6369         tcg_temp_free(t0);
6370         return;
6371     }
6372     tcg_temp_free(t0);
6373 }
6374
6375 static void gen_lsa(DisasContext *ctx, int opc, int rd, int rs, int rt,
6376                     int imm2)
6377 {
6378     TCGv t0;
6379     TCGv t1;
6380     if (rd == 0) {
6381         /* Treat as NOP. */
6382         return;
6383     }
6384     t0 = tcg_temp_new();
6385     t1 = tcg_temp_new();
6386     gen_load_gpr(t0, rs);
6387     gen_load_gpr(t1, rt);
6388     tcg_gen_shli_tl(t0, t0, imm2 + 1);
6389     tcg_gen_add_tl(cpu_gpr[rd], t0, t1);
6390     if (opc == OPC_LSA) {
6391         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
6392     }
6393
6394     tcg_temp_free(t1);
6395     tcg_temp_free(t0);
6396
6397     return;
6398 }
6399
6400 static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
6401                            int rt, int bits)
6402 {
6403     TCGv t0;
6404     if (rd == 0) {
6405         /* Treat as NOP. */
6406         return;
6407     }
6408     t0 = tcg_temp_new();
6409     if (bits == 0 || bits == wordsz) {
6410         if (bits == 0) {
6411             gen_load_gpr(t0, rt);
6412         } else {
6413             gen_load_gpr(t0, rs);
6414         }
6415         switch (wordsz) {
6416         case 32:
6417             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
6418             break;
6419 #if defined(TARGET_MIPS64)
6420         case 64:
6421             tcg_gen_mov_tl(cpu_gpr[rd], t0);
6422             break;
6423 #endif
6424         }
6425     } else {
6426         TCGv t1 = tcg_temp_new();
6427         gen_load_gpr(t0, rt);
6428         gen_load_gpr(t1, rs);
6429         switch (wordsz) {
6430         case 32:
6431             {
6432                 TCGv_i64 t2 = tcg_temp_new_i64();
6433                 tcg_gen_concat_tl_i64(t2, t1, t0);
6434                 tcg_gen_shri_i64(t2, t2, 32 - bits);
6435                 gen_move_low32(cpu_gpr[rd], t2);
6436                 tcg_temp_free_i64(t2);
6437             }
6438             break;
6439 #if defined(TARGET_MIPS64)
6440         case 64:
6441             tcg_gen_shli_tl(t0, t0, bits);
6442             tcg_gen_shri_tl(t1, t1, 64 - bits);
6443             tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
6444             break;
6445 #endif
6446         }
6447         tcg_temp_free(t1);
6448     }
6449
6450     tcg_temp_free(t0);
6451 }
6452
6453 static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6454                       int bp)
6455 {
6456     gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
6457 }
6458
6459 static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
6460                     int shift)
6461 {
6462     gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
6463 }
6464
6465 static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
6466 {
6467     TCGv t0;
6468     if (rd == 0) {
6469         /* Treat as NOP. */
6470         return;
6471     }
6472     t0 = tcg_temp_new();
6473     gen_load_gpr(t0, rt);
6474     switch (opc) {
6475     case OPC_BITSWAP:
6476         gen_helper_bitswap(cpu_gpr[rd], t0);
6477         break;
6478 #if defined(TARGET_MIPS64)
6479     case OPC_DBITSWAP:
6480         gen_helper_dbitswap(cpu_gpr[rd], t0);
6481         break;
6482 #endif
6483     }
6484     tcg_temp_free(t0);
6485 }
6486
6487 #ifndef CONFIG_USER_ONLY
6488 /* CP0 (MMU and control) */
6489 static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
6490 {
6491     TCGv_i64 t0 = tcg_temp_new_i64();
6492     TCGv_i64 t1 = tcg_temp_new_i64();
6493
6494     tcg_gen_ext_tl_i64(t0, arg);
6495     tcg_gen_ld_i64(t1, cpu_env, off);
6496 #if defined(TARGET_MIPS64)
6497     tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
6498 #else
6499     tcg_gen_concat32_i64(t1, t1, t0);
6500 #endif
6501     tcg_gen_st_i64(t1, cpu_env, off);
6502     tcg_temp_free_i64(t1);
6503     tcg_temp_free_i64(t0);
6504 }
6505
6506 static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
6507 {
6508     TCGv_i64 t0 = tcg_temp_new_i64();
6509     TCGv_i64 t1 = tcg_temp_new_i64();
6510
6511     tcg_gen_ext_tl_i64(t0, arg);
6512     tcg_gen_ld_i64(t1, cpu_env, off);
6513     tcg_gen_concat32_i64(t1, t1, t0);
6514     tcg_gen_st_i64(t1, cpu_env, off);
6515     tcg_temp_free_i64(t1);
6516     tcg_temp_free_i64(t0);
6517 }
6518
6519 static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
6520 {
6521     TCGv_i64 t0 = tcg_temp_new_i64();
6522
6523     tcg_gen_ld_i64(t0, cpu_env, off);
6524 #if defined(TARGET_MIPS64)
6525     tcg_gen_shri_i64(t0, t0, 30);
6526 #else
6527     tcg_gen_shri_i64(t0, t0, 32);
6528 #endif
6529     gen_move_low32(arg, t0);
6530     tcg_temp_free_i64(t0);
6531 }
6532
6533 static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
6534 {
6535     TCGv_i64 t0 = tcg_temp_new_i64();
6536
6537     tcg_gen_ld_i64(t0, cpu_env, off);
6538     tcg_gen_shri_i64(t0, t0, 32 + shift);
6539     gen_move_low32(arg, t0);
6540     tcg_temp_free_i64(t0);
6541 }
6542
6543 static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
6544 {
6545     TCGv_i32 t0 = tcg_temp_new_i32();
6546
6547     tcg_gen_ld_i32(t0, cpu_env, off);
6548     tcg_gen_ext_i32_tl(arg, t0);
6549     tcg_temp_free_i32(t0);
6550 }
6551
6552 static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
6553 {
6554     tcg_gen_ld_tl(arg, cpu_env, off);
6555     tcg_gen_ext32s_tl(arg, arg);
6556 }
6557
6558 static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
6559 {
6560     TCGv_i32 t0 = tcg_temp_new_i32();
6561
6562     tcg_gen_trunc_tl_i32(t0, arg);
6563     tcg_gen_st_i32(t0, cpu_env, off);
6564     tcg_temp_free_i32(t0);
6565 }
6566
6567 #define CP0_CHECK(c)                            \
6568     do {                                        \
6569         if (!(c)) {                             \
6570             goto cp0_unimplemented;             \
6571         }                                       \
6572     } while (0)
6573
6574 static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6575 {
6576     const char *register_name = "invalid";
6577
6578     switch (reg) {
6579     case CP0_REGISTER_02:
6580         switch (sel) {
6581         case 0:
6582             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6583             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6584             register_name = "EntryLo0";
6585             break;
6586         default:
6587             goto cp0_unimplemented;
6588         }
6589         break;
6590     case CP0_REGISTER_03:
6591         switch (sel) {
6592         case 0:
6593             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6594             gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6595             register_name = "EntryLo1";
6596             break;
6597         default:
6598             goto cp0_unimplemented;
6599         }
6600         break;
6601     case CP0_REGISTER_09:
6602         switch (sel) {
6603         case 7:
6604             CP0_CHECK(ctx->saar);
6605             gen_helper_mfhc0_saar(arg, cpu_env);
6606             register_name = "SAAR";
6607             break;
6608         default:
6609             goto cp0_unimplemented;
6610         }
6611         break;
6612     case CP0_REGISTER_17:
6613         switch (sel) {
6614         case 0:
6615             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, lladdr),
6616                              ctx->CP0_LLAddr_shift);
6617             register_name = "LLAddr";
6618             break;
6619         case 1:
6620             CP0_CHECK(ctx->mrp);
6621             gen_helper_mfhc0_maar(arg, cpu_env);
6622             register_name = "MAAR";
6623             break;
6624         default:
6625             goto cp0_unimplemented;
6626         }
6627         break;
6628     case CP0_REGISTER_28:
6629         switch (sel) {
6630         case 0:
6631         case 2:
6632         case 4:
6633         case 6:
6634             gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
6635             register_name = "TagLo";
6636             break;
6637         default:
6638             goto cp0_unimplemented;
6639         }
6640         break;
6641     default:
6642         goto cp0_unimplemented;
6643     }
6644     trace_mips_translate_c0("mfhc0", register_name, reg, sel);
6645     return;
6646
6647 cp0_unimplemented:
6648     qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
6649                   register_name, reg, sel);
6650     tcg_gen_movi_tl(arg, 0);
6651 }
6652
6653 static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6654 {
6655     const char *register_name = "invalid";
6656     uint64_t mask = ctx->PAMask >> 36;
6657
6658     switch (reg) {
6659     case CP0_REGISTER_02:
6660         switch (sel) {
6661         case 0:
6662             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6663             tcg_gen_andi_tl(arg, arg, mask);
6664             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
6665             register_name = "EntryLo0";
6666             break;
6667         default:
6668             goto cp0_unimplemented;
6669         }
6670         break;
6671     case CP0_REGISTER_03:
6672         switch (sel) {
6673         case 0:
6674             CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
6675             tcg_gen_andi_tl(arg, arg, mask);
6676             gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
6677             register_name = "EntryLo1";
6678             break;
6679         default:
6680             goto cp0_unimplemented;
6681         }
6682         break;
6683     case CP0_REGISTER_09:
6684         switch (sel) {
6685         case 7:
6686             CP0_CHECK(ctx->saar);
6687             gen_helper_mthc0_saar(cpu_env, arg);
6688             register_name = "SAAR";
6689             break;
6690         default:
6691             goto cp0_unimplemented;
6692         }
6693     case CP0_REGISTER_17:
6694         switch (sel) {
6695         case 0:
6696             /* LLAddr is read-only (the only exception is bit 0 if LLB is
6697                supported); the CP0_LLAddr_rw_bitmask does not seem to be
6698                relevant for modern MIPS cores supporting MTHC0, therefore
6699                treating MTHC0 to LLAddr as NOP. */
6700             register_name = "LLAddr";
6701             break;
6702         case 1:
6703             CP0_CHECK(ctx->mrp);
6704             gen_helper_mthc0_maar(cpu_env, arg);
6705             register_name = "MAAR";
6706             break;
6707         default:
6708             goto cp0_unimplemented;
6709         }
6710         break;
6711     case CP0_REGISTER_28:
6712         switch (sel) {
6713         case 0:
6714         case 2:
6715         case 4:
6716         case 6:
6717             tcg_gen_andi_tl(arg, arg, mask);
6718             gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
6719             register_name = "TagLo";
6720             break;
6721         default:
6722             goto cp0_unimplemented;
6723         }
6724         break;
6725     default:
6726         goto cp0_unimplemented;
6727     }
6728     trace_mips_translate_c0("mthc0", register_name, reg, sel);
6729
6730 cp0_unimplemented:
6731     qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
6732                   register_name, reg, sel);
6733 }
6734
6735 static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
6736 {
6737     if (ctx->insn_flags & ISA_MIPS32R6) {
6738         tcg_gen_movi_tl(arg, 0);
6739     } else {
6740         tcg_gen_movi_tl(arg, ~0);
6741     }
6742 }
6743
6744 static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6745 {
6746     const char *register_name = "invalid";
6747
6748     if (sel != 0)
6749         check_insn(ctx, ISA_MIPS32);
6750
6751     switch (reg) {
6752     case CP0_REGISTER_00:
6753         switch (sel) {
6754         case 0:
6755             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
6756             register_name = "Index";
6757             break;
6758         case 1:
6759             CP0_CHECK(ctx->insn_flags & ASE_MT);
6760             gen_helper_mfc0_mvpcontrol(arg, cpu_env);
6761             register_name = "MVPControl";
6762             break;
6763         case 2:
6764             CP0_CHECK(ctx->insn_flags & ASE_MT);
6765             gen_helper_mfc0_mvpconf0(arg, cpu_env);
6766             register_name = "MVPConf0";
6767             break;
6768         case 3:
6769             CP0_CHECK(ctx->insn_flags & ASE_MT);
6770             gen_helper_mfc0_mvpconf1(arg, cpu_env);
6771             register_name = "MVPConf1";
6772             break;
6773         case 4:
6774             CP0_CHECK(ctx->vp);
6775             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
6776             register_name = "VPControl";
6777             break;
6778         default:
6779             goto cp0_unimplemented;
6780         }
6781         break;
6782     case CP0_REGISTER_01:
6783         switch (sel) {
6784         case 0:
6785             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
6786             gen_helper_mfc0_random(arg, cpu_env);
6787             register_name = "Random";
6788             break;
6789         case 1:
6790             CP0_CHECK(ctx->insn_flags & ASE_MT);
6791             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6792             register_name = "VPEControl";
6793             break;
6794         case 2:
6795             CP0_CHECK(ctx->insn_flags & ASE_MT);
6796             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6797             register_name = "VPEConf0";
6798             break;
6799         case 3:
6800             CP0_CHECK(ctx->insn_flags & ASE_MT);
6801             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6802             register_name = "VPEConf1";
6803             break;
6804         case 4:
6805             CP0_CHECK(ctx->insn_flags & ASE_MT);
6806             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
6807             register_name = "YQMask";
6808             break;
6809         case 5:
6810             CP0_CHECK(ctx->insn_flags & ASE_MT);
6811             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
6812             register_name = "VPESchedule";
6813             break;
6814         case 6:
6815             CP0_CHECK(ctx->insn_flags & ASE_MT);
6816             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6817             register_name = "VPEScheFBack";
6818             break;
6819         case 7:
6820             CP0_CHECK(ctx->insn_flags & ASE_MT);
6821             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6822             register_name = "VPEOpt";
6823             break;
6824         default:
6825             goto cp0_unimplemented;
6826         }
6827         break;
6828     case CP0_REGISTER_02:
6829         switch (sel) {
6830         case 0:
6831             {
6832                 TCGv_i64 tmp = tcg_temp_new_i64();
6833                 tcg_gen_ld_i64(tmp, cpu_env,
6834                                offsetof(CPUMIPSState, CP0_EntryLo0));
6835 #if defined(TARGET_MIPS64)
6836                 if (ctx->rxi) {
6837                     /* Move RI/XI fields to bits 31:30 */
6838                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6839                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6840                 }
6841 #endif
6842                 gen_move_low32(arg, tmp);
6843                 tcg_temp_free_i64(tmp);
6844             }
6845             register_name = "EntryLo0";
6846             break;
6847         case 1:
6848             CP0_CHECK(ctx->insn_flags & ASE_MT);
6849             gen_helper_mfc0_tcstatus(arg, cpu_env);
6850             register_name = "TCStatus";
6851             break;
6852         case 2:
6853             CP0_CHECK(ctx->insn_flags & ASE_MT);
6854             gen_helper_mfc0_tcbind(arg, cpu_env);
6855             register_name = "TCBind";
6856             break;
6857         case 3:
6858             CP0_CHECK(ctx->insn_flags & ASE_MT);
6859             gen_helper_mfc0_tcrestart(arg, cpu_env);
6860             register_name = "TCRestart";
6861             break;
6862         case 4:
6863             CP0_CHECK(ctx->insn_flags & ASE_MT);
6864             gen_helper_mfc0_tchalt(arg, cpu_env);
6865             register_name = "TCHalt";
6866             break;
6867         case 5:
6868             CP0_CHECK(ctx->insn_flags & ASE_MT);
6869             gen_helper_mfc0_tccontext(arg, cpu_env);
6870             register_name = "TCContext";
6871             break;
6872         case 6:
6873             CP0_CHECK(ctx->insn_flags & ASE_MT);
6874             gen_helper_mfc0_tcschedule(arg, cpu_env);
6875             register_name = "TCSchedule";
6876             break;
6877         case 7:
6878             CP0_CHECK(ctx->insn_flags & ASE_MT);
6879             gen_helper_mfc0_tcschefback(arg, cpu_env);
6880             register_name = "TCScheFBack";
6881             break;
6882         default:
6883             goto cp0_unimplemented;
6884         }
6885         break;
6886     case CP0_REGISTER_03:
6887         switch (sel) {
6888         case 0:
6889             {
6890                 TCGv_i64 tmp = tcg_temp_new_i64();
6891                 tcg_gen_ld_i64(tmp, cpu_env,
6892                                offsetof(CPUMIPSState, CP0_EntryLo1));
6893 #if defined(TARGET_MIPS64)
6894                 if (ctx->rxi) {
6895                     /* Move RI/XI fields to bits 31:30 */
6896                     tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6897                     tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6898                 }
6899 #endif
6900                 gen_move_low32(arg, tmp);
6901                 tcg_temp_free_i64(tmp);
6902             }
6903             register_name = "EntryLo1";
6904             break;
6905         case 1:
6906             CP0_CHECK(ctx->vp);
6907             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6908             register_name = "GlobalNumber";
6909             break;
6910         default:
6911             goto cp0_unimplemented;
6912         }
6913         break;
6914     case CP0_REGISTER_04:
6915         switch (sel) {
6916         case 0:
6917             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6918             tcg_gen_ext32s_tl(arg, arg);
6919             register_name = "Context";
6920             break;
6921         case 1:
6922 //            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
6923             register_name = "ContextConfig";
6924             goto cp0_unimplemented;
6925         case 2:
6926             CP0_CHECK(ctx->ulri);
6927             tcg_gen_ld_tl(arg, cpu_env,
6928                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6929             tcg_gen_ext32s_tl(arg, arg);
6930             register_name = "UserLocal";
6931             break;
6932         default:
6933             goto cp0_unimplemented;
6934         }
6935         break;
6936     case CP0_REGISTER_05:
6937         switch (sel) {
6938         case 0:
6939             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6940             register_name = "PageMask";
6941             break;
6942         case 1:
6943             check_insn(ctx, ISA_MIPS32R2);
6944             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6945             register_name = "PageGrain";
6946             break;
6947         case 2:
6948             CP0_CHECK(ctx->sc);
6949             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6950             tcg_gen_ext32s_tl(arg, arg);
6951             register_name = "SegCtl0";
6952             break;
6953         case 3:
6954             CP0_CHECK(ctx->sc);
6955             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6956             tcg_gen_ext32s_tl(arg, arg);
6957             register_name = "SegCtl1";
6958             break;
6959         case 4:
6960             CP0_CHECK(ctx->sc);
6961             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6962             tcg_gen_ext32s_tl(arg, arg);
6963             register_name = "SegCtl2";
6964             break;
6965         case 5:
6966             check_pw(ctx);
6967             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6968             register_name = "PWBase";
6969             break;
6970         case 6:
6971             check_pw(ctx);
6972             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
6973             register_name = "PWField";
6974             break;
6975         case 7:
6976             check_pw(ctx);
6977             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
6978             register_name = "PWSize";
6979             break;
6980         default:
6981             goto cp0_unimplemented;
6982         }
6983         break;
6984     case CP0_REGISTER_06:
6985         switch (sel) {
6986         case 0:
6987             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6988             register_name = "Wired";
6989             break;
6990         case 1:
6991             check_insn(ctx, ISA_MIPS32R2);
6992             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6993             register_name = "SRSConf0";
6994             break;
6995         case 2:
6996             check_insn(ctx, ISA_MIPS32R2);
6997             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6998             register_name = "SRSConf1";
6999             break;
7000         case 3:
7001             check_insn(ctx, ISA_MIPS32R2);
7002             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7003             register_name = "SRSConf2";
7004             break;
7005         case 4:
7006             check_insn(ctx, ISA_MIPS32R2);
7007             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7008             register_name = "SRSConf3";
7009             break;
7010         case 5:
7011             check_insn(ctx, ISA_MIPS32R2);
7012             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7013             register_name = "SRSConf4";
7014             break;
7015         case 6:
7016             check_pw(ctx);
7017             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7018             register_name = "PWCtl";
7019             break;
7020         default:
7021             goto cp0_unimplemented;
7022         }
7023         break;
7024     case CP0_REGISTER_07:
7025         switch (sel) {
7026         case 0:
7027             check_insn(ctx, ISA_MIPS32R2);
7028             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7029             register_name = "HWREna";
7030             break;
7031         default:
7032             goto cp0_unimplemented;
7033         }
7034         break;
7035     case CP0_REGISTER_08:
7036         switch (sel) {
7037         case 0:
7038             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7039             tcg_gen_ext32s_tl(arg, arg);
7040             register_name = "BadVAddr";
7041             break;
7042         case 1:
7043             CP0_CHECK(ctx->bi);
7044             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7045             register_name = "BadInstr";
7046             break;
7047         case 2:
7048             CP0_CHECK(ctx->bp);
7049             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7050             register_name = "BadInstrP";
7051             break;
7052         case 3:
7053             CP0_CHECK(ctx->bi);
7054             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7055             tcg_gen_andi_tl(arg, arg, ~0xffff);
7056             register_name = "BadInstrX";
7057             break;
7058        default:
7059             goto cp0_unimplemented;
7060         }
7061         break;
7062     case CP0_REGISTER_09:
7063         switch (sel) {
7064         case 0:
7065             /* Mark as an IO operation because we read the time.  */
7066             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7067                 gen_io_start();
7068             }
7069             gen_helper_mfc0_count(arg, cpu_env);
7070             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7071                 gen_io_end();
7072             }
7073             /* Break the TB to be able to take timer interrupts immediately
7074                after reading count. DISAS_STOP isn't sufficient, we need to
7075                ensure we break completely out of translated code.  */
7076             gen_save_pc(ctx->base.pc_next + 4);
7077             ctx->base.is_jmp = DISAS_EXIT;
7078             register_name = "Count";
7079             break;
7080         case 6:
7081             CP0_CHECK(ctx->saar);
7082             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7083             register_name = "SAARI";
7084             break;
7085         case 7:
7086             CP0_CHECK(ctx->saar);
7087             gen_helper_mfc0_saar(arg, cpu_env);
7088             register_name = "SAAR";
7089             break;
7090         default:
7091             goto cp0_unimplemented;
7092         }
7093         break;
7094     case CP0_REGISTER_10:
7095         switch (sel) {
7096         case 0:
7097             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7098             tcg_gen_ext32s_tl(arg, arg);
7099             register_name = "EntryHi";
7100             break;
7101         default:
7102             goto cp0_unimplemented;
7103         }
7104         break;
7105     case CP0_REGISTER_11:
7106         switch (sel) {
7107         case 0:
7108             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7109             register_name = "Compare";
7110             break;
7111         /* 6,7 are implementation dependent */
7112         default:
7113             goto cp0_unimplemented;
7114         }
7115         break;
7116     case CP0_REGISTER_12:
7117         switch (sel) {
7118         case 0:
7119             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7120             register_name = "Status";
7121             break;
7122         case 1:
7123             check_insn(ctx, ISA_MIPS32R2);
7124             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7125             register_name = "IntCtl";
7126             break;
7127         case 2:
7128             check_insn(ctx, ISA_MIPS32R2);
7129             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7130             register_name = "SRSCtl";
7131             break;
7132         case 3:
7133             check_insn(ctx, ISA_MIPS32R2);
7134             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7135             register_name = "SRSMap";
7136             break;
7137         default:
7138             goto cp0_unimplemented;
7139        }
7140         break;
7141     case CP0_REGISTER_13:
7142         switch (sel) {
7143         case 0:
7144             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7145             register_name = "Cause";
7146             break;
7147         default:
7148             goto cp0_unimplemented;
7149        }
7150         break;
7151     case CP0_REGISTER_14:
7152         switch (sel) {
7153         case 0:
7154             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7155             tcg_gen_ext32s_tl(arg, arg);
7156             register_name = "EPC";
7157             break;
7158         default:
7159             goto cp0_unimplemented;
7160         }
7161         break;
7162     case CP0_REGISTER_15:
7163         switch (sel) {
7164         case 0:
7165             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7166             register_name = "PRid";
7167             break;
7168         case 1:
7169             check_insn(ctx, ISA_MIPS32R2);
7170             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7171             tcg_gen_ext32s_tl(arg, arg);
7172             register_name = "EBase";
7173             break;
7174         case 3:
7175             check_insn(ctx, ISA_MIPS32R2);
7176             CP0_CHECK(ctx->cmgcr);
7177             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7178             tcg_gen_ext32s_tl(arg, arg);
7179             register_name = "CMGCRBase";
7180             break;
7181         default:
7182             goto cp0_unimplemented;
7183        }
7184         break;
7185     case CP0_REGISTER_16:
7186         switch (sel) {
7187         case 0:
7188             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7189             register_name = "Config";
7190             break;
7191         case 1:
7192             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7193             register_name = "Config1";
7194             break;
7195         case 2:
7196             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7197             register_name = "Config2";
7198             break;
7199         case 3:
7200             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7201             register_name = "Config3";
7202             break;
7203         case 4:
7204             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7205             register_name = "Config4";
7206             break;
7207         case 5:
7208             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7209             register_name = "Config5";
7210             break;
7211         /* 6,7 are implementation dependent */
7212         case 6:
7213             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7214             register_name = "Config6";
7215             break;
7216         case 7:
7217             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7218             register_name = "Config7";
7219             break;
7220         default:
7221             goto cp0_unimplemented;
7222         }
7223         break;
7224     case CP0_REGISTER_17:
7225         switch (sel) {
7226         case 0:
7227             gen_helper_mfc0_lladdr(arg, cpu_env);
7228             register_name = "LLAddr";
7229             break;
7230         case 1:
7231             CP0_CHECK(ctx->mrp);
7232             gen_helper_mfc0_maar(arg, cpu_env);
7233             register_name = "MAAR";
7234             break;
7235         case 2:
7236             CP0_CHECK(ctx->mrp);
7237             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7238             register_name = "MAARI";
7239             break;
7240         default:
7241             goto cp0_unimplemented;
7242         }
7243         break;
7244     case CP0_REGISTER_18:
7245         switch (sel) {
7246         case 0:
7247         case 1:
7248         case 2:
7249         case 3:
7250         case 4:
7251         case 5:
7252         case 6:
7253         case 7:
7254             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7255             gen_helper_1e0i(mfc0_watchlo, arg, sel);
7256             register_name = "WatchLo";
7257             break;
7258         default:
7259             goto cp0_unimplemented;
7260         }
7261         break;
7262     case CP0_REGISTER_19:
7263         switch (sel) {
7264         case 0:
7265         case 1:
7266         case 2:
7267         case 3:
7268         case 4:
7269         case 5:
7270         case 6:
7271         case 7:
7272             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7273             gen_helper_1e0i(mfc0_watchhi, arg, sel);
7274             register_name = "WatchHi";
7275             break;
7276         default:
7277             goto cp0_unimplemented;
7278         }
7279         break;
7280     case CP0_REGISTER_20:
7281         switch (sel) {
7282         case 0:
7283 #if defined(TARGET_MIPS64)
7284             check_insn(ctx, ISA_MIPS3);
7285             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7286             tcg_gen_ext32s_tl(arg, arg);
7287             register_name = "XContext";
7288             break;
7289 #endif
7290         default:
7291             goto cp0_unimplemented;
7292         }
7293         break;
7294     case CP0_REGISTER_21:
7295        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7296         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
7297         switch (sel) {
7298         case 0:
7299             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7300             register_name = "Framemask";
7301             break;
7302         default:
7303             goto cp0_unimplemented;
7304         }
7305         break;
7306     case CP0_REGISTER_22:
7307         tcg_gen_movi_tl(arg, 0); /* unimplemented */
7308         register_name = "'Diagnostic"; /* implementation dependent */
7309         break;
7310     case CP0_REGISTER_23:
7311         switch (sel) {
7312         case 0:
7313             gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7314             register_name = "Debug";
7315             break;
7316         case 1:
7317 //            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
7318             register_name = "TraceControl";
7319             goto cp0_unimplemented;
7320         case 2:
7321 //            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
7322             register_name = "TraceControl2";
7323             goto cp0_unimplemented;
7324         case 3:
7325 //            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
7326             register_name = "UserTraceData";
7327             goto cp0_unimplemented;
7328         case 4:
7329 //            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
7330             register_name = "TraceBPC";
7331             goto cp0_unimplemented;
7332         default:
7333             goto cp0_unimplemented;
7334         }
7335         break;
7336     case CP0_REGISTER_24:
7337         switch (sel) {
7338         case 0:
7339             /* EJTAG support */
7340             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7341             tcg_gen_ext32s_tl(arg, arg);
7342             register_name = "DEPC";
7343             break;
7344         default:
7345             goto cp0_unimplemented;
7346         }
7347         break;
7348     case CP0_REGISTER_25:
7349         switch (sel) {
7350         case 0:
7351             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7352             register_name = "Performance0";
7353             break;
7354         case 1:
7355 //            gen_helper_mfc0_performance1(arg);
7356             register_name = "Performance1";
7357             goto cp0_unimplemented;
7358         case 2:
7359 //            gen_helper_mfc0_performance2(arg);
7360             register_name = "Performance2";
7361             goto cp0_unimplemented;
7362         case 3:
7363 //            gen_helper_mfc0_performance3(arg);
7364             register_name = "Performance3";
7365             goto cp0_unimplemented;
7366         case 4:
7367 //            gen_helper_mfc0_performance4(arg);
7368             register_name = "Performance4";
7369             goto cp0_unimplemented;
7370         case 5:
7371 //            gen_helper_mfc0_performance5(arg);
7372             register_name = "Performance5";
7373             goto cp0_unimplemented;
7374         case 6:
7375 //            gen_helper_mfc0_performance6(arg);
7376             register_name = "Performance6";
7377             goto cp0_unimplemented;
7378         case 7:
7379 //            gen_helper_mfc0_performance7(arg);
7380             register_name = "Performance7";
7381             goto cp0_unimplemented;
7382         default:
7383             goto cp0_unimplemented;
7384         }
7385         break;
7386     case CP0_REGISTER_26:
7387         switch (sel) {
7388         case 0:
7389             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7390             register_name = "ErrCtl";
7391             break;
7392         default:
7393             goto cp0_unimplemented;
7394         }
7395         break;
7396     case CP0_REGISTER_27:
7397         switch (sel) {
7398         case 0:
7399         case 1:
7400         case 2:
7401         case 3:
7402             tcg_gen_movi_tl(arg, 0); /* unimplemented */
7403             register_name = "CacheErr";
7404             break;
7405         default:
7406             goto cp0_unimplemented;
7407         }
7408         break;
7409     case CP0_REGISTER_28:
7410         switch (sel) {
7411         case 0:
7412         case 2:
7413         case 4:
7414         case 6:
7415             {
7416                 TCGv_i64 tmp = tcg_temp_new_i64();
7417                 tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
7418                 gen_move_low32(arg, tmp);
7419                 tcg_temp_free_i64(tmp);
7420             }
7421             register_name = "TagLo";
7422             break;
7423         case 1:
7424         case 3:
7425         case 5:
7426         case 7:
7427             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7428             register_name = "DataLo";
7429             break;
7430         default:
7431             goto cp0_unimplemented;
7432         }
7433         break;
7434     case CP0_REGISTER_29:
7435         switch (sel) {
7436         case 0:
7437         case 2:
7438         case 4:
7439         case 6:
7440             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7441             register_name = "TagHi";
7442             break;
7443         case 1:
7444         case 3:
7445         case 5:
7446         case 7:
7447             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7448             register_name = "DataHi";
7449             break;
7450         default:
7451             goto cp0_unimplemented;
7452         }
7453         break;
7454     case CP0_REGISTER_30:
7455         switch (sel) {
7456         case 0:
7457             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7458             tcg_gen_ext32s_tl(arg, arg);
7459             register_name = "ErrorEPC";
7460             break;
7461         default:
7462             goto cp0_unimplemented;
7463         }
7464         break;
7465     case CP0_REGISTER_31:
7466         switch (sel) {
7467         case 0:
7468             /* EJTAG support */
7469             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7470             register_name = "DESAVE";
7471             break;
7472         case 2:
7473         case 3:
7474         case 4:
7475         case 5:
7476         case 6:
7477         case 7:
7478             CP0_CHECK(ctx->kscrexist & (1 << sel));
7479             tcg_gen_ld_tl(arg, cpu_env,
7480                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
7481             tcg_gen_ext32s_tl(arg, arg);
7482             register_name = "KScratch";
7483             break;
7484         default:
7485             goto cp0_unimplemented;
7486         }
7487         break;
7488     default:
7489        goto cp0_unimplemented;
7490     }
7491     trace_mips_translate_c0("mfc0", register_name, reg, sel);
7492     return;
7493
7494 cp0_unimplemented:
7495     qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
7496                   register_name, reg, sel);
7497     gen_mfc0_unimplemented(ctx, arg);
7498 }
7499
7500 static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7501 {
7502     const char *register_name = "invalid";
7503
7504     if (sel != 0)
7505         check_insn(ctx, ISA_MIPS32);
7506
7507     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7508         gen_io_start();
7509     }
7510
7511     switch (reg) {
7512     case CP0_REGISTER_00:
7513         switch (sel) {
7514         case 0:
7515             gen_helper_mtc0_index(cpu_env, arg);
7516             register_name = "Index";
7517             break;
7518         case 1:
7519             CP0_CHECK(ctx->insn_flags & ASE_MT);
7520             gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7521             register_name = "MVPControl";
7522             break;
7523         case 2:
7524             CP0_CHECK(ctx->insn_flags & ASE_MT);
7525             /* ignored */
7526             register_name = "MVPConf0";
7527             break;
7528         case 3:
7529             CP0_CHECK(ctx->insn_flags & ASE_MT);
7530             /* ignored */
7531             register_name = "MVPConf1";
7532             break;
7533         case 4:
7534             CP0_CHECK(ctx->vp);
7535             /* ignored */
7536             register_name = "VPControl";
7537             break;
7538         default:
7539             goto cp0_unimplemented;
7540         }
7541         break;
7542     case CP0_REGISTER_01:
7543         switch (sel) {
7544         case 0:
7545             /* ignored */
7546             register_name = "Random";
7547             break;
7548         case 1:
7549             CP0_CHECK(ctx->insn_flags & ASE_MT);
7550             gen_helper_mtc0_vpecontrol(cpu_env, arg);
7551             register_name = "VPEControl";
7552             break;
7553         case 2:
7554             CP0_CHECK(ctx->insn_flags & ASE_MT);
7555             gen_helper_mtc0_vpeconf0(cpu_env, arg);
7556             register_name = "VPEConf0";
7557             break;
7558         case 3:
7559             CP0_CHECK(ctx->insn_flags & ASE_MT);
7560             gen_helper_mtc0_vpeconf1(cpu_env, arg);
7561             register_name = "VPEConf1";
7562             break;
7563         case 4:
7564             CP0_CHECK(ctx->insn_flags & ASE_MT);
7565             gen_helper_mtc0_yqmask(cpu_env, arg);
7566             register_name = "YQMask";
7567             break;
7568         case 5:
7569             CP0_CHECK(ctx->insn_flags & ASE_MT);
7570             tcg_gen_st_tl(arg, cpu_env,
7571                           offsetof(CPUMIPSState, CP0_VPESchedule));
7572             register_name = "VPESchedule";
7573             break;
7574         case 6:
7575             CP0_CHECK(ctx->insn_flags & ASE_MT);
7576             tcg_gen_st_tl(arg, cpu_env,
7577                           offsetof(CPUMIPSState, CP0_VPEScheFBack));
7578             register_name = "VPEScheFBack";
7579             break;
7580         case 7:
7581             CP0_CHECK(ctx->insn_flags & ASE_MT);
7582             gen_helper_mtc0_vpeopt(cpu_env, arg);
7583             register_name = "VPEOpt";
7584             break;
7585         default:
7586             goto cp0_unimplemented;
7587         }
7588         break;
7589     case CP0_REGISTER_02:
7590         switch (sel) {
7591         case 0:
7592             gen_helper_mtc0_entrylo0(cpu_env, arg);
7593             register_name = "EntryLo0";
7594             break;
7595         case 1:
7596             CP0_CHECK(ctx->insn_flags & ASE_MT);
7597             gen_helper_mtc0_tcstatus(cpu_env, arg);
7598             register_name = "TCStatus";
7599             break;
7600         case 2:
7601             CP0_CHECK(ctx->insn_flags & ASE_MT);
7602             gen_helper_mtc0_tcbind(cpu_env, arg);
7603             register_name = "TCBind";
7604             break;
7605         case 3:
7606             CP0_CHECK(ctx->insn_flags & ASE_MT);
7607             gen_helper_mtc0_tcrestart(cpu_env, arg);
7608             register_name = "TCRestart";
7609             break;
7610         case 4:
7611             CP0_CHECK(ctx->insn_flags & ASE_MT);
7612             gen_helper_mtc0_tchalt(cpu_env, arg);
7613             register_name = "TCHalt";
7614             break;
7615         case 5:
7616             CP0_CHECK(ctx->insn_flags & ASE_MT);
7617             gen_helper_mtc0_tccontext(cpu_env, arg);
7618             register_name = "TCContext";
7619             break;
7620         case 6:
7621             CP0_CHECK(ctx->insn_flags & ASE_MT);
7622             gen_helper_mtc0_tcschedule(cpu_env, arg);
7623             register_name = "TCSchedule";
7624             break;
7625         case 7:
7626             CP0_CHECK(ctx->insn_flags & ASE_MT);
7627             gen_helper_mtc0_tcschefback(cpu_env, arg);
7628             register_name = "TCScheFBack";
7629             break;
7630         default:
7631             goto cp0_unimplemented;
7632         }
7633         break;
7634     case CP0_REGISTER_03:
7635         switch (sel) {
7636         case 0:
7637             gen_helper_mtc0_entrylo1(cpu_env, arg);
7638             register_name = "EntryLo1";
7639             break;
7640         case 1:
7641             CP0_CHECK(ctx->vp);
7642             /* ignored */
7643             register_name = "GlobalNumber";
7644             break;
7645         default:
7646             goto cp0_unimplemented;
7647         }
7648         break;
7649     case CP0_REGISTER_04:
7650         switch (sel) {
7651         case 0:
7652             gen_helper_mtc0_context(cpu_env, arg);
7653             register_name = "Context";
7654             break;
7655         case 1:
7656 //            gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
7657             register_name = "ContextConfig";
7658             goto cp0_unimplemented;
7659         case 2:
7660             CP0_CHECK(ctx->ulri);
7661             tcg_gen_st_tl(arg, cpu_env,
7662                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7663             register_name = "UserLocal";
7664             break;
7665         default:
7666             goto cp0_unimplemented;
7667         }
7668         break;
7669     case CP0_REGISTER_05:
7670         switch (sel) {
7671         case 0:
7672             gen_helper_mtc0_pagemask(cpu_env, arg);
7673             register_name = "PageMask";
7674             break;
7675         case 1:
7676             check_insn(ctx, ISA_MIPS32R2);
7677             gen_helper_mtc0_pagegrain(cpu_env, arg);
7678             register_name = "PageGrain";
7679             ctx->base.is_jmp = DISAS_STOP;
7680             break;
7681         case 2:
7682             CP0_CHECK(ctx->sc);
7683             gen_helper_mtc0_segctl0(cpu_env, arg);
7684             register_name = "SegCtl0";
7685             break;
7686         case 3:
7687             CP0_CHECK(ctx->sc);
7688             gen_helper_mtc0_segctl1(cpu_env, arg);
7689             register_name = "SegCtl1";
7690             break;
7691         case 4:
7692             CP0_CHECK(ctx->sc);
7693             gen_helper_mtc0_segctl2(cpu_env, arg);
7694             register_name = "SegCtl2";
7695             break;
7696         case 5:
7697             check_pw(ctx);
7698             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
7699             register_name = "PWBase";
7700             break;
7701         case 6:
7702             check_pw(ctx);
7703             gen_helper_mtc0_pwfield(cpu_env, arg);
7704             register_name = "PWField";
7705             break;
7706         case 7:
7707             check_pw(ctx);
7708             gen_helper_mtc0_pwsize(cpu_env, arg);
7709             register_name = "PWSize";
7710             break;
7711         default:
7712             goto cp0_unimplemented;
7713         }
7714         break;
7715     case CP0_REGISTER_06:
7716         switch (sel) {
7717         case 0:
7718             gen_helper_mtc0_wired(cpu_env, arg);
7719             register_name = "Wired";
7720             break;
7721         case 1:
7722             check_insn(ctx, ISA_MIPS32R2);
7723             gen_helper_mtc0_srsconf0(cpu_env, arg);
7724             register_name = "SRSConf0";
7725             break;
7726         case 2:
7727             check_insn(ctx, ISA_MIPS32R2);
7728             gen_helper_mtc0_srsconf1(cpu_env, arg);
7729             register_name = "SRSConf1";
7730             break;
7731         case 3:
7732             check_insn(ctx, ISA_MIPS32R2);
7733             gen_helper_mtc0_srsconf2(cpu_env, arg);
7734             register_name = "SRSConf2";
7735             break;
7736         case 4:
7737             check_insn(ctx, ISA_MIPS32R2);
7738             gen_helper_mtc0_srsconf3(cpu_env, arg);
7739             register_name = "SRSConf3";
7740             break;
7741         case 5:
7742             check_insn(ctx, ISA_MIPS32R2);
7743             gen_helper_mtc0_srsconf4(cpu_env, arg);
7744             register_name = "SRSConf4";
7745             break;
7746         case 6:
7747             check_pw(ctx);
7748             gen_helper_mtc0_pwctl(cpu_env, arg);
7749             register_name = "PWCtl";
7750             break;
7751         default:
7752             goto cp0_unimplemented;
7753         }
7754         break;
7755     case CP0_REGISTER_07:
7756         switch (sel) {
7757         case 0:
7758             check_insn(ctx, ISA_MIPS32R2);
7759             gen_helper_mtc0_hwrena(cpu_env, arg);
7760             ctx->base.is_jmp = DISAS_STOP;
7761             register_name = "HWREna";
7762             break;
7763         default:
7764             goto cp0_unimplemented;
7765         }
7766         break;
7767     case CP0_REGISTER_08:
7768         switch (sel) {
7769         case 0:
7770             /* ignored */
7771             register_name = "BadVAddr";
7772             break;
7773         case 1:
7774             /* ignored */
7775             register_name = "BadInstr";
7776             break;
7777         case 2:
7778             /* ignored */
7779             register_name = "BadInstrP";
7780             break;
7781         case 3:
7782             /* ignored */
7783             register_name = "BadInstrX";
7784             break;
7785         default:
7786             goto cp0_unimplemented;
7787         }
7788         break;
7789     case CP0_REGISTER_09:
7790         switch (sel) {
7791         case 0:
7792             gen_helper_mtc0_count(cpu_env, arg);
7793             register_name = "Count";
7794             break;
7795         case 6:
7796             CP0_CHECK(ctx->saar);
7797             gen_helper_mtc0_saari(cpu_env, arg);
7798             register_name = "SAARI";
7799             break;
7800         case 7:
7801             CP0_CHECK(ctx->saar);
7802             gen_helper_mtc0_saar(cpu_env, arg);
7803             register_name = "SAAR";
7804             break;
7805         default:
7806             goto cp0_unimplemented;
7807         }
7808         break;
7809     case CP0_REGISTER_10:
7810         switch (sel) {
7811         case 0:
7812             gen_helper_mtc0_entryhi(cpu_env, arg);
7813             register_name = "EntryHi";
7814             break;
7815         default:
7816             goto cp0_unimplemented;
7817         }
7818         break;
7819     case CP0_REGISTER_11:
7820         switch (sel) {
7821         case 0:
7822             gen_helper_mtc0_compare(cpu_env, arg);
7823             register_name = "Compare";
7824             break;
7825         /* 6,7 are implementation dependent */
7826         default:
7827             goto cp0_unimplemented;
7828         }
7829         break;
7830     case CP0_REGISTER_12:
7831         switch (sel) {
7832         case 0:
7833             save_cpu_state(ctx, 1);
7834             gen_helper_mtc0_status(cpu_env, arg);
7835             /* DISAS_STOP isn't good enough here, hflags may have changed. */
7836             gen_save_pc(ctx->base.pc_next + 4);
7837             ctx->base.is_jmp = DISAS_EXIT;
7838             register_name = "Status";
7839             break;
7840         case 1:
7841             check_insn(ctx, ISA_MIPS32R2);
7842             gen_helper_mtc0_intctl(cpu_env, arg);
7843             /* Stop translation as we may have switched the execution mode */
7844             ctx->base.is_jmp = DISAS_STOP;
7845             register_name = "IntCtl";
7846             break;
7847         case 2:
7848             check_insn(ctx, ISA_MIPS32R2);
7849             gen_helper_mtc0_srsctl(cpu_env, arg);
7850             /* Stop translation as we may have switched the execution mode */
7851             ctx->base.is_jmp = DISAS_STOP;
7852             register_name = "SRSCtl";
7853             break;
7854         case 3:
7855             check_insn(ctx, ISA_MIPS32R2);
7856             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7857             /* Stop translation as we may have switched the execution mode */
7858             ctx->base.is_jmp = DISAS_STOP;
7859             register_name = "SRSMap";
7860             break;
7861         default:
7862             goto cp0_unimplemented;
7863         }
7864         break;
7865     case CP0_REGISTER_13:
7866         switch (sel) {
7867         case 0:
7868             save_cpu_state(ctx, 1);
7869             gen_helper_mtc0_cause(cpu_env, arg);
7870             /* Stop translation as we may have triggered an interrupt.
7871              * DISAS_STOP isn't sufficient, we need to ensure we break out of
7872              * translated code to check for pending interrupts.  */
7873             gen_save_pc(ctx->base.pc_next + 4);
7874             ctx->base.is_jmp = DISAS_EXIT;
7875             register_name = "Cause";
7876             break;
7877         default:
7878             goto cp0_unimplemented;
7879         }
7880         break;
7881     case CP0_REGISTER_14:
7882         switch (sel) {
7883         case 0:
7884             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7885             register_name = "EPC";
7886             break;
7887         default:
7888             goto cp0_unimplemented;
7889         }
7890         break;
7891     case CP0_REGISTER_15:
7892         switch (sel) {
7893         case 0:
7894             /* ignored */
7895             register_name = "PRid";
7896             break;
7897         case 1:
7898             check_insn(ctx, ISA_MIPS32R2);
7899             gen_helper_mtc0_ebase(cpu_env, arg);
7900             register_name = "EBase";
7901             break;
7902         default:
7903             goto cp0_unimplemented;
7904         }
7905         break;
7906     case CP0_REGISTER_16:
7907         switch (sel) {
7908         case 0:
7909             gen_helper_mtc0_config0(cpu_env, arg);
7910             register_name = "Config";
7911             /* Stop translation as we may have switched the execution mode */
7912             ctx->base.is_jmp = DISAS_STOP;
7913             break;
7914         case 1:
7915             /* ignored, read only */
7916             register_name = "Config1";
7917             break;
7918         case 2:
7919             gen_helper_mtc0_config2(cpu_env, arg);
7920             register_name = "Config2";
7921             /* Stop translation as we may have switched the execution mode */
7922             ctx->base.is_jmp = DISAS_STOP;
7923             break;
7924         case 3:
7925             gen_helper_mtc0_config3(cpu_env, arg);
7926             register_name = "Config3";
7927             /* Stop translation as we may have switched the execution mode */
7928             ctx->base.is_jmp = DISAS_STOP;
7929             break;
7930         case 4:
7931             gen_helper_mtc0_config4(cpu_env, arg);
7932             register_name = "Config4";
7933             ctx->base.is_jmp = DISAS_STOP;
7934             break;
7935         case 5:
7936             gen_helper_mtc0_config5(cpu_env, arg);
7937             register_name = "Config5";
7938             /* Stop translation as we may have switched the execution mode */
7939             ctx->base.is_jmp = DISAS_STOP;
7940             break;
7941         /* 6,7 are implementation dependent */
7942         case 6:
7943             /* ignored */
7944             register_name = "Config6";
7945             break;
7946         case 7:
7947             /* ignored */
7948             register_name = "Config7";
7949             break;
7950         default:
7951             register_name = "Invalid config selector";
7952             goto cp0_unimplemented;
7953         }
7954         break;
7955     case CP0_REGISTER_17:
7956         switch (sel) {
7957         case 0:
7958             gen_helper_mtc0_lladdr(cpu_env, arg);
7959             register_name = "LLAddr";
7960             break;
7961         case 1:
7962             CP0_CHECK(ctx->mrp);
7963             gen_helper_mtc0_maar(cpu_env, arg);
7964             register_name = "MAAR";
7965             break;
7966         case 2:
7967             CP0_CHECK(ctx->mrp);
7968             gen_helper_mtc0_maari(cpu_env, arg);
7969             register_name = "MAARI";
7970             break;
7971         default:
7972             goto cp0_unimplemented;
7973         }
7974         break;
7975     case CP0_REGISTER_18:
7976         switch (sel) {
7977         case 0:
7978         case 1:
7979         case 2:
7980         case 3:
7981         case 4:
7982         case 5:
7983         case 6:
7984         case 7:
7985             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7986             gen_helper_0e1i(mtc0_watchlo, arg, sel);
7987             register_name = "WatchLo";
7988             break;
7989         default:
7990             goto cp0_unimplemented;
7991         }
7992         break;
7993     case CP0_REGISTER_19:
7994         switch (sel) {
7995         case 0:
7996         case 1:
7997         case 2:
7998         case 3:
7999         case 4:
8000         case 5:
8001         case 6:
8002         case 7:
8003             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8004             gen_helper_0e1i(mtc0_watchhi, arg, sel);
8005             register_name = "WatchHi";
8006             break;
8007         default:
8008             goto cp0_unimplemented;
8009         }
8010         break;
8011     case CP0_REGISTER_20:
8012         switch (sel) {
8013         case 0:
8014 #if defined(TARGET_MIPS64)
8015             check_insn(ctx, ISA_MIPS3);
8016             gen_helper_mtc0_xcontext(cpu_env, arg);
8017             register_name = "XContext";
8018             break;
8019 #endif
8020         default:
8021             goto cp0_unimplemented;
8022         }
8023         break;
8024     case CP0_REGISTER_21:
8025        /* Officially reserved, but sel 0 is used for R1x000 framemask */
8026         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8027         switch (sel) {
8028         case 0:
8029             gen_helper_mtc0_framemask(cpu_env, arg);
8030             register_name = "Framemask";
8031             break;
8032         default:
8033             goto cp0_unimplemented;
8034         }
8035         break;
8036     case CP0_REGISTER_22:
8037         /* ignored */
8038         register_name = "Diagnostic"; /* implementation dependent */
8039         break;
8040     case CP0_REGISTER_23:
8041         switch (sel) {
8042         case 0:
8043             gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8044             /* DISAS_STOP isn't good enough here, hflags may have changed. */
8045             gen_save_pc(ctx->base.pc_next + 4);
8046             ctx->base.is_jmp = DISAS_EXIT;
8047             register_name = "Debug";
8048             break;
8049         case 1:
8050 //            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
8051             register_name = "TraceControl";
8052             /* Stop translation as we may have switched the execution mode */
8053             ctx->base.is_jmp = DISAS_STOP;
8054             goto cp0_unimplemented;
8055         case 2:
8056 //            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
8057             register_name = "TraceControl2";
8058             /* Stop translation as we may have switched the execution mode */
8059             ctx->base.is_jmp = DISAS_STOP;
8060             goto cp0_unimplemented;
8061         case 3:
8062             /* Stop translation as we may have switched the execution mode */
8063             ctx->base.is_jmp = DISAS_STOP;
8064 //            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
8065             register_name = "UserTraceData";
8066             /* Stop translation as we may have switched the execution mode */
8067             ctx->base.is_jmp = DISAS_STOP;
8068             goto cp0_unimplemented;
8069         case 4:
8070 //            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
8071             /* Stop translation as we may have switched the execution mode */
8072             ctx->base.is_jmp = DISAS_STOP;
8073             register_name = "TraceBPC";
8074             goto cp0_unimplemented;
8075         default:
8076             goto cp0_unimplemented;
8077         }
8078         break;
8079     case CP0_REGISTER_24:
8080         switch (sel) {
8081         case 0:
8082             /* EJTAG support */
8083             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8084             register_name = "DEPC";
8085             break;
8086         default:
8087             goto cp0_unimplemented;
8088         }
8089         break;
8090     case CP0_REGISTER_25:
8091         switch (sel) {
8092         case 0:
8093             gen_helper_mtc0_performance0(cpu_env, arg);
8094             register_name = "Performance0";
8095             break;
8096         case 1:
8097 //            gen_helper_mtc0_performance1(arg);
8098             register_name = "Performance1";
8099             goto cp0_unimplemented;
8100         case 2:
8101 //            gen_helper_mtc0_performance2(arg);
8102             register_name = "Performance2";
8103             goto cp0_unimplemented;
8104         case 3:
8105 //            gen_helper_mtc0_performance3(arg);
8106             register_name = "Performance3";
8107             goto cp0_unimplemented;
8108         case 4:
8109 //            gen_helper_mtc0_performance4(arg);
8110             register_name = "Performance4";
8111             goto cp0_unimplemented;
8112         case 5:
8113 //            gen_helper_mtc0_performance5(arg);
8114             register_name = "Performance5";
8115             goto cp0_unimplemented;
8116         case 6:
8117 //            gen_helper_mtc0_performance6(arg);
8118             register_name = "Performance6";
8119             goto cp0_unimplemented;
8120         case 7:
8121 //            gen_helper_mtc0_performance7(arg);
8122             register_name = "Performance7";
8123             goto cp0_unimplemented;
8124         default:
8125             goto cp0_unimplemented;
8126         }
8127        break;
8128     case CP0_REGISTER_26:
8129         switch (sel) {
8130         case 0:
8131             gen_helper_mtc0_errctl(cpu_env, arg);
8132             ctx->base.is_jmp = DISAS_STOP;
8133             register_name = "ErrCtl";
8134             break;
8135         default:
8136             goto cp0_unimplemented;
8137         }
8138         break;
8139     case CP0_REGISTER_27:
8140         switch (sel) {
8141         case 0:
8142         case 1:
8143         case 2:
8144         case 3:
8145             /* ignored */
8146             register_name = "CacheErr";
8147             break;
8148         default:
8149             goto cp0_unimplemented;
8150         }
8151        break;
8152     case CP0_REGISTER_28:
8153         switch (sel) {
8154         case 0:
8155         case 2:
8156         case 4:
8157         case 6:
8158             gen_helper_mtc0_taglo(cpu_env, arg);
8159             register_name = "TagLo";
8160             break;
8161         case 1:
8162         case 3:
8163         case 5:
8164         case 7:
8165             gen_helper_mtc0_datalo(cpu_env, arg);
8166             register_name = "DataLo";
8167             break;
8168         default:
8169             goto cp0_unimplemented;
8170         }
8171         break;
8172     case CP0_REGISTER_29:
8173         switch (sel) {
8174         case 0:
8175         case 2:
8176         case 4:
8177         case 6:
8178             gen_helper_mtc0_taghi(cpu_env, arg);
8179             register_name = "TagHi";
8180             break;
8181         case 1:
8182         case 3:
8183         case 5:
8184         case 7:
8185             gen_helper_mtc0_datahi(cpu_env, arg);
8186             register_name = "DataHi";
8187             break;
8188         default:
8189             register_name = "invalid sel";
8190             goto cp0_unimplemented;
8191         }
8192        break;
8193     case CP0_REGISTER_30:
8194         switch (sel) {
8195         case 0:
8196             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8197             register_name = "ErrorEPC";
8198             break;
8199         default:
8200             goto cp0_unimplemented;
8201         }
8202         break;
8203     case CP0_REGISTER_31:
8204         switch (sel) {
8205         case 0:
8206             /* EJTAG support */
8207             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8208             register_name = "DESAVE";
8209             break;
8210         case 2:
8211         case 3:
8212         case 4:
8213         case 5:
8214         case 6:
8215         case 7:
8216             CP0_CHECK(ctx->kscrexist & (1 << sel));
8217             tcg_gen_st_tl(arg, cpu_env,
8218                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8219             register_name = "KScratch";
8220             break;
8221         default:
8222             goto cp0_unimplemented;
8223         }
8224         break;
8225     default:
8226        goto cp0_unimplemented;
8227     }
8228     trace_mips_translate_c0("mtc0", register_name, reg, sel);
8229
8230     /* For simplicity assume that all writes can cause interrupts.  */
8231     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8232         gen_io_end();
8233         /* DISAS_STOP isn't sufficient, we need to ensure we break out of
8234          * translated code to check for pending interrupts.  */
8235         gen_save_pc(ctx->base.pc_next + 4);
8236         ctx->base.is_jmp = DISAS_EXIT;
8237     }
8238     return;
8239
8240 cp0_unimplemented:
8241     qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
8242                   register_name, reg, sel);
8243 }
8244
8245 #if defined(TARGET_MIPS64)
8246 static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8247 {
8248     const char *register_name = "invalid";
8249
8250     if (sel != 0)
8251         check_insn(ctx, ISA_MIPS64);
8252
8253     switch (reg) {
8254     case CP0_REGISTER_00:
8255         switch (sel) {
8256         case 0:
8257             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
8258             register_name = "Index";
8259             break;
8260         case 1:
8261             CP0_CHECK(ctx->insn_flags & ASE_MT);
8262             gen_helper_mfc0_mvpcontrol(arg, cpu_env);
8263             register_name = "MVPControl";
8264             break;
8265         case 2:
8266             CP0_CHECK(ctx->insn_flags & ASE_MT);
8267             gen_helper_mfc0_mvpconf0(arg, cpu_env);
8268             register_name = "MVPConf0";
8269             break;
8270         case 3:
8271             CP0_CHECK(ctx->insn_flags & ASE_MT);
8272             gen_helper_mfc0_mvpconf1(arg, cpu_env);
8273             register_name = "MVPConf1";
8274             break;
8275         case 4:
8276             CP0_CHECK(ctx->vp);
8277             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
8278             register_name = "VPControl";
8279             break;
8280         default:
8281             goto cp0_unimplemented;
8282         }
8283         break;
8284     case CP0_REGISTER_01:
8285         switch (sel) {
8286         case 0:
8287             CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8288             gen_helper_mfc0_random(arg, cpu_env);
8289             register_name = "Random";
8290             break;
8291         case 1:
8292             CP0_CHECK(ctx->insn_flags & ASE_MT);
8293             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
8294             register_name = "VPEControl";
8295             break;
8296         case 2:
8297             CP0_CHECK(ctx->insn_flags & ASE_MT);
8298             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
8299             register_name = "VPEConf0";
8300             break;
8301         case 3:
8302             CP0_CHECK(ctx->insn_flags & ASE_MT);
8303             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
8304             register_name = "VPEConf1";
8305             break;
8306         case 4:
8307             CP0_CHECK(ctx->insn_flags & ASE_MT);
8308             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
8309             register_name = "YQMask";
8310             break;
8311         case 5:
8312             CP0_CHECK(ctx->insn_flags & ASE_MT);
8313             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
8314             register_name = "VPESchedule";
8315             break;
8316         case 6:
8317             CP0_CHECK(ctx->insn_flags & ASE_MT);
8318             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
8319             register_name = "VPEScheFBack";
8320             break;
8321         case 7:
8322             CP0_CHECK(ctx->insn_flags & ASE_MT);
8323             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
8324             register_name = "VPEOpt";
8325             break;
8326         default:
8327             goto cp0_unimplemented;
8328         }
8329         break;
8330     case CP0_REGISTER_02:
8331         switch (sel) {
8332         case 0:
8333             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
8334             register_name = "EntryLo0";
8335             break;
8336         case 1:
8337             CP0_CHECK(ctx->insn_flags & ASE_MT);
8338             gen_helper_mfc0_tcstatus(arg, cpu_env);
8339             register_name = "TCStatus";
8340             break;
8341         case 2:
8342             CP0_CHECK(ctx->insn_flags & ASE_MT);
8343             gen_helper_mfc0_tcbind(arg, cpu_env);
8344             register_name = "TCBind";
8345             break;
8346         case 3:
8347             CP0_CHECK(ctx->insn_flags & ASE_MT);
8348             gen_helper_dmfc0_tcrestart(arg, cpu_env);
8349             register_name = "TCRestart";
8350             break;
8351         case 4:
8352             CP0_CHECK(ctx->insn_flags & ASE_MT);
8353             gen_helper_dmfc0_tchalt(arg, cpu_env);
8354             register_name = "TCHalt";
8355             break;
8356         case 5:
8357             CP0_CHECK(ctx->insn_flags & ASE_MT);
8358             gen_helper_dmfc0_tccontext(arg, cpu_env);
8359             register_name = "TCContext";
8360             break;
8361         case 6:
8362             CP0_CHECK(ctx->insn_flags & ASE_MT);
8363             gen_helper_dmfc0_tcschedule(arg, cpu_env);
8364             register_name = "TCSchedule";
8365             break;
8366         case 7:
8367             CP0_CHECK(ctx->insn_flags & ASE_MT);
8368             gen_helper_dmfc0_tcschefback(arg, cpu_env);
8369             register_name = "TCScheFBack";
8370             break;
8371         default:
8372             goto cp0_unimplemented;
8373         }
8374         break;
8375     case CP0_REGISTER_03:
8376         switch (sel) {
8377         case 0:
8378             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
8379             register_name = "EntryLo1";
8380             break;
8381         case 1:
8382             CP0_CHECK(ctx->vp);
8383             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
8384             register_name = "GlobalNumber";
8385             break;
8386         default:
8387             goto cp0_unimplemented;
8388         }
8389         break;
8390     case CP0_REGISTER_04:
8391         switch (sel) {
8392         case 0:
8393             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
8394             register_name = "Context";
8395             break;
8396         case 1:
8397 //            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
8398             register_name = "ContextConfig";
8399             goto cp0_unimplemented;
8400         case 2:
8401             CP0_CHECK(ctx->ulri);
8402             tcg_gen_ld_tl(arg, cpu_env,
8403                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8404             register_name = "UserLocal";
8405             break;
8406         default:
8407             goto cp0_unimplemented;
8408         }
8409         break;
8410     case CP0_REGISTER_05:
8411         switch (sel) {
8412         case 0:
8413             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
8414             register_name = "PageMask";
8415             break;
8416         case 1:
8417             check_insn(ctx, ISA_MIPS32R2);
8418             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
8419             register_name = "PageGrain";
8420             break;
8421         case 2:
8422             CP0_CHECK(ctx->sc);
8423             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
8424             register_name = "SegCtl0";
8425             break;
8426         case 3:
8427             CP0_CHECK(ctx->sc);
8428             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
8429             register_name = "SegCtl1";
8430             break;
8431         case 4:
8432             CP0_CHECK(ctx->sc);
8433             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
8434             register_name = "SegCtl2";
8435             break;
8436         case 5:
8437             check_pw(ctx);
8438             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8439             register_name = "PWBase";
8440             break;
8441         case 6:
8442             check_pw(ctx);
8443             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
8444             register_name = "PWField";
8445             break;
8446         case 7:
8447             check_pw(ctx);
8448             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
8449             register_name = "PWSize";
8450             break;
8451         default:
8452             goto cp0_unimplemented;
8453         }
8454         break;
8455     case CP0_REGISTER_06:
8456         switch (sel) {
8457         case 0:
8458             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
8459             register_name = "Wired";
8460             break;
8461         case 1:
8462             check_insn(ctx, ISA_MIPS32R2);
8463             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
8464             register_name = "SRSConf0";
8465             break;
8466         case 2:
8467             check_insn(ctx, ISA_MIPS32R2);
8468             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
8469             register_name = "SRSConf1";
8470             break;
8471         case 3:
8472             check_insn(ctx, ISA_MIPS32R2);
8473             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
8474             register_name = "SRSConf2";
8475             break;
8476         case 4:
8477             check_insn(ctx, ISA_MIPS32R2);
8478             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
8479             register_name = "SRSConf3";
8480             break;
8481         case 5:
8482             check_insn(ctx, ISA_MIPS32R2);
8483             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
8484             register_name = "SRSConf4";
8485             break;
8486         case 6:
8487             check_pw(ctx);
8488             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
8489             register_name = "PWCtl";
8490             break;
8491         default:
8492             goto cp0_unimplemented;
8493         }
8494         break;
8495     case CP0_REGISTER_07:
8496         switch (sel) {
8497         case 0:
8498             check_insn(ctx, ISA_MIPS32R2);
8499             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
8500             register_name = "HWREna";
8501             break;
8502         default:
8503             goto cp0_unimplemented;
8504         }
8505         break;
8506     case CP0_REGISTER_08:
8507         switch (sel) {
8508         case 0:
8509             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
8510             register_name = "BadVAddr";
8511             break;
8512         case 1:
8513             CP0_CHECK(ctx->bi);
8514             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
8515             register_name = "BadInstr";
8516             break;
8517         case 2:
8518             CP0_CHECK(ctx->bp);
8519             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
8520             register_name = "BadInstrP";
8521             break;
8522         case 3:
8523             CP0_CHECK(ctx->bi);
8524             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
8525             tcg_gen_andi_tl(arg, arg, ~0xffff);
8526             register_name = "BadInstrX";
8527             break;
8528         default:
8529             goto cp0_unimplemented;
8530         }
8531         break;
8532     case CP0_REGISTER_09:
8533         switch (sel) {
8534         case 0:
8535             /* Mark as an IO operation because we read the time.  */
8536             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8537                 gen_io_start();
8538             }
8539             gen_helper_mfc0_count(arg, cpu_env);
8540             if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8541                 gen_io_end();
8542             }
8543             /* Break the TB to be able to take timer interrupts immediately
8544                after reading count. DISAS_STOP isn't sufficient, we need to
8545                ensure we break completely out of translated code.  */
8546             gen_save_pc(ctx->base.pc_next + 4);
8547             ctx->base.is_jmp = DISAS_EXIT;
8548             register_name = "Count";
8549             break;
8550         case 6:
8551             CP0_CHECK(ctx->saar);
8552             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
8553             register_name = "SAARI";
8554             break;
8555         case 7:
8556             CP0_CHECK(ctx->saar);
8557             gen_helper_dmfc0_saar(arg, cpu_env);
8558             register_name = "SAAR";
8559             break;
8560         default:
8561             goto cp0_unimplemented;
8562         }
8563         break;
8564     case CP0_REGISTER_10:
8565         switch (sel) {
8566         case 0:
8567             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
8568             register_name = "EntryHi";
8569             break;
8570         default:
8571             goto cp0_unimplemented;
8572         }
8573         break;
8574     case CP0_REGISTER_11:
8575         switch (sel) {
8576         case 0:
8577             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
8578             register_name = "Compare";
8579             break;
8580         /* 6,7 are implementation dependent */
8581         default:
8582             goto cp0_unimplemented;
8583         }
8584         break;
8585     case CP0_REGISTER_12:
8586         switch (sel) {
8587         case 0:
8588             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
8589             register_name = "Status";
8590             break;
8591         case 1:
8592             check_insn(ctx, ISA_MIPS32R2);
8593             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
8594             register_name = "IntCtl";
8595             break;
8596         case 2:
8597             check_insn(ctx, ISA_MIPS32R2);
8598             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
8599             register_name = "SRSCtl";
8600             break;
8601         case 3:
8602             check_insn(ctx, ISA_MIPS32R2);
8603             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8604             register_name = "SRSMap";
8605             break;
8606         default:
8607             goto cp0_unimplemented;
8608         }
8609         break;
8610     case CP0_REGISTER_13:
8611         switch (sel) {
8612         case 0:
8613             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
8614             register_name = "Cause";
8615             break;
8616         default:
8617             goto cp0_unimplemented;
8618         }
8619         break;
8620     case CP0_REGISTER_14:
8621         switch (sel) {
8622         case 0:
8623             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8624             register_name = "EPC";
8625             break;
8626         default:
8627             goto cp0_unimplemented;
8628         }
8629         break;
8630     case CP0_REGISTER_15:
8631         switch (sel) {
8632         case 0:
8633             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
8634             register_name = "PRid";
8635             break;
8636         case 1:
8637             check_insn(ctx, ISA_MIPS32R2);
8638             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
8639             register_name = "EBase";
8640             break;
8641         case 3:
8642             check_insn(ctx, ISA_MIPS32R2);
8643             CP0_CHECK(ctx->cmgcr);
8644             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
8645             register_name = "CMGCRBase";
8646             break;
8647         default:
8648             goto cp0_unimplemented;
8649         }
8650         break;
8651     case CP0_REGISTER_16:
8652         switch (sel) {
8653         case 0:
8654             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
8655             register_name = "Config";
8656             break;
8657         case 1:
8658             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
8659             register_name = "Config1";
8660             break;
8661         case 2:
8662             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
8663             register_name = "Config2";
8664             break;
8665         case 3:
8666             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
8667             register_name = "Config3";
8668             break;
8669         case 4:
8670             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
8671             register_name = "Config4";
8672             break;
8673         case 5:
8674             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
8675             register_name = "Config5";
8676             break;
8677        /* 6,7 are implementation dependent */
8678         case 6:
8679             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
8680             register_name = "Config6";
8681             break;
8682         case 7:
8683             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
8684             register_name = "Config7";
8685             break;
8686         default:
8687             goto cp0_unimplemented;
8688         }
8689         break;
8690     case CP0_REGISTER_17:
8691         switch (sel) {
8692         case 0:
8693             gen_helper_dmfc0_lladdr(arg, cpu_env);
8694             register_name = "LLAddr";
8695             break;
8696         case 1:
8697             CP0_CHECK(ctx->mrp);
8698             gen_helper_dmfc0_maar(arg, cpu_env);
8699             register_name = "MAAR";
8700             break;
8701         case 2:
8702             CP0_CHECK(ctx->mrp);
8703             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
8704             register_name = "MAARI";
8705             break;
8706         default:
8707             goto cp0_unimplemented;
8708         }
8709         break;
8710     case CP0_REGISTER_18:
8711         switch (sel) {
8712         case 0:
8713         case 1:
8714         case 2:
8715         case 3:
8716         case 4:
8717         case 5:
8718         case 6:
8719         case 7:
8720             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8721             gen_helper_1e0i(dmfc0_watchlo, arg, sel);
8722             register_name = "WatchLo";
8723             break;
8724         default:
8725             goto cp0_unimplemented;
8726         }
8727         break;
8728     case CP0_REGISTER_19:
8729         switch (sel) {
8730         case 0:
8731         case 1:
8732         case 2:
8733         case 3:
8734         case 4:
8735         case 5:
8736         case 6:
8737         case 7:
8738             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8739             gen_helper_1e0i(mfc0_watchhi, arg, sel);
8740             register_name = "WatchHi";
8741             break;
8742         default:
8743             goto cp0_unimplemented;
8744         }
8745         break;
8746     case CP0_REGISTER_20:
8747         switch (sel) {
8748         case 0:
8749             check_insn(ctx, ISA_MIPS3);
8750             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
8751             register_name = "XContext";
8752             break;
8753         default:
8754             goto cp0_unimplemented;
8755         }
8756         break;
8757     case CP0_REGISTER_21:
8758        /* Officially reserved, but sel 0 is used for R1x000 framemask */
8759         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
8760         switch (sel) {
8761         case 0:
8762             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
8763             register_name = "Framemask";
8764             break;
8765         default:
8766             goto cp0_unimplemented;
8767         }
8768         break;
8769     case CP0_REGISTER_22:
8770         tcg_gen_movi_tl(arg, 0); /* unimplemented */
8771         register_name = "'Diagnostic"; /* implementation dependent */
8772         break;
8773     case CP0_REGISTER_23:
8774         switch (sel) {
8775         case 0:
8776             gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
8777             register_name = "Debug";
8778             break;
8779         case 1:
8780 //            gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
8781             register_name = "TraceControl";
8782             goto cp0_unimplemented;
8783         case 2:
8784 //            gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
8785             register_name = "TraceControl2";
8786             goto cp0_unimplemented;
8787         case 3:
8788 //            gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
8789             register_name = "UserTraceData";
8790             goto cp0_unimplemented;
8791         case 4:
8792 //            gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
8793             register_name = "TraceBPC";
8794             goto cp0_unimplemented;
8795         default:
8796             goto cp0_unimplemented;
8797         }
8798         break;
8799     case CP0_REGISTER_24:
8800         switch (sel) {
8801         case 0:
8802             /* EJTAG support */
8803             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8804             register_name = "DEPC";
8805             break;
8806         default:
8807             goto cp0_unimplemented;
8808         }
8809         break;
8810     case CP0_REGISTER_25:
8811         switch (sel) {
8812         case 0:
8813             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
8814             register_name = "Performance0";
8815             break;
8816         case 1:
8817 //            gen_helper_dmfc0_performance1(arg);
8818             register_name = "Performance1";
8819             goto cp0_unimplemented;
8820         case 2:
8821 //            gen_helper_dmfc0_performance2(arg);
8822             register_name = "Performance2";
8823             goto cp0_unimplemented;
8824         case 3:
8825 //            gen_helper_dmfc0_performance3(arg);
8826             register_name = "Performance3";
8827             goto cp0_unimplemented;
8828         case 4:
8829 //            gen_helper_dmfc0_performance4(arg);
8830             register_name = "Performance4";
8831             goto cp0_unimplemented;
8832         case 5:
8833 //            gen_helper_dmfc0_performance5(arg);
8834             register_name = "Performance5";
8835             goto cp0_unimplemented;
8836         case 6:
8837 //            gen_helper_dmfc0_performance6(arg);
8838             register_name = "Performance6";
8839             goto cp0_unimplemented;
8840         case 7:
8841 //            gen_helper_dmfc0_performance7(arg);
8842             register_name = "Performance7";
8843             goto cp0_unimplemented;
8844         default:
8845             goto cp0_unimplemented;
8846         }
8847         break;
8848     case CP0_REGISTER_26:
8849         switch (sel) {
8850         case 0:
8851             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8852             register_name = "ErrCtl";
8853             break;
8854         default:
8855             goto cp0_unimplemented;
8856         }
8857         break;
8858     case CP0_REGISTER_27:
8859         switch (sel) {
8860         /* ignored */
8861         case 0:
8862         case 1:
8863         case 2:
8864         case 3:
8865             tcg_gen_movi_tl(arg, 0); /* unimplemented */
8866             register_name = "CacheErr";
8867             break;
8868         default:
8869             goto cp0_unimplemented;
8870         }
8871         break;
8872     case CP0_REGISTER_28:
8873         switch (sel) {
8874         case 0:
8875         case 2:
8876         case 4:
8877         case 6:
8878             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
8879             register_name = "TagLo";
8880             break;
8881         case 1:
8882         case 3:
8883         case 5:
8884         case 7:
8885             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
8886             register_name = "DataLo";
8887             break;
8888         default:
8889             goto cp0_unimplemented;
8890         }
8891         break;
8892     case CP0_REGISTER_29:
8893         switch (sel) {
8894         case 0:
8895         case 2:
8896         case 4:
8897         case 6:
8898             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
8899             register_name = "TagHi";
8900             break;
8901         case 1:
8902         case 3:
8903         case 5:
8904         case 7:
8905             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
8906             register_name = "DataHi";
8907             break;
8908         default:
8909             goto cp0_unimplemented;
8910         }
8911         break;
8912     case CP0_REGISTER_30:
8913         switch (sel) {
8914         case 0:
8915             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8916             register_name = "ErrorEPC";
8917             break;
8918         default:
8919             goto cp0_unimplemented;
8920         }
8921         break;
8922     case CP0_REGISTER_31:
8923         switch (sel) {
8924         case 0:
8925             /* EJTAG support */
8926             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8927             register_name = "DESAVE";
8928             break;
8929         case 2:
8930         case 3:
8931         case 4:
8932         case 5:
8933         case 6:
8934         case 7:
8935             CP0_CHECK(ctx->kscrexist & (1 << sel));
8936             tcg_gen_ld_tl(arg, cpu_env,
8937                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
8938             register_name = "KScratch";
8939             break;
8940         default:
8941             goto cp0_unimplemented;
8942         }
8943         break;
8944     default:
8945         goto cp0_unimplemented;
8946     }
8947     trace_mips_translate_c0("dmfc0", register_name, reg, sel);
8948     return;
8949
8950 cp0_unimplemented:
8951     qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
8952                   register_name, reg, sel);
8953     gen_mfc0_unimplemented(ctx, arg);
8954 }
8955
8956 static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8957 {
8958     const char *register_name = "invalid";
8959
8960     if (sel != 0)
8961         check_insn(ctx, ISA_MIPS64);
8962
8963     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8964         gen_io_start();
8965     }
8966
8967     switch (reg) {
8968     case CP0_REGISTER_00:
8969         switch (sel) {
8970         case 0:
8971             gen_helper_mtc0_index(cpu_env, arg);
8972             register_name = "Index";
8973             break;
8974         case 1:
8975             CP0_CHECK(ctx->insn_flags & ASE_MT);
8976             gen_helper_mtc0_mvpcontrol(cpu_env, arg);
8977             register_name = "MVPControl";
8978             break;
8979         case 2:
8980             CP0_CHECK(ctx->insn_flags & ASE_MT);
8981             /* ignored */
8982             register_name = "MVPConf0";
8983             break;
8984         case 3:
8985             CP0_CHECK(ctx->insn_flags & ASE_MT);
8986             /* ignored */
8987             register_name = "MVPConf1";
8988             break;
8989         case 4:
8990             CP0_CHECK(ctx->vp);
8991             /* ignored */
8992             register_name = "VPControl";
8993             break;
8994         default:
8995             goto cp0_unimplemented;
8996         }
8997         break;
8998     case CP0_REGISTER_01:
8999         switch (sel) {
9000         case 0:
9001             /* ignored */
9002             register_name = "Random";
9003             break;
9004         case 1:
9005             CP0_CHECK(ctx->insn_flags & ASE_MT);
9006             gen_helper_mtc0_vpecontrol(cpu_env, arg);
9007             register_name = "VPEControl";
9008             break;
9009         case 2:
9010             CP0_CHECK(ctx->insn_flags & ASE_MT);
9011             gen_helper_mtc0_vpeconf0(cpu_env, arg);
9012             register_name = "VPEConf0";
9013             break;
9014         case 3:
9015             CP0_CHECK(ctx->insn_flags & ASE_MT);
9016             gen_helper_mtc0_vpeconf1(cpu_env, arg);
9017             register_name = "VPEConf1";
9018             break;
9019         case 4:
9020             CP0_CHECK(ctx->insn_flags & ASE_MT);
9021             gen_helper_mtc0_yqmask(cpu_env, arg);
9022             register_name = "YQMask";
9023             break;
9024         case 5:
9025             CP0_CHECK(ctx->insn_flags & ASE_MT);
9026             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
9027             register_name = "VPESchedule";
9028             break;
9029         case 6:
9030             CP0_CHECK(ctx->insn_flags & ASE_MT);
9031             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
9032             register_name = "VPEScheFBack";
9033             break;
9034         case 7:
9035             CP0_CHECK(ctx->insn_flags & ASE_MT);
9036             gen_helper_mtc0_vpeopt(cpu_env, arg);
9037             register_name = "VPEOpt";
9038             break;
9039         default:
9040             goto cp0_unimplemented;
9041         }
9042         break;
9043     case CP0_REGISTER_02:
9044         switch (sel) {
9045         case 0:
9046             gen_helper_dmtc0_entrylo0(cpu_env, arg);
9047             register_name = "EntryLo0";
9048             break;
9049         case 1:
9050             CP0_CHECK(ctx->insn_flags & ASE_MT);
9051             gen_helper_mtc0_tcstatus(cpu_env, arg);
9052             register_name = "TCStatus";
9053             break;
9054         case 2:
9055             CP0_CHECK(ctx->insn_flags & ASE_MT);
9056             gen_helper_mtc0_tcbind(cpu_env, arg);
9057             register_name = "TCBind";
9058             break;
9059         case 3:
9060             CP0_CHECK(ctx->insn_flags & ASE_MT);
9061             gen_helper_mtc0_tcrestart(cpu_env, arg);
9062             register_name = "TCRestart";
9063             break;
9064         case 4:
9065             CP0_CHECK(ctx->insn_flags & ASE_MT);
9066             gen_helper_mtc0_tchalt(cpu_env, arg);
9067             register_name = "TCHalt";
9068             break;
9069         case 5:
9070             CP0_CHECK(ctx->insn_flags & ASE_MT);
9071             gen_helper_mtc0_tccontext(cpu_env, arg);
9072             register_name = "TCContext";
9073             break;
9074         case 6:
9075             CP0_CHECK(ctx->insn_flags & ASE_MT);
9076             gen_helper_mtc0_tcschedule(cpu_env, arg);
9077             register_name = "TCSchedule";
9078             break;
9079         case 7:
9080             CP0_CHECK(ctx->insn_flags & ASE_MT);
9081             gen_helper_mtc0_tcschefback(cpu_env, arg);
9082             register_name = "TCScheFBack";
9083             break;
9084         default:
9085             goto cp0_unimplemented;
9086         }
9087         break;
9088     case CP0_REGISTER_03:
9089         switch (sel) {
9090         case 0:
9091             gen_helper_dmtc0_entrylo1(cpu_env, arg);
9092             register_name = "EntryLo1";
9093             break;
9094         case 1:
9095             CP0_CHECK(ctx->vp);
9096             /* ignored */
9097             register_name = "GlobalNumber";
9098             break;
9099         default:
9100             goto cp0_unimplemented;
9101         }
9102         break;
9103     case CP0_REGISTER_04:
9104         switch (sel) {
9105         case 0:
9106             gen_helper_mtc0_context(cpu_env, arg);
9107             register_name = "Context";
9108             break;
9109         case 1:
9110 //           gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
9111             register_name = "ContextConfig";
9112             goto cp0_unimplemented;
9113         case 2:
9114             CP0_CHECK(ctx->ulri);
9115             tcg_gen_st_tl(arg, cpu_env,
9116                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
9117             register_name = "UserLocal";
9118             break;
9119         default:
9120             goto cp0_unimplemented;
9121         }
9122         break;
9123     case CP0_REGISTER_05:
9124         switch (sel) {
9125         case 0:
9126             gen_helper_mtc0_pagemask(cpu_env, arg);
9127             register_name = "PageMask";
9128             break;
9129         case 1:
9130             check_insn(ctx, ISA_MIPS32R2);
9131             gen_helper_mtc0_pagegrain(cpu_env, arg);
9132             register_name = "PageGrain";
9133             break;
9134         case 2:
9135             CP0_CHECK(ctx->sc);
9136             gen_helper_mtc0_segctl0(cpu_env, arg);
9137             register_name = "SegCtl0";
9138             break;
9139         case 3:
9140             CP0_CHECK(ctx->sc);
9141             gen_helper_mtc0_segctl1(cpu_env, arg);
9142             register_name = "SegCtl1";
9143             break;
9144         case 4:
9145             CP0_CHECK(ctx->sc);
9146             gen_helper_mtc0_segctl2(cpu_env, arg);
9147             register_name = "SegCtl2";
9148             break;
9149         case 5:
9150             check_pw(ctx);
9151             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
9152             register_name = "PWBase";
9153             break;
9154         case 6:
9155             check_pw(ctx);
9156             gen_helper_mtc0_pwfield(cpu_env, arg);
9157             register_name = "PWField";
9158             break;
9159         case 7:
9160             check_pw(ctx);
9161             gen_helper_mtc0_pwsize(cpu_env, arg);
9162             register_name = "PWSize";
9163             break;
9164         default:
9165             goto cp0_unimplemented;
9166         }
9167         break;
9168     case CP0_REGISTER_06:
9169         switch (sel) {
9170         case 0:
9171             gen_helper_mtc0_wired(cpu_env, arg);
9172             register_name = "Wired";
9173             break;
9174         case 1:
9175             check_insn(ctx, ISA_MIPS32R2);
9176             gen_helper_mtc0_srsconf0(cpu_env, arg);
9177             register_name = "SRSConf0";
9178             break;
9179         case 2:
9180             check_insn(ctx, ISA_MIPS32R2);
9181             gen_helper_mtc0_srsconf1(cpu_env, arg);
9182             register_name = "SRSConf1";
9183             break;
9184         case 3:
9185             check_insn(ctx, ISA_MIPS32R2);
9186             gen_helper_mtc0_srsconf2(cpu_env, arg);
9187             register_name = "SRSConf2";
9188             break;
9189         case 4:
9190             check_insn(ctx, ISA_MIPS32R2);
9191             gen_helper_mtc0_srsconf3(cpu_env, arg);
9192             register_name = "SRSConf3";
9193             break;
9194         case 5:
9195             check_insn(ctx, ISA_MIPS32R2);
9196             gen_helper_mtc0_srsconf4(cpu_env, arg);
9197             register_name = "SRSConf4";
9198             break;
9199         case 6:
9200             check_pw(ctx);
9201             gen_helper_mtc0_pwctl(cpu_env, arg);
9202             register_name = "PWCtl";
9203             break;
9204         default:
9205             goto cp0_unimplemented;
9206         }
9207         break;
9208     case CP0_REGISTER_07:
9209         switch (sel) {
9210         case 0:
9211             check_insn(ctx, ISA_MIPS32R2);
9212             gen_helper_mtc0_hwrena(cpu_env, arg);
9213             ctx->base.is_jmp = DISAS_STOP;
9214             register_name = "HWREna";
9215             break;
9216         default:
9217             goto cp0_unimplemented;
9218         }
9219         break;
9220     case CP0_REGISTER_08:
9221         switch (sel) {
9222         case 0:
9223             /* ignored */
9224             register_name = "BadVAddr";
9225             break;
9226         case 1:
9227             /* ignored */
9228             register_name = "BadInstr";
9229             break;
9230         case 2:
9231             /* ignored */
9232             register_name = "BadInstrP";
9233             break;
9234         case 3:
9235             /* ignored */
9236             register_name = "BadInstrX";
9237             break;
9238         default:
9239             goto cp0_unimplemented;
9240         }
9241         break;
9242     case CP0_REGISTER_09:
9243         switch (sel) {
9244         case 0:
9245             gen_helper_mtc0_count(cpu_env, arg);
9246             register_name = "Count";
9247             break;
9248         case 6:
9249             CP0_CHECK(ctx->saar);
9250             gen_helper_mtc0_saari(cpu_env, arg);
9251             register_name = "SAARI";
9252             break;
9253         case 7:
9254             CP0_CHECK(ctx->saar);
9255             gen_helper_mtc0_saar(cpu_env, arg);
9256             register_name = "SAAR";
9257             break;
9258         default:
9259             goto cp0_unimplemented;
9260         }
9261         /* Stop translation as we may have switched the execution mode */
9262         ctx->base.is_jmp = DISAS_STOP;
9263         break;
9264     case CP0_REGISTER_10:
9265         switch (sel) {
9266         case 0:
9267             gen_helper_mtc0_entryhi(cpu_env, arg);
9268             register_name = "EntryHi";
9269             break;
9270         default:
9271             goto cp0_unimplemented;
9272         }
9273         break;
9274     case CP0_REGISTER_11:
9275         switch (sel) {
9276         case 0:
9277             gen_helper_mtc0_compare(cpu_env, arg);
9278             register_name = "Compare";
9279             break;
9280         /* 6,7 are implementation dependent */
9281         default:
9282             goto cp0_unimplemented;
9283         }
9284         /* Stop translation as we may have switched the execution mode */
9285         ctx->base.is_jmp = DISAS_STOP;
9286         break;
9287     case CP0_REGISTER_12:
9288         switch (sel) {
9289         case 0:
9290             save_cpu_state(ctx, 1);
9291             gen_helper_mtc0_status(cpu_env, arg);
9292             /* DISAS_STOP isn't good enough here, hflags may have changed. */
9293             gen_save_pc(ctx->base.pc_next + 4);
9294             ctx->base.is_jmp = DISAS_EXIT;
9295             register_name = "Status";
9296             break;
9297         case 1:
9298             check_insn(ctx, ISA_MIPS32R2);
9299             gen_helper_mtc0_intctl(cpu_env, arg);
9300             /* Stop translation as we may have switched the execution mode */
9301             ctx->base.is_jmp = DISAS_STOP;
9302             register_name = "IntCtl";
9303             break;
9304         case 2:
9305             check_insn(ctx, ISA_MIPS32R2);
9306             gen_helper_mtc0_srsctl(cpu_env, arg);
9307             /* Stop translation as we may have switched the execution mode */
9308             ctx->base.is_jmp = DISAS_STOP;
9309             register_name = "SRSCtl";
9310             break;
9311         case 3:
9312             check_insn(ctx, ISA_MIPS32R2);
9313             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
9314             /* Stop translation as we may have switched the execution mode */
9315             ctx->base.is_jmp = DISAS_STOP;
9316             register_name = "SRSMap";
9317             break;
9318         default:
9319             goto cp0_unimplemented;
9320         }
9321         break;
9322     case CP0_REGISTER_13:
9323         switch (sel) {
9324         case 0:
9325             save_cpu_state(ctx, 1);
9326             gen_helper_mtc0_cause(cpu_env, arg);
9327             /* Stop translation as we may have triggered an interrupt.
9328              * DISAS_STOP isn't sufficient, we need to ensure we break out of
9329              * translated code to check for pending interrupts.  */
9330             gen_save_pc(ctx->base.pc_next + 4);
9331             ctx->base.is_jmp = DISAS_EXIT;
9332             register_name = "Cause";
9333             break;
9334         default:
9335             goto cp0_unimplemented;
9336         }
9337         break;
9338     case CP0_REGISTER_14:
9339         switch (sel) {
9340         case 0:
9341             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
9342             register_name = "EPC";
9343             break;
9344         default:
9345             goto cp0_unimplemented;
9346         }
9347         break;
9348     case CP0_REGISTER_15:
9349         switch (sel) {
9350         case 0:
9351             /* ignored */
9352             register_name = "PRid";
9353             break;
9354         case 1:
9355             check_insn(ctx, ISA_MIPS32R2);
9356             gen_helper_mtc0_ebase(cpu_env, arg);
9357             register_name = "EBase";
9358             break;
9359         default:
9360             goto cp0_unimplemented;
9361         }
9362         break;
9363     case CP0_REGISTER_16:
9364         switch (sel) {
9365         case 0:
9366             gen_helper_mtc0_config0(cpu_env, arg);
9367             register_name = "Config";
9368             /* Stop translation as we may have switched the execution mode */
9369             ctx->base.is_jmp = DISAS_STOP;
9370             break;
9371         case 1:
9372             /* ignored, read only */
9373             register_name = "Config1";
9374             break;
9375         case 2:
9376             gen_helper_mtc0_config2(cpu_env, arg);
9377             register_name = "Config2";
9378             /* Stop translation as we may have switched the execution mode */
9379             ctx->base.is_jmp = DISAS_STOP;
9380             break;
9381         case 3:
9382             gen_helper_mtc0_config3(cpu_env, arg);
9383             register_name = "Config3";
9384             /* Stop translation as we may have switched the execution mode */
9385             ctx->base.is_jmp = DISAS_STOP;
9386             break;
9387         case 4:
9388             /* currently ignored */
9389             register_name = "Config4";
9390             break;
9391         case 5:
9392             gen_helper_mtc0_config5(cpu_env, arg);
9393             register_name = "Config5";
9394             /* Stop translation as we may have switched the execution mode */
9395             ctx->base.is_jmp = DISAS_STOP;
9396             break;
9397         /* 6,7 are implementation dependent */
9398         default:
9399             register_name = "Invalid config selector";
9400             goto cp0_unimplemented;
9401         }
9402         break;
9403     case CP0_REGISTER_17:
9404         switch (sel) {
9405         case 0:
9406             gen_helper_mtc0_lladdr(cpu_env, arg);
9407             register_name = "LLAddr";
9408             break;
9409         case 1:
9410             CP0_CHECK(ctx->mrp);
9411             gen_helper_mtc0_maar(cpu_env, arg);
9412             register_name = "MAAR";
9413             break;
9414         case 2:
9415             CP0_CHECK(ctx->mrp);
9416             gen_helper_mtc0_maari(cpu_env, arg);
9417             register_name = "MAARI";
9418             break;
9419         default:
9420             goto cp0_unimplemented;
9421         }
9422         break;
9423     case CP0_REGISTER_18:
9424         switch (sel) {
9425         case 0:
9426         case 1:
9427         case 2:
9428         case 3:
9429         case 4:
9430         case 5:
9431         case 6:
9432         case 7:
9433             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9434             gen_helper_0e1i(mtc0_watchlo, arg, sel);
9435             register_name = "WatchLo";
9436             break;
9437         default:
9438             goto cp0_unimplemented;
9439         }
9440         break;
9441     case CP0_REGISTER_19:
9442         switch (sel) {
9443         case 0:
9444         case 1:
9445         case 2:
9446         case 3:
9447         case 4:
9448         case 5:
9449         case 6:
9450         case 7:
9451             CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
9452             gen_helper_0e1i(mtc0_watchhi, arg, sel);
9453             register_name = "WatchHi";
9454             break;
9455         default:
9456             goto cp0_unimplemented;
9457         }
9458         break;
9459     case CP0_REGISTER_20:
9460         switch (sel) {
9461         case 0:
9462             check_insn(ctx, ISA_MIPS3);
9463             gen_helper_mtc0_xcontext(cpu_env, arg);
9464             register_name = "XContext";
9465             break;
9466         default:
9467             goto cp0_unimplemented;
9468         }
9469         break;
9470     case CP0_REGISTER_21:
9471        /* Officially reserved, but sel 0 is used for R1x000 framemask */
9472         CP0_CHECK(!(ctx->insn_flags & ISA_MIPS32R6));
9473         switch (sel) {
9474         case 0:
9475             gen_helper_mtc0_framemask(cpu_env, arg);
9476             register_name = "Framemask";
9477             break;
9478         default:
9479             goto cp0_unimplemented;
9480         }
9481         break;
9482     case CP0_REGISTER_22:
9483         /* ignored */
9484         register_name = "Diagnostic"; /* implementation dependent */
9485         break;
9486     case CP0_REGISTER_23:
9487         switch (sel) {
9488         case 0:
9489             gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
9490             /* DISAS_STOP isn't good enough here, hflags may have changed. */
9491             gen_save_pc(ctx->base.pc_next + 4);
9492             ctx->base.is_jmp = DISAS_EXIT;
9493             register_name = "Debug";
9494             break;
9495         case 1:
9496 //            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
9497             /* Stop translation as we may have switched the execution mode */
9498             ctx->base.is_jmp = DISAS_STOP;
9499             register_name = "TraceControl";
9500             goto cp0_unimplemented;
9501         case 2:
9502 //            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
9503             /* Stop translation as we may have switched the execution mode */
9504             ctx->base.is_jmp = DISAS_STOP;
9505             register_name = "TraceControl2";
9506             goto cp0_unimplemented;
9507         case 3:
9508 //            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
9509             /* Stop translation as we may have switched the execution mode */
9510             ctx->base.is_jmp = DISAS_STOP;
9511             register_name = "UserTraceData";
9512             goto cp0_unimplemented;
9513         case 4:
9514 //            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
9515             /* Stop translation as we may have switched the execution mode */
9516             ctx->base.is_jmp = DISAS_STOP;
9517             register_name = "TraceBPC";
9518             goto cp0_unimplemented;
9519         default:
9520             goto cp0_unimplemented;
9521         }
9522         break;
9523     case CP0_REGISTER_24:
9524         switch (sel) {
9525         case 0:
9526             /* EJTAG support */
9527             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
9528             register_name = "DEPC";
9529             break;
9530         default:
9531             goto cp0_unimplemented;
9532         }
9533         break;
9534     case CP0_REGISTER_25:
9535         switch (sel) {
9536         case 0:
9537             gen_helper_mtc0_performance0(cpu_env, arg);
9538             register_name = "Performance0";
9539             break;
9540         case 1:
9541 //            gen_helper_mtc0_performance1(cpu_env, arg);
9542             register_name = "Performance1";
9543             goto cp0_unimplemented;
9544         case 2:
9545 //            gen_helper_mtc0_performance2(cpu_env, arg);
9546             register_name = "Performance2";
9547             goto cp0_unimplemented;
9548         case 3:
9549 //            gen_helper_mtc0_performance3(cpu_env, arg);
9550             register_name = "Performance3";
9551             goto cp0_unimplemented;
9552         case 4:
9553 //            gen_helper_mtc0_performance4(cpu_env, arg);
9554             register_name = "Performance4";
9555             goto cp0_unimplemented;
9556         case 5:
9557 //            gen_helper_mtc0_performance5(cpu_env, arg);
9558             register_name = "Performance5";
9559             goto cp0_unimplemented;
9560         case 6:
9561 //            gen_helper_mtc0_performance6(cpu_env, arg);
9562             register_name = "Performance6";
9563             goto cp0_unimplemented;
9564         case 7:
9565 //            gen_helper_mtc0_performance7(cpu_env, arg);
9566             register_name = "Performance7";
9567             goto cp0_unimplemented;
9568         default:
9569             goto cp0_unimplemented;
9570         }
9571         break;
9572     case CP0_REGISTER_26:
9573         switch (sel) {
9574         case 0:
9575             gen_helper_mtc0_errctl(cpu_env, arg);
9576             ctx->base.is_jmp = DISAS_STOP;
9577             register_name = "ErrCtl";
9578             break;
9579         default:
9580             goto cp0_unimplemented;
9581         }
9582         break;
9583     case CP0_REGISTER_27:
9584         switch (sel) {
9585         case 0:
9586         case 1:
9587         case 2:
9588         case 3:
9589             /* ignored */
9590             register_name = "CacheErr";
9591             break;
9592         default:
9593             goto cp0_unimplemented;
9594         }
9595         break;
9596     case CP0_REGISTER_28:
9597         switch (sel) {
9598         case 0:
9599         case 2:
9600         case 4:
9601         case 6:
9602             gen_helper_mtc0_taglo(cpu_env, arg);
9603             register_name = "TagLo";
9604             break;
9605         case 1:
9606         case 3:
9607         case 5:
9608         case 7:
9609             gen_helper_mtc0_datalo(cpu_env, arg);
9610             register_name = "DataLo";
9611             break;
9612         default:
9613             goto cp0_unimplemented;
9614         }
9615         break;
9616     case CP0_REGISTER_29:
9617         switch (sel) {
9618         case 0:
9619         case 2:
9620         case 4:
9621         case 6:
9622             gen_helper_mtc0_taghi(cpu_env, arg);
9623             register_name = "TagHi";
9624             break;
9625         case 1:
9626         case 3:
9627         case 5:
9628         case 7:
9629             gen_helper_mtc0_datahi(cpu_env, arg);
9630             register_name = "DataHi";
9631             break;
9632         default:
9633             register_name = "invalid sel";
9634             goto cp0_unimplemented;
9635         }
9636         break;
9637     case CP0_REGISTER_30:
9638         switch (sel) {
9639         case 0:
9640             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
9641             register_name = "ErrorEPC";
9642             break;
9643         default:
9644             goto cp0_unimplemented;
9645         }
9646         break;
9647     case CP0_REGISTER_31:
9648         switch (sel) {
9649         case 0:
9650             /* EJTAG support */
9651             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
9652             register_name = "DESAVE";
9653             break;
9654         case 2:
9655         case 3:
9656         case 4:
9657         case 5:
9658         case 6:
9659         case 7:
9660             CP0_CHECK(ctx->kscrexist & (1 << sel));
9661             tcg_gen_st_tl(arg, cpu_env,
9662                           offsetof(CPUMIPSState, CP0_KScratch[sel-2]));
9663             register_name = "KScratch";
9664             break;
9665         default:
9666             goto cp0_unimplemented;
9667         }
9668         break;
9669     default:
9670         goto cp0_unimplemented;
9671     }
9672     trace_mips_translate_c0("dmtc0", register_name, reg, sel);
9673
9674     /* For simplicity assume that all writes can cause interrupts.  */
9675     if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
9676         gen_io_end();
9677         /* DISAS_STOP isn't sufficient, we need to ensure we break out of
9678          * translated code to check for pending interrupts.  */
9679         gen_save_pc(ctx->base.pc_next + 4);
9680         ctx->base.is_jmp = DISAS_EXIT;
9681     }
9682     return;
9683
9684 cp0_unimplemented:
9685     qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
9686                   register_name, reg, sel);
9687 }
9688 #endif /* TARGET_MIPS64 */
9689
9690 static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
9691                      int u, int sel, int h)
9692 {
9693     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9694     TCGv t0 = tcg_temp_local_new();
9695
9696     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9697         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9698          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9699         tcg_gen_movi_tl(t0, -1);
9700     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9701              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9702         tcg_gen_movi_tl(t0, -1);
9703     else if (u == 0) {
9704         switch (rt) {
9705         case 1:
9706             switch (sel) {
9707             case 1:
9708                 gen_helper_mftc0_vpecontrol(t0, cpu_env);
9709                 break;
9710             case 2:
9711                 gen_helper_mftc0_vpeconf0(t0, cpu_env);
9712                 break;
9713             default:
9714                 goto die;
9715                 break;
9716             }
9717             break;
9718         case 2:
9719             switch (sel) {
9720             case 1:
9721                 gen_helper_mftc0_tcstatus(t0, cpu_env);
9722                 break;
9723             case 2:
9724                 gen_helper_mftc0_tcbind(t0, cpu_env);
9725                 break;
9726             case 3:
9727                 gen_helper_mftc0_tcrestart(t0, cpu_env);
9728                 break;
9729             case 4:
9730                 gen_helper_mftc0_tchalt(t0, cpu_env);
9731                 break;
9732             case 5:
9733                 gen_helper_mftc0_tccontext(t0, cpu_env);
9734                 break;
9735             case 6:
9736                 gen_helper_mftc0_tcschedule(t0, cpu_env);
9737                 break;
9738             case 7:
9739                 gen_helper_mftc0_tcschefback(t0, cpu_env);
9740                 break;
9741             default:
9742                 gen_mfc0(ctx, t0, rt, sel);
9743                 break;
9744             }
9745             break;
9746         case 10:
9747             switch (sel) {
9748             case 0:
9749                 gen_helper_mftc0_entryhi(t0, cpu_env);
9750                 break;
9751             default:
9752                 gen_mfc0(ctx, t0, rt, sel);
9753                 break;
9754             }
9755         case 12:
9756             switch (sel) {
9757             case 0:
9758                 gen_helper_mftc0_status(t0, cpu_env);
9759                 break;
9760             default:
9761                 gen_mfc0(ctx, t0, rt, sel);
9762                 break;
9763             }
9764         case 13:
9765             switch (sel) {
9766             case 0:
9767                 gen_helper_mftc0_cause(t0, cpu_env);
9768                 break;
9769             default:
9770                 goto die;
9771                 break;
9772             }
9773             break;
9774         case 14:
9775             switch (sel) {
9776             case 0:
9777                 gen_helper_mftc0_epc(t0, cpu_env);
9778                 break;
9779             default:
9780                 goto die;
9781                 break;
9782             }
9783             break;
9784         case 15:
9785             switch (sel) {
9786             case 1:
9787                 gen_helper_mftc0_ebase(t0, cpu_env);
9788                 break;
9789             default:
9790                 goto die;
9791                 break;
9792             }
9793             break;
9794         case 16:
9795             switch (sel) {
9796             case 0:
9797             case 1:
9798             case 2:
9799             case 3:
9800             case 4:
9801             case 5:
9802             case 6:
9803             case 7:
9804                 gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
9805                 break;
9806             default:
9807                 goto die;
9808                 break;
9809             }
9810             break;
9811         case 23:
9812             switch (sel) {
9813             case 0:
9814                 gen_helper_mftc0_debug(t0, cpu_env);
9815                 break;
9816             default:
9817                 gen_mfc0(ctx, t0, rt, sel);
9818                 break;
9819             }
9820             break;
9821         default:
9822             gen_mfc0(ctx, t0, rt, sel);
9823         }
9824     } else switch (sel) {
9825     /* GPR registers. */
9826     case 0:
9827         gen_helper_1e0i(mftgpr, t0, rt);
9828         break;
9829     /* Auxiliary CPU registers */
9830     case 1:
9831         switch (rt) {
9832         case 0:
9833             gen_helper_1e0i(mftlo, t0, 0);
9834             break;
9835         case 1:
9836             gen_helper_1e0i(mfthi, t0, 0);
9837             break;
9838         case 2:
9839             gen_helper_1e0i(mftacx, t0, 0);
9840             break;
9841         case 4:
9842             gen_helper_1e0i(mftlo, t0, 1);
9843             break;
9844         case 5:
9845             gen_helper_1e0i(mfthi, t0, 1);
9846             break;
9847         case 6:
9848             gen_helper_1e0i(mftacx, t0, 1);
9849             break;
9850         case 8:
9851             gen_helper_1e0i(mftlo, t0, 2);
9852             break;
9853         case 9:
9854             gen_helper_1e0i(mfthi, t0, 2);
9855             break;
9856         case 10:
9857             gen_helper_1e0i(mftacx, t0, 2);
9858             break;
9859         case 12:
9860             gen_helper_1e0i(mftlo, t0, 3);
9861             break;
9862         case 13:
9863             gen_helper_1e0i(mfthi, t0, 3);
9864             break;
9865         case 14:
9866             gen_helper_1e0i(mftacx, t0, 3);
9867             break;
9868         case 16:
9869             gen_helper_mftdsp(t0, cpu_env);
9870             break;
9871         default:
9872             goto die;
9873         }
9874         break;
9875     /* Floating point (COP1). */
9876     case 2:
9877         /* XXX: For now we support only a single FPU context. */
9878         if (h == 0) {
9879             TCGv_i32 fp0 = tcg_temp_new_i32();
9880
9881             gen_load_fpr32(ctx, fp0, rt);
9882             tcg_gen_ext_i32_tl(t0, fp0);
9883             tcg_temp_free_i32(fp0);
9884         } else {
9885             TCGv_i32 fp0 = tcg_temp_new_i32();
9886
9887             gen_load_fpr32h(ctx, fp0, rt);
9888             tcg_gen_ext_i32_tl(t0, fp0);
9889             tcg_temp_free_i32(fp0);
9890         }
9891         break;
9892     case 3:
9893         /* XXX: For now we support only a single FPU context. */
9894         gen_helper_1e0i(cfc1, t0, rt);
9895         break;
9896     /* COP2: Not implemented. */
9897     case 4:
9898     case 5:
9899         /* fall through */
9900     default:
9901         goto die;
9902     }
9903     trace_mips_translate_tr("mftr", rt, u, sel, h);
9904     gen_store_gpr(t0, rd);
9905     tcg_temp_free(t0);
9906     return;
9907
9908 die:
9909     tcg_temp_free(t0);
9910     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9911     generate_exception_end(ctx, EXCP_RI);
9912 }
9913
9914 static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
9915                      int u, int sel, int h)
9916 {
9917     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9918     TCGv t0 = tcg_temp_local_new();
9919
9920     gen_load_gpr(t0, rt);
9921     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9922         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9923          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
9924         /* NOP */ ;
9925     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9926              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
9927         /* NOP */ ;
9928     else if (u == 0) {
9929         switch (rd) {
9930         case 1:
9931             switch (sel) {
9932             case 1:
9933                 gen_helper_mttc0_vpecontrol(cpu_env, t0);
9934                 break;
9935             case 2:
9936                 gen_helper_mttc0_vpeconf0(cpu_env, t0);
9937                 break;
9938             default:
9939                 goto die;
9940                 break;
9941             }
9942             break;
9943         case 2:
9944             switch (sel) {
9945             case 1:
9946                 gen_helper_mttc0_tcstatus(cpu_env, t0);
9947                 break;
9948             case 2:
9949                 gen_helper_mttc0_tcbind(cpu_env, t0);
9950                 break;
9951             case 3:
9952                 gen_helper_mttc0_tcrestart(cpu_env, t0);
9953                 break;
9954             case 4:
9955                 gen_helper_mttc0_tchalt(cpu_env, t0);
9956                 break;
9957             case 5:
9958                 gen_helper_mttc0_tccontext(cpu_env, t0);
9959                 break;
9960             case 6:
9961                 gen_helper_mttc0_tcschedule(cpu_env, t0);
9962                 break;
9963             case 7:
9964                 gen_helper_mttc0_tcschefback(cpu_env, t0);
9965                 break;
9966             default:
9967                 gen_mtc0(ctx, t0, rd, sel);
9968                 break;
9969             }
9970             break;
9971         case 10:
9972             switch (sel) {
9973             case 0:
9974                 gen_helper_mttc0_entryhi(cpu_env, t0);
9975                 break;
9976             default:
9977                 gen_mtc0(ctx, t0, rd, sel);
9978                 break;
9979             }
9980         case 12:
9981             switch (sel) {
9982             case 0:
9983                 gen_helper_mttc0_status(cpu_env, t0);
9984                 break;
9985             default:
9986                 gen_mtc0(ctx, t0, rd, sel);
9987                 break;
9988             }
9989         case 13:
9990             switch (sel) {
9991             case 0:
9992                 gen_helper_mttc0_cause(cpu_env, t0);
9993                 break;
9994             default:
9995                 goto die;
9996                 break;
9997             }
9998             break;
9999         case 15:
10000             switch (sel) {
10001             case 1:
10002                 gen_helper_mttc0_ebase(cpu_env, t0);
10003                 break;
10004             default:
10005                 goto die;
10006                 break;
10007             }
10008             break;
10009         case 23:
10010             switch (sel) {
10011             case 0:
10012                 gen_helper_mttc0_debug(cpu_env, t0);
10013                 break;
10014             default:
10015                 gen_mtc0(ctx, t0, rd, sel);
10016                 break;
10017             }
10018             break;
10019         default:
10020             gen_mtc0(ctx, t0, rd, sel);
10021         }
10022     } else switch (sel) {
10023     /* GPR registers. */
10024     case 0:
10025         gen_helper_0e1i(mttgpr, t0, rd);
10026         break;
10027     /* Auxiliary CPU registers */
10028     case 1:
10029         switch (rd) {
10030         case 0:
10031             gen_helper_0e1i(mttlo, t0, 0);
10032             break;
10033         case 1:
10034             gen_helper_0e1i(mtthi, t0, 0);
10035             break;
10036         case 2:
10037             gen_helper_0e1i(mttacx, t0, 0);
10038             break;
10039         case 4:
10040             gen_helper_0e1i(mttlo, t0, 1);
10041             break;
10042         case 5:
10043             gen_helper_0e1i(mtthi, t0, 1);
10044             break;
10045         case 6:
10046             gen_helper_0e1i(mttacx, t0, 1);
10047             break;
10048         case 8:
10049             gen_helper_0e1i(mttlo, t0, 2);
10050             break;
10051         case 9:
10052             gen_helper_0e1i(mtthi, t0, 2);
10053             break;
10054         case 10:
10055             gen_helper_0e1i(mttacx, t0, 2);
10056             break;
10057         case 12:
10058             gen_helper_0e1i(mttlo, t0, 3);
10059             break;
10060         case 13:
10061             gen_helper_0e1i(mtthi, t0, 3);
10062             break;
10063         case 14:
10064             gen_helper_0e1i(mttacx, t0, 3);
10065             break;
10066         case 16:
10067             gen_helper_mttdsp(cpu_env, t0);
10068             break;
10069         default:
10070             goto die;
10071         }
10072         break;
10073     /* Floating point (COP1). */
10074     case 2:
10075         /* XXX: For now we support only a single FPU context. */
10076         if (h == 0) {
10077             TCGv_i32 fp0 = tcg_temp_new_i32();
10078
10079             tcg_gen_trunc_tl_i32(fp0, t0);
10080             gen_store_fpr32(ctx, fp0, rd);
10081             tcg_temp_free_i32(fp0);
10082         } else {
10083             TCGv_i32 fp0 = tcg_temp_new_i32();
10084
10085             tcg_gen_trunc_tl_i32(fp0, t0);
10086             gen_store_fpr32h(ctx, fp0, rd);
10087             tcg_temp_free_i32(fp0);
10088         }
10089         break;
10090     case 3:
10091         /* XXX: For now we support only a single FPU context. */
10092         {
10093             TCGv_i32 fs_tmp = tcg_const_i32(rd);
10094
10095             gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10096             tcg_temp_free_i32(fs_tmp);
10097         }
10098         /* Stop translation as we may have changed hflags */
10099         ctx->base.is_jmp = DISAS_STOP;
10100         break;
10101     /* COP2: Not implemented. */
10102     case 4:
10103     case 5:
10104         /* fall through */
10105     default:
10106         goto die;
10107     }
10108     trace_mips_translate_tr("mttr", rd, u, sel, h);
10109     tcg_temp_free(t0);
10110     return;
10111
10112 die:
10113     tcg_temp_free(t0);
10114     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
10115     generate_exception_end(ctx, EXCP_RI);
10116 }
10117
10118 static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
10119 {
10120     const char *opn = "ldst";
10121
10122     check_cp0_enabled(ctx);
10123     switch (opc) {
10124     case OPC_MFC0:
10125         if (rt == 0) {
10126             /* Treat as NOP. */
10127             return;
10128         }
10129         gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10130         opn = "mfc0";
10131         break;
10132     case OPC_MTC0:
10133         {
10134             TCGv t0 = tcg_temp_new();
10135
10136             gen_load_gpr(t0, rt);
10137             gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
10138             tcg_temp_free(t0);
10139         }
10140         opn = "mtc0";
10141         break;
10142 #if defined(TARGET_MIPS64)
10143     case OPC_DMFC0:
10144         check_insn(ctx, ISA_MIPS3);
10145         if (rt == 0) {
10146             /* Treat as NOP. */
10147             return;
10148         }
10149         gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10150         opn = "dmfc0";
10151         break;
10152     case OPC_DMTC0:
10153         check_insn(ctx, ISA_MIPS3);
10154         {
10155             TCGv t0 = tcg_temp_new();
10156
10157             gen_load_gpr(t0, rt);
10158             gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
10159             tcg_temp_free(t0);
10160         }
10161         opn = "dmtc0";
10162         break;
10163 #endif
10164     case OPC_MFHC0:
10165         check_mvh(ctx);
10166         if (rt == 0) {
10167             /* Treat as NOP. */
10168             return;
10169         }
10170         gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
10171         opn = "mfhc0";
10172         break;
10173     case OPC_MTHC0:
10174         check_mvh(ctx);
10175         {
10176             TCGv t0 = tcg_temp_new();
10177             gen_load_gpr(t0, rt);
10178             gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
10179             tcg_temp_free(t0);
10180         }
10181         opn = "mthc0";
10182         break;
10183     case OPC_MFTR:
10184         check_cp0_enabled(ctx);
10185         if (rd == 0) {
10186             /* Treat as NOP. */
10187             return;
10188         }
10189         gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
10190                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10191         opn = "mftr";
10192         break;
10193     case OPC_MTTR:
10194         check_cp0_enabled(ctx);
10195         gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
10196                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
10197         opn = "mttr";
10198         break;
10199     case OPC_TLBWI:
10200         opn = "tlbwi";
10201         if (!env->tlb->helper_tlbwi)
10202             goto die;
10203         gen_helper_tlbwi(cpu_env);
10204         break;
10205     case OPC_TLBINV:
10206         opn = "tlbinv";
10207         if (ctx->ie >= 2) {
10208             if (!env->tlb->helper_tlbinv) {
10209                 goto die;
10210             }
10211             gen_helper_tlbinv(cpu_env);
10212         } /* treat as nop if TLBINV not supported */
10213         break;
10214     case OPC_TLBINVF:
10215         opn = "tlbinvf";
10216         if (ctx->ie >= 2) {
10217             if (!env->tlb->helper_tlbinvf) {
10218                 goto die;
10219             }
10220             gen_helper_tlbinvf(cpu_env);
10221         } /* treat as nop if TLBINV not supported */
10222         break;
10223     case OPC_TLBWR:
10224         opn = "tlbwr";
10225         if (!env->tlb->helper_tlbwr)
10226             goto die;
10227         gen_helper_tlbwr(cpu_env);
10228         break;
10229     case OPC_TLBP:
10230         opn = "tlbp";
10231         if (!env->tlb->helper_tlbp)
10232             goto die;
10233         gen_helper_tlbp(cpu_env);
10234         break;
10235     case OPC_TLBR:
10236         opn = "tlbr";
10237         if (!env->tlb->helper_tlbr)
10238             goto die;
10239         gen_helper_tlbr(cpu_env);
10240         break;
10241     case OPC_ERET: /* OPC_ERETNC */
10242         if ((ctx->insn_flags & ISA_MIPS32R6) &&
10243             (ctx->hflags & MIPS_HFLAG_BMASK)) {
10244             goto die;
10245         } else {
10246             int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
10247             if (ctx->opcode & (1 << bit_shift)) {
10248                 /* OPC_ERETNC */
10249                 opn = "eretnc";
10250                 check_insn(ctx, ISA_MIPS32R5);
10251                 gen_helper_eretnc(cpu_env);
10252             } else {
10253                 /* OPC_ERET */
10254                 opn = "eret";
10255                 check_insn(ctx, ISA_MIPS2);
10256                 gen_helper_eret(cpu_env);
10257             }
10258             ctx->base.is_jmp = DISAS_EXIT;
10259         }
10260         break;
10261     case OPC_DERET:
10262         opn = "deret";
10263         check_insn(ctx, ISA_MIPS32);
10264         if ((ctx->insn_flags & ISA_MIPS32R6) &&
10265             (ctx->hflags & MIPS_HFLAG_BMASK)) {
10266             goto die;
10267         }
10268         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10269             MIPS_INVAL(opn);
10270             generate_exception_end(ctx, EXCP_RI);
10271         } else {
10272             gen_helper_deret(cpu_env);
10273             ctx->base.is_jmp = DISAS_EXIT;
10274         }
10275         break;
10276     case OPC_WAIT:
10277         opn = "wait";
10278         check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
10279         if ((ctx->insn_flags & ISA_MIPS32R6) &&
10280             (ctx->hflags & MIPS_HFLAG_BMASK)) {
10281             goto die;
10282         }
10283         /* If we get an exception, we want to restart at next instruction */
10284         ctx->base.pc_next += 4;
10285         save_cpu_state(ctx, 1);
10286         ctx->base.pc_next -= 4;
10287         gen_helper_wait(cpu_env);
10288         ctx->base.is_jmp = DISAS_NORETURN;
10289         break;
10290     default:
10291  die:
10292         MIPS_INVAL(opn);
10293         generate_exception_end(ctx, EXCP_RI);
10294         return;
10295     }
10296     (void)opn; /* avoid a compiler warning */
10297 }
10298 #endif /* !CONFIG_USER_ONLY */
10299
10300 /* CP1 Branches (before delay slot) */
10301 static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
10302                                 int32_t cc, int32_t offset)
10303 {
10304     target_ulong btarget;
10305     TCGv_i32 t0 = tcg_temp_new_i32();
10306
10307     if ((ctx->insn_flags & ISA_MIPS32R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
10308         generate_exception_end(ctx, EXCP_RI);
10309         goto out;
10310     }
10311
10312     if (cc != 0)
10313         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
10314
10315     btarget = ctx->base.pc_next + 4 + offset;
10316
10317     switch (op) {
10318     case OPC_BC1F:
10319         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10320         tcg_gen_not_i32(t0, t0);
10321         tcg_gen_andi_i32(t0, t0, 1);
10322         tcg_gen_extu_i32_tl(bcond, t0);
10323         goto not_likely;
10324     case OPC_BC1FL:
10325         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10326         tcg_gen_not_i32(t0, t0);
10327         tcg_gen_andi_i32(t0, t0, 1);
10328         tcg_gen_extu_i32_tl(bcond, t0);
10329         goto likely;
10330     case OPC_BC1T:
10331         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10332         tcg_gen_andi_i32(t0, t0, 1);
10333         tcg_gen_extu_i32_tl(bcond, t0);
10334         goto not_likely;
10335     case OPC_BC1TL:
10336         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10337         tcg_gen_andi_i32(t0, t0, 1);
10338         tcg_gen_extu_i32_tl(bcond, t0);
10339     likely:
10340         ctx->hflags |= MIPS_HFLAG_BL;
10341         break;
10342     case OPC_BC1FANY2:
10343         {
10344             TCGv_i32 t1 = tcg_temp_new_i32();
10345             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10346             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10347             tcg_gen_nand_i32(t0, t0, t1);
10348             tcg_temp_free_i32(t1);
10349             tcg_gen_andi_i32(t0, t0, 1);
10350             tcg_gen_extu_i32_tl(bcond, t0);
10351         }
10352         goto not_likely;
10353     case OPC_BC1TANY2:
10354         {
10355             TCGv_i32 t1 = tcg_temp_new_i32();
10356             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10357             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10358             tcg_gen_or_i32(t0, t0, t1);
10359             tcg_temp_free_i32(t1);
10360             tcg_gen_andi_i32(t0, t0, 1);
10361             tcg_gen_extu_i32_tl(bcond, t0);
10362         }
10363         goto not_likely;
10364     case OPC_BC1FANY4:
10365         {
10366             TCGv_i32 t1 = tcg_temp_new_i32();
10367             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10368             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10369             tcg_gen_and_i32(t0, t0, t1);
10370             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10371             tcg_gen_and_i32(t0, t0, t1);
10372             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10373             tcg_gen_nand_i32(t0, t0, t1);
10374             tcg_temp_free_i32(t1);
10375             tcg_gen_andi_i32(t0, t0, 1);
10376             tcg_gen_extu_i32_tl(bcond, t0);
10377         }
10378         goto not_likely;
10379     case OPC_BC1TANY4:
10380         {
10381             TCGv_i32 t1 = tcg_temp_new_i32();
10382             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
10383             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
10384             tcg_gen_or_i32(t0, t0, t1);
10385             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
10386             tcg_gen_or_i32(t0, t0, t1);
10387             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
10388             tcg_gen_or_i32(t0, t0, t1);
10389             tcg_temp_free_i32(t1);
10390             tcg_gen_andi_i32(t0, t0, 1);
10391             tcg_gen_extu_i32_tl(bcond, t0);
10392         }
10393     not_likely:
10394         ctx->hflags |= MIPS_HFLAG_BC;
10395         break;
10396     default:
10397         MIPS_INVAL("cp1 cond branch");
10398         generate_exception_end(ctx, EXCP_RI);
10399         goto out;
10400     }
10401     ctx->btarget = btarget;
10402     ctx->hflags |= MIPS_HFLAG_BDS32;
10403  out:
10404     tcg_temp_free_i32(t0);
10405 }
10406
10407 /* R6 CP1 Branches */
10408 static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
10409                                    int32_t ft, int32_t offset,
10410                                    int delayslot_size)
10411 {
10412     target_ulong btarget;
10413     TCGv_i64 t0 = tcg_temp_new_i64();
10414
10415     if (ctx->hflags & MIPS_HFLAG_BMASK) {
10416 #ifdef MIPS_DEBUG_DISAS
10417         LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
10418                   "\n", ctx->base.pc_next);
10419 #endif
10420         generate_exception_end(ctx, EXCP_RI);
10421         goto out;
10422     }
10423
10424     gen_load_fpr64(ctx, t0, ft);
10425     tcg_gen_andi_i64(t0, t0, 1);
10426
10427     btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
10428
10429     switch (op) {
10430     case OPC_BC1EQZ:
10431         tcg_gen_xori_i64(t0, t0, 1);
10432         ctx->hflags |= MIPS_HFLAG_BC;
10433         break;
10434     case OPC_BC1NEZ:
10435         /* t0 already set */
10436         ctx->hflags |= MIPS_HFLAG_BC;
10437         break;
10438     default:
10439         MIPS_INVAL("cp1 cond branch");
10440         generate_exception_end(ctx, EXCP_RI);
10441         goto out;
10442     }
10443
10444     tcg_gen_trunc_i64_tl(bcond, t0);
10445
10446     ctx->btarget = btarget;
10447
10448     switch (delayslot_size) {
10449     case 2:
10450         ctx->hflags |= MIPS_HFLAG_BDS16;
10451         break;
10452     case 4:
10453         ctx->hflags |= MIPS_HFLAG_BDS32;
10454         break;
10455     }
10456
10457 out:
10458     tcg_temp_free_i64(t0);
10459 }
10460
10461 /* Coprocessor 1 (FPU) */
10462
10463 #define FOP(func, fmt) (((fmt) << 21) | (func))
10464
10465 enum fopcode {
10466     OPC_ADD_S = FOP(0, FMT_S),
10467     OPC_SUB_S = FOP(1, FMT_S),
10468     OPC_MUL_S = FOP(2, FMT_S),
10469     OPC_DIV_S = FOP(3, FMT_S),
10470     OPC_SQRT_S = FOP(4, FMT_S),
10471     OPC_ABS_S = FOP(5, FMT_S),
10472     OPC_MOV_S = FOP(6, FMT_S),
10473     OPC_NEG_S = FOP(7, FMT_S),
10474     OPC_ROUND_L_S = FOP(8, FMT_S),
10475     OPC_TRUNC_L_S = FOP(9, FMT_S),
10476     OPC_CEIL_L_S = FOP(10, FMT_S),
10477     OPC_FLOOR_L_S = FOP(11, FMT_S),
10478     OPC_ROUND_W_S = FOP(12, FMT_S),
10479     OPC_TRUNC_W_S = FOP(13, FMT_S),
10480     OPC_CEIL_W_S = FOP(14, FMT_S),
10481     OPC_FLOOR_W_S = FOP(15, FMT_S),
10482     OPC_SEL_S = FOP(16, FMT_S),
10483     OPC_MOVCF_S = FOP(17, FMT_S),
10484     OPC_MOVZ_S = FOP(18, FMT_S),
10485     OPC_MOVN_S = FOP(19, FMT_S),
10486     OPC_SELEQZ_S = FOP(20, FMT_S),
10487     OPC_RECIP_S = FOP(21, FMT_S),
10488     OPC_RSQRT_S = FOP(22, FMT_S),
10489     OPC_SELNEZ_S = FOP(23, FMT_S),
10490     OPC_MADDF_S = FOP(24, FMT_S),
10491     OPC_MSUBF_S = FOP(25, FMT_S),
10492     OPC_RINT_S = FOP(26, FMT_S),
10493     OPC_CLASS_S = FOP(27, FMT_S),
10494     OPC_MIN_S = FOP(28, FMT_S),
10495     OPC_RECIP2_S = FOP(28, FMT_S),
10496     OPC_MINA_S = FOP(29, FMT_S),
10497     OPC_RECIP1_S = FOP(29, FMT_S),
10498     OPC_MAX_S = FOP(30, FMT_S),
10499     OPC_RSQRT1_S = FOP(30, FMT_S),
10500     OPC_MAXA_S = FOP(31, FMT_S),
10501     OPC_RSQRT2_S = FOP(31, FMT_S),
10502     OPC_CVT_D_S = FOP(33, FMT_S),
10503     OPC_CVT_W_S = FOP(36, FMT_S),
10504     OPC_CVT_L_S = FOP(37, FMT_S),
10505     OPC_CVT_PS_S = FOP(38, FMT_S),
10506     OPC_CMP_F_S = FOP (48, FMT_S),
10507     OPC_CMP_UN_S = FOP (49, FMT_S),
10508     OPC_CMP_EQ_S = FOP (50, FMT_S),
10509     OPC_CMP_UEQ_S = FOP (51, FMT_S),
10510     OPC_CMP_OLT_S = FOP (52, FMT_S),
10511     OPC_CMP_ULT_S = FOP (53, FMT_S),
10512     OPC_CMP_OLE_S = FOP (54, FMT_S),
10513     OPC_CMP_ULE_S = FOP (55, FMT_S),
10514     OPC_CMP_SF_S = FOP (56, FMT_S),
10515     OPC_CMP_NGLE_S = FOP (57, FMT_S),
10516     OPC_CMP_SEQ_S = FOP (58, FMT_S),
10517     OPC_CMP_NGL_S = FOP (59, FMT_S),
10518     OPC_CMP_LT_S = FOP (60, FMT_S),
10519     OPC_CMP_NGE_S = FOP (61, FMT_S),
10520     OPC_CMP_LE_S = FOP (62, FMT_S),
10521     OPC_CMP_NGT_S = FOP (63, FMT_S),
10522
10523     OPC_ADD_D = FOP(0, FMT_D),
10524     OPC_SUB_D = FOP(1, FMT_D),
10525     OPC_MUL_D = FOP(2, FMT_D),
10526     OPC_DIV_D = FOP(3, FMT_D),
10527     OPC_SQRT_D = FOP(4, FMT_D),
10528     OPC_ABS_D = FOP(5, FMT_D),
10529     OPC_MOV_D = FOP(6, FMT_D),
10530     OPC_NEG_D = FOP(7, FMT_D),
10531     OPC_ROUND_L_D = FOP(8, FMT_D),
10532     OPC_TRUNC_L_D = FOP(9, FMT_D),
10533     OPC_CEIL_L_D = FOP(10, FMT_D),
10534     OPC_FLOOR_L_D = FOP(11, FMT_D),
10535     OPC_ROUND_W_D = FOP(12, FMT_D),
10536     OPC_TRUNC_W_D = FOP(13, FMT_D),
10537     OPC_CEIL_W_D = FOP(14, FMT_D),
10538     OPC_FLOOR_W_D = FOP(15, FMT_D),
10539     OPC_SEL_D = FOP(16, FMT_D),
10540     OPC_MOVCF_D = FOP(17, FMT_D),
10541     OPC_MOVZ_D = FOP(18, FMT_D),
10542     OPC_MOVN_D = FOP(19, FMT_D),
10543     OPC_SELEQZ_D = FOP(20, FMT_D),
10544     OPC_RECIP_D = FOP(21, FMT_D),
10545     OPC_RSQRT_D = FOP(22, FMT_D),
10546     OPC_SELNEZ_D = FOP(23, FMT_D),
10547     OPC_MADDF_D = FOP(24, FMT_D),
10548     OPC_MSUBF_D = FOP(25, FMT_D),
10549     OPC_RINT_D = FOP(26, FMT_D),
10550     OPC_CLASS_D = FOP(27, FMT_D),
10551     OPC_MIN_D = FOP(28, FMT_D),
10552     OPC_RECIP2_D = FOP(28, FMT_D),
10553     OPC_MINA_D = FOP(29, FMT_D),
10554     OPC_RECIP1_D = FOP(29, FMT_D),
10555     OPC_MAX_D = FOP(30, FMT_D),
10556     OPC_RSQRT1_D = FOP(30, FMT_D),
10557     OPC_MAXA_D = FOP(31, FMT_D),
10558     OPC_RSQRT2_D = FOP(31, FMT_D),
10559     OPC_CVT_S_D = FOP(32, FMT_D),
10560     OPC_CVT_W_D = FOP(36, FMT_D),
10561     OPC_CVT_L_D = FOP(37, FMT_D),
10562     OPC_CMP_F_D = FOP (48, FMT_D),
10563     OPC_CMP_UN_D = FOP (49, FMT_D),
10564     OPC_CMP_EQ_D = FOP (50, FMT_D),
10565     OPC_CMP_UEQ_D = FOP (51, FMT_D),
10566     OPC_CMP_OLT_D = FOP (52, FMT_D),
10567     OPC_CMP_ULT_D = FOP (53, FMT_D),
10568     OPC_CMP_OLE_D = FOP (54, FMT_D),
10569     OPC_CMP_ULE_D = FOP (55, FMT_D),
10570     OPC_CMP_SF_D = FOP (56, FMT_D),
10571     OPC_CMP_NGLE_D = FOP (57, FMT_D),
10572     OPC_CMP_SEQ_D = FOP (58, FMT_D),
10573     OPC_CMP_NGL_D = FOP (59, FMT_D),
10574     OPC_CMP_LT_D = FOP (60, FMT_D),
10575     OPC_CMP_NGE_D = FOP (61, FMT_D),
10576     OPC_CMP_LE_D = FOP (62, FMT_D),
10577     OPC_CMP_NGT_D = FOP (63, FMT_D),
10578
10579     OPC_CVT_S_W = FOP(32, FMT_W),
10580     OPC_CVT_D_W = FOP(33, FMT_W),
10581     OPC_CVT_S_L = FOP(32, FMT_L),
10582     OPC_CVT_D_L = FOP(33, FMT_L),
10583     OPC_CVT_PS_PW = FOP(38, FMT_W),
10584
10585     OPC_ADD_PS = FOP(0, FMT_PS),
10586     OPC_SUB_PS = FOP(1, FMT_PS),
10587     OPC_MUL_PS = FOP(2, FMT_PS),
10588     OPC_DIV_PS = FOP(3, FMT_PS),
10589     OPC_ABS_PS = FOP(5, FMT_PS),
10590     OPC_MOV_PS = FOP(6, FMT_PS),
10591     OPC_NEG_PS = FOP(7, FMT_PS),
10592     OPC_MOVCF_PS = FOP(17, FMT_PS),
10593     OPC_MOVZ_PS = FOP(18, FMT_PS),
10594     OPC_MOVN_PS = FOP(19, FMT_PS),
10595     OPC_ADDR_PS = FOP(24, FMT_PS),
10596     OPC_MULR_PS = FOP(26, FMT_PS),
10597     OPC_RECIP2_PS = FOP(28, FMT_PS),
10598     OPC_RECIP1_PS = FOP(29, FMT_PS),
10599     OPC_RSQRT1_PS = FOP(30, FMT_PS),
10600     OPC_RSQRT2_PS = FOP(31, FMT_PS),
10601
10602     OPC_CVT_S_PU = FOP(32, FMT_PS),
10603     OPC_CVT_PW_PS = FOP(36, FMT_PS),
10604     OPC_CVT_S_PL = FOP(40, FMT_PS),
10605     OPC_PLL_PS = FOP(44, FMT_PS),
10606     OPC_PLU_PS = FOP(45, FMT_PS),
10607     OPC_PUL_PS = FOP(46, FMT_PS),
10608     OPC_PUU_PS = FOP(47, FMT_PS),
10609     OPC_CMP_F_PS = FOP (48, FMT_PS),
10610     OPC_CMP_UN_PS = FOP (49, FMT_PS),
10611     OPC_CMP_EQ_PS = FOP (50, FMT_PS),
10612     OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
10613     OPC_CMP_OLT_PS = FOP (52, FMT_PS),
10614     OPC_CMP_ULT_PS = FOP (53, FMT_PS),
10615     OPC_CMP_OLE_PS = FOP (54, FMT_PS),
10616     OPC_CMP_ULE_PS = FOP (55, FMT_PS),
10617     OPC_CMP_SF_PS = FOP (56, FMT_PS),
10618     OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
10619     OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
10620     OPC_CMP_NGL_PS = FOP (59, FMT_PS),
10621     OPC_CMP_LT_PS = FOP (60, FMT_PS),
10622     OPC_CMP_NGE_PS = FOP (61, FMT_PS),
10623     OPC_CMP_LE_PS = FOP (62, FMT_PS),
10624     OPC_CMP_NGT_PS = FOP (63, FMT_PS),
10625 };
10626
10627 enum r6_f_cmp_op {
10628     R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
10629     R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
10630     R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
10631     R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
10632     R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
10633     R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
10634     R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
10635     R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
10636     R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
10637     R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
10638     R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
10639     R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
10640     R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
10641     R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
10642     R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
10643     R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
10644     R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
10645     R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
10646     R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
10647     R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
10648     R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
10649     R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
10650
10651     R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
10652     R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
10653     R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
10654     R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
10655     R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
10656     R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
10657     R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
10658     R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
10659     R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
10660     R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
10661     R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
10662     R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
10663     R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
10664     R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
10665     R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
10666     R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
10667     R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
10668     R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
10669     R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
10670     R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
10671     R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
10672     R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
10673 };
10674 static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
10675 {
10676     TCGv t0 = tcg_temp_new();
10677
10678     switch (opc) {
10679     case OPC_MFC1:
10680         {
10681             TCGv_i32 fp0 = tcg_temp_new_i32();
10682
10683             gen_load_fpr32(ctx, fp0, fs);
10684             tcg_gen_ext_i32_tl(t0, fp0);
10685             tcg_temp_free_i32(fp0);
10686         }
10687         gen_store_gpr(t0, rt);
10688         break;
10689     case OPC_MTC1:
10690         gen_load_gpr(t0, rt);
10691         {
10692             TCGv_i32 fp0 = tcg_temp_new_i32();
10693
10694             tcg_gen_trunc_tl_i32(fp0, t0);
10695             gen_store_fpr32(ctx, fp0, fs);
10696             tcg_temp_free_i32(fp0);
10697         }
10698         break;
10699     case OPC_CFC1:
10700         gen_helper_1e0i(cfc1, t0, fs);
10701         gen_store_gpr(t0, rt);
10702         break;
10703     case OPC_CTC1:
10704         gen_load_gpr(t0, rt);
10705         save_cpu_state(ctx, 0);
10706         {
10707             TCGv_i32 fs_tmp = tcg_const_i32(fs);
10708
10709             gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10710             tcg_temp_free_i32(fs_tmp);
10711         }
10712         /* Stop translation as we may have changed hflags */
10713         ctx->base.is_jmp = DISAS_STOP;
10714         break;
10715 #if defined(TARGET_MIPS64)
10716     case OPC_DMFC1:
10717         gen_load_fpr64(ctx, t0, fs);
10718         gen_store_gpr(t0, rt);
10719         break;
10720     case OPC_DMTC1:
10721         gen_load_gpr(t0, rt);
10722         gen_store_fpr64(ctx, t0, fs);
10723         break;
10724 #endif
10725     case OPC_MFHC1:
10726         {
10727             TCGv_i32 fp0 = tcg_temp_new_i32();
10728
10729             gen_load_fpr32h(ctx, fp0, fs);
10730             tcg_gen_ext_i32_tl(t0, fp0);
10731             tcg_temp_free_i32(fp0);
10732         }
10733         gen_store_gpr(t0, rt);
10734         break;
10735     case OPC_MTHC1:
10736         gen_load_gpr(t0, rt);
10737         {
10738             TCGv_i32 fp0 = tcg_temp_new_i32();
10739
10740             tcg_gen_trunc_tl_i32(fp0, t0);
10741             gen_store_fpr32h(ctx, fp0, fs);
10742             tcg_temp_free_i32(fp0);
10743         }
10744         break;
10745     default:
10746         MIPS_INVAL("cp1 move");
10747         generate_exception_end(ctx, EXCP_RI);
10748         goto out;
10749     }
10750
10751  out:
10752     tcg_temp_free(t0);
10753 }
10754
10755 static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
10756 {
10757     TCGLabel *l1;
10758     TCGCond cond;
10759     TCGv_i32 t0;
10760
10761     if (rd == 0) {
10762         /* Treat as NOP. */
10763         return;
10764     }
10765
10766     if (tf)
10767         cond = TCG_COND_EQ;
10768     else
10769         cond = TCG_COND_NE;
10770
10771     l1 = gen_new_label();
10772     t0 = tcg_temp_new_i32();
10773     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10774     tcg_gen_brcondi_i32(cond, t0, 0, l1);
10775     tcg_temp_free_i32(t0);
10776     if (rs == 0) {
10777         tcg_gen_movi_tl(cpu_gpr[rd], 0);
10778     } else {
10779         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
10780     }
10781     gen_set_label(l1);
10782 }
10783
10784 static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
10785                                int tf)
10786 {
10787     int cond;
10788     TCGv_i32 t0 = tcg_temp_new_i32();
10789     TCGLabel *l1 = gen_new_label();
10790
10791     if (tf)
10792         cond = TCG_COND_EQ;
10793     else
10794         cond = TCG_COND_NE;
10795
10796     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10797     tcg_gen_brcondi_i32(cond, t0, 0, l1);
10798     gen_load_fpr32(ctx, t0, fs);
10799     gen_store_fpr32(ctx, t0, fd);
10800     gen_set_label(l1);
10801     tcg_temp_free_i32(t0);
10802 }
10803
10804 static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
10805 {
10806     int cond;
10807     TCGv_i32 t0 = tcg_temp_new_i32();
10808     TCGv_i64 fp0;
10809     TCGLabel *l1 = gen_new_label();
10810
10811     if (tf)
10812         cond = TCG_COND_EQ;
10813     else
10814         cond = TCG_COND_NE;
10815
10816     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10817     tcg_gen_brcondi_i32(cond, t0, 0, l1);
10818     tcg_temp_free_i32(t0);
10819     fp0 = tcg_temp_new_i64();
10820     gen_load_fpr64(ctx, fp0, fs);
10821     gen_store_fpr64(ctx, fp0, fd);
10822     tcg_temp_free_i64(fp0);
10823     gen_set_label(l1);
10824 }
10825
10826 static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
10827                                 int cc, int tf)
10828 {
10829     int cond;
10830     TCGv_i32 t0 = tcg_temp_new_i32();
10831     TCGLabel *l1 = gen_new_label();
10832     TCGLabel *l2 = gen_new_label();
10833
10834     if (tf)
10835         cond = TCG_COND_EQ;
10836     else
10837         cond = TCG_COND_NE;
10838
10839     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10840     tcg_gen_brcondi_i32(cond, t0, 0, l1);
10841     gen_load_fpr32(ctx, t0, fs);
10842     gen_store_fpr32(ctx, t0, fd);
10843     gen_set_label(l1);
10844
10845     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
10846     tcg_gen_brcondi_i32(cond, t0, 0, l2);
10847     gen_load_fpr32h(ctx, t0, fs);
10848     gen_store_fpr32h(ctx, t0, fd);
10849     tcg_temp_free_i32(t0);
10850     gen_set_label(l2);
10851 }
10852
10853 static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10854                       int fs)
10855 {
10856     TCGv_i32 t1 = tcg_const_i32(0);
10857     TCGv_i32 fp0 = tcg_temp_new_i32();
10858     TCGv_i32 fp1 = tcg_temp_new_i32();
10859     TCGv_i32 fp2 = tcg_temp_new_i32();
10860     gen_load_fpr32(ctx, fp0, fd);
10861     gen_load_fpr32(ctx, fp1, ft);
10862     gen_load_fpr32(ctx, fp2, fs);
10863
10864     switch (op1) {
10865     case OPC_SEL_S:
10866         tcg_gen_andi_i32(fp0, fp0, 1);
10867         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10868         break;
10869     case OPC_SELEQZ_S:
10870         tcg_gen_andi_i32(fp1, fp1, 1);
10871         tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10872         break;
10873     case OPC_SELNEZ_S:
10874         tcg_gen_andi_i32(fp1, fp1, 1);
10875         tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10876         break;
10877     default:
10878         MIPS_INVAL("gen_sel_s");
10879         generate_exception_end(ctx, EXCP_RI);
10880         break;
10881     }
10882
10883     gen_store_fpr32(ctx, fp0, fd);
10884     tcg_temp_free_i32(fp2);
10885     tcg_temp_free_i32(fp1);
10886     tcg_temp_free_i32(fp0);
10887     tcg_temp_free_i32(t1);
10888 }
10889
10890 static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10891                       int fs)
10892 {
10893     TCGv_i64 t1 = tcg_const_i64(0);
10894     TCGv_i64 fp0 = tcg_temp_new_i64();
10895     TCGv_i64 fp1 = tcg_temp_new_i64();
10896     TCGv_i64 fp2 = tcg_temp_new_i64();
10897     gen_load_fpr64(ctx, fp0, fd);
10898     gen_load_fpr64(ctx, fp1, ft);
10899     gen_load_fpr64(ctx, fp2, fs);
10900
10901     switch (op1) {
10902     case OPC_SEL_D:
10903         tcg_gen_andi_i64(fp0, fp0, 1);
10904         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10905         break;
10906     case OPC_SELEQZ_D:
10907         tcg_gen_andi_i64(fp1, fp1, 1);
10908         tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10909         break;
10910     case OPC_SELNEZ_D:
10911         tcg_gen_andi_i64(fp1, fp1, 1);
10912         tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10913         break;
10914     default:
10915         MIPS_INVAL("gen_sel_d");
10916         generate_exception_end(ctx, EXCP_RI);
10917         break;
10918     }
10919
10920     gen_store_fpr64(ctx, fp0, fd);
10921     tcg_temp_free_i64(fp2);
10922     tcg_temp_free_i64(fp1);
10923     tcg_temp_free_i64(fp0);
10924     tcg_temp_free_i64(t1);
10925 }
10926
10927 static void gen_farith (DisasContext *ctx, enum fopcode op1,
10928                         int ft, int fs, int fd, int cc)
10929 {
10930     uint32_t func = ctx->opcode & 0x3f;
10931     switch (op1) {
10932     case OPC_ADD_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_add_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_SUB_S:
10946         {
10947             TCGv_i32 fp0 = tcg_temp_new_i32();
10948             TCGv_i32 fp1 = tcg_temp_new_i32();
10949
10950             gen_load_fpr32(ctx, fp0, fs);
10951             gen_load_fpr32(ctx, fp1, ft);
10952             gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
10953             tcg_temp_free_i32(fp1);
10954             gen_store_fpr32(ctx, fp0, fd);
10955             tcg_temp_free_i32(fp0);
10956         }
10957         break;
10958     case OPC_MUL_S:
10959         {
10960             TCGv_i32 fp0 = tcg_temp_new_i32();
10961             TCGv_i32 fp1 = tcg_temp_new_i32();
10962
10963             gen_load_fpr32(ctx, fp0, fs);
10964             gen_load_fpr32(ctx, fp1, ft);
10965             gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
10966             tcg_temp_free_i32(fp1);
10967             gen_store_fpr32(ctx, fp0, fd);
10968             tcg_temp_free_i32(fp0);
10969         }
10970         break;
10971     case OPC_DIV_S:
10972         {
10973             TCGv_i32 fp0 = tcg_temp_new_i32();
10974             TCGv_i32 fp1 = tcg_temp_new_i32();
10975
10976             gen_load_fpr32(ctx, fp0, fs);
10977             gen_load_fpr32(ctx, fp1, ft);
10978             gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
10979             tcg_temp_free_i32(fp1);
10980             gen_store_fpr32(ctx, fp0, fd);
10981             tcg_temp_free_i32(fp0);
10982         }
10983         break;
10984     case OPC_SQRT_S:
10985         {
10986             TCGv_i32 fp0 = tcg_temp_new_i32();
10987
10988             gen_load_fpr32(ctx, fp0, fs);
10989             gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
10990             gen_store_fpr32(ctx, fp0, fd);
10991             tcg_temp_free_i32(fp0);
10992         }
10993         break;
10994     case OPC_ABS_S:
10995         {
10996             TCGv_i32 fp0 = tcg_temp_new_i32();
10997
10998             gen_load_fpr32(ctx, fp0, fs);
10999             if (ctx->abs2008) {
11000                 tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
11001             } else {
11002                 gen_helper_float_abs_s(fp0, fp0);
11003             }
11004             gen_store_fpr32(ctx, fp0, fd);
11005             tcg_temp_free_i32(fp0);
11006         }
11007         break;
11008     case OPC_MOV_S:
11009         {
11010             TCGv_i32 fp0 = tcg_temp_new_i32();
11011
11012             gen_load_fpr32(ctx, fp0, fs);
11013             gen_store_fpr32(ctx, fp0, fd);
11014             tcg_temp_free_i32(fp0);
11015         }
11016         break;
11017     case OPC_NEG_S:
11018         {
11019             TCGv_i32 fp0 = tcg_temp_new_i32();
11020
11021             gen_load_fpr32(ctx, fp0, fs);
11022             if (ctx->abs2008) {
11023                 tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
11024             } else {
11025                 gen_helper_float_chs_s(fp0, fp0);
11026             }
11027             gen_store_fpr32(ctx, fp0, fd);
11028             tcg_temp_free_i32(fp0);
11029         }
11030         break;
11031     case OPC_ROUND_L_S:
11032         check_cp1_64bitmode(ctx);
11033         {
11034             TCGv_i32 fp32 = tcg_temp_new_i32();
11035             TCGv_i64 fp64 = tcg_temp_new_i64();
11036
11037             gen_load_fpr32(ctx, fp32, fs);
11038             if (ctx->nan2008) {
11039                 gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
11040             } else {
11041                 gen_helper_float_round_l_s(fp64, cpu_env, fp32);
11042             }
11043             tcg_temp_free_i32(fp32);
11044             gen_store_fpr64(ctx, fp64, fd);
11045             tcg_temp_free_i64(fp64);
11046         }
11047         break;
11048     case OPC_TRUNC_L_S:
11049         check_cp1_64bitmode(ctx);
11050         {
11051             TCGv_i32 fp32 = tcg_temp_new_i32();
11052             TCGv_i64 fp64 = tcg_temp_new_i64();
11053
11054             gen_load_fpr32(ctx, fp32, fs);
11055             if (ctx->nan2008) {
11056                 gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
11057             } else {
11058                 gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
11059             }
11060             tcg_temp_free_i32(fp32);
11061             gen_store_fpr64(ctx, fp64, fd);
11062             tcg_temp_free_i64(fp64);
11063         }
11064         break;
11065     case OPC_CEIL_L_S:
11066         check_cp1_64bitmode(ctx);
11067         {
11068             TCGv_i32 fp32 = tcg_temp_new_i32();
11069             TCGv_i64 fp64 = tcg_temp_new_i64();
11070
11071             gen_load_fpr32(ctx, fp32, fs);
11072             if (ctx->nan2008) {
11073                 gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
11074             } else {
11075                 gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
11076             }
11077             tcg_temp_free_i32(fp32);
11078             gen_store_fpr64(ctx, fp64, fd);
11079             tcg_temp_free_i64(fp64);
11080         }
11081         break;
11082     case OPC_FLOOR_L_S:
11083         check_cp1_64bitmode(ctx);
11084         {
11085             TCGv_i32 fp32 = tcg_temp_new_i32();
11086             TCGv_i64 fp64 = tcg_temp_new_i64();
11087
11088             gen_load_fpr32(ctx, fp32, fs);
11089             if (ctx->nan2008) {
11090                 gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
11091             } else {
11092                 gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
11093             }
11094             tcg_temp_free_i32(fp32);
11095             gen_store_fpr64(ctx, fp64, fd);
11096             tcg_temp_free_i64(fp64);
11097         }
11098         break;
11099     case OPC_ROUND_W_S:
11100         {
11101             TCGv_i32 fp0 = tcg_temp_new_i32();
11102
11103             gen_load_fpr32(ctx, fp0, fs);
11104             if (ctx->nan2008) {
11105                 gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
11106             } else {
11107                 gen_helper_float_round_w_s(fp0, cpu_env, fp0);
11108             }
11109             gen_store_fpr32(ctx, fp0, fd);
11110             tcg_temp_free_i32(fp0);
11111         }
11112         break;
11113     case OPC_TRUNC_W_S:
11114         {
11115             TCGv_i32 fp0 = tcg_temp_new_i32();
11116
11117             gen_load_fpr32(ctx, fp0, fs);
11118             if (ctx->nan2008) {
11119                 gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
11120             } else {
11121                 gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
11122             }
11123             gen_store_fpr32(ctx, fp0, fd);
11124             tcg_temp_free_i32(fp0);
11125         }
11126         break;
11127     case OPC_CEIL_W_S:
11128         {
11129             TCGv_i32 fp0 = tcg_temp_new_i32();
11130
11131             gen_load_fpr32(ctx, fp0, fs);
11132             if (ctx->nan2008) {
11133                 gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
11134             } else {
11135                 gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
11136             }
11137             gen_store_fpr32(ctx, fp0, fd);
11138             tcg_temp_free_i32(fp0);
11139         }
11140         break;
11141     case OPC_FLOOR_W_S:
11142         {
11143             TCGv_i32 fp0 = tcg_temp_new_i32();
11144
11145             gen_load_fpr32(ctx, fp0, fs);
11146             if (ctx->nan2008) {
11147                 gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
11148             } else {
11149                 gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
11150             }
11151             gen_store_fpr32(ctx, fp0, fd);
11152             tcg_temp_free_i32(fp0);
11153         }
11154         break;
11155     case OPC_SEL_S:
11156         check_insn(ctx, ISA_MIPS32R6);
11157         gen_sel_s(ctx, op1, fd, ft, fs);
11158         break;
11159     case OPC_SELEQZ_S:
11160         check_insn(ctx, ISA_MIPS32R6);
11161         gen_sel_s(ctx, op1, fd, ft, fs);
11162         break;
11163     case OPC_SELNEZ_S:
11164         check_insn(ctx, ISA_MIPS32R6);
11165         gen_sel_s(ctx, op1, fd, ft, fs);
11166         break;
11167     case OPC_MOVCF_S:
11168         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11169         gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11170         break;
11171     case OPC_MOVZ_S:
11172         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11173         {
11174             TCGLabel *l1 = gen_new_label();
11175             TCGv_i32 fp0;
11176
11177             if (ft != 0) {
11178                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11179             }
11180             fp0 = tcg_temp_new_i32();
11181             gen_load_fpr32(ctx, fp0, fs);
11182             gen_store_fpr32(ctx, fp0, fd);
11183             tcg_temp_free_i32(fp0);
11184             gen_set_label(l1);
11185         }
11186         break;
11187     case OPC_MOVN_S:
11188         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11189         {
11190             TCGLabel *l1 = gen_new_label();
11191             TCGv_i32 fp0;
11192
11193             if (ft != 0) {
11194                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11195                 fp0 = tcg_temp_new_i32();
11196                 gen_load_fpr32(ctx, fp0, fs);
11197                 gen_store_fpr32(ctx, fp0, fd);
11198                 tcg_temp_free_i32(fp0);
11199                 gen_set_label(l1);
11200             }
11201         }
11202         break;
11203     case OPC_RECIP_S:
11204         {
11205             TCGv_i32 fp0 = tcg_temp_new_i32();
11206
11207             gen_load_fpr32(ctx, fp0, fs);
11208             gen_helper_float_recip_s(fp0, cpu_env, fp0);
11209             gen_store_fpr32(ctx, fp0, fd);
11210             tcg_temp_free_i32(fp0);
11211         }
11212         break;
11213     case OPC_RSQRT_S:
11214         {
11215             TCGv_i32 fp0 = tcg_temp_new_i32();
11216
11217             gen_load_fpr32(ctx, fp0, fs);
11218             gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
11219             gen_store_fpr32(ctx, fp0, fd);
11220             tcg_temp_free_i32(fp0);
11221         }
11222         break;
11223     case OPC_MADDF_S:
11224         check_insn(ctx, ISA_MIPS32R6);
11225         {
11226             TCGv_i32 fp0 = tcg_temp_new_i32();
11227             TCGv_i32 fp1 = tcg_temp_new_i32();
11228             TCGv_i32 fp2 = tcg_temp_new_i32();
11229             gen_load_fpr32(ctx, fp0, fs);
11230             gen_load_fpr32(ctx, fp1, ft);
11231             gen_load_fpr32(ctx, fp2, fd);
11232             gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
11233             gen_store_fpr32(ctx, fp2, fd);
11234             tcg_temp_free_i32(fp2);
11235             tcg_temp_free_i32(fp1);
11236             tcg_temp_free_i32(fp0);
11237         }
11238         break;
11239     case OPC_MSUBF_S:
11240         check_insn(ctx, ISA_MIPS32R6);
11241         {
11242             TCGv_i32 fp0 = tcg_temp_new_i32();
11243             TCGv_i32 fp1 = tcg_temp_new_i32();
11244             TCGv_i32 fp2 = tcg_temp_new_i32();
11245             gen_load_fpr32(ctx, fp0, fs);
11246             gen_load_fpr32(ctx, fp1, ft);
11247             gen_load_fpr32(ctx, fp2, fd);
11248             gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
11249             gen_store_fpr32(ctx, fp2, fd);
11250             tcg_temp_free_i32(fp2);
11251             tcg_temp_free_i32(fp1);
11252             tcg_temp_free_i32(fp0);
11253         }
11254         break;
11255     case OPC_RINT_S:
11256         check_insn(ctx, ISA_MIPS32R6);
11257         {
11258             TCGv_i32 fp0 = tcg_temp_new_i32();
11259             gen_load_fpr32(ctx, fp0, fs);
11260             gen_helper_float_rint_s(fp0, cpu_env, fp0);
11261             gen_store_fpr32(ctx, fp0, fd);
11262             tcg_temp_free_i32(fp0);
11263         }
11264         break;
11265     case OPC_CLASS_S:
11266         check_insn(ctx, ISA_MIPS32R6);
11267         {
11268             TCGv_i32 fp0 = tcg_temp_new_i32();
11269             gen_load_fpr32(ctx, fp0, fs);
11270             gen_helper_float_class_s(fp0, cpu_env, fp0);
11271             gen_store_fpr32(ctx, fp0, fd);
11272             tcg_temp_free_i32(fp0);
11273         }
11274         break;
11275     case OPC_MIN_S: /* OPC_RECIP2_S */
11276         if (ctx->insn_flags & ISA_MIPS32R6) {
11277             /* OPC_MIN_S */
11278             TCGv_i32 fp0 = tcg_temp_new_i32();
11279             TCGv_i32 fp1 = tcg_temp_new_i32();
11280             TCGv_i32 fp2 = tcg_temp_new_i32();
11281             gen_load_fpr32(ctx, fp0, fs);
11282             gen_load_fpr32(ctx, fp1, ft);
11283             gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
11284             gen_store_fpr32(ctx, fp2, fd);
11285             tcg_temp_free_i32(fp2);
11286             tcg_temp_free_i32(fp1);
11287             tcg_temp_free_i32(fp0);
11288         } else {
11289             /* OPC_RECIP2_S */
11290             check_cp1_64bitmode(ctx);
11291             {
11292                 TCGv_i32 fp0 = tcg_temp_new_i32();
11293                 TCGv_i32 fp1 = tcg_temp_new_i32();
11294
11295                 gen_load_fpr32(ctx, fp0, fs);
11296                 gen_load_fpr32(ctx, fp1, ft);
11297                 gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
11298                 tcg_temp_free_i32(fp1);
11299                 gen_store_fpr32(ctx, fp0, fd);
11300                 tcg_temp_free_i32(fp0);
11301             }
11302         }
11303         break;
11304     case OPC_MINA_S: /* OPC_RECIP1_S */
11305         if (ctx->insn_flags & ISA_MIPS32R6) {
11306             /* OPC_MINA_S */
11307             TCGv_i32 fp0 = tcg_temp_new_i32();
11308             TCGv_i32 fp1 = tcg_temp_new_i32();
11309             TCGv_i32 fp2 = tcg_temp_new_i32();
11310             gen_load_fpr32(ctx, fp0, fs);
11311             gen_load_fpr32(ctx, fp1, ft);
11312             gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
11313             gen_store_fpr32(ctx, fp2, fd);
11314             tcg_temp_free_i32(fp2);
11315             tcg_temp_free_i32(fp1);
11316             tcg_temp_free_i32(fp0);
11317         } else {
11318             /* OPC_RECIP1_S */
11319             check_cp1_64bitmode(ctx);
11320             {
11321                 TCGv_i32 fp0 = tcg_temp_new_i32();
11322
11323                 gen_load_fpr32(ctx, fp0, fs);
11324                 gen_helper_float_recip1_s(fp0, cpu_env, fp0);
11325                 gen_store_fpr32(ctx, fp0, fd);
11326                 tcg_temp_free_i32(fp0);
11327             }
11328         }
11329         break;
11330     case OPC_MAX_S: /* OPC_RSQRT1_S */
11331         if (ctx->insn_flags & ISA_MIPS32R6) {
11332             /* OPC_MAX_S */
11333             TCGv_i32 fp0 = tcg_temp_new_i32();
11334             TCGv_i32 fp1 = tcg_temp_new_i32();
11335             gen_load_fpr32(ctx, fp0, fs);
11336             gen_load_fpr32(ctx, fp1, ft);
11337             gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
11338             gen_store_fpr32(ctx, fp1, fd);
11339             tcg_temp_free_i32(fp1);
11340             tcg_temp_free_i32(fp0);
11341         } else {
11342             /* OPC_RSQRT1_S */
11343             check_cp1_64bitmode(ctx);
11344             {
11345                 TCGv_i32 fp0 = tcg_temp_new_i32();
11346
11347                 gen_load_fpr32(ctx, fp0, fs);
11348                 gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
11349                 gen_store_fpr32(ctx, fp0, fd);
11350                 tcg_temp_free_i32(fp0);
11351             }
11352         }
11353         break;
11354     case OPC_MAXA_S: /* OPC_RSQRT2_S */
11355         if (ctx->insn_flags & ISA_MIPS32R6) {
11356             /* OPC_MAXA_S */
11357             TCGv_i32 fp0 = tcg_temp_new_i32();
11358             TCGv_i32 fp1 = tcg_temp_new_i32();
11359             gen_load_fpr32(ctx, fp0, fs);
11360             gen_load_fpr32(ctx, fp1, ft);
11361             gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
11362             gen_store_fpr32(ctx, fp1, fd);
11363             tcg_temp_free_i32(fp1);
11364             tcg_temp_free_i32(fp0);
11365         } else {
11366             /* OPC_RSQRT2_S */
11367             check_cp1_64bitmode(ctx);
11368             {
11369                 TCGv_i32 fp0 = tcg_temp_new_i32();
11370                 TCGv_i32 fp1 = tcg_temp_new_i32();
11371
11372                 gen_load_fpr32(ctx, fp0, fs);
11373                 gen_load_fpr32(ctx, fp1, ft);
11374                 gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
11375                 tcg_temp_free_i32(fp1);
11376                 gen_store_fpr32(ctx, fp0, fd);
11377                 tcg_temp_free_i32(fp0);
11378             }
11379         }
11380         break;
11381     case OPC_CVT_D_S:
11382         check_cp1_registers(ctx, fd);
11383         {
11384             TCGv_i32 fp32 = tcg_temp_new_i32();
11385             TCGv_i64 fp64 = tcg_temp_new_i64();
11386
11387             gen_load_fpr32(ctx, fp32, fs);
11388             gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
11389             tcg_temp_free_i32(fp32);
11390             gen_store_fpr64(ctx, fp64, fd);
11391             tcg_temp_free_i64(fp64);
11392         }
11393         break;
11394     case OPC_CVT_W_S:
11395         {
11396             TCGv_i32 fp0 = tcg_temp_new_i32();
11397
11398             gen_load_fpr32(ctx, fp0, fs);
11399             if (ctx->nan2008) {
11400                 gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
11401             } else {
11402                 gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
11403             }
11404             gen_store_fpr32(ctx, fp0, fd);
11405             tcg_temp_free_i32(fp0);
11406         }
11407         break;
11408     case OPC_CVT_L_S:
11409         check_cp1_64bitmode(ctx);
11410         {
11411             TCGv_i32 fp32 = tcg_temp_new_i32();
11412             TCGv_i64 fp64 = tcg_temp_new_i64();
11413
11414             gen_load_fpr32(ctx, fp32, fs);
11415             if (ctx->nan2008) {
11416                 gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
11417             } else {
11418                 gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
11419             }
11420             tcg_temp_free_i32(fp32);
11421             gen_store_fpr64(ctx, fp64, fd);
11422             tcg_temp_free_i64(fp64);
11423         }
11424         break;
11425     case OPC_CVT_PS_S:
11426         check_ps(ctx);
11427         {
11428             TCGv_i64 fp64 = tcg_temp_new_i64();
11429             TCGv_i32 fp32_0 = tcg_temp_new_i32();
11430             TCGv_i32 fp32_1 = tcg_temp_new_i32();
11431
11432             gen_load_fpr32(ctx, fp32_0, fs);
11433             gen_load_fpr32(ctx, fp32_1, ft);
11434             tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
11435             tcg_temp_free_i32(fp32_1);
11436             tcg_temp_free_i32(fp32_0);
11437             gen_store_fpr64(ctx, fp64, fd);
11438             tcg_temp_free_i64(fp64);
11439         }
11440         break;
11441     case OPC_CMP_F_S:
11442     case OPC_CMP_UN_S:
11443     case OPC_CMP_EQ_S:
11444     case OPC_CMP_UEQ_S:
11445     case OPC_CMP_OLT_S:
11446     case OPC_CMP_ULT_S:
11447     case OPC_CMP_OLE_S:
11448     case OPC_CMP_ULE_S:
11449     case OPC_CMP_SF_S:
11450     case OPC_CMP_NGLE_S:
11451     case OPC_CMP_SEQ_S:
11452     case OPC_CMP_NGL_S:
11453     case OPC_CMP_LT_S:
11454     case OPC_CMP_NGE_S:
11455     case OPC_CMP_LE_S:
11456     case OPC_CMP_NGT_S:
11457         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11458         if (ctx->opcode & (1 << 6)) {
11459             gen_cmpabs_s(ctx, func-48, ft, fs, cc);
11460         } else {
11461             gen_cmp_s(ctx, func-48, ft, fs, cc);
11462         }
11463         break;
11464     case OPC_ADD_D:
11465         check_cp1_registers(ctx, fs | ft | fd);
11466         {
11467             TCGv_i64 fp0 = tcg_temp_new_i64();
11468             TCGv_i64 fp1 = tcg_temp_new_i64();
11469
11470             gen_load_fpr64(ctx, fp0, fs);
11471             gen_load_fpr64(ctx, fp1, ft);
11472             gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
11473             tcg_temp_free_i64(fp1);
11474             gen_store_fpr64(ctx, fp0, fd);
11475             tcg_temp_free_i64(fp0);
11476         }
11477         break;
11478     case OPC_SUB_D:
11479         check_cp1_registers(ctx, fs | ft | fd);
11480         {
11481             TCGv_i64 fp0 = tcg_temp_new_i64();
11482             TCGv_i64 fp1 = tcg_temp_new_i64();
11483
11484             gen_load_fpr64(ctx, fp0, fs);
11485             gen_load_fpr64(ctx, fp1, ft);
11486             gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
11487             tcg_temp_free_i64(fp1);
11488             gen_store_fpr64(ctx, fp0, fd);
11489             tcg_temp_free_i64(fp0);
11490         }
11491         break;
11492     case OPC_MUL_D:
11493         check_cp1_registers(ctx, fs | ft | fd);
11494         {
11495             TCGv_i64 fp0 = tcg_temp_new_i64();
11496             TCGv_i64 fp1 = tcg_temp_new_i64();
11497
11498             gen_load_fpr64(ctx, fp0, fs);
11499             gen_load_fpr64(ctx, fp1, ft);
11500             gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
11501             tcg_temp_free_i64(fp1);
11502             gen_store_fpr64(ctx, fp0, fd);
11503             tcg_temp_free_i64(fp0);
11504         }
11505         break;
11506     case OPC_DIV_D:
11507         check_cp1_registers(ctx, fs | ft | fd);
11508         {
11509             TCGv_i64 fp0 = tcg_temp_new_i64();
11510             TCGv_i64 fp1 = tcg_temp_new_i64();
11511
11512             gen_load_fpr64(ctx, fp0, fs);
11513             gen_load_fpr64(ctx, fp1, ft);
11514             gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
11515             tcg_temp_free_i64(fp1);
11516             gen_store_fpr64(ctx, fp0, fd);
11517             tcg_temp_free_i64(fp0);
11518         }
11519         break;
11520     case OPC_SQRT_D:
11521         check_cp1_registers(ctx, fs | fd);
11522         {
11523             TCGv_i64 fp0 = tcg_temp_new_i64();
11524
11525             gen_load_fpr64(ctx, fp0, fs);
11526             gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
11527             gen_store_fpr64(ctx, fp0, fd);
11528             tcg_temp_free_i64(fp0);
11529         }
11530         break;
11531     case OPC_ABS_D:
11532         check_cp1_registers(ctx, fs | fd);
11533         {
11534             TCGv_i64 fp0 = tcg_temp_new_i64();
11535
11536             gen_load_fpr64(ctx, fp0, fs);
11537             if (ctx->abs2008) {
11538                 tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
11539             } else {
11540                 gen_helper_float_abs_d(fp0, fp0);
11541             }
11542             gen_store_fpr64(ctx, fp0, fd);
11543             tcg_temp_free_i64(fp0);
11544         }
11545         break;
11546     case OPC_MOV_D:
11547         check_cp1_registers(ctx, fs | fd);
11548         {
11549             TCGv_i64 fp0 = tcg_temp_new_i64();
11550
11551             gen_load_fpr64(ctx, fp0, fs);
11552             gen_store_fpr64(ctx, fp0, fd);
11553             tcg_temp_free_i64(fp0);
11554         }
11555         break;
11556     case OPC_NEG_D:
11557         check_cp1_registers(ctx, fs | fd);
11558         {
11559             TCGv_i64 fp0 = tcg_temp_new_i64();
11560
11561             gen_load_fpr64(ctx, fp0, fs);
11562             if (ctx->abs2008) {
11563                 tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
11564             } else {
11565                 gen_helper_float_chs_d(fp0, fp0);
11566             }
11567             gen_store_fpr64(ctx, fp0, fd);
11568             tcg_temp_free_i64(fp0);
11569         }
11570         break;
11571     case OPC_ROUND_L_D:
11572         check_cp1_64bitmode(ctx);
11573         {
11574             TCGv_i64 fp0 = tcg_temp_new_i64();
11575
11576             gen_load_fpr64(ctx, fp0, fs);
11577             if (ctx->nan2008) {
11578                 gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
11579             } else {
11580                 gen_helper_float_round_l_d(fp0, cpu_env, fp0);
11581             }
11582             gen_store_fpr64(ctx, fp0, fd);
11583             tcg_temp_free_i64(fp0);
11584         }
11585         break;
11586     case OPC_TRUNC_L_D:
11587         check_cp1_64bitmode(ctx);
11588         {
11589             TCGv_i64 fp0 = tcg_temp_new_i64();
11590
11591             gen_load_fpr64(ctx, fp0, fs);
11592             if (ctx->nan2008) {
11593                 gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
11594             } else {
11595                 gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
11596             }
11597             gen_store_fpr64(ctx, fp0, fd);
11598             tcg_temp_free_i64(fp0);
11599         }
11600         break;
11601     case OPC_CEIL_L_D:
11602         check_cp1_64bitmode(ctx);
11603         {
11604             TCGv_i64 fp0 = tcg_temp_new_i64();
11605
11606             gen_load_fpr64(ctx, fp0, fs);
11607             if (ctx->nan2008) {
11608                 gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
11609             } else {
11610                 gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
11611             }
11612             gen_store_fpr64(ctx, fp0, fd);
11613             tcg_temp_free_i64(fp0);
11614         }
11615         break;
11616     case OPC_FLOOR_L_D:
11617         check_cp1_64bitmode(ctx);
11618         {
11619             TCGv_i64 fp0 = tcg_temp_new_i64();
11620
11621             gen_load_fpr64(ctx, fp0, fs);
11622             if (ctx->nan2008) {
11623                 gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
11624             } else {
11625                 gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
11626             }
11627             gen_store_fpr64(ctx, fp0, fd);
11628             tcg_temp_free_i64(fp0);
11629         }
11630         break;
11631     case OPC_ROUND_W_D:
11632         check_cp1_registers(ctx, fs);
11633         {
11634             TCGv_i32 fp32 = tcg_temp_new_i32();
11635             TCGv_i64 fp64 = tcg_temp_new_i64();
11636
11637             gen_load_fpr64(ctx, fp64, fs);
11638             if (ctx->nan2008) {
11639                 gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
11640             } else {
11641                 gen_helper_float_round_w_d(fp32, cpu_env, fp64);
11642             }
11643             tcg_temp_free_i64(fp64);
11644             gen_store_fpr32(ctx, fp32, fd);
11645             tcg_temp_free_i32(fp32);
11646         }
11647         break;
11648     case OPC_TRUNC_W_D:
11649         check_cp1_registers(ctx, fs);
11650         {
11651             TCGv_i32 fp32 = tcg_temp_new_i32();
11652             TCGv_i64 fp64 = tcg_temp_new_i64();
11653
11654             gen_load_fpr64(ctx, fp64, fs);
11655             if (ctx->nan2008) {
11656                 gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
11657             } else {
11658                 gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
11659             }
11660             tcg_temp_free_i64(fp64);
11661             gen_store_fpr32(ctx, fp32, fd);
11662             tcg_temp_free_i32(fp32);
11663         }
11664         break;
11665     case OPC_CEIL_W_D:
11666         check_cp1_registers(ctx, fs);
11667         {
11668             TCGv_i32 fp32 = tcg_temp_new_i32();
11669             TCGv_i64 fp64 = tcg_temp_new_i64();
11670
11671             gen_load_fpr64(ctx, fp64, fs);
11672             if (ctx->nan2008) {
11673                 gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
11674             } else {
11675                 gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
11676             }
11677             tcg_temp_free_i64(fp64);
11678             gen_store_fpr32(ctx, fp32, fd);
11679             tcg_temp_free_i32(fp32);
11680         }
11681         break;
11682     case OPC_FLOOR_W_D:
11683         check_cp1_registers(ctx, fs);
11684         {
11685             TCGv_i32 fp32 = tcg_temp_new_i32();
11686             TCGv_i64 fp64 = tcg_temp_new_i64();
11687
11688             gen_load_fpr64(ctx, fp64, fs);
11689             if (ctx->nan2008) {
11690                 gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
11691             } else {
11692                 gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
11693             }
11694             tcg_temp_free_i64(fp64);
11695             gen_store_fpr32(ctx, fp32, fd);
11696             tcg_temp_free_i32(fp32);
11697         }
11698         break;
11699     case OPC_SEL_D:
11700         check_insn(ctx, ISA_MIPS32R6);
11701         gen_sel_d(ctx, op1, fd, ft, fs);
11702         break;
11703     case OPC_SELEQZ_D:
11704         check_insn(ctx, ISA_MIPS32R6);
11705         gen_sel_d(ctx, op1, fd, ft, fs);
11706         break;
11707     case OPC_SELNEZ_D:
11708         check_insn(ctx, ISA_MIPS32R6);
11709         gen_sel_d(ctx, op1, fd, ft, fs);
11710         break;
11711     case OPC_MOVCF_D:
11712         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11713         gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11714         break;
11715     case OPC_MOVZ_D:
11716         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11717         {
11718             TCGLabel *l1 = gen_new_label();
11719             TCGv_i64 fp0;
11720
11721             if (ft != 0) {
11722                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11723             }
11724             fp0 = tcg_temp_new_i64();
11725             gen_load_fpr64(ctx, fp0, fs);
11726             gen_store_fpr64(ctx, fp0, fd);
11727             tcg_temp_free_i64(fp0);
11728             gen_set_label(l1);
11729         }
11730         break;
11731     case OPC_MOVN_D:
11732         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11733         {
11734             TCGLabel *l1 = gen_new_label();
11735             TCGv_i64 fp0;
11736
11737             if (ft != 0) {
11738                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11739                 fp0 = tcg_temp_new_i64();
11740                 gen_load_fpr64(ctx, fp0, fs);
11741                 gen_store_fpr64(ctx, fp0, fd);
11742                 tcg_temp_free_i64(fp0);
11743                 gen_set_label(l1);
11744             }
11745         }
11746         break;
11747     case OPC_RECIP_D:
11748         check_cp1_registers(ctx, fs | fd);
11749         {
11750             TCGv_i64 fp0 = tcg_temp_new_i64();
11751
11752             gen_load_fpr64(ctx, fp0, fs);
11753             gen_helper_float_recip_d(fp0, cpu_env, fp0);
11754             gen_store_fpr64(ctx, fp0, fd);
11755             tcg_temp_free_i64(fp0);
11756         }
11757         break;
11758     case OPC_RSQRT_D:
11759         check_cp1_registers(ctx, fs | fd);
11760         {
11761             TCGv_i64 fp0 = tcg_temp_new_i64();
11762
11763             gen_load_fpr64(ctx, fp0, fs);
11764             gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
11765             gen_store_fpr64(ctx, fp0, fd);
11766             tcg_temp_free_i64(fp0);
11767         }
11768         break;
11769     case OPC_MADDF_D:
11770         check_insn(ctx, ISA_MIPS32R6);
11771         {
11772             TCGv_i64 fp0 = tcg_temp_new_i64();
11773             TCGv_i64 fp1 = tcg_temp_new_i64();
11774             TCGv_i64 fp2 = tcg_temp_new_i64();
11775             gen_load_fpr64(ctx, fp0, fs);
11776             gen_load_fpr64(ctx, fp1, ft);
11777             gen_load_fpr64(ctx, fp2, fd);
11778             gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
11779             gen_store_fpr64(ctx, fp2, fd);
11780             tcg_temp_free_i64(fp2);
11781             tcg_temp_free_i64(fp1);
11782             tcg_temp_free_i64(fp0);
11783         }
11784         break;
11785     case OPC_MSUBF_D:
11786         check_insn(ctx, ISA_MIPS32R6);
11787         {
11788             TCGv_i64 fp0 = tcg_temp_new_i64();
11789             TCGv_i64 fp1 = tcg_temp_new_i64();
11790             TCGv_i64 fp2 = tcg_temp_new_i64();
11791             gen_load_fpr64(ctx, fp0, fs);
11792             gen_load_fpr64(ctx, fp1, ft);
11793             gen_load_fpr64(ctx, fp2, fd);
11794             gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
11795             gen_store_fpr64(ctx, fp2, fd);
11796             tcg_temp_free_i64(fp2);
11797             tcg_temp_free_i64(fp1);
11798             tcg_temp_free_i64(fp0);
11799         }
11800         break;
11801     case OPC_RINT_D:
11802         check_insn(ctx, ISA_MIPS32R6);
11803         {
11804             TCGv_i64 fp0 = tcg_temp_new_i64();
11805             gen_load_fpr64(ctx, fp0, fs);
11806             gen_helper_float_rint_d(fp0, cpu_env, fp0);
11807             gen_store_fpr64(ctx, fp0, fd);
11808             tcg_temp_free_i64(fp0);
11809         }
11810         break;
11811     case OPC_CLASS_D:
11812         check_insn(ctx, ISA_MIPS32R6);
11813         {
11814             TCGv_i64 fp0 = tcg_temp_new_i64();
11815             gen_load_fpr64(ctx, fp0, fs);
11816             gen_helper_float_class_d(fp0, cpu_env, fp0);
11817             gen_store_fpr64(ctx, fp0, fd);
11818             tcg_temp_free_i64(fp0);
11819         }
11820         break;
11821     case OPC_MIN_D: /* OPC_RECIP2_D */
11822         if (ctx->insn_flags & ISA_MIPS32R6) {
11823             /* OPC_MIN_D */
11824             TCGv_i64 fp0 = tcg_temp_new_i64();
11825             TCGv_i64 fp1 = tcg_temp_new_i64();
11826             gen_load_fpr64(ctx, fp0, fs);
11827             gen_load_fpr64(ctx, fp1, ft);
11828             gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
11829             gen_store_fpr64(ctx, fp1, fd);
11830             tcg_temp_free_i64(fp1);
11831             tcg_temp_free_i64(fp0);
11832         } else {
11833             /* OPC_RECIP2_D */
11834             check_cp1_64bitmode(ctx);
11835             {
11836                 TCGv_i64 fp0 = tcg_temp_new_i64();
11837                 TCGv_i64 fp1 = tcg_temp_new_i64();
11838
11839                 gen_load_fpr64(ctx, fp0, fs);
11840                 gen_load_fpr64(ctx, fp1, ft);
11841                 gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
11842                 tcg_temp_free_i64(fp1);
11843                 gen_store_fpr64(ctx, fp0, fd);
11844                 tcg_temp_free_i64(fp0);
11845             }
11846         }
11847         break;
11848     case OPC_MINA_D: /* OPC_RECIP1_D */
11849         if (ctx->insn_flags & ISA_MIPS32R6) {
11850             /* OPC_MINA_D */
11851             TCGv_i64 fp0 = tcg_temp_new_i64();
11852             TCGv_i64 fp1 = tcg_temp_new_i64();
11853             gen_load_fpr64(ctx, fp0, fs);
11854             gen_load_fpr64(ctx, fp1, ft);
11855             gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
11856             gen_store_fpr64(ctx, fp1, fd);
11857             tcg_temp_free_i64(fp1);
11858             tcg_temp_free_i64(fp0);
11859         } else {
11860             /* OPC_RECIP1_D */
11861             check_cp1_64bitmode(ctx);
11862             {
11863                 TCGv_i64 fp0 = tcg_temp_new_i64();
11864
11865                 gen_load_fpr64(ctx, fp0, fs);
11866                 gen_helper_float_recip1_d(fp0, cpu_env, fp0);
11867                 gen_store_fpr64(ctx, fp0, fd);
11868                 tcg_temp_free_i64(fp0);
11869             }
11870         }
11871         break;
11872     case OPC_MAX_D: /*  OPC_RSQRT1_D */
11873         if (ctx->insn_flags & ISA_MIPS32R6) {
11874             /* OPC_MAX_D */
11875             TCGv_i64 fp0 = tcg_temp_new_i64();
11876             TCGv_i64 fp1 = tcg_temp_new_i64();
11877             gen_load_fpr64(ctx, fp0, fs);
11878             gen_load_fpr64(ctx, fp1, ft);
11879             gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
11880             gen_store_fpr64(ctx, fp1, fd);
11881             tcg_temp_free_i64(fp1);
11882             tcg_temp_free_i64(fp0);
11883         } else {
11884             /* OPC_RSQRT1_D */
11885             check_cp1_64bitmode(ctx);
11886             {
11887                 TCGv_i64 fp0 = tcg_temp_new_i64();
11888
11889                 gen_load_fpr64(ctx, fp0, fs);
11890                 gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
11891                 gen_store_fpr64(ctx, fp0, fd);
11892                 tcg_temp_free_i64(fp0);
11893             }
11894         }
11895         break;
11896     case OPC_MAXA_D: /* OPC_RSQRT2_D */
11897         if (ctx->insn_flags & ISA_MIPS32R6) {
11898             /* OPC_MAXA_D */
11899             TCGv_i64 fp0 = tcg_temp_new_i64();
11900             TCGv_i64 fp1 = tcg_temp_new_i64();
11901             gen_load_fpr64(ctx, fp0, fs);
11902             gen_load_fpr64(ctx, fp1, ft);
11903             gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11904             gen_store_fpr64(ctx, fp1, fd);
11905             tcg_temp_free_i64(fp1);
11906             tcg_temp_free_i64(fp0);
11907         } else {
11908             /* OPC_RSQRT2_D */
11909             check_cp1_64bitmode(ctx);
11910             {
11911                 TCGv_i64 fp0 = tcg_temp_new_i64();
11912                 TCGv_i64 fp1 = tcg_temp_new_i64();
11913
11914                 gen_load_fpr64(ctx, fp0, fs);
11915                 gen_load_fpr64(ctx, fp1, ft);
11916                 gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11917                 tcg_temp_free_i64(fp1);
11918                 gen_store_fpr64(ctx, fp0, fd);
11919                 tcg_temp_free_i64(fp0);
11920             }
11921         }
11922         break;
11923     case OPC_CMP_F_D:
11924     case OPC_CMP_UN_D:
11925     case OPC_CMP_EQ_D:
11926     case OPC_CMP_UEQ_D:
11927     case OPC_CMP_OLT_D:
11928     case OPC_CMP_ULT_D:
11929     case OPC_CMP_OLE_D:
11930     case OPC_CMP_ULE_D:
11931     case OPC_CMP_SF_D:
11932     case OPC_CMP_NGLE_D:
11933     case OPC_CMP_SEQ_D:
11934     case OPC_CMP_NGL_D:
11935     case OPC_CMP_LT_D:
11936     case OPC_CMP_NGE_D:
11937     case OPC_CMP_LE_D:
11938     case OPC_CMP_NGT_D:
11939         check_insn_opc_removed(ctx, ISA_MIPS32R6);
11940         if (ctx->opcode & (1 << 6)) {
11941             gen_cmpabs_d(ctx, func-48, ft, fs, cc);
11942         } else {
11943             gen_cmp_d(ctx, func-48, ft, fs, cc);
11944         }
11945         break;
11946     case OPC_CVT_S_D:
11947         check_cp1_registers(ctx, fs);
11948         {
11949             TCGv_i32 fp32 = tcg_temp_new_i32();
11950             TCGv_i64 fp64 = tcg_temp_new_i64();
11951
11952             gen_load_fpr64(ctx, fp64, fs);
11953             gen_helper_float_cvts_d(fp32, cpu_env, fp64);
11954             tcg_temp_free_i64(fp64);
11955             gen_store_fpr32(ctx, fp32, fd);
11956             tcg_temp_free_i32(fp32);
11957         }
11958         break;
11959     case OPC_CVT_W_D:
11960         check_cp1_registers(ctx, fs);
11961         {
11962             TCGv_i32 fp32 = tcg_temp_new_i32();
11963             TCGv_i64 fp64 = tcg_temp_new_i64();
11964
11965             gen_load_fpr64(ctx, fp64, fs);
11966             if (ctx->nan2008) {
11967                 gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11968             } else {
11969                 gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11970             }
11971             tcg_temp_free_i64(fp64);
11972             gen_store_fpr32(ctx, fp32, fd);
11973             tcg_temp_free_i32(fp32);
11974         }
11975         break;
11976     case OPC_CVT_L_D:
11977         check_cp1_64bitmode(ctx);
11978         {
11979             TCGv_i64 fp0 = tcg_temp_new_i64();
11980
11981             gen_load_fpr64(ctx, fp0, fs);
11982             if (ctx->nan2008) {
11983                 gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11984             } else {
11985                 gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11986             }
11987             gen_store_fpr64(ctx, fp0, fd);
11988             tcg_temp_free_i64(fp0);
11989         }
11990         break;
11991     case OPC_CVT_S_W:
11992         {
11993             TCGv_i32 fp0 = tcg_temp_new_i32();
11994
11995             gen_load_fpr32(ctx, fp0, fs);
11996             gen_helper_float_cvts_w(fp0, cpu_env, fp0);
11997             gen_store_fpr32(ctx, fp0, fd);
11998             tcg_temp_free_i32(fp0);
11999         }
12000         break;
12001     case OPC_CVT_D_W:
12002         check_cp1_registers(ctx, fd);
12003         {
12004             TCGv_i32 fp32 = tcg_temp_new_i32();
12005             TCGv_i64 fp64 = tcg_temp_new_i64();
12006
12007             gen_load_fpr32(ctx, fp32, fs);
12008             gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
12009             tcg_temp_free_i32(fp32);
12010             gen_store_fpr64(ctx, fp64, fd);
12011             tcg_temp_free_i64(fp64);
12012         }
12013         break;
12014     case OPC_CVT_S_L:
12015         check_cp1_64bitmode(ctx);
12016         {
12017             TCGv_i32 fp32 = tcg_temp_new_i32();
12018             TCGv_i64 fp64 = tcg_temp_new_i64();
12019
12020             gen_load_fpr64(ctx, fp64, fs);
12021             gen_helper_float_cvts_l(fp32, cpu_env, fp64);
12022             tcg_temp_free_i64(fp64);
12023             gen_store_fpr32(ctx, fp32, fd);
12024             tcg_temp_free_i32(fp32);
12025         }
12026         break;
12027     case OPC_CVT_D_L:
12028         check_cp1_64bitmode(ctx);
12029         {
12030             TCGv_i64 fp0 = tcg_temp_new_i64();
12031
12032             gen_load_fpr64(ctx, fp0, fs);
12033             gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
12034             gen_store_fpr64(ctx, fp0, fd);
12035             tcg_temp_free_i64(fp0);
12036         }
12037         break;
12038     case OPC_CVT_PS_PW:
12039         check_ps(ctx);
12040         {
12041             TCGv_i64 fp0 = tcg_temp_new_i64();
12042
12043             gen_load_fpr64(ctx, fp0, fs);
12044             gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
12045             gen_store_fpr64(ctx, fp0, fd);
12046             tcg_temp_free_i64(fp0);
12047         }
12048         break;
12049     case OPC_ADD_PS:
12050         check_ps(ctx);
12051         {
12052             TCGv_i64 fp0 = tcg_temp_new_i64();
12053             TCGv_i64 fp1 = tcg_temp_new_i64();
12054
12055             gen_load_fpr64(ctx, fp0, fs);
12056             gen_load_fpr64(ctx, fp1, ft);
12057             gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
12058             tcg_temp_free_i64(fp1);
12059             gen_store_fpr64(ctx, fp0, fd);
12060             tcg_temp_free_i64(fp0);
12061         }
12062         break;
12063     case OPC_SUB_PS:
12064         check_ps(ctx);
12065         {
12066             TCGv_i64 fp0 = tcg_temp_new_i64();
12067             TCGv_i64 fp1 = tcg_temp_new_i64();
12068
12069             gen_load_fpr64(ctx, fp0, fs);
12070             gen_load_fpr64(ctx, fp1, ft);
12071             gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
12072             tcg_temp_free_i64(fp1);
12073             gen_store_fpr64(ctx, fp0, fd);
12074             tcg_temp_free_i64(fp0);
12075         }
12076         break;
12077     case OPC_MUL_PS:
12078         check_ps(ctx);
12079         {
12080             TCGv_i64 fp0 = tcg_temp_new_i64();
12081             TCGv_i64 fp1 = tcg_temp_new_i64();
12082
12083             gen_load_fpr64(ctx, fp0, fs);
12084             gen_load_fpr64(ctx, fp1, ft);
12085             gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
12086             tcg_temp_free_i64(fp1);
12087             gen_store_fpr64(ctx, fp0, fd);
12088             tcg_temp_free_i64(fp0);
12089         }
12090         break;
12091     case OPC_ABS_PS:
12092         check_ps(ctx);
12093         {
12094             TCGv_i64 fp0 = tcg_temp_new_i64();
12095
12096             gen_load_fpr64(ctx, fp0, fs);
12097             gen_helper_float_abs_ps(fp0, fp0);
12098             gen_store_fpr64(ctx, fp0, fd);
12099             tcg_temp_free_i64(fp0);
12100         }
12101         break;
12102     case OPC_MOV_PS:
12103         check_ps(ctx);
12104         {
12105             TCGv_i64 fp0 = tcg_temp_new_i64();
12106
12107             gen_load_fpr64(ctx, fp0, fs);
12108             gen_store_fpr64(ctx, fp0, fd);
12109             tcg_temp_free_i64(fp0);
12110         }
12111         break;
12112     case OPC_NEG_PS:
12113         check_ps(ctx);
12114         {
12115             TCGv_i64 fp0 = tcg_temp_new_i64();
12116
12117             gen_load_fpr64(ctx, fp0, fs);
12118             gen_helper_float_chs_ps(fp0, fp0);
12119             gen_store_fpr64(ctx, fp0, fd);
12120             tcg_temp_free_i64(fp0);
12121         }
12122         break;
12123     case OPC_MOVCF_PS:
12124         check_ps(ctx);
12125         gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
12126         break;
12127     case OPC_MOVZ_PS:
12128         check_ps(ctx);
12129         {
12130             TCGLabel *l1 = gen_new_label();
12131             TCGv_i64 fp0;
12132
12133             if (ft != 0)
12134                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
12135             fp0 = tcg_temp_new_i64();
12136             gen_load_fpr64(ctx, fp0, fs);
12137             gen_store_fpr64(ctx, fp0, fd);
12138             tcg_temp_free_i64(fp0);
12139             gen_set_label(l1);
12140         }
12141         break;
12142     case OPC_MOVN_PS:
12143         check_ps(ctx);
12144         {
12145             TCGLabel *l1 = gen_new_label();
12146             TCGv_i64 fp0;
12147
12148             if (ft != 0) {
12149                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
12150                 fp0 = tcg_temp_new_i64();
12151                 gen_load_fpr64(ctx, fp0, fs);
12152                 gen_store_fpr64(ctx, fp0, fd);
12153                 tcg_temp_free_i64(fp0);
12154                 gen_set_label(l1);
12155             }
12156         }
12157         break;
12158     case OPC_ADDR_PS:
12159         check_ps(ctx);
12160         {
12161             TCGv_i64 fp0 = tcg_temp_new_i64();
12162             TCGv_i64 fp1 = tcg_temp_new_i64();
12163
12164             gen_load_fpr64(ctx, fp0, ft);
12165             gen_load_fpr64(ctx, fp1, fs);
12166             gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
12167             tcg_temp_free_i64(fp1);
12168             gen_store_fpr64(ctx, fp0, fd);
12169             tcg_temp_free_i64(fp0);
12170         }
12171         break;
12172     case OPC_MULR_PS:
12173         check_ps(ctx);
12174         {
12175             TCGv_i64 fp0 = tcg_temp_new_i64();
12176             TCGv_i64 fp1 = tcg_temp_new_i64();
12177
12178             gen_load_fpr64(ctx, fp0, ft);
12179             gen_load_fpr64(ctx, fp1, fs);
12180             gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
12181             tcg_temp_free_i64(fp1);
12182             gen_store_fpr64(ctx, fp0, fd);
12183             tcg_temp_free_i64(fp0);
12184         }
12185         break;
12186     case OPC_RECIP2_PS:
12187         check_ps(ctx);
12188         {
12189             TCGv_i64 fp0 = tcg_temp_new_i64();
12190             TCGv_i64 fp1 = tcg_temp_new_i64();
12191
12192             gen_load_fpr64(ctx, fp0, fs);
12193             gen_load_fpr64(ctx, fp1, ft);
12194             gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
12195             tcg_temp_free_i64(fp1);
12196             gen_store_fpr64(ctx, fp0, fd);
12197             tcg_temp_free_i64(fp0);
12198         }
12199         break;
12200     case OPC_RECIP1_PS:
12201         check_ps(ctx);
12202         {
12203             TCGv_i64 fp0 = tcg_temp_new_i64();
12204
12205             gen_load_fpr64(ctx, fp0, fs);
12206             gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
12207             gen_store_fpr64(ctx, fp0, fd);
12208             tcg_temp_free_i64(fp0);
12209         }
12210         break;
12211     case OPC_RSQRT1_PS:
12212         check_ps(ctx);
12213         {
12214             TCGv_i64 fp0 = tcg_temp_new_i64();
12215
12216             gen_load_fpr64(ctx, fp0, fs);
12217             gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
12218             gen_store_fpr64(ctx, fp0, fd);
12219             tcg_temp_free_i64(fp0);
12220         }
12221         break;
12222     case OPC_RSQRT2_PS:
12223         check_ps(ctx);
12224         {
12225             TCGv_i64 fp0 = tcg_temp_new_i64();
12226             TCGv_i64 fp1 = tcg_temp_new_i64();
12227
12228             gen_load_fpr64(ctx, fp0, fs);
12229             gen_load_fpr64(ctx, fp1, ft);
12230             gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
12231             tcg_temp_free_i64(fp1);
12232             gen_store_fpr64(ctx, fp0, fd);
12233             tcg_temp_free_i64(fp0);
12234         }
12235         break;
12236     case OPC_CVT_S_PU:
12237         check_cp1_64bitmode(ctx);
12238         {
12239             TCGv_i32 fp0 = tcg_temp_new_i32();
12240
12241             gen_load_fpr32h(ctx, fp0, fs);
12242             gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
12243             gen_store_fpr32(ctx, fp0, fd);
12244             tcg_temp_free_i32(fp0);
12245         }
12246         break;
12247     case OPC_CVT_PW_PS:
12248         check_ps(ctx);
12249         {
12250             TCGv_i64 fp0 = tcg_temp_new_i64();
12251
12252             gen_load_fpr64(ctx, fp0, fs);
12253             gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
12254             gen_store_fpr64(ctx, fp0, fd);
12255             tcg_temp_free_i64(fp0);
12256         }
12257         break;
12258     case OPC_CVT_S_PL:
12259         check_cp1_64bitmode(ctx);
12260         {
12261             TCGv_i32 fp0 = tcg_temp_new_i32();
12262
12263             gen_load_fpr32(ctx, fp0, fs);
12264             gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
12265             gen_store_fpr32(ctx, fp0, fd);
12266             tcg_temp_free_i32(fp0);
12267         }
12268         break;
12269     case OPC_PLL_PS:
12270         check_ps(ctx);
12271         {
12272             TCGv_i32 fp0 = tcg_temp_new_i32();
12273             TCGv_i32 fp1 = tcg_temp_new_i32();
12274
12275             gen_load_fpr32(ctx, fp0, fs);
12276             gen_load_fpr32(ctx, fp1, ft);
12277             gen_store_fpr32h(ctx, fp0, fd);
12278             gen_store_fpr32(ctx, fp1, fd);
12279             tcg_temp_free_i32(fp0);
12280             tcg_temp_free_i32(fp1);
12281         }
12282         break;
12283     case OPC_PLU_PS:
12284         check_ps(ctx);
12285         {
12286             TCGv_i32 fp0 = tcg_temp_new_i32();
12287             TCGv_i32 fp1 = tcg_temp_new_i32();
12288
12289             gen_load_fpr32(ctx, fp0, fs);
12290             gen_load_fpr32h(ctx, fp1, ft);
12291             gen_store_fpr32(ctx, fp1, fd);
12292             gen_store_fpr32h(ctx, fp0, fd);
12293             tcg_temp_free_i32(fp0);
12294             tcg_temp_free_i32(fp1);
12295         }
12296         break;
12297     case OPC_PUL_PS:
12298         check_ps(ctx);
12299         {
12300             TCGv_i32 fp0 = tcg_temp_new_i32();
12301             TCGv_i32 fp1 = tcg_temp_new_i32();
12302
12303             gen_load_fpr32h(ctx, fp0, fs);
12304             gen_load_fpr32(ctx, fp1, ft);
12305             gen_store_fpr32(ctx, fp1, fd);
12306             gen_store_fpr32h(ctx, fp0, fd);
12307             tcg_temp_free_i32(fp0);
12308             tcg_temp_free_i32(fp1);
12309         }
12310         break;
12311     case OPC_PUU_PS:
12312         check_ps(ctx);
12313         {
12314             TCGv_i32 fp0 = tcg_temp_new_i32();
12315             TCGv_i32 fp1 = tcg_temp_new_i32();
12316
12317             gen_load_fpr32h(ctx, fp0, fs);
12318             gen_load_fpr32h(ctx, fp1, ft);
12319             gen_store_fpr32(ctx, fp1, fd);
12320             gen_store_fpr32h(ctx, fp0, fd);
12321             tcg_temp_free_i32(fp0);
12322             tcg_temp_free_i32(fp1);
12323         }
12324         break;
12325     case OPC_CMP_F_PS:
12326     case OPC_CMP_UN_PS:
12327     case OPC_CMP_EQ_PS:
12328     case OPC_CMP_UEQ_PS:
12329     case OPC_CMP_OLT_PS:
12330     case OPC_CMP_ULT_PS:
12331     case OPC_CMP_OLE_PS:
12332     case OPC_CMP_ULE_PS:
12333     case OPC_CMP_SF_PS:
12334     case OPC_CMP_NGLE_PS:
12335     case OPC_CMP_SEQ_PS:
12336     case OPC_CMP_NGL_PS:
12337     case OPC_CMP_LT_PS:
12338     case OPC_CMP_NGE_PS:
12339     case OPC_CMP_LE_PS:
12340     case OPC_CMP_NGT_PS:
12341         if (ctx->opcode & (1 << 6)) {
12342             gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
12343         } else {
12344             gen_cmp_ps(ctx, func-48, ft, fs, cc);
12345         }
12346         break;
12347     default:
12348         MIPS_INVAL("farith");
12349         generate_exception_end(ctx, EXCP_RI);
12350         return;
12351     }
12352 }
12353
12354 /* Coprocessor 3 (FPU) */
12355 static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
12356                            int fd, int fs, int base, int index)
12357 {
12358     TCGv t0 = tcg_temp_new();
12359
12360     if (base == 0) {
12361         gen_load_gpr(t0, index);
12362     } else if (index == 0) {
12363         gen_load_gpr(t0, base);
12364     } else {
12365         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
12366     }
12367     /* Don't do NOP if destination is zero: we must perform the actual
12368        memory access. */
12369     switch (opc) {
12370     case OPC_LWXC1:
12371         check_cop1x(ctx);
12372         {
12373             TCGv_i32 fp0 = tcg_temp_new_i32();
12374
12375             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12376             tcg_gen_trunc_tl_i32(fp0, t0);
12377             gen_store_fpr32(ctx, fp0, fd);
12378             tcg_temp_free_i32(fp0);
12379         }
12380         break;
12381     case OPC_LDXC1:
12382         check_cop1x(ctx);
12383         check_cp1_registers(ctx, fd);
12384         {
12385             TCGv_i64 fp0 = tcg_temp_new_i64();
12386             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12387             gen_store_fpr64(ctx, fp0, fd);
12388             tcg_temp_free_i64(fp0);
12389         }
12390         break;
12391     case OPC_LUXC1:
12392         check_cp1_64bitmode(ctx);
12393         tcg_gen_andi_tl(t0, t0, ~0x7);
12394         {
12395             TCGv_i64 fp0 = tcg_temp_new_i64();
12396
12397             tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12398             gen_store_fpr64(ctx, fp0, fd);
12399             tcg_temp_free_i64(fp0);
12400         }
12401         break;
12402     case OPC_SWXC1:
12403         check_cop1x(ctx);
12404         {
12405             TCGv_i32 fp0 = tcg_temp_new_i32();
12406             gen_load_fpr32(ctx, fp0, fs);
12407             tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
12408             tcg_temp_free_i32(fp0);
12409         }
12410         break;
12411     case OPC_SDXC1:
12412         check_cop1x(ctx);
12413         check_cp1_registers(ctx, fs);
12414         {
12415             TCGv_i64 fp0 = tcg_temp_new_i64();
12416             gen_load_fpr64(ctx, fp0, fs);
12417             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12418             tcg_temp_free_i64(fp0);
12419         }
12420         break;
12421     case OPC_SUXC1:
12422         check_cp1_64bitmode(ctx);
12423         tcg_gen_andi_tl(t0, t0, ~0x7);
12424         {
12425             TCGv_i64 fp0 = tcg_temp_new_i64();
12426             gen_load_fpr64(ctx, fp0, fs);
12427             tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
12428             tcg_temp_free_i64(fp0);
12429         }
12430         break;
12431     }
12432     tcg_temp_free(t0);
12433 }
12434
12435 static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
12436                             int fd, int fr, int fs, int ft)
12437 {
12438     switch (opc) {
12439     case OPC_ALNV_PS:
12440         check_ps(ctx);
12441         {
12442             TCGv t0 = tcg_temp_local_new();
12443             TCGv_i32 fp = tcg_temp_new_i32();
12444             TCGv_i32 fph = tcg_temp_new_i32();
12445             TCGLabel *l1 = gen_new_label();
12446             TCGLabel *l2 = gen_new_label();
12447
12448             gen_load_gpr(t0, fr);
12449             tcg_gen_andi_tl(t0, t0, 0x7);
12450
12451             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
12452             gen_load_fpr32(ctx, fp, fs);
12453             gen_load_fpr32h(ctx, fph, fs);
12454             gen_store_fpr32(ctx, fp, fd);
12455             gen_store_fpr32h(ctx, fph, fd);
12456             tcg_gen_br(l2);
12457             gen_set_label(l1);
12458             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
12459             tcg_temp_free(t0);
12460 #ifdef TARGET_WORDS_BIGENDIAN
12461             gen_load_fpr32(ctx, fp, fs);
12462             gen_load_fpr32h(ctx, fph, ft);
12463             gen_store_fpr32h(ctx, fp, fd);
12464             gen_store_fpr32(ctx, fph, fd);
12465 #else
12466             gen_load_fpr32h(ctx, fph, fs);
12467             gen_load_fpr32(ctx, fp, ft);
12468             gen_store_fpr32(ctx, fph, fd);
12469             gen_store_fpr32h(ctx, fp, fd);
12470 #endif
12471             gen_set_label(l2);
12472             tcg_temp_free_i32(fp);
12473             tcg_temp_free_i32(fph);
12474         }
12475         break;
12476     case OPC_MADD_S:
12477         check_cop1x(ctx);
12478         {
12479             TCGv_i32 fp0 = tcg_temp_new_i32();
12480             TCGv_i32 fp1 = tcg_temp_new_i32();
12481             TCGv_i32 fp2 = tcg_temp_new_i32();
12482
12483             gen_load_fpr32(ctx, fp0, fs);
12484             gen_load_fpr32(ctx, fp1, ft);
12485             gen_load_fpr32(ctx, fp2, fr);
12486             gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
12487             tcg_temp_free_i32(fp0);
12488             tcg_temp_free_i32(fp1);
12489             gen_store_fpr32(ctx, fp2, fd);
12490             tcg_temp_free_i32(fp2);
12491         }
12492         break;
12493     case OPC_MADD_D:
12494         check_cop1x(ctx);
12495         check_cp1_registers(ctx, fd | fs | ft | fr);
12496         {
12497             TCGv_i64 fp0 = tcg_temp_new_i64();
12498             TCGv_i64 fp1 = tcg_temp_new_i64();
12499             TCGv_i64 fp2 = tcg_temp_new_i64();
12500
12501             gen_load_fpr64(ctx, fp0, fs);
12502             gen_load_fpr64(ctx, fp1, ft);
12503             gen_load_fpr64(ctx, fp2, fr);
12504             gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
12505             tcg_temp_free_i64(fp0);
12506             tcg_temp_free_i64(fp1);
12507             gen_store_fpr64(ctx, fp2, fd);
12508             tcg_temp_free_i64(fp2);
12509         }
12510         break;
12511     case OPC_MADD_PS:
12512         check_ps(ctx);
12513         {
12514             TCGv_i64 fp0 = tcg_temp_new_i64();
12515             TCGv_i64 fp1 = tcg_temp_new_i64();
12516             TCGv_i64 fp2 = tcg_temp_new_i64();
12517
12518             gen_load_fpr64(ctx, fp0, fs);
12519             gen_load_fpr64(ctx, fp1, ft);
12520             gen_load_fpr64(ctx, fp2, fr);
12521             gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
12522             tcg_temp_free_i64(fp0);
12523             tcg_temp_free_i64(fp1);
12524             gen_store_fpr64(ctx, fp2, fd);
12525             tcg_temp_free_i64(fp2);
12526         }
12527         break;
12528     case OPC_MSUB_S:
12529         check_cop1x(ctx);
12530         {
12531             TCGv_i32 fp0 = tcg_temp_new_i32();
12532             TCGv_i32 fp1 = tcg_temp_new_i32();
12533             TCGv_i32 fp2 = tcg_temp_new_i32();
12534
12535             gen_load_fpr32(ctx, fp0, fs);
12536             gen_load_fpr32(ctx, fp1, ft);
12537             gen_load_fpr32(ctx, fp2, fr);
12538             gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
12539             tcg_temp_free_i32(fp0);
12540             tcg_temp_free_i32(fp1);
12541             gen_store_fpr32(ctx, fp2, fd);
12542             tcg_temp_free_i32(fp2);
12543         }
12544         break;
12545     case OPC_MSUB_D:
12546         check_cop1x(ctx);
12547         check_cp1_registers(ctx, fd | fs | ft | fr);
12548         {
12549             TCGv_i64 fp0 = tcg_temp_new_i64();
12550             TCGv_i64 fp1 = tcg_temp_new_i64();
12551             TCGv_i64 fp2 = tcg_temp_new_i64();
12552
12553             gen_load_fpr64(ctx, fp0, fs);
12554             gen_load_fpr64(ctx, fp1, ft);
12555             gen_load_fpr64(ctx, fp2, fr);
12556             gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
12557             tcg_temp_free_i64(fp0);
12558             tcg_temp_free_i64(fp1);
12559             gen_store_fpr64(ctx, fp2, fd);
12560             tcg_temp_free_i64(fp2);
12561         }
12562         break;
12563     case OPC_MSUB_PS:
12564         check_ps(ctx);
12565         {
12566             TCGv_i64 fp0 = tcg_temp_new_i64();
12567             TCGv_i64 fp1 = tcg_temp_new_i64();
12568             TCGv_i64 fp2 = tcg_temp_new_i64();
12569
12570             gen_load_fpr64(ctx, fp0, fs);
12571             gen_load_fpr64(ctx, fp1, ft);
12572             gen_load_fpr64(ctx, fp2, fr);
12573             gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
12574             tcg_temp_free_i64(fp0);
12575             tcg_temp_free_i64(fp1);
12576             gen_store_fpr64(ctx, fp2, fd);
12577             tcg_temp_free_i64(fp2);
12578         }
12579         break;
12580     case OPC_NMADD_S:
12581         check_cop1x(ctx);
12582         {
12583             TCGv_i32 fp0 = tcg_temp_new_i32();
12584             TCGv_i32 fp1 = tcg_temp_new_i32();
12585             TCGv_i32 fp2 = tcg_temp_new_i32();
12586
12587             gen_load_fpr32(ctx, fp0, fs);
12588             gen_load_fpr32(ctx, fp1, ft);
12589             gen_load_fpr32(ctx, fp2, fr);
12590             gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
12591             tcg_temp_free_i32(fp0);
12592             tcg_temp_free_i32(fp1);
12593             gen_store_fpr32(ctx, fp2, fd);
12594             tcg_temp_free_i32(fp2);
12595         }
12596         break;
12597     case OPC_NMADD_D:
12598         check_cop1x(ctx);
12599         check_cp1_registers(ctx, fd | fs | ft | fr);
12600         {
12601             TCGv_i64 fp0 = tcg_temp_new_i64();
12602             TCGv_i64 fp1 = tcg_temp_new_i64();
12603             TCGv_i64 fp2 = tcg_temp_new_i64();
12604
12605             gen_load_fpr64(ctx, fp0, fs);
12606             gen_load_fpr64(ctx, fp1, ft);
12607             gen_load_fpr64(ctx, fp2, fr);
12608             gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
12609             tcg_temp_free_i64(fp0);
12610             tcg_temp_free_i64(fp1);
12611             gen_store_fpr64(ctx, fp2, fd);
12612             tcg_temp_free_i64(fp2);
12613         }
12614         break;
12615     case OPC_NMADD_PS:
12616         check_ps(ctx);
12617         {
12618             TCGv_i64 fp0 = tcg_temp_new_i64();
12619             TCGv_i64 fp1 = tcg_temp_new_i64();
12620             TCGv_i64 fp2 = tcg_temp_new_i64();
12621
12622             gen_load_fpr64(ctx, fp0, fs);
12623             gen_load_fpr64(ctx, fp1, ft);
12624             gen_load_fpr64(ctx, fp2, fr);
12625             gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
12626             tcg_temp_free_i64(fp0);
12627             tcg_temp_free_i64(fp1);
12628             gen_store_fpr64(ctx, fp2, fd);
12629             tcg_temp_free_i64(fp2);
12630         }
12631         break;
12632     case OPC_NMSUB_S:
12633         check_cop1x(ctx);
12634         {
12635             TCGv_i32 fp0 = tcg_temp_new_i32();
12636             TCGv_i32 fp1 = tcg_temp_new_i32();
12637             TCGv_i32 fp2 = tcg_temp_new_i32();
12638
12639             gen_load_fpr32(ctx, fp0, fs);
12640             gen_load_fpr32(ctx, fp1, ft);
12641             gen_load_fpr32(ctx, fp2, fr);
12642             gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
12643             tcg_temp_free_i32(fp0);
12644             tcg_temp_free_i32(fp1);
12645             gen_store_fpr32(ctx, fp2, fd);
12646             tcg_temp_free_i32(fp2);
12647         }
12648         break;
12649     case OPC_NMSUB_D:
12650         check_cop1x(ctx);
12651         check_cp1_registers(ctx, fd | fs | ft | fr);
12652         {
12653             TCGv_i64 fp0 = tcg_temp_new_i64();
12654             TCGv_i64 fp1 = tcg_temp_new_i64();
12655             TCGv_i64 fp2 = tcg_temp_new_i64();
12656
12657             gen_load_fpr64(ctx, fp0, fs);
12658             gen_load_fpr64(ctx, fp1, ft);
12659             gen_load_fpr64(ctx, fp2, fr);
12660             gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
12661             tcg_temp_free_i64(fp0);
12662             tcg_temp_free_i64(fp1);
12663             gen_store_fpr64(ctx, fp2, fd);
12664             tcg_temp_free_i64(fp2);
12665         }
12666         break;
12667     case OPC_NMSUB_PS:
12668         check_ps(ctx);
12669         {
12670             TCGv_i64 fp0 = tcg_temp_new_i64();
12671             TCGv_i64 fp1 = tcg_temp_new_i64();
12672             TCGv_i64 fp2 = tcg_temp_new_i64();
12673
12674             gen_load_fpr64(ctx, fp0, fs);
12675             gen_load_fpr64(ctx, fp1, ft);
12676             gen_load_fpr64(ctx, fp2, fr);
12677             gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
12678             tcg_temp_free_i64(fp0);
12679             tcg_temp_free_i64(fp1);
12680             gen_store_fpr64(ctx, fp2, fd);
12681             tcg_temp_free_i64(fp2);
12682         }
12683         break;
12684     default:
12685         MIPS_INVAL("flt3_arith");
12686         generate_exception_end(ctx, EXCP_RI);
12687         return;
12688     }
12689 }
12690
12691 static void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
12692 {
12693     TCGv t0;
12694
12695 #if !defined(CONFIG_USER_ONLY)
12696     /* The Linux kernel will emulate rdhwr if it's not supported natively.
12697        Therefore only check the ISA in system mode.  */
12698     check_insn(ctx, ISA_MIPS32R2);
12699 #endif
12700     t0 = tcg_temp_new();
12701
12702     switch (rd) {
12703     case 0:
12704         gen_helper_rdhwr_cpunum(t0, cpu_env);
12705         gen_store_gpr(t0, rt);
12706         break;
12707     case 1:
12708         gen_helper_rdhwr_synci_step(t0, cpu_env);
12709         gen_store_gpr(t0, rt);
12710         break;
12711     case 2:
12712         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12713             gen_io_start();
12714         }
12715         gen_helper_rdhwr_cc(t0, cpu_env);
12716         if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12717             gen_io_end();
12718         }
12719         gen_store_gpr(t0, rt);
12720         /* Break the TB to be able to take timer interrupts immediately
12721            after reading count. DISAS_STOP isn't sufficient, we need to ensure
12722            we break completely out of translated code.  */
12723         gen_save_pc(ctx->base.pc_next + 4);
12724         ctx->base.is_jmp = DISAS_EXIT;
12725         break;
12726     case 3:
12727         gen_helper_rdhwr_ccres(t0, cpu_env);
12728         gen_store_gpr(t0, rt);
12729         break;
12730     case 4:
12731         check_insn(ctx, ISA_MIPS32R6);
12732         if (sel != 0) {
12733             /* Performance counter registers are not implemented other than
12734              * control register 0.
12735              */
12736             generate_exception(ctx, EXCP_RI);
12737         }
12738         gen_helper_rdhwr_performance(t0, cpu_env);
12739         gen_store_gpr(t0, rt);
12740         break;
12741     case 5:
12742         check_insn(ctx, ISA_MIPS32R6);
12743         gen_helper_rdhwr_xnp(t0, cpu_env);
12744         gen_store_gpr(t0, rt);
12745         break;
12746     case 29:
12747 #if defined(CONFIG_USER_ONLY)
12748         tcg_gen_ld_tl(t0, cpu_env,
12749                       offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12750         gen_store_gpr(t0, rt);
12751         break;
12752 #else
12753         if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12754             (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12755             tcg_gen_ld_tl(t0, cpu_env,
12756                           offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12757             gen_store_gpr(t0, rt);
12758         } else {
12759             generate_exception_end(ctx, EXCP_RI);
12760         }
12761         break;
12762 #endif
12763     default:            /* Invalid */
12764         MIPS_INVAL("rdhwr");
12765         generate_exception_end(ctx, EXCP_RI);
12766         break;
12767     }
12768     tcg_temp_free(t0);
12769 }
12770
12771 static inline void clear_branch_hflags(DisasContext *ctx)
12772 {
12773     ctx->hflags &= ~MIPS_HFLAG_BMASK;
12774     if (ctx->base.is_jmp == DISAS_NEXT) {
12775         save_cpu_state(ctx, 0);
12776     } else {
12777         /* it is not safe to save ctx->hflags as hflags may be changed
12778            in execution time by the instruction in delay / forbidden slot. */
12779         tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
12780     }
12781 }
12782
12783 static void gen_branch(DisasContext *ctx, int insn_bytes)
12784 {
12785     if (ctx->hflags & MIPS_HFLAG_BMASK) {
12786         int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
12787         /* Branches completion */
12788         clear_branch_hflags(ctx);
12789         ctx->base.is_jmp = DISAS_NORETURN;
12790         /* FIXME: Need to clear can_do_io.  */
12791         switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
12792         case MIPS_HFLAG_FBNSLOT:
12793             gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
12794             break;
12795         case MIPS_HFLAG_B:
12796             /* unconditional branch */
12797             if (proc_hflags & MIPS_HFLAG_BX) {
12798                 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
12799             }
12800             gen_goto_tb(ctx, 0, ctx->btarget);
12801             break;
12802         case MIPS_HFLAG_BL:
12803             /* blikely taken case */
12804             gen_goto_tb(ctx, 0, ctx->btarget);
12805             break;
12806         case MIPS_HFLAG_BC:
12807             /* Conditional branch */
12808             {
12809                 TCGLabel *l1 = gen_new_label();
12810
12811                 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
12812                 gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
12813                 gen_set_label(l1);
12814                 gen_goto_tb(ctx, 0, ctx->btarget);
12815             }
12816             break;
12817         case MIPS_HFLAG_BR:
12818             /* unconditional branch to register */
12819             if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
12820                 TCGv t0 = tcg_temp_new();
12821                 TCGv_i32 t1 = tcg_temp_new_i32();
12822
12823                 tcg_gen_andi_tl(t0, btarget, 0x1);
12824                 tcg_gen_trunc_tl_i32(t1, t0);
12825                 tcg_temp_free(t0);
12826                 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
12827                 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
12828                 tcg_gen_or_i32(hflags, hflags, t1);
12829                 tcg_temp_free_i32(t1);
12830
12831                 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
12832             } else {
12833                 tcg_gen_mov_tl(cpu_PC, btarget);
12834             }
12835             if (ctx->base.singlestep_enabled) {
12836                 save_cpu_state(ctx, 0);
12837                 gen_helper_raise_exception_debug(cpu_env);
12838             }
12839             tcg_gen_lookup_and_goto_ptr();
12840             break;
12841         default:
12842             fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
12843             abort();
12844         }
12845     }
12846 }
12847
12848 /* Compact Branches */
12849 static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
12850                                        int rs, int rt, int32_t offset)
12851 {
12852     int bcond_compute = 0;
12853     TCGv t0 = tcg_temp_new();
12854     TCGv t1 = tcg_temp_new();
12855     int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
12856
12857     if (ctx->hflags & MIPS_HFLAG_BMASK) {
12858 #ifdef MIPS_DEBUG_DISAS
12859         LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12860                   "\n", ctx->base.pc_next);
12861 #endif
12862         generate_exception_end(ctx, EXCP_RI);
12863         goto out;
12864     }
12865
12866     /* Load needed operands and calculate btarget */
12867     switch (opc) {
12868     /* compact branch */
12869     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12870     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12871         gen_load_gpr(t0, rs);
12872         gen_load_gpr(t1, rt);
12873         bcond_compute = 1;
12874         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12875         if (rs <= rt && rs == 0) {
12876             /* OPC_BEQZALC, OPC_BNEZALC */
12877             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12878         }
12879         break;
12880     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12881     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12882         gen_load_gpr(t0, rs);
12883         gen_load_gpr(t1, rt);
12884         bcond_compute = 1;
12885         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12886         break;
12887     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12888     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12889         if (rs == 0 || rs == rt) {
12890             /* OPC_BLEZALC, OPC_BGEZALC */
12891             /* OPC_BGTZALC, OPC_BLTZALC */
12892             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12893         }
12894         gen_load_gpr(t0, rs);
12895         gen_load_gpr(t1, rt);
12896         bcond_compute = 1;
12897         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12898         break;
12899     case OPC_BC:
12900     case OPC_BALC:
12901         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12902         break;
12903     case OPC_BEQZC:
12904     case OPC_BNEZC:
12905         if (rs != 0) {
12906             /* OPC_BEQZC, OPC_BNEZC */
12907             gen_load_gpr(t0, rs);
12908             bcond_compute = 1;
12909             ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12910         } else {
12911             /* OPC_JIC, OPC_JIALC */
12912             TCGv tbase = tcg_temp_new();
12913             TCGv toffset = tcg_temp_new();
12914
12915             gen_load_gpr(tbase, rt);
12916             tcg_gen_movi_tl(toffset, offset);
12917             gen_op_addr_add(ctx, btarget, tbase, toffset);
12918             tcg_temp_free(tbase);
12919             tcg_temp_free(toffset);
12920         }
12921         break;
12922     default:
12923         MIPS_INVAL("Compact branch/jump");
12924         generate_exception_end(ctx, EXCP_RI);
12925         goto out;
12926     }
12927
12928     if (bcond_compute == 0) {
12929         /* Uncoditional compact branch */
12930         switch (opc) {
12931         case OPC_JIALC:
12932             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12933             /* Fallthrough */
12934         case OPC_JIC:
12935             ctx->hflags |= MIPS_HFLAG_BR;
12936             break;
12937         case OPC_BALC:
12938             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12939             /* Fallthrough */
12940         case OPC_BC:
12941             ctx->hflags |= MIPS_HFLAG_B;
12942             break;
12943         default:
12944             MIPS_INVAL("Compact branch/jump");
12945             generate_exception_end(ctx, EXCP_RI);
12946             goto out;
12947         }
12948
12949         /* Generating branch here as compact branches don't have delay slot */
12950         gen_branch(ctx, 4);
12951     } else {
12952         /* Conditional compact branch */
12953         TCGLabel *fs = gen_new_label();
12954         save_cpu_state(ctx, 0);
12955
12956         switch (opc) {
12957         case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12958             if (rs == 0 && rt != 0) {
12959                 /* OPC_BLEZALC */
12960                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12961             } else if (rs != 0 && rt != 0 && rs == rt) {
12962                 /* OPC_BGEZALC */
12963                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12964             } else {
12965                 /* OPC_BGEUC */
12966                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12967             }
12968             break;
12969         case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12970             if (rs == 0 && rt != 0) {
12971                 /* OPC_BGTZALC */
12972                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12973             } else if (rs != 0 && rt != 0 && rs == rt) {
12974                 /* OPC_BLTZALC */
12975                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12976             } else {
12977                 /* OPC_BLTUC */
12978                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12979             }
12980             break;
12981         case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12982             if (rs == 0 && rt != 0) {
12983                 /* OPC_BLEZC */
12984                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12985             } else if (rs != 0 && rt != 0 && rs == rt) {
12986                 /* OPC_BGEZC */
12987                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12988             } else {
12989                 /* OPC_BGEC */
12990                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12991             }
12992             break;
12993         case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12994             if (rs == 0 && rt != 0) {
12995                 /* OPC_BGTZC */
12996                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12997             } else if (rs != 0 && rt != 0 && rs == rt) {
12998                 /* OPC_BLTZC */
12999                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
13000             } else {
13001                 /* OPC_BLTC */
13002                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
13003             }
13004             break;
13005         case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
13006         case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
13007             if (rs >= rt) {
13008                 /* OPC_BOVC, OPC_BNVC */
13009                 TCGv t2 = tcg_temp_new();
13010                 TCGv t3 = tcg_temp_new();
13011                 TCGv t4 = tcg_temp_new();
13012                 TCGv input_overflow = tcg_temp_new();
13013
13014                 gen_load_gpr(t0, rs);
13015                 gen_load_gpr(t1, rt);
13016                 tcg_gen_ext32s_tl(t2, t0);
13017                 tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
13018                 tcg_gen_ext32s_tl(t3, t1);
13019                 tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
13020                 tcg_gen_or_tl(input_overflow, input_overflow, t4);
13021
13022                 tcg_gen_add_tl(t4, t2, t3);
13023                 tcg_gen_ext32s_tl(t4, t4);
13024                 tcg_gen_xor_tl(t2, t2, t3);
13025                 tcg_gen_xor_tl(t3, t4, t3);
13026                 tcg_gen_andc_tl(t2, t3, t2);
13027                 tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
13028                 tcg_gen_or_tl(t4, t4, input_overflow);
13029                 if (opc == OPC_BOVC) {
13030                     /* OPC_BOVC */
13031                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
13032                 } else {
13033                     /* OPC_BNVC */
13034                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
13035                 }
13036                 tcg_temp_free(input_overflow);
13037                 tcg_temp_free(t4);
13038                 tcg_temp_free(t3);
13039                 tcg_temp_free(t2);
13040             } else if (rs < rt && rs == 0) {
13041                 /* OPC_BEQZALC, OPC_BNEZALC */
13042                 if (opc == OPC_BEQZALC) {
13043                     /* OPC_BEQZALC */
13044                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
13045                 } else {
13046                     /* OPC_BNEZALC */
13047                     tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
13048                 }
13049             } else {
13050                 /* OPC_BEQC, OPC_BNEC */
13051                 if (opc == OPC_BEQC) {
13052                     /* OPC_BEQC */
13053                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
13054                 } else {
13055                     /* OPC_BNEC */
13056                     tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
13057                 }
13058             }
13059             break;
13060         case OPC_BEQZC:
13061             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
13062             break;
13063         case OPC_BNEZC:
13064             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
13065             break;
13066         default:
13067             MIPS_INVAL("Compact conditional branch/jump");
13068             generate_exception_end(ctx, EXCP_RI);
13069             goto out;
13070         }
13071
13072         /* Generating branch here as compact branches don't have delay slot */
13073         gen_goto_tb(ctx, 1, ctx->btarget);
13074         gen_set_label(fs);
13075
13076         ctx->hflags |= MIPS_HFLAG_FBNSLOT;
13077     }
13078
13079 out:
13080     tcg_temp_free(t0);
13081     tcg_temp_free(t1);
13082 }
13083
13084 /* ISA extensions (ASEs) */
13085 /* MIPS16 extension to MIPS32 */
13086
13087 /* MIPS16 major opcodes */
13088 enum {
13089   M16_OPC_ADDIUSP = 0x00,
13090   M16_OPC_ADDIUPC = 0x01,
13091   M16_OPC_B = 0x02,
13092   M16_OPC_JAL = 0x03,
13093   M16_OPC_BEQZ = 0x04,
13094   M16_OPC_BNEQZ = 0x05,
13095   M16_OPC_SHIFT = 0x06,
13096   M16_OPC_LD = 0x07,
13097   M16_OPC_RRIA = 0x08,
13098   M16_OPC_ADDIU8 = 0x09,
13099   M16_OPC_SLTI = 0x0a,
13100   M16_OPC_SLTIU = 0x0b,
13101   M16_OPC_I8 = 0x0c,
13102   M16_OPC_LI = 0x0d,
13103   M16_OPC_CMPI = 0x0e,
13104   M16_OPC_SD = 0x0f,
13105   M16_OPC_LB = 0x10,
13106   M16_OPC_LH = 0x11,
13107   M16_OPC_LWSP = 0x12,
13108   M16_OPC_LW = 0x13,
13109   M16_OPC_LBU = 0x14,
13110   M16_OPC_LHU = 0x15,
13111   M16_OPC_LWPC = 0x16,
13112   M16_OPC_LWU = 0x17,
13113   M16_OPC_SB = 0x18,
13114   M16_OPC_SH = 0x19,
13115   M16_OPC_SWSP = 0x1a,
13116   M16_OPC_SW = 0x1b,
13117   M16_OPC_RRR = 0x1c,
13118   M16_OPC_RR = 0x1d,
13119   M16_OPC_EXTEND = 0x1e,
13120   M16_OPC_I64 = 0x1f
13121 };
13122
13123 /* I8 funct field */
13124 enum {
13125   I8_BTEQZ = 0x0,
13126   I8_BTNEZ = 0x1,
13127   I8_SWRASP = 0x2,
13128   I8_ADJSP = 0x3,
13129   I8_SVRS = 0x4,
13130   I8_MOV32R = 0x5,
13131   I8_MOVR32 = 0x7
13132 };
13133
13134 /* RRR f field */
13135 enum {
13136   RRR_DADDU = 0x0,
13137   RRR_ADDU = 0x1,
13138   RRR_DSUBU = 0x2,
13139   RRR_SUBU = 0x3
13140 };
13141
13142 /* RR funct field */
13143 enum {
13144   RR_JR = 0x00,
13145   RR_SDBBP = 0x01,
13146   RR_SLT = 0x02,
13147   RR_SLTU = 0x03,
13148   RR_SLLV = 0x04,
13149   RR_BREAK = 0x05,
13150   RR_SRLV = 0x06,
13151   RR_SRAV = 0x07,
13152   RR_DSRL = 0x08,
13153   RR_CMP = 0x0a,
13154   RR_NEG = 0x0b,
13155   RR_AND = 0x0c,
13156   RR_OR = 0x0d,
13157   RR_XOR = 0x0e,
13158   RR_NOT = 0x0f,
13159   RR_MFHI = 0x10,
13160   RR_CNVT = 0x11,
13161   RR_MFLO = 0x12,
13162   RR_DSRA = 0x13,
13163   RR_DSLLV = 0x14,
13164   RR_DSRLV = 0x16,
13165   RR_DSRAV = 0x17,
13166   RR_MULT = 0x18,
13167   RR_MULTU = 0x19,
13168   RR_DIV = 0x1a,
13169   RR_DIVU = 0x1b,
13170   RR_DMULT = 0x1c,
13171   RR_DMULTU = 0x1d,
13172   RR_DDIV = 0x1e,
13173   RR_DDIVU = 0x1f
13174 };
13175
13176 /* I64 funct field */
13177 enum {
13178   I64_LDSP = 0x0,
13179   I64_SDSP = 0x1,
13180   I64_SDRASP = 0x2,
13181   I64_DADJSP = 0x3,
13182   I64_LDPC = 0x4,
13183   I64_DADDIU5 = 0x5,
13184   I64_DADDIUPC = 0x6,
13185   I64_DADDIUSP = 0x7
13186 };
13187
13188 /* RR ry field for CNVT */
13189 enum {
13190   RR_RY_CNVT_ZEB = 0x0,
13191   RR_RY_CNVT_ZEH = 0x1,
13192   RR_RY_CNVT_ZEW = 0x2,
13193   RR_RY_CNVT_SEB = 0x4,
13194   RR_RY_CNVT_SEH = 0x5,
13195   RR_RY_CNVT_SEW = 0x6,
13196 };
13197
13198 static int xlat (int r)
13199 {
13200   static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
13201
13202   return map[r];
13203 }
13204
13205 static void gen_mips16_save (DisasContext *ctx,
13206                              int xsregs, int aregs,
13207                              int do_ra, int do_s0, int do_s1,
13208                              int framesize)
13209 {
13210     TCGv t0 = tcg_temp_new();
13211     TCGv t1 = tcg_temp_new();
13212     TCGv t2 = tcg_temp_new();
13213     int args, astatic;
13214
13215     switch (aregs) {
13216     case 0:
13217     case 1:
13218     case 2:
13219     case 3:
13220     case 11:
13221         args = 0;
13222         break;
13223     case 4:
13224     case 5:
13225     case 6:
13226     case 7:
13227         args = 1;
13228         break;
13229     case 8:
13230     case 9:
13231     case 10:
13232         args = 2;
13233         break;
13234     case 12:
13235     case 13:
13236         args = 3;
13237         break;
13238     case 14:
13239         args = 4;
13240         break;
13241     default:
13242         generate_exception_end(ctx, EXCP_RI);
13243         return;
13244     }
13245
13246     switch (args) {
13247     case 4:
13248         gen_base_offset_addr(ctx, t0, 29, 12);
13249         gen_load_gpr(t1, 7);
13250         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13251         /* Fall through */
13252     case 3:
13253         gen_base_offset_addr(ctx, t0, 29, 8);
13254         gen_load_gpr(t1, 6);
13255         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13256         /* Fall through */
13257     case 2:
13258         gen_base_offset_addr(ctx, t0, 29, 4);
13259         gen_load_gpr(t1, 5);
13260         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13261         /* Fall through */
13262     case 1:
13263         gen_base_offset_addr(ctx, t0, 29, 0);
13264         gen_load_gpr(t1, 4);
13265         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
13266     }
13267
13268     gen_load_gpr(t0, 29);
13269
13270 #define DECR_AND_STORE(reg) do {                                 \
13271         tcg_gen_movi_tl(t2, -4);                                 \
13272         gen_op_addr_add(ctx, t0, t0, t2);                        \
13273         gen_load_gpr(t1, reg);                                   \
13274         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
13275     } while (0)
13276
13277     if (do_ra) {
13278         DECR_AND_STORE(31);
13279     }
13280
13281     switch (xsregs) {
13282     case 7:
13283         DECR_AND_STORE(30);
13284         /* Fall through */
13285     case 6:
13286         DECR_AND_STORE(23);
13287         /* Fall through */
13288     case 5:
13289         DECR_AND_STORE(22);
13290         /* Fall through */
13291     case 4:
13292         DECR_AND_STORE(21);
13293         /* Fall through */
13294     case 3:
13295         DECR_AND_STORE(20);
13296         /* Fall through */
13297     case 2:
13298         DECR_AND_STORE(19);
13299         /* Fall through */
13300     case 1:
13301         DECR_AND_STORE(18);
13302     }
13303
13304     if (do_s1) {
13305         DECR_AND_STORE(17);
13306     }
13307     if (do_s0) {
13308         DECR_AND_STORE(16);
13309     }
13310
13311     switch (aregs) {
13312     case 0:
13313     case 4:
13314     case 8:
13315     case 12:
13316     case 14:
13317         astatic = 0;
13318         break;
13319     case 1:
13320     case 5:
13321     case 9:
13322     case 13:
13323         astatic = 1;
13324         break;
13325     case 2:
13326     case 6:
13327     case 10:
13328         astatic = 2;
13329         break;
13330     case 3:
13331     case 7:
13332         astatic = 3;
13333         break;
13334     case 11:
13335         astatic = 4;
13336         break;
13337     default:
13338         generate_exception_end(ctx, EXCP_RI);
13339         return;
13340     }
13341
13342     if (astatic > 0) {
13343         DECR_AND_STORE(7);
13344         if (astatic > 1) {
13345             DECR_AND_STORE(6);
13346             if (astatic > 2) {
13347                 DECR_AND_STORE(5);
13348                 if (astatic > 3) {
13349                     DECR_AND_STORE(4);
13350                 }
13351             }
13352         }
13353     }
13354 #undef DECR_AND_STORE
13355
13356     tcg_gen_movi_tl(t2, -framesize);
13357     gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13358     tcg_temp_free(t0);
13359     tcg_temp_free(t1);
13360     tcg_temp_free(t2);
13361 }
13362
13363 static void gen_mips16_restore (DisasContext *ctx,
13364                                 int xsregs, int aregs,
13365                                 int do_ra, int do_s0, int do_s1,
13366                                 int framesize)
13367 {
13368     int astatic;
13369     TCGv t0 = tcg_temp_new();
13370     TCGv t1 = tcg_temp_new();
13371     TCGv t2 = tcg_temp_new();
13372
13373     tcg_gen_movi_tl(t2, framesize);
13374     gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
13375
13376 #define DECR_AND_LOAD(reg) do {                            \
13377         tcg_gen_movi_tl(t2, -4);                           \
13378         gen_op_addr_add(ctx, t0, t0, t2);                  \
13379         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
13380         gen_store_gpr(t1, reg);                            \
13381     } while (0)
13382
13383     if (do_ra) {
13384         DECR_AND_LOAD(31);
13385     }
13386
13387     switch (xsregs) {
13388     case 7:
13389         DECR_AND_LOAD(30);
13390         /* Fall through */
13391     case 6:
13392         DECR_AND_LOAD(23);
13393         /* Fall through */
13394     case 5:
13395         DECR_AND_LOAD(22);
13396         /* Fall through */
13397     case 4:
13398         DECR_AND_LOAD(21);
13399         /* Fall through */
13400     case 3:
13401         DECR_AND_LOAD(20);
13402         /* Fall through */
13403     case 2:
13404         DECR_AND_LOAD(19);
13405         /* Fall through */
13406     case 1:
13407         DECR_AND_LOAD(18);
13408     }
13409
13410     if (do_s1) {
13411         DECR_AND_LOAD(17);
13412     }
13413     if (do_s0) {
13414         DECR_AND_LOAD(16);
13415     }
13416
13417     switch (aregs) {
13418     case 0:
13419     case 4:
13420     case 8:
13421     case 12:
13422     case 14:
13423         astatic = 0;
13424         break;
13425     case 1:
13426     case 5:
13427     case 9:
13428     case 13:
13429         astatic = 1;
13430         break;
13431     case 2:
13432     case 6:
13433     case 10:
13434         astatic = 2;
13435         break;
13436     case 3:
13437     case 7:
13438         astatic = 3;
13439         break;
13440     case 11:
13441         astatic = 4;
13442         break;
13443     default:
13444         generate_exception_end(ctx, EXCP_RI);
13445         return;
13446     }
13447
13448     if (astatic > 0) {
13449         DECR_AND_LOAD(7);
13450         if (astatic > 1) {
13451             DECR_AND_LOAD(6);
13452             if (astatic > 2) {
13453                 DECR_AND_LOAD(5);
13454                 if (astatic > 3) {
13455                     DECR_AND_LOAD(4);
13456                 }
13457             }
13458         }
13459     }
13460 #undef DECR_AND_LOAD
13461
13462     tcg_gen_movi_tl(t2, framesize);
13463     gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
13464     tcg_temp_free(t0);
13465     tcg_temp_free(t1);
13466     tcg_temp_free(t2);
13467 }
13468
13469 static void gen_addiupc (DisasContext *ctx, int rx, int imm,
13470                          int is_64_bit, int extended)
13471 {
13472     TCGv t0;
13473
13474     if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13475         generate_exception_end(ctx, EXCP_RI);
13476         return;
13477     }
13478
13479     t0 = tcg_temp_new();
13480
13481     tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
13482     tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
13483     if (!is_64_bit) {
13484         tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13485     }
13486
13487     tcg_temp_free(t0);
13488 }
13489
13490 static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
13491                                 int16_t offset)
13492 {
13493     TCGv_i32 t0 = tcg_const_i32(op);
13494     TCGv t1 = tcg_temp_new();
13495     gen_base_offset_addr(ctx, t1, base, offset);
13496     gen_helper_cache(cpu_env, t1, t0);
13497 }
13498
13499 #if defined(TARGET_MIPS64)
13500 static void decode_i64_mips16 (DisasContext *ctx,
13501                                int ry, int funct, int16_t offset,
13502                                int extended)
13503 {
13504     switch (funct) {
13505     case I64_LDSP:
13506         check_insn(ctx, ISA_MIPS3);
13507         check_mips_64(ctx);
13508         offset = extended ? offset : offset << 3;
13509         gen_ld(ctx, OPC_LD, ry, 29, offset);
13510         break;
13511     case I64_SDSP:
13512         check_insn(ctx, ISA_MIPS3);
13513         check_mips_64(ctx);
13514         offset = extended ? offset : offset << 3;
13515         gen_st(ctx, OPC_SD, ry, 29, offset);
13516         break;
13517     case I64_SDRASP:
13518         check_insn(ctx, ISA_MIPS3);
13519         check_mips_64(ctx);
13520         offset = extended ? offset : (ctx->opcode & 0xff) << 3;
13521         gen_st(ctx, OPC_SD, 31, 29, offset);
13522         break;
13523     case I64_DADJSP:
13524         check_insn(ctx, ISA_MIPS3);
13525         check_mips_64(ctx);
13526         offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
13527         gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
13528         break;
13529     case I64_LDPC:
13530         check_insn(ctx, ISA_MIPS3);
13531         check_mips_64(ctx);
13532         if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
13533             generate_exception_end(ctx, EXCP_RI);
13534         } else {
13535             offset = extended ? offset : offset << 3;
13536             gen_ld(ctx, OPC_LDPC, ry, 0, offset);
13537         }
13538         break;
13539     case I64_DADDIU5:
13540         check_insn(ctx, ISA_MIPS3);
13541         check_mips_64(ctx);
13542         offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
13543         gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
13544         break;
13545     case I64_DADDIUPC:
13546         check_insn(ctx, ISA_MIPS3);
13547         check_mips_64(ctx);
13548         offset = extended ? offset : offset << 2;
13549         gen_addiupc(ctx, ry, offset, 1, extended);
13550         break;
13551     case I64_DADDIUSP:
13552         check_insn(ctx, ISA_MIPS3);
13553         check_mips_64(ctx);
13554         offset = extended ? offset : offset << 2;
13555         gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
13556         break;
13557     }
13558 }
13559 #endif
13560
13561 static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13562 {
13563     int extend = cpu_lduw_code(env, ctx->base.pc_next + 2);
13564     int op, rx, ry, funct, sa;
13565     int16_t imm, offset;
13566
13567     ctx->opcode = (ctx->opcode << 16) | extend;
13568     op = (ctx->opcode >> 11) & 0x1f;
13569     sa = (ctx->opcode >> 22) & 0x1f;
13570     funct = (ctx->opcode >> 8) & 0x7;
13571     rx = xlat((ctx->opcode >> 8) & 0x7);
13572     ry = xlat((ctx->opcode >> 5) & 0x7);
13573     offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
13574                               | ((ctx->opcode >> 21) & 0x3f) << 5
13575                               | (ctx->opcode & 0x1f));
13576
13577     /* The extended opcodes cleverly reuse the opcodes from their 16-bit
13578        counterparts.  */
13579     switch (op) {
13580     case M16_OPC_ADDIUSP:
13581         gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13582         break;
13583     case M16_OPC_ADDIUPC:
13584         gen_addiupc(ctx, rx, imm, 0, 1);
13585         break;
13586     case M16_OPC_B:
13587         gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
13588         /* No delay slot, so just process as a normal instruction */
13589         break;
13590     case M16_OPC_BEQZ:
13591         gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
13592         /* No delay slot, so just process as a normal instruction */
13593         break;
13594     case M16_OPC_BNEQZ:
13595         gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
13596         /* No delay slot, so just process as a normal instruction */
13597         break;
13598     case M16_OPC_SHIFT:
13599         switch (ctx->opcode & 0x3) {
13600         case 0x0:
13601             gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13602             break;
13603         case 0x1:
13604 #if defined(TARGET_MIPS64)
13605             check_mips_64(ctx);
13606             gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13607 #else
13608             generate_exception_end(ctx, EXCP_RI);
13609 #endif
13610             break;
13611         case 0x2:
13612             gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13613             break;
13614         case 0x3:
13615             gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13616             break;
13617         }
13618         break;
13619 #if defined(TARGET_MIPS64)
13620     case M16_OPC_LD:
13621         check_insn(ctx, ISA_MIPS3);
13622         check_mips_64(ctx);
13623         gen_ld(ctx, OPC_LD, ry, rx, offset);
13624         break;
13625 #endif
13626     case M16_OPC_RRIA:
13627         imm = ctx->opcode & 0xf;
13628         imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
13629         imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
13630         imm = (int16_t) (imm << 1) >> 1;
13631         if ((ctx->opcode >> 4) & 0x1) {
13632 #if defined(TARGET_MIPS64)
13633             check_mips_64(ctx);
13634             gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13635 #else
13636             generate_exception_end(ctx, EXCP_RI);
13637 #endif
13638         } else {
13639             gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13640         }
13641         break;
13642     case M16_OPC_ADDIU8:
13643         gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13644         break;
13645     case M16_OPC_SLTI:
13646         gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13647         break;
13648     case M16_OPC_SLTIU:
13649         gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13650         break;
13651     case M16_OPC_I8:
13652         switch (funct) {
13653         case I8_BTEQZ:
13654             gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
13655             break;
13656         case I8_BTNEZ:
13657             gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
13658             break;
13659         case I8_SWRASP:
13660             gen_st(ctx, OPC_SW, 31, 29, imm);
13661             break;
13662         case I8_ADJSP:
13663             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
13664             break;
13665         case I8_SVRS:
13666             check_insn(ctx, ISA_MIPS32);
13667             {
13668                 int xsregs = (ctx->opcode >> 24) & 0x7;
13669                 int aregs = (ctx->opcode >> 16) & 0xf;
13670                 int do_ra = (ctx->opcode >> 6) & 0x1;
13671                 int do_s0 = (ctx->opcode >> 5) & 0x1;
13672                 int do_s1 = (ctx->opcode >> 4) & 0x1;
13673                 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
13674                                  | (ctx->opcode & 0xf)) << 3;
13675
13676                 if (ctx->opcode & (1 << 7)) {
13677                     gen_mips16_save(ctx, xsregs, aregs,
13678                                     do_ra, do_s0, do_s1,
13679                                     framesize);
13680                 } else {
13681                     gen_mips16_restore(ctx, xsregs, aregs,
13682                                        do_ra, do_s0, do_s1,
13683                                        framesize);
13684                 }
13685             }
13686             break;
13687         default:
13688             generate_exception_end(ctx, EXCP_RI);
13689             break;
13690         }
13691         break;
13692     case M16_OPC_LI:
13693         tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13694         break;
13695     case M16_OPC_CMPI:
13696         tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13697         break;
13698 #if defined(TARGET_MIPS64)
13699     case M16_OPC_SD:
13700         check_insn(ctx, ISA_MIPS3);
13701         check_mips_64(ctx);
13702         gen_st(ctx, OPC_SD, ry, rx, offset);
13703         break;
13704 #endif
13705     case M16_OPC_LB:
13706         gen_ld(ctx, OPC_LB, ry, rx, offset);
13707         break;
13708     case M16_OPC_LH:
13709         gen_ld(ctx, OPC_LH, ry, rx, offset);
13710         break;
13711     case M16_OPC_LWSP:
13712         gen_ld(ctx, OPC_LW, rx, 29, offset);
13713         break;
13714     case M16_OPC_LW:
13715         gen_ld(ctx, OPC_LW, ry, rx, offset);
13716         break;
13717     case M16_OPC_LBU:
13718         gen_ld(ctx, OPC_LBU, ry, rx, offset);
13719         break;
13720     case M16_OPC_LHU:
13721         gen_ld(ctx, OPC_LHU, ry, rx, offset);
13722         break;
13723     case M16_OPC_LWPC:
13724         gen_ld(ctx, OPC_LWPC, rx, 0, offset);
13725         break;
13726 #if defined(TARGET_MIPS64)
13727     case M16_OPC_LWU:
13728         check_insn(ctx, ISA_MIPS3);
13729         check_mips_64(ctx);
13730         gen_ld(ctx, OPC_LWU, ry, rx, offset);
13731         break;
13732 #endif
13733     case M16_OPC_SB:
13734         gen_st(ctx, OPC_SB, ry, rx, offset);
13735         break;
13736     case M16_OPC_SH:
13737         gen_st(ctx, OPC_SH, ry, rx, offset);
13738         break;
13739     case M16_OPC_SWSP:
13740         gen_st(ctx, OPC_SW, rx, 29, offset);
13741         break;
13742     case M16_OPC_SW:
13743         gen_st(ctx, OPC_SW, ry, rx, offset);
13744         break;
13745 #if defined(TARGET_MIPS64)
13746     case M16_OPC_I64:
13747         decode_i64_mips16(ctx, ry, funct, offset, 1);
13748         break;
13749 #endif
13750     default:
13751         generate_exception_end(ctx, EXCP_RI);
13752         break;
13753     }
13754
13755     return 4;
13756 }
13757
13758 static inline bool is_uhi(int sdbbp_code)
13759 {
13760 #ifdef CONFIG_USER_ONLY
13761     return false;
13762 #else
13763     return semihosting_enabled() && sdbbp_code == 1;
13764 #endif
13765 }
13766
13767 static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
13768 {
13769     int rx, ry;
13770     int sa;
13771     int op, cnvt_op, op1, offset;
13772     int funct;
13773     int n_bytes;
13774
13775     op = (ctx->opcode >> 11) & 0x1f;
13776     sa = (ctx->opcode >> 2) & 0x7;
13777     sa = sa == 0 ? 8 : sa;
13778     rx = xlat((ctx->opcode >> 8) & 0x7);
13779     cnvt_op = (ctx->opcode >> 5) & 0x7;
13780     ry = xlat((ctx->opcode >> 5) & 0x7);
13781     op1 = offset = ctx->opcode & 0x1f;
13782
13783     n_bytes = 2;
13784
13785     switch (op) {
13786     case M16_OPC_ADDIUSP:
13787         {
13788             int16_t imm = ((uint8_t) ctx->opcode) << 2;
13789
13790             gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13791         }
13792         break;
13793     case M16_OPC_ADDIUPC:
13794         gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
13795         break;
13796     case M16_OPC_B:
13797         offset = (ctx->opcode & 0x7ff) << 1;
13798         offset = (int16_t)(offset << 4) >> 4;
13799         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
13800         /* No delay slot, so just process as a normal instruction */
13801         break;
13802     case M16_OPC_JAL:
13803         offset = cpu_lduw_code(env, ctx->base.pc_next + 2);
13804         offset = (((ctx->opcode & 0x1f) << 21)
13805                   | ((ctx->opcode >> 5) & 0x1f) << 16
13806                   | offset) << 2;
13807         op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
13808         gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
13809         n_bytes = 4;
13810         break;
13811     case M16_OPC_BEQZ:
13812         gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
13813                            ((int8_t)ctx->opcode) << 1, 0);
13814         /* No delay slot, so just process as a normal instruction */
13815         break;
13816     case M16_OPC_BNEQZ:
13817         gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
13818                            ((int8_t)ctx->opcode) << 1, 0);
13819         /* No delay slot, so just process as a normal instruction */
13820         break;
13821     case M16_OPC_SHIFT:
13822         switch (ctx->opcode & 0x3) {
13823         case 0x0:
13824             gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13825             break;
13826         case 0x1:
13827 #if defined(TARGET_MIPS64)
13828             check_insn(ctx, ISA_MIPS3);
13829             check_mips_64(ctx);
13830             gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13831 #else
13832             generate_exception_end(ctx, EXCP_RI);
13833 #endif
13834             break;
13835         case 0x2:
13836             gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13837             break;
13838         case 0x3:
13839             gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13840             break;
13841         }
13842         break;
13843 #if defined(TARGET_MIPS64)
13844     case M16_OPC_LD:
13845         check_insn(ctx, ISA_MIPS3);
13846         check_mips_64(ctx);
13847         gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
13848         break;
13849 #endif
13850     case M16_OPC_RRIA:
13851         {
13852             int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
13853
13854             if ((ctx->opcode >> 4) & 1) {
13855 #if defined(TARGET_MIPS64)
13856                 check_insn(ctx, ISA_MIPS3);
13857                 check_mips_64(ctx);
13858                 gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13859 #else
13860                 generate_exception_end(ctx, EXCP_RI);
13861 #endif
13862             } else {
13863                 gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13864             }
13865         }
13866         break;
13867     case M16_OPC_ADDIU8:
13868         {
13869             int16_t imm = (int8_t) ctx->opcode;
13870
13871             gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13872         }
13873         break;
13874     case M16_OPC_SLTI:
13875         {
13876             int16_t imm = (uint8_t) ctx->opcode;
13877             gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13878         }
13879         break;
13880     case M16_OPC_SLTIU:
13881         {
13882             int16_t imm = (uint8_t) ctx->opcode;
13883             gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13884         }
13885         break;
13886     case M16_OPC_I8:
13887         {
13888             int reg32;
13889
13890             funct = (ctx->opcode >> 8) & 0x7;
13891             switch (funct) {
13892             case I8_BTEQZ:
13893                 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
13894                                    ((int8_t)ctx->opcode) << 1, 0);
13895                 break;
13896             case I8_BTNEZ:
13897                 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
13898                                    ((int8_t)ctx->opcode) << 1, 0);
13899                 break;
13900             case I8_SWRASP:
13901                 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
13902                 break;
13903             case I8_ADJSP:
13904                 gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
13905                               ((int8_t)ctx->opcode) << 3);
13906                 break;
13907             case I8_SVRS:
13908                 check_insn(ctx, ISA_MIPS32);
13909                 {
13910                     int do_ra = ctx->opcode & (1 << 6);
13911                     int do_s0 = ctx->opcode & (1 << 5);
13912                     int do_s1 = ctx->opcode & (1 << 4);
13913                     int framesize = ctx->opcode & 0xf;
13914
13915                     if (framesize == 0) {
13916                         framesize = 128;
13917                     } else {
13918                         framesize = framesize << 3;
13919                     }
13920
13921                     if (ctx->opcode & (1 << 7)) {
13922                         gen_mips16_save(ctx, 0, 0,
13923                                         do_ra, do_s0, do_s1, framesize);
13924                     } else {
13925                         gen_mips16_restore(ctx, 0, 0,
13926                                            do_ra, do_s0, do_s1, framesize);
13927                     }
13928                 }
13929                 break;
13930             case I8_MOV32R:
13931                 {
13932                     int rz = xlat(ctx->opcode & 0x7);
13933
13934                     reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
13935                         ((ctx->opcode >> 5) & 0x7);
13936                     gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
13937                 }
13938                 break;
13939             case I8_MOVR32:
13940                 reg32 = ctx->opcode & 0x1f;
13941                 gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
13942                 break;
13943             default:
13944                 generate_exception_end(ctx, EXCP_RI);
13945                 break;
13946             }
13947         }
13948         break;
13949     case M16_OPC_LI:
13950         {
13951             int16_t imm = (uint8_t) ctx->opcode;
13952
13953             gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
13954         }
13955         break;
13956     case M16_OPC_CMPI:
13957         {
13958             int16_t imm = (uint8_t) ctx->opcode;
13959             gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
13960         }
13961         break;
13962 #if defined(TARGET_MIPS64)
13963     case M16_OPC_SD:
13964         check_insn(ctx, ISA_MIPS3);
13965         check_mips_64(ctx);
13966         gen_st(ctx, OPC_SD, ry, rx, offset << 3);
13967         break;
13968 #endif
13969     case M16_OPC_LB:
13970         gen_ld(ctx, OPC_LB, ry, rx, offset);
13971         break;
13972     case M16_OPC_LH:
13973         gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
13974         break;
13975     case M16_OPC_LWSP:
13976         gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13977         break;
13978     case M16_OPC_LW:
13979         gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
13980         break;
13981     case M16_OPC_LBU:
13982         gen_ld(ctx, OPC_LBU, ry, rx, offset);
13983         break;
13984     case M16_OPC_LHU:
13985         gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
13986         break;
13987     case M16_OPC_LWPC:
13988         gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
13989         break;
13990 #if defined (TARGET_MIPS64)
13991     case M16_OPC_LWU:
13992         check_insn(ctx, ISA_MIPS3);
13993         check_mips_64(ctx);
13994         gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
13995         break;
13996 #endif
13997     case M16_OPC_SB:
13998         gen_st(ctx, OPC_SB, ry, rx, offset);
13999         break;
14000     case M16_OPC_SH:
14001         gen_st(ctx, OPC_SH, ry, rx, offset << 1);
14002         break;
14003     case M16_OPC_SWSP:
14004         gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
14005         break;
14006     case M16_OPC_SW:
14007         gen_st(ctx, OPC_SW, ry, rx, offset << 2);
14008         break;
14009     case M16_OPC_RRR:
14010         {
14011             int rz = xlat((ctx->opcode >> 2) & 0x7);
14012             int mips32_op;
14013
14014             switch (ctx->opcode & 0x3) {
14015             case RRR_ADDU:
14016                 mips32_op = OPC_ADDU;
14017                 break;
14018             case RRR_SUBU:
14019                 mips32_op = OPC_SUBU;
14020                 break;
14021 #if defined(TARGET_MIPS64)
14022             case RRR_DADDU:
14023                 mips32_op = OPC_DADDU;
14024                 check_insn(ctx, ISA_MIPS3);
14025                 check_mips_64(ctx);
14026                 break;
14027             case RRR_DSUBU:
14028                 mips32_op = OPC_DSUBU;
14029                 check_insn(ctx, ISA_MIPS3);
14030                 check_mips_64(ctx);
14031                 break;
14032 #endif
14033             default:
14034                 generate_exception_end(ctx, EXCP_RI);
14035                 goto done;
14036             }
14037
14038             gen_arith(ctx, mips32_op, rz, rx, ry);
14039         done:
14040             ;
14041         }
14042         break;
14043     case M16_OPC_RR:
14044         switch (op1) {
14045         case RR_JR:
14046             {
14047                 int nd = (ctx->opcode >> 7) & 0x1;
14048                 int link = (ctx->opcode >> 6) & 0x1;
14049                 int ra = (ctx->opcode >> 5) & 0x1;
14050
14051                 if (nd) {
14052                     check_insn(ctx, ISA_MIPS32);
14053                 }
14054
14055                 if (link) {
14056                     op = OPC_JALR;
14057                 } else {
14058                     op = OPC_JR;
14059                 }
14060
14061                 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
14062                                    (nd ? 0 : 2));
14063             }
14064             break;
14065         case RR_SDBBP:
14066             if (is_uhi(extract32(ctx->opcode, 5, 6))) {
14067                 gen_helper_do_semihosting(cpu_env);
14068             } else {
14069                 /* XXX: not clear which exception should be raised
14070                  *      when in debug mode...
14071                  */
14072                 check_insn(ctx, ISA_MIPS32);
14073                 generate_exception_end(ctx, EXCP_DBp);
14074             }
14075             break;
14076         case RR_SLT:
14077             gen_slt(ctx, OPC_SLT, 24, rx, ry);
14078             break;
14079         case RR_SLTU:
14080             gen_slt(ctx, OPC_SLTU, 24, rx, ry);
14081             break;
14082         case RR_BREAK:
14083             generate_exception_end(ctx, EXCP_BREAK);
14084             break;
14085         case RR_SLLV:
14086             gen_shift(ctx, OPC_SLLV, ry, rx, ry);
14087             break;
14088         case RR_SRLV:
14089             gen_shift(ctx, OPC_SRLV, ry, rx, ry);
14090             break;
14091         case RR_SRAV:
14092             gen_shift(ctx, OPC_SRAV, ry, rx, ry);
14093             break;
14094 #if defined (TARGET_MIPS64)
14095         case RR_DSRL:
14096             check_insn(ctx, ISA_MIPS3);
14097             check_mips_64(ctx);
14098             gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
14099             break;
14100 #endif
14101         case RR_CMP:
14102             gen_logic(ctx, OPC_XOR, 24, rx, ry);
14103             break;
14104         case RR_NEG:
14105             gen_arith(ctx, OPC_SUBU, rx, 0, ry);
14106             break;
14107         case RR_AND:
14108             gen_logic(ctx, OPC_AND, rx, rx, ry);
14109             break;
14110         case RR_OR:
14111             gen_logic(ctx, OPC_OR, rx, rx, ry);
14112             break;
14113         case RR_XOR:
14114             gen_logic(ctx, OPC_XOR, rx, rx, ry);
14115             break;
14116         case RR_NOT:
14117             gen_logic(ctx, OPC_NOR, rx, ry, 0);
14118             break;
14119         case RR_MFHI:
14120             gen_HILO(ctx, OPC_MFHI, 0, rx);
14121             break;
14122         case RR_CNVT:
14123             check_insn(ctx, ISA_MIPS32);
14124             switch (cnvt_op) {
14125             case RR_RY_CNVT_ZEB:
14126                 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14127                 break;
14128             case RR_RY_CNVT_ZEH:
14129                 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14130                 break;
14131             case RR_RY_CNVT_SEB:
14132                 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14133                 break;
14134             case RR_RY_CNVT_SEH:
14135                 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14136                 break;
14137 #if defined (TARGET_MIPS64)
14138             case RR_RY_CNVT_ZEW:
14139                 check_insn(ctx, ISA_MIPS64);
14140                 check_mips_64(ctx);
14141                 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
14142                 break;
14143             case RR_RY_CNVT_SEW:
14144                 check_insn(ctx, ISA_MIPS64);
14145                 check_mips_64(ctx);
14146                 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
14147                 break;
14148 #endif
14149             default:
14150                 generate_exception_end(ctx, EXCP_RI);
14151                 break;
14152             }
14153             break;
14154         case RR_MFLO:
14155             gen_HILO(ctx, OPC_MFLO, 0, rx);
14156             break;
14157 #if defined (TARGET_MIPS64)
14158         case RR_DSRA:
14159             check_insn(ctx, ISA_MIPS3);
14160             check_mips_64(ctx);
14161             gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
14162             break;
14163         case RR_DSLLV:
14164             check_insn(ctx, ISA_MIPS3);
14165             check_mips_64(ctx);
14166             gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
14167             break;
14168         case RR_DSRLV:
14169             check_insn(ctx, ISA_MIPS3);
14170             check_mips_64(ctx);
14171             gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
14172             break;
14173         case RR_DSRAV:
14174             check_insn(ctx, ISA_MIPS3);
14175             check_mips_64(ctx);
14176             gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
14177             break;
14178 #endif
14179         case RR_MULT:
14180             gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
14181             break;
14182         case RR_MULTU:
14183             gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
14184             break;
14185         case RR_DIV:
14186             gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
14187             break;
14188         case RR_DIVU:
14189             gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
14190             break;
14191 #if defined (TARGET_MIPS64)
14192         case RR_DMULT:
14193             check_insn(ctx, ISA_MIPS3);
14194             check_mips_64(ctx);
14195             gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
14196             break;
14197         case RR_DMULTU:
14198             check_insn(ctx, ISA_MIPS3);
14199             check_mips_64(ctx);
14200             gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
14201             break;
14202         case RR_DDIV:
14203             check_insn(ctx, ISA_MIPS3);
14204             check_mips_64(ctx);
14205             gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
14206             break;
14207         case RR_DDIVU:
14208             check_insn(ctx, ISA_MIPS3);
14209             check_mips_64(ctx);
14210             gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
14211             break;
14212 #endif
14213         default:
14214             generate_exception_end(ctx, EXCP_RI);
14215             break;
14216         }
14217         break;
14218     case M16_OPC_EXTEND:
14219         decode_extended_mips16_opc(env, ctx);
14220         n_bytes = 4;
14221         break;
14222 #if defined(TARGET_MIPS64)
14223     case M16_OPC_I64:
14224         funct = (ctx->opcode >> 8) & 0x7;
14225         decode_i64_mips16(ctx, ry, funct, offset, 0);
14226         break;
14227 #endif
14228     default:
14229         generate_exception_end(ctx, EXCP_RI);
14230         break;
14231     }
14232
14233     return n_bytes;
14234 }
14235
14236 /* microMIPS extension to MIPS32/MIPS64 */
14237
14238 /*
14239  * microMIPS32/microMIPS64 major opcodes
14240  *
14241  * 1. MIPS Architecture for Programmers Volume II-B:
14242  *      The microMIPS32 Instruction Set (Revision 3.05)
14243  *
14244  *    Table 6.2 microMIPS32 Encoding of Major Opcode Field
14245  *
14246  * 2. MIPS Architecture For Programmers Volume II-A:
14247  *      The MIPS64 Instruction Set (Revision 3.51)
14248  */
14249
14250 enum {
14251     POOL32A = 0x00,
14252     POOL16A = 0x01,
14253     LBU16 = 0x02,
14254     MOVE16 = 0x03,
14255     ADDI32 = 0x04,
14256     R6_LUI = 0x04,
14257     AUI = 0x04,
14258     LBU32 = 0x05,
14259     SB32 = 0x06,
14260     LB32 = 0x07,
14261
14262     POOL32B = 0x08,
14263     POOL16B = 0x09,
14264     LHU16 = 0x0a,
14265     ANDI16 = 0x0b,
14266     ADDIU32 = 0x0c,
14267     LHU32 = 0x0d,
14268     SH32 = 0x0e,
14269     LH32 = 0x0f,
14270
14271     POOL32I = 0x10,
14272     POOL16C = 0x11,
14273     LWSP16 = 0x12,
14274     POOL16D = 0x13,
14275     ORI32 = 0x14,
14276     POOL32F = 0x15,
14277     POOL32S = 0x16,  /* MIPS64 */
14278     DADDIU32 = 0x17, /* MIPS64 */
14279
14280     POOL32C = 0x18,
14281     LWGP16 = 0x19,
14282     LW16 = 0x1a,
14283     POOL16E = 0x1b,
14284     XORI32 = 0x1c,
14285     JALS32 = 0x1d,
14286     BOVC = 0x1d,
14287     BEQC = 0x1d,
14288     BEQZALC = 0x1d,
14289     ADDIUPC = 0x1e,
14290     PCREL = 0x1e,
14291     BNVC = 0x1f,
14292     BNEC = 0x1f,
14293     BNEZALC = 0x1f,
14294
14295     R6_BEQZC = 0x20,
14296     JIC = 0x20,
14297     POOL16F = 0x21,
14298     SB16 = 0x22,
14299     BEQZ16 = 0x23,
14300     BEQZC16 = 0x23,
14301     SLTI32 = 0x24,
14302     BEQ32 = 0x25,
14303     BC = 0x25,
14304     SWC132 = 0x26,
14305     LWC132 = 0x27,
14306
14307     /* 0x29 is reserved */
14308     RES_29 = 0x29,
14309     R6_BNEZC = 0x28,
14310     JIALC = 0x28,
14311     SH16 = 0x2a,
14312     BNEZ16 = 0x2b,
14313     BNEZC16 = 0x2b,
14314     SLTIU32 = 0x2c,
14315     BNE32 = 0x2d,
14316     BALC = 0x2d,
14317     SDC132 = 0x2e,
14318     LDC132 = 0x2f,
14319
14320     /* 0x31 is reserved */
14321     RES_31 = 0x31,
14322     BLEZALC = 0x30,
14323     BGEZALC = 0x30,
14324     BGEUC = 0x30,
14325     SWSP16 = 0x32,
14326     B16 = 0x33,
14327     BC16 = 0x33,
14328     ANDI32 = 0x34,
14329     J32 = 0x35,
14330     BGTZC = 0x35,
14331     BLTZC = 0x35,
14332     BLTC = 0x35,
14333     SD32 = 0x36, /* MIPS64 */
14334     LD32 = 0x37, /* MIPS64 */
14335
14336     /* 0x39 is reserved */
14337     RES_39 = 0x39,
14338     BGTZALC = 0x38,
14339     BLTZALC = 0x38,
14340     BLTUC = 0x38,
14341     SW16 = 0x3a,
14342     LI16 = 0x3b,
14343     JALX32 = 0x3c,
14344     JAL32 = 0x3d,
14345     BLEZC = 0x3d,
14346     BGEZC = 0x3d,
14347     BGEC = 0x3d,
14348     SW32 = 0x3e,
14349     LW32 = 0x3f
14350 };
14351
14352 /* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
14353 enum {
14354     ADDIUPC_00 = 0x00,
14355     ADDIUPC_01 = 0x01,
14356     ADDIUPC_02 = 0x02,
14357     ADDIUPC_03 = 0x03,
14358     ADDIUPC_04 = 0x04,
14359     ADDIUPC_05 = 0x05,
14360     ADDIUPC_06 = 0x06,
14361     ADDIUPC_07 = 0x07,
14362     AUIPC = 0x1e,
14363     ALUIPC = 0x1f,
14364     LWPC_08 = 0x08,
14365     LWPC_09 = 0x09,
14366     LWPC_0A = 0x0A,
14367     LWPC_0B = 0x0B,
14368     LWPC_0C = 0x0C,
14369     LWPC_0D = 0x0D,
14370     LWPC_0E = 0x0E,
14371     LWPC_0F = 0x0F,
14372 };
14373
14374 /* POOL32A encoding of minor opcode field */
14375
14376 enum {
14377     /* These opcodes are distinguished only by bits 9..6; those bits are
14378      * what are recorded below. */
14379     SLL32 = 0x0,
14380     SRL32 = 0x1,
14381     SRA = 0x2,
14382     ROTR = 0x3,
14383     SELEQZ = 0x5,
14384     SELNEZ = 0x6,
14385     R6_RDHWR = 0x7,
14386
14387     SLLV = 0x0,
14388     SRLV = 0x1,
14389     SRAV = 0x2,
14390     ROTRV = 0x3,
14391     ADD = 0x4,
14392     ADDU32 = 0x5,
14393     SUB = 0x6,
14394     SUBU32 = 0x7,
14395     MUL = 0x8,
14396     AND = 0x9,
14397     OR32 = 0xa,
14398     NOR = 0xb,
14399     XOR32 = 0xc,
14400     SLT = 0xd,
14401     SLTU = 0xe,
14402
14403     MOVN = 0x0,
14404     R6_MUL  = 0x0,
14405     MOVZ = 0x1,
14406     MUH  = 0x1,
14407     MULU = 0x2,
14408     MUHU = 0x3,
14409     LWXS = 0x4,
14410     R6_DIV  = 0x4,
14411     MOD  = 0x5,
14412     R6_DIVU = 0x6,
14413     MODU = 0x7,
14414
14415     /* The following can be distinguished by their lower 6 bits. */
14416     BREAK32 = 0x07,
14417     INS = 0x0c,
14418     LSA = 0x0f,
14419     ALIGN = 0x1f,
14420     EXT = 0x2c,
14421     POOL32AXF = 0x3c,
14422     SIGRIE = 0x3f
14423 };
14424
14425 /* POOL32AXF encoding of minor opcode field extension */
14426
14427 /*
14428  * 1. MIPS Architecture for Programmers Volume II-B:
14429  *      The microMIPS32 Instruction Set (Revision 3.05)
14430  *
14431  *    Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
14432  *
14433  * 2. MIPS Architecture for Programmers VolumeIV-e:
14434  *      The MIPS DSP Application-Specific Extension
14435  *        to the microMIPS32 Architecture (Revision 2.34)
14436  *
14437  *    Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
14438  */
14439
14440 enum {
14441     /* bits 11..6 */
14442     TEQ = 0x00,
14443     TGE = 0x08,
14444     TGEU = 0x10,
14445     TLT = 0x20,
14446     TLTU = 0x28,
14447     TNE = 0x30,
14448
14449     MFC0 = 0x03,
14450     MTC0 = 0x0b,
14451
14452     /* begin of microMIPS32 DSP */
14453
14454     /* bits 13..12 for 0x01 */
14455     MFHI_ACC = 0x0,
14456     MFLO_ACC = 0x1,
14457     MTHI_ACC = 0x2,
14458     MTLO_ACC = 0x3,
14459
14460     /* bits 13..12 for 0x2a */
14461     MADD_ACC = 0x0,
14462     MADDU_ACC = 0x1,
14463     MSUB_ACC = 0x2,
14464     MSUBU_ACC = 0x3,
14465
14466     /* bits 13..12 for 0x32 */
14467     MULT_ACC = 0x0,
14468     MULTU_ACC = 0x1,
14469
14470     /* end of microMIPS32 DSP */
14471
14472     /* bits 15..12 for 0x2c */
14473     BITSWAP = 0x0,
14474     SEB = 0x2,
14475     SEH = 0x3,
14476     CLO = 0x4,
14477     CLZ = 0x5,
14478     RDHWR = 0x6,
14479     WSBH = 0x7,
14480     MULT = 0x8,
14481     MULTU = 0x9,
14482     DIV = 0xa,
14483     DIVU = 0xb,
14484     MADD = 0xc,
14485     MADDU = 0xd,
14486     MSUB = 0xe,
14487     MSUBU = 0xf,
14488
14489     /* bits 15..12 for 0x34 */
14490     MFC2 = 0x4,
14491     MTC2 = 0x5,
14492     MFHC2 = 0x8,
14493     MTHC2 = 0x9,
14494     CFC2 = 0xc,
14495     CTC2 = 0xd,
14496
14497     /* bits 15..12 for 0x3c */
14498     JALR = 0x0,
14499     JR = 0x0,                   /* alias */
14500     JALRC = 0x0,
14501     JRC = 0x0,
14502     JALR_HB = 0x1,
14503     JALRC_HB = 0x1,
14504     JALRS = 0x4,
14505     JALRS_HB = 0x5,
14506
14507     /* bits 15..12 for 0x05 */
14508     RDPGPR = 0xe,
14509     WRPGPR = 0xf,
14510
14511     /* bits 15..12 for 0x0d */
14512     TLBP = 0x0,
14513     TLBR = 0x1,
14514     TLBWI = 0x2,
14515     TLBWR = 0x3,
14516     TLBINV = 0x4,
14517     TLBINVF = 0x5,
14518     WAIT = 0x9,
14519     IRET = 0xd,
14520     DERET = 0xe,
14521     ERET = 0xf,
14522
14523     /* bits 15..12 for 0x15 */
14524     DMT = 0x0,
14525     DVPE = 0x1,
14526     EMT = 0x2,
14527     EVPE = 0x3,
14528
14529     /* bits 15..12 for 0x1d */
14530     DI = 0x4,
14531     EI = 0x5,
14532
14533     /* bits 15..12 for 0x2d */
14534     SYNC = 0x6,
14535     SYSCALL = 0x8,
14536     SDBBP = 0xd,
14537
14538     /* bits 15..12 for 0x35 */
14539     MFHI32 = 0x0,
14540     MFLO32 = 0x1,
14541     MTHI32 = 0x2,
14542     MTLO32 = 0x3,
14543 };
14544
14545 /* POOL32B encoding of minor opcode field (bits 15..12) */
14546
14547 enum {
14548     LWC2 = 0x0,
14549     LWP = 0x1,
14550     LDP = 0x4,
14551     LWM32 = 0x5,
14552     CACHE = 0x6,
14553     LDM = 0x7,
14554     SWC2 = 0x8,
14555     SWP = 0x9,
14556     SDP = 0xc,
14557     SWM32 = 0xd,
14558     SDM = 0xf
14559 };
14560
14561 /* POOL32C encoding of minor opcode field (bits 15..12) */
14562
14563 enum {
14564     LWL = 0x0,
14565     SWL = 0x8,
14566     LWR = 0x1,
14567     SWR = 0x9,
14568     PREF = 0x2,
14569     ST_EVA = 0xa,
14570     LL = 0x3,
14571     SC = 0xb,
14572     LDL = 0x4,
14573     SDL = 0xc,
14574     LDR = 0x5,
14575     SDR = 0xd,
14576     LD_EVA = 0x6,
14577     LWU = 0xe,
14578     LLD = 0x7,
14579     SCD = 0xf
14580 };
14581
14582 /* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
14583
14584 enum {
14585     LBUE = 0x0,
14586     LHUE = 0x1,
14587     LWLE = 0x2,
14588     LWRE = 0x3,
14589     LBE = 0x4,
14590     LHE = 0x5,
14591     LLE = 0x6,
14592     LWE = 0x7,
14593 };
14594
14595 /* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
14596
14597 enum {
14598     SWLE = 0x0,
14599     SWRE = 0x1,
14600     PREFE = 0x2,
14601     CACHEE = 0x3,
14602     SBE = 0x4,
14603     SHE = 0x5,
14604     SCE = 0x6,
14605     SWE = 0x7,
14606 };
14607
14608 /* POOL32F encoding of minor opcode field (bits 5..0) */
14609
14610 enum {
14611     /* These are the bit 7..6 values */
14612     ADD_FMT = 0x0,
14613
14614     SUB_FMT = 0x1,
14615
14616     MUL_FMT = 0x2,
14617
14618     DIV_FMT = 0x3,
14619
14620     /* These are the bit 8..6 values */
14621     MOVN_FMT = 0x0,
14622     RSQRT2_FMT = 0x0,
14623     MOVF_FMT = 0x0,
14624     RINT_FMT = 0x0,
14625     SELNEZ_FMT = 0x0,
14626
14627     MOVZ_FMT = 0x1,
14628     LWXC1 = 0x1,
14629     MOVT_FMT = 0x1,
14630     CLASS_FMT = 0x1,
14631     SELEQZ_FMT = 0x1,
14632
14633     PLL_PS = 0x2,
14634     SWXC1 = 0x2,
14635     SEL_FMT = 0x2,
14636
14637     PLU_PS = 0x3,
14638     LDXC1 = 0x3,
14639
14640     MOVN_FMT_04 = 0x4,
14641     PUL_PS = 0x4,
14642     SDXC1 = 0x4,
14643     RECIP2_FMT = 0x4,
14644
14645     MOVZ_FMT_05 = 0x05,
14646     PUU_PS = 0x5,
14647     LUXC1 = 0x5,
14648
14649     CVT_PS_S = 0x6,
14650     SUXC1 = 0x6,
14651     ADDR_PS = 0x6,
14652     PREFX = 0x6,
14653     MADDF_FMT = 0x6,
14654
14655     MULR_PS = 0x7,
14656     MSUBF_FMT = 0x7,
14657
14658     MADD_S = 0x01,
14659     MADD_D = 0x09,
14660     MADD_PS = 0x11,
14661     ALNV_PS = 0x19,
14662     MSUB_S = 0x21,
14663     MSUB_D = 0x29,
14664     MSUB_PS = 0x31,
14665
14666     NMADD_S = 0x02,
14667     NMADD_D = 0x0a,
14668     NMADD_PS = 0x12,
14669     NMSUB_S = 0x22,
14670     NMSUB_D = 0x2a,
14671     NMSUB_PS = 0x32,
14672
14673     MIN_FMT = 0x3,
14674     MAX_FMT = 0xb,
14675     MINA_FMT = 0x23,
14676     MAXA_FMT = 0x2b,
14677     POOL32FXF = 0x3b,
14678
14679     CABS_COND_FMT = 0x1c,              /* MIPS3D */
14680     C_COND_FMT = 0x3c,
14681
14682     CMP_CONDN_S = 0x5,
14683     CMP_CONDN_D = 0x15
14684 };
14685
14686 /* POOL32Fxf encoding of minor opcode extension field */
14687
14688 enum {
14689     CVT_L = 0x04,
14690     RSQRT_FMT = 0x08,
14691     FLOOR_L = 0x0c,
14692     CVT_PW_PS = 0x1c,
14693     CVT_W = 0x24,
14694     SQRT_FMT = 0x28,
14695     FLOOR_W = 0x2c,
14696     CVT_PS_PW = 0x3c,
14697     CFC1 = 0x40,
14698     RECIP_FMT = 0x48,
14699     CEIL_L = 0x4c,
14700     CTC1 = 0x60,
14701     CEIL_W = 0x6c,
14702     MFC1 = 0x80,
14703     CVT_S_PL = 0x84,
14704     TRUNC_L = 0x8c,
14705     MTC1 = 0xa0,
14706     CVT_S_PU = 0xa4,
14707     TRUNC_W = 0xac,
14708     MFHC1 = 0xc0,
14709     ROUND_L = 0xcc,
14710     MTHC1 = 0xe0,
14711     ROUND_W = 0xec,
14712
14713     MOV_FMT = 0x01,
14714     MOVF = 0x05,
14715     ABS_FMT = 0x0d,
14716     RSQRT1_FMT = 0x1d,
14717     MOVT = 0x25,
14718     NEG_FMT = 0x2d,
14719     CVT_D = 0x4d,
14720     RECIP1_FMT = 0x5d,
14721     CVT_S = 0x6d
14722 };
14723
14724 /* POOL32I encoding of minor opcode field (bits 25..21) */
14725
14726 enum {
14727     BLTZ = 0x00,
14728     BLTZAL = 0x01,
14729     BGEZ = 0x02,
14730     BGEZAL = 0x03,
14731     BLEZ = 0x04,
14732     BNEZC = 0x05,
14733     BGTZ = 0x06,
14734     BEQZC = 0x07,
14735     TLTI = 0x08,
14736     BC1EQZC = 0x08,
14737     TGEI = 0x09,
14738     BC1NEZC = 0x09,
14739     TLTIU = 0x0a,
14740     BC2EQZC = 0x0a,
14741     TGEIU = 0x0b,
14742     BC2NEZC = 0x0a,
14743     TNEI = 0x0c,
14744     R6_SYNCI = 0x0c,
14745     LUI = 0x0d,
14746     TEQI = 0x0e,
14747     SYNCI = 0x10,
14748     BLTZALS = 0x11,
14749     BGEZALS = 0x13,
14750     BC2F = 0x14,
14751     BC2T = 0x15,
14752     BPOSGE64 = 0x1a,
14753     BPOSGE32 = 0x1b,
14754     /* These overlap and are distinguished by bit16 of the instruction */
14755     BC1F = 0x1c,
14756     BC1T = 0x1d,
14757     BC1ANY2F = 0x1c,
14758     BC1ANY2T = 0x1d,
14759     BC1ANY4F = 0x1e,
14760     BC1ANY4T = 0x1f
14761 };
14762
14763 /* POOL16A encoding of minor opcode field */
14764
14765 enum {
14766     ADDU16 = 0x0,
14767     SUBU16 = 0x1
14768 };
14769
14770 /* POOL16B encoding of minor opcode field */
14771
14772 enum {
14773     SLL16 = 0x0,
14774     SRL16 = 0x1
14775 };
14776
14777 /* POOL16C encoding of minor opcode field */
14778
14779 enum {
14780     NOT16 = 0x00,
14781     XOR16 = 0x04,
14782     AND16 = 0x08,
14783     OR16 = 0x0c,
14784     LWM16 = 0x10,
14785     SWM16 = 0x14,
14786     JR16 = 0x18,
14787     JRC16 = 0x1a,
14788     JALR16 = 0x1c,
14789     JALR16S = 0x1e,
14790     MFHI16 = 0x20,
14791     MFLO16 = 0x24,
14792     BREAK16 = 0x28,
14793     SDBBP16 = 0x2c,
14794     JRADDIUSP = 0x30
14795 };
14796
14797 /* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14798
14799 enum {
14800     R6_NOT16    = 0x00,
14801     R6_AND16    = 0x01,
14802     R6_LWM16    = 0x02,
14803     R6_JRC16    = 0x03,
14804     MOVEP       = 0x04,
14805     MOVEP_05    = 0x05,
14806     MOVEP_06    = 0x06,
14807     MOVEP_07    = 0x07,
14808     R6_XOR16    = 0x08,
14809     R6_OR16     = 0x09,
14810     R6_SWM16    = 0x0a,
14811     JALRC16     = 0x0b,
14812     MOVEP_0C    = 0x0c,
14813     MOVEP_0D    = 0x0d,
14814     MOVEP_0E    = 0x0e,
14815     MOVEP_0F    = 0x0f,
14816     JRCADDIUSP  = 0x13,
14817     R6_BREAK16  = 0x1b,
14818     R6_SDBBP16  = 0x3b
14819 };
14820
14821 /* POOL16D encoding of minor opcode field */
14822
14823 enum {
14824     ADDIUS5 = 0x0,
14825     ADDIUSP = 0x1
14826 };
14827
14828 /* POOL16E encoding of minor opcode field */
14829
14830 enum {
14831     ADDIUR2 = 0x0,
14832     ADDIUR1SP = 0x1
14833 };
14834
14835 static int mmreg (int r)
14836 {
14837     static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14838
14839     return map[r];
14840 }
14841
14842 /* Used for 16-bit store instructions.  */
14843 static int mmreg2 (int r)
14844 {
14845     static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14846
14847     return map[r];
14848 }
14849
14850 #define uMIPS_RD(op) ((op >> 7) & 0x7)
14851 #define uMIPS_RS(op) ((op >> 4) & 0x7)
14852 #define uMIPS_RS2(op) uMIPS_RS(op)
14853 #define uMIPS_RS1(op) ((op >> 1) & 0x7)
14854 #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14855 #define uMIPS_RS5(op) (op & 0x1f)
14856
14857 /* Signed immediate */
14858 #define SIMM(op, start, width)                                          \
14859     ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
14860                << (32-width))                                           \
14861      >> (32-width))
14862 /* Zero-extended immediate */
14863 #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
14864
14865 static void gen_addiur1sp(DisasContext *ctx)
14866 {
14867     int rd = mmreg(uMIPS_RD(ctx->opcode));
14868
14869     gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
14870 }
14871
14872 static void gen_addiur2(DisasContext *ctx)
14873 {
14874     static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14875     int rd = mmreg(uMIPS_RD(ctx->opcode));
14876     int rs = mmreg(uMIPS_RS(ctx->opcode));
14877
14878     gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
14879 }
14880
14881 static void gen_addiusp(DisasContext *ctx)
14882 {
14883     int encoded = ZIMM(ctx->opcode, 1, 9);
14884     int decoded;
14885
14886     if (encoded <= 1) {
14887         decoded = 256 + encoded;
14888     } else if (encoded <= 255) {
14889         decoded = encoded;
14890     } else if (encoded <= 509) {
14891         decoded = encoded - 512;
14892     } else {
14893         decoded = encoded - 768;
14894     }
14895
14896     gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
14897 }
14898
14899 static void gen_addius5(DisasContext *ctx)
14900 {
14901     int imm = SIMM(ctx->opcode, 1, 4);
14902     int rd = (ctx->opcode >> 5) & 0x1f;
14903
14904     gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
14905 }
14906
14907 static void gen_andi16(DisasContext *ctx)
14908 {
14909     static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14910                                  31, 32, 63, 64, 255, 32768, 65535 };
14911     int rd = mmreg(uMIPS_RD(ctx->opcode));
14912     int rs = mmreg(uMIPS_RS(ctx->opcode));
14913     int encoded = ZIMM(ctx->opcode, 0, 4);
14914
14915     gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
14916 }
14917
14918 static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
14919                                int base, int16_t offset)
14920 {
14921     TCGv t0, t1;
14922     TCGv_i32 t2;
14923
14924     if (ctx->hflags & MIPS_HFLAG_BMASK) {
14925         generate_exception_end(ctx, EXCP_RI);
14926         return;
14927     }
14928
14929     t0 = tcg_temp_new();
14930
14931     gen_base_offset_addr(ctx, t0, base, offset);
14932
14933     t1 = tcg_const_tl(reglist);
14934     t2 = tcg_const_i32(ctx->mem_idx);
14935
14936     save_cpu_state(ctx, 1);
14937     switch (opc) {
14938     case LWM32:
14939         gen_helper_lwm(cpu_env, t0, t1, t2);
14940         break;
14941     case SWM32:
14942         gen_helper_swm(cpu_env, t0, t1, t2);
14943         break;
14944 #ifdef TARGET_MIPS64
14945     case LDM:
14946         gen_helper_ldm(cpu_env, t0, t1, t2);
14947         break;
14948     case SDM:
14949         gen_helper_sdm(cpu_env, t0, t1, t2);
14950         break;
14951 #endif
14952     }
14953     tcg_temp_free(t0);
14954     tcg_temp_free(t1);
14955     tcg_temp_free_i32(t2);
14956 }
14957
14958
14959 static void gen_pool16c_insn(DisasContext *ctx)
14960 {
14961     int rd = mmreg((ctx->opcode >> 3) & 0x7);
14962     int rs = mmreg(ctx->opcode & 0x7);
14963
14964     switch (((ctx->opcode) >> 4) & 0x3f) {
14965     case NOT16 + 0:
14966     case NOT16 + 1:
14967     case NOT16 + 2:
14968     case NOT16 + 3:
14969         gen_logic(ctx, OPC_NOR, rd, rs, 0);
14970         break;
14971     case XOR16 + 0:
14972     case XOR16 + 1:
14973     case XOR16 + 2:
14974     case XOR16 + 3:
14975         gen_logic(ctx, OPC_XOR, rd, rd, rs);
14976         break;
14977     case AND16 + 0:
14978     case AND16 + 1:
14979     case AND16 + 2:
14980     case AND16 + 3:
14981         gen_logic(ctx, OPC_AND, rd, rd, rs);
14982         break;
14983     case OR16 + 0:
14984     case OR16 + 1:
14985     case OR16 + 2:
14986     case OR16 + 3:
14987         gen_logic(ctx, OPC_OR, rd, rd, rs);
14988         break;
14989     case LWM16 + 0:
14990     case LWM16 + 1:
14991     case LWM16 + 2:
14992     case LWM16 + 3:
14993         {
14994             static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14995             int offset = ZIMM(ctx->opcode, 0, 4);
14996
14997             gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14998                               29, offset << 2);
14999         }
15000         break;
15001     case SWM16 + 0:
15002     case SWM16 + 1:
15003     case SWM16 + 2:
15004     case SWM16 + 3:
15005         {
15006             static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
15007             int offset = ZIMM(ctx->opcode, 0, 4);
15008
15009             gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
15010                               29, offset << 2);
15011         }
15012         break;
15013     case JR16 + 0:
15014     case JR16 + 1:
15015         {
15016             int reg = ctx->opcode & 0x1f;
15017
15018             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
15019         }
15020         break;
15021     case JRC16 + 0:
15022     case JRC16 + 1:
15023         {
15024             int reg = ctx->opcode & 0x1f;
15025             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
15026             /* Let normal delay slot handling in our caller take us
15027                to the branch target.  */
15028         }
15029         break;
15030     case JALR16 + 0:
15031     case JALR16 + 1:
15032         gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
15033         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15034         break;
15035     case JALR16S + 0:
15036     case JALR16S + 1:
15037         gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
15038         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15039         break;
15040     case MFHI16 + 0:
15041     case MFHI16 + 1:
15042         gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
15043         break;
15044     case MFLO16 + 0:
15045     case MFLO16 + 1:
15046         gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
15047         break;
15048     case BREAK16:
15049         generate_exception_end(ctx, EXCP_BREAK);
15050         break;
15051     case SDBBP16:
15052         if (is_uhi(extract32(ctx->opcode, 0, 4))) {
15053             gen_helper_do_semihosting(cpu_env);
15054         } else {
15055             /* XXX: not clear which exception should be raised
15056              *      when in debug mode...
15057              */
15058             check_insn(ctx, ISA_MIPS32);
15059             generate_exception_end(ctx, EXCP_DBp);
15060         }
15061         break;
15062     case JRADDIUSP + 0:
15063     case JRADDIUSP + 1:
15064         {
15065             int imm = ZIMM(ctx->opcode, 0, 5);
15066             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15067             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15068             /* Let normal delay slot handling in our caller take us
15069                to the branch target.  */
15070         }
15071         break;
15072     default:
15073         generate_exception_end(ctx, EXCP_RI);
15074         break;
15075     }
15076 }
15077
15078 static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
15079                              int enc_rs)
15080 {
15081     int rd, rs, re, rt;
15082     static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
15083     static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
15084     static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
15085     rd = rd_enc[enc_dest];
15086     re = re_enc[enc_dest];
15087     rs = rs_rt_enc[enc_rs];
15088     rt = rs_rt_enc[enc_rt];
15089     if (rs) {
15090         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
15091     } else {
15092         tcg_gen_movi_tl(cpu_gpr[rd], 0);
15093     }
15094     if (rt) {
15095         tcg_gen_mov_tl(cpu_gpr[re], cpu_gpr[rt]);
15096     } else {
15097         tcg_gen_movi_tl(cpu_gpr[re], 0);
15098     }
15099 }
15100
15101 static void gen_pool16c_r6_insn(DisasContext *ctx)
15102 {
15103     int rt = mmreg((ctx->opcode >> 7) & 0x7);
15104     int rs = mmreg((ctx->opcode >> 4) & 0x7);
15105
15106     switch (ctx->opcode & 0xf) {
15107     case R6_NOT16:
15108         gen_logic(ctx, OPC_NOR, rt, rs, 0);
15109         break;
15110     case R6_AND16:
15111         gen_logic(ctx, OPC_AND, rt, rt, rs);
15112         break;
15113     case R6_LWM16:
15114         {
15115             int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15116             int offset = extract32(ctx->opcode, 4, 4);
15117             gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
15118         }
15119         break;
15120     case R6_JRC16: /* JRCADDIUSP */
15121         if ((ctx->opcode >> 4) & 1) {
15122             /* JRCADDIUSP */
15123             int imm = extract32(ctx->opcode, 5, 5);
15124             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
15125             gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
15126         } else {
15127             /* JRC16 */
15128             rs = extract32(ctx->opcode, 5, 5);
15129             gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
15130         }
15131         break;
15132     case MOVEP:
15133     case MOVEP_05:
15134     case MOVEP_06:
15135     case MOVEP_07:
15136     case MOVEP_0C:
15137     case MOVEP_0D:
15138     case MOVEP_0E:
15139     case MOVEP_0F:
15140         {
15141             int enc_dest = uMIPS_RD(ctx->opcode);
15142             int enc_rt = uMIPS_RS2(ctx->opcode);
15143             int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
15144             gen_movep(ctx, enc_dest, enc_rt, enc_rs);
15145         }
15146         break;
15147     case R6_XOR16:
15148         gen_logic(ctx, OPC_XOR, rt, rt, rs);
15149         break;
15150     case R6_OR16:
15151         gen_logic(ctx, OPC_OR, rt, rt, rs);
15152         break;
15153     case R6_SWM16:
15154         {
15155             int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
15156             int offset = extract32(ctx->opcode, 4, 4);
15157             gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
15158         }
15159         break;
15160     case JALRC16: /* BREAK16, SDBBP16 */
15161         switch (ctx->opcode & 0x3f) {
15162         case JALRC16:
15163         case JALRC16 + 0x20:
15164             /* JALRC16 */
15165             gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
15166                                31, 0, 0);
15167             break;
15168         case R6_BREAK16:
15169             /* BREAK16 */
15170             generate_exception(ctx, EXCP_BREAK);
15171             break;
15172         case R6_SDBBP16:
15173             /* SDBBP16 */
15174             if (is_uhi(extract32(ctx->opcode, 6, 4))) {
15175                 gen_helper_do_semihosting(cpu_env);
15176             } else {
15177                 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15178                     generate_exception(ctx, EXCP_RI);
15179                 } else {
15180                     generate_exception(ctx, EXCP_DBp);
15181                 }
15182             }
15183             break;
15184         }
15185         break;
15186     default:
15187         generate_exception(ctx, EXCP_RI);
15188         break;
15189     }
15190 }
15191
15192 static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
15193 {
15194     TCGv t0 = tcg_temp_new();
15195     TCGv t1 = tcg_temp_new();
15196
15197     gen_load_gpr(t0, base);
15198
15199     if (index != 0) {
15200         gen_load_gpr(t1, index);
15201         tcg_gen_shli_tl(t1, t1, 2);
15202         gen_op_addr_add(ctx, t0, t1, t0);
15203     }
15204
15205     tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15206     gen_store_gpr(t1, rd);
15207
15208     tcg_temp_free(t0);
15209     tcg_temp_free(t1);
15210 }
15211
15212 static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
15213                            int base, int16_t offset)
15214 {
15215     TCGv t0, t1;
15216
15217     if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
15218         generate_exception_end(ctx, EXCP_RI);
15219         return;
15220     }
15221
15222     t0 = tcg_temp_new();
15223     t1 = tcg_temp_new();
15224
15225     gen_base_offset_addr(ctx, t0, base, offset);
15226
15227     switch (opc) {
15228     case LWP:
15229         if (rd == base) {
15230             generate_exception_end(ctx, EXCP_RI);
15231             return;
15232         }
15233         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15234         gen_store_gpr(t1, rd);
15235         tcg_gen_movi_tl(t1, 4);
15236         gen_op_addr_add(ctx, t0, t0, t1);
15237         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
15238         gen_store_gpr(t1, rd+1);
15239         break;
15240     case SWP:
15241         gen_load_gpr(t1, rd);
15242         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15243         tcg_gen_movi_tl(t1, 4);
15244         gen_op_addr_add(ctx, t0, t0, t1);
15245         gen_load_gpr(t1, rd+1);
15246         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
15247         break;
15248 #ifdef TARGET_MIPS64
15249     case LDP:
15250         if (rd == base) {
15251             generate_exception_end(ctx, EXCP_RI);
15252             return;
15253         }
15254         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15255         gen_store_gpr(t1, rd);
15256         tcg_gen_movi_tl(t1, 8);
15257         gen_op_addr_add(ctx, t0, t0, t1);
15258         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15259         gen_store_gpr(t1, rd+1);
15260         break;
15261     case SDP:
15262         gen_load_gpr(t1, rd);
15263         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15264         tcg_gen_movi_tl(t1, 8);
15265         gen_op_addr_add(ctx, t0, t0, t1);
15266         gen_load_gpr(t1, rd+1);
15267         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
15268         break;
15269 #endif
15270     }
15271     tcg_temp_free(t0);
15272     tcg_temp_free(t1);
15273 }
15274
15275 static void gen_sync(int stype)
15276 {
15277     TCGBar tcg_mo = TCG_BAR_SC;
15278
15279     switch (stype) {
15280     case 0x4: /* SYNC_WMB */
15281         tcg_mo |= TCG_MO_ST_ST;
15282         break;
15283     case 0x10: /* SYNC_MB */
15284         tcg_mo |= TCG_MO_ALL;
15285         break;
15286     case 0x11: /* SYNC_ACQUIRE */
15287         tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
15288         break;
15289     case 0x12: /* SYNC_RELEASE */
15290         tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
15291         break;
15292     case 0x13: /* SYNC_RMB */
15293         tcg_mo |= TCG_MO_LD_LD;
15294         break;
15295     default:
15296         tcg_mo |= TCG_MO_ALL;
15297         break;
15298     }
15299
15300     tcg_gen_mb(tcg_mo);
15301 }
15302
15303 static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
15304 {
15305     int extension = (ctx->opcode >> 6) & 0x3f;
15306     int minor = (ctx->opcode >> 12) & 0xf;
15307     uint32_t mips32_op;
15308
15309     switch (extension) {
15310     case TEQ:
15311         mips32_op = OPC_TEQ;
15312         goto do_trap;
15313     case TGE:
15314         mips32_op = OPC_TGE;
15315         goto do_trap;
15316     case TGEU:
15317         mips32_op = OPC_TGEU;
15318         goto do_trap;
15319     case TLT:
15320         mips32_op = OPC_TLT;
15321         goto do_trap;
15322     case TLTU:
15323         mips32_op = OPC_TLTU;
15324         goto do_trap;
15325     case TNE:
15326         mips32_op = OPC_TNE;
15327     do_trap:
15328         gen_trap(ctx, mips32_op, rs, rt, -1);
15329         break;
15330 #ifndef CONFIG_USER_ONLY
15331     case MFC0:
15332     case MFC0 + 32:
15333         check_cp0_enabled(ctx);
15334         if (rt == 0) {
15335             /* Treat as NOP. */
15336             break;
15337         }
15338         gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
15339         break;
15340     case MTC0:
15341     case MTC0 + 32:
15342         check_cp0_enabled(ctx);
15343         {
15344             TCGv t0 = tcg_temp_new();
15345
15346             gen_load_gpr(t0, rt);
15347             gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
15348             tcg_temp_free(t0);
15349         }
15350         break;
15351 #endif
15352     case 0x2a:
15353         switch (minor & 3) {
15354         case MADD_ACC:
15355             gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
15356             break;
15357         case MADDU_ACC:
15358             gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
15359             break;
15360         case MSUB_ACC:
15361             gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
15362             break;
15363         case MSUBU_ACC:
15364             gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
15365             break;
15366         default:
15367             goto pool32axf_invalid;
15368         }
15369         break;
15370     case 0x32:
15371         switch (minor & 3) {
15372         case MULT_ACC:
15373             gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
15374             break;
15375         case MULTU_ACC:
15376             gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
15377             break;
15378         default:
15379             goto pool32axf_invalid;
15380         }
15381         break;
15382     case 0x2c:
15383         switch (minor) {
15384         case BITSWAP:
15385             check_insn(ctx, ISA_MIPS32R6);
15386             gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
15387             break;
15388         case SEB:
15389             gen_bshfl(ctx, OPC_SEB, rs, rt);
15390             break;
15391         case SEH:
15392             gen_bshfl(ctx, OPC_SEH, rs, rt);
15393             break;
15394         case CLO:
15395             mips32_op = OPC_CLO;
15396             goto do_cl;
15397         case CLZ:
15398             mips32_op = OPC_CLZ;
15399         do_cl:
15400             check_insn(ctx, ISA_MIPS32);
15401             gen_cl(ctx, mips32_op, rt, rs);
15402             break;
15403         case RDHWR:
15404             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15405             gen_rdhwr(ctx, rt, rs, 0);
15406             break;
15407         case WSBH:
15408             gen_bshfl(ctx, OPC_WSBH, rs, rt);
15409             break;
15410         case MULT:
15411             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15412             mips32_op = OPC_MULT;
15413             goto do_mul;
15414         case MULTU:
15415             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15416             mips32_op = OPC_MULTU;
15417             goto do_mul;
15418         case DIV:
15419             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15420             mips32_op = OPC_DIV;
15421             goto do_div;
15422         case DIVU:
15423             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15424             mips32_op = OPC_DIVU;
15425             goto do_div;
15426         do_div:
15427             check_insn(ctx, ISA_MIPS32);
15428             gen_muldiv(ctx, mips32_op, 0, rs, rt);
15429             break;
15430         case MADD:
15431             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15432             mips32_op = OPC_MADD;
15433             goto do_mul;
15434         case MADDU:
15435             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15436             mips32_op = OPC_MADDU;
15437             goto do_mul;
15438         case MSUB:
15439             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15440             mips32_op = OPC_MSUB;
15441             goto do_mul;
15442         case MSUBU:
15443             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15444             mips32_op = OPC_MSUBU;
15445         do_mul:
15446             check_insn(ctx, ISA_MIPS32);
15447             gen_muldiv(ctx, mips32_op, 0, rs, rt);
15448             break;
15449         default:
15450             goto pool32axf_invalid;
15451         }
15452         break;
15453     case 0x34:
15454         switch (minor) {
15455         case MFC2:
15456         case MTC2:
15457         case MFHC2:
15458         case MTHC2:
15459         case CFC2:
15460         case CTC2:
15461             generate_exception_err(ctx, EXCP_CpU, 2);
15462             break;
15463         default:
15464             goto pool32axf_invalid;
15465         }
15466         break;
15467     case 0x3c:
15468         switch (minor) {
15469         case JALR:    /* JALRC */
15470         case JALR_HB: /* JALRC_HB */
15471             if (ctx->insn_flags & ISA_MIPS32R6) {
15472                 /* JALRC, JALRC_HB */
15473                 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
15474             } else {
15475                 /* JALR, JALR_HB */
15476                 gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
15477                 ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15478             }
15479             break;
15480         case JALRS:
15481         case JALRS_HB:
15482             check_insn_opc_removed(ctx, ISA_MIPS32R6);
15483             gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
15484             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15485             break;
15486         default:
15487             goto pool32axf_invalid;
15488         }
15489         break;
15490     case 0x05:
15491         switch (minor) {
15492         case RDPGPR:
15493             check_cp0_enabled(ctx);
15494             check_insn(ctx, ISA_MIPS32R2);
15495             gen_load_srsgpr(rs, rt);
15496             break;
15497         case WRPGPR:
15498             check_cp0_enabled(ctx);
15499             check_insn(ctx, ISA_MIPS32R2);
15500             gen_store_srsgpr(rs, rt);
15501             break;
15502         default:
15503             goto pool32axf_invalid;
15504         }
15505         break;
15506 #ifndef CONFIG_USER_ONLY
15507     case 0x0d:
15508         switch (minor) {
15509         case TLBP:
15510             mips32_op = OPC_TLBP;
15511             goto do_cp0;
15512         case TLBR:
15513             mips32_op = OPC_TLBR;
15514             goto do_cp0;
15515         case TLBWI:
15516             mips32_op = OPC_TLBWI;
15517             goto do_cp0;
15518         case TLBWR:
15519             mips32_op = OPC_TLBWR;
15520             goto do_cp0;
15521         case TLBINV:
15522             mips32_op = OPC_TLBINV;
15523             goto do_cp0;
15524         case TLBINVF:
15525             mips32_op = OPC_TLBINVF;
15526             goto do_cp0;
15527         case WAIT:
15528             mips32_op = OPC_WAIT;
15529             goto do_cp0;
15530         case DERET:
15531             mips32_op = OPC_DERET;
15532             goto do_cp0;
15533         case ERET:
15534             mips32_op = OPC_ERET;
15535         do_cp0:
15536             gen_cp0(env, ctx, mips32_op, rt, rs);
15537             break;
15538         default:
15539             goto pool32axf_invalid;
15540         }
15541         break;
15542     case 0x1d:
15543         switch (minor) {
15544         case DI:
15545             check_cp0_enabled(ctx);
15546             {
15547                 TCGv t0 = tcg_temp_new();
15548
15549                 save_cpu_state(ctx, 1);
15550                 gen_helper_di(t0, cpu_env);
15551                 gen_store_gpr(t0, rs);
15552                 /* Stop translation as we may have switched the execution mode */
15553                 ctx->base.is_jmp = DISAS_STOP;
15554                 tcg_temp_free(t0);
15555             }
15556             break;
15557         case EI:
15558             check_cp0_enabled(ctx);
15559             {
15560                 TCGv t0 = tcg_temp_new();
15561
15562                 save_cpu_state(ctx, 1);
15563                 gen_helper_ei(t0, cpu_env);
15564                 gen_store_gpr(t0, rs);
15565                 /* DISAS_STOP isn't sufficient, we need to ensure we break out
15566                    of translated code to check for pending interrupts.  */
15567                 gen_save_pc(ctx->base.pc_next + 4);
15568                 ctx->base.is_jmp = DISAS_EXIT;
15569                 tcg_temp_free(t0);
15570             }
15571             break;
15572         default:
15573             goto pool32axf_invalid;
15574         }
15575         break;
15576 #endif
15577     case 0x2d:
15578         switch (minor) {
15579         case SYNC:
15580             gen_sync(extract32(ctx->opcode, 16, 5));
15581             break;
15582         case SYSCALL:
15583             generate_exception_end(ctx, EXCP_SYSCALL);
15584             break;
15585         case SDBBP:
15586             if (is_uhi(extract32(ctx->opcode, 16, 10))) {
15587                 gen_helper_do_semihosting(cpu_env);
15588             } else {
15589                 check_insn(ctx, ISA_MIPS32);
15590                 if (ctx->hflags & MIPS_HFLAG_SBRI) {
15591                     generate_exception_end(ctx, EXCP_RI);
15592                 } else {
15593                     generate_exception_end(ctx, EXCP_DBp);
15594                 }
15595             }
15596             break;
15597         default:
15598             goto pool32axf_invalid;
15599         }
15600         break;
15601     case 0x01:
15602         switch (minor & 3) {
15603         case MFHI_ACC:
15604             gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
15605             break;
15606         case MFLO_ACC:
15607             gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
15608             break;
15609         case MTHI_ACC:
15610             gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
15611             break;
15612         case MTLO_ACC:
15613             gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
15614             break;
15615         default:
15616             goto pool32axf_invalid;
15617         }
15618         break;
15619     case 0x35:
15620         check_insn_opc_removed(ctx, ISA_MIPS32R6);
15621         switch (minor) {
15622         case MFHI32:
15623             gen_HILO(ctx, OPC_MFHI, 0, rs);
15624             break;
15625         case MFLO32:
15626             gen_HILO(ctx, OPC_MFLO, 0, rs);
15627             break;
15628         case MTHI32:
15629             gen_HILO(ctx, OPC_MTHI, 0, rs);
15630             break;
15631         case MTLO32:
15632             gen_HILO(ctx, OPC_MTLO, 0, rs);
15633             break;
15634         default:
15635             goto pool32axf_invalid;
15636         }
15637         break;
15638     default:
15639     pool32axf_invalid:
15640         MIPS_INVAL("pool32axf");
15641         generate_exception_end(ctx, EXCP_RI);
15642         break;
15643     }
15644 }
15645
15646 /* Values for microMIPS fmt field.  Variable-width, depending on which
15647    formats the instruction supports.  */
15648
15649 enum {
15650     FMT_SD_S = 0,
15651     FMT_SD_D = 1,
15652
15653     FMT_SDPS_S = 0,
15654     FMT_SDPS_D = 1,
15655     FMT_SDPS_PS = 2,
15656
15657     FMT_SWL_S = 0,
15658     FMT_SWL_W = 1,
15659     FMT_SWL_L = 2,
15660
15661     FMT_DWL_D = 0,
15662     FMT_DWL_W = 1,
15663     FMT_DWL_L = 2
15664 };
15665
15666 static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
15667 {
15668     int extension = (ctx->opcode >> 6) & 0x3ff;
15669     uint32_t mips32_op;
15670
15671 #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
15672 #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
15673 #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
15674
15675     switch (extension) {
15676     case FLOAT_1BIT_FMT(CFC1, 0):
15677         mips32_op = OPC_CFC1;
15678         goto do_cp1;
15679     case FLOAT_1BIT_FMT(CTC1, 0):
15680         mips32_op = OPC_CTC1;
15681         goto do_cp1;
15682     case FLOAT_1BIT_FMT(MFC1, 0):
15683         mips32_op = OPC_MFC1;
15684         goto do_cp1;
15685     case FLOAT_1BIT_FMT(MTC1, 0):
15686         mips32_op = OPC_MTC1;
15687         goto do_cp1;
15688     case FLOAT_1BIT_FMT(MFHC1, 0):
15689         mips32_op = OPC_MFHC1;
15690         goto do_cp1;
15691     case FLOAT_1BIT_FMT(MTHC1, 0):
15692         mips32_op = OPC_MTHC1;
15693     do_cp1:
15694         gen_cp1(ctx, mips32_op, rt, rs);
15695         break;
15696
15697         /* Reciprocal square root */
15698     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15699         mips32_op = OPC_RSQRT_S;
15700         goto do_unaryfp;
15701     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15702         mips32_op = OPC_RSQRT_D;
15703         goto do_unaryfp;
15704
15705         /* Square root */
15706     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15707         mips32_op = OPC_SQRT_S;
15708         goto do_unaryfp;
15709     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15710         mips32_op = OPC_SQRT_D;
15711         goto do_unaryfp;
15712
15713         /* Reciprocal */
15714     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15715         mips32_op = OPC_RECIP_S;
15716         goto do_unaryfp;
15717     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15718         mips32_op = OPC_RECIP_D;
15719         goto do_unaryfp;
15720
15721         /* Floor */
15722     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15723         mips32_op = OPC_FLOOR_L_S;
15724         goto do_unaryfp;
15725     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15726         mips32_op = OPC_FLOOR_L_D;
15727         goto do_unaryfp;
15728     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15729         mips32_op = OPC_FLOOR_W_S;
15730         goto do_unaryfp;
15731     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15732         mips32_op = OPC_FLOOR_W_D;
15733         goto do_unaryfp;
15734
15735         /* Ceiling */
15736     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15737         mips32_op = OPC_CEIL_L_S;
15738         goto do_unaryfp;
15739     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
15740         mips32_op = OPC_CEIL_L_D;
15741         goto do_unaryfp;
15742     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
15743         mips32_op = OPC_CEIL_W_S;
15744         goto do_unaryfp;
15745     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
15746         mips32_op = OPC_CEIL_W_D;
15747         goto do_unaryfp;
15748
15749         /* Truncation */
15750     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
15751         mips32_op = OPC_TRUNC_L_S;
15752         goto do_unaryfp;
15753     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
15754         mips32_op = OPC_TRUNC_L_D;
15755         goto do_unaryfp;
15756     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
15757         mips32_op = OPC_TRUNC_W_S;
15758         goto do_unaryfp;
15759     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
15760         mips32_op = OPC_TRUNC_W_D;
15761         goto do_unaryfp;
15762
15763         /* Round */
15764     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
15765         mips32_op = OPC_ROUND_L_S;
15766         goto do_unaryfp;
15767     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
15768         mips32_op = OPC_ROUND_L_D;
15769         goto do_unaryfp;
15770     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
15771         mips32_op = OPC_ROUND_W_S;
15772         goto do_unaryfp;
15773     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
15774         mips32_op = OPC_ROUND_W_D;
15775         goto do_unaryfp;
15776
15777         /* Integer to floating-point conversion */
15778     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
15779         mips32_op = OPC_CVT_L_S;
15780         goto do_unaryfp;
15781     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
15782         mips32_op = OPC_CVT_L_D;
15783         goto do_unaryfp;
15784     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
15785         mips32_op = OPC_CVT_W_S;
15786         goto do_unaryfp;
15787     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
15788         mips32_op = OPC_CVT_W_D;
15789         goto do_unaryfp;
15790
15791         /* Paired-foo conversions */
15792     case FLOAT_1BIT_FMT(CVT_S_PL, 0):
15793         mips32_op = OPC_CVT_S_PL;
15794         goto do_unaryfp;
15795     case FLOAT_1BIT_FMT(CVT_S_PU, 0):
15796         mips32_op = OPC_CVT_S_PU;
15797         goto do_unaryfp;
15798     case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
15799         mips32_op = OPC_CVT_PW_PS;
15800         goto do_unaryfp;
15801     case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
15802         mips32_op = OPC_CVT_PS_PW;
15803         goto do_unaryfp;
15804
15805         /* Floating-point moves */
15806     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
15807         mips32_op = OPC_MOV_S;
15808         goto do_unaryfp;
15809     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
15810         mips32_op = OPC_MOV_D;
15811         goto do_unaryfp;
15812     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
15813         mips32_op = OPC_MOV_PS;
15814         goto do_unaryfp;
15815
15816         /* Absolute value */
15817     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
15818         mips32_op = OPC_ABS_S;
15819         goto do_unaryfp;
15820     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
15821         mips32_op = OPC_ABS_D;
15822         goto do_unaryfp;
15823     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
15824         mips32_op = OPC_ABS_PS;
15825         goto do_unaryfp;
15826
15827         /* Negation */
15828     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
15829         mips32_op = OPC_NEG_S;
15830         goto do_unaryfp;
15831     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
15832         mips32_op = OPC_NEG_D;
15833         goto do_unaryfp;
15834     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
15835         mips32_op = OPC_NEG_PS;
15836         goto do_unaryfp;
15837
15838         /* Reciprocal square root step */
15839     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
15840         mips32_op = OPC_RSQRT1_S;
15841         goto do_unaryfp;
15842     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
15843         mips32_op = OPC_RSQRT1_D;
15844         goto do_unaryfp;
15845     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
15846         mips32_op = OPC_RSQRT1_PS;
15847         goto do_unaryfp;
15848
15849         /* Reciprocal step */
15850     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
15851         mips32_op = OPC_RECIP1_S;
15852         goto do_unaryfp;
15853     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
15854         mips32_op = OPC_RECIP1_S;
15855         goto do_unaryfp;
15856     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
15857         mips32_op = OPC_RECIP1_PS;
15858         goto do_unaryfp;
15859
15860         /* Conversions from double */
15861     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
15862         mips32_op = OPC_CVT_D_S;
15863         goto do_unaryfp;
15864     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
15865         mips32_op = OPC_CVT_D_W;
15866         goto do_unaryfp;
15867     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
15868         mips32_op = OPC_CVT_D_L;
15869         goto do_unaryfp;
15870
15871         /* Conversions from single */
15872     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
15873         mips32_op = OPC_CVT_S_D;
15874         goto do_unaryfp;
15875     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
15876         mips32_op = OPC_CVT_S_W;
15877         goto do_unaryfp;
15878     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
15879         mips32_op = OPC_CVT_S_L;
15880     do_unaryfp:
15881         gen_farith(ctx, mips32_op, -1, rs, rt, 0);
15882         break;
15883
15884         /* Conditional moves on floating-point codes */
15885     case COND_FLOAT_MOV(MOVT, 0):
15886     case COND_FLOAT_MOV(MOVT, 1):
15887     case COND_FLOAT_MOV(MOVT, 2):
15888     case COND_FLOAT_MOV(MOVT, 3):
15889     case COND_FLOAT_MOV(MOVT, 4):
15890     case COND_FLOAT_MOV(MOVT, 5):
15891     case COND_FLOAT_MOV(MOVT, 6):
15892     case COND_FLOAT_MOV(MOVT, 7):
15893         check_insn_opc_removed(ctx, ISA_MIPS32R6);
15894         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
15895         break;
15896     case COND_FLOAT_MOV(MOVF, 0):
15897     case COND_FLOAT_MOV(MOVF, 1):
15898     case COND_FLOAT_MOV(MOVF, 2):
15899     case COND_FLOAT_MOV(MOVF, 3):
15900     case COND_FLOAT_MOV(MOVF, 4):
15901     case COND_FLOAT_MOV(MOVF, 5):
15902     case COND_FLOAT_MOV(MOVF, 6):
15903     case COND_FLOAT_MOV(MOVF, 7):
15904         check_insn_opc_removed(ctx, ISA_MIPS32R6);
15905         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
15906         break;
15907     default:
15908         MIPS_INVAL("pool32fxf");
15909         generate_exception_end(ctx, EXCP_RI);
15910         break;
15911     }
15912 }
15913
15914 static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
15915 {
15916     int32_t offset;
15917     uint16_t insn;
15918     int rt, rs, rd, rr;
15919     int16_t imm;
15920     uint32_t op, minor, minor2, mips32_op;
15921     uint32_t cond, fmt, cc;
15922
15923     insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
15924     ctx->opcode = (ctx->opcode << 16) | insn;
15925
15926     rt = (ctx->opcode >> 21) & 0x1f;
15927     rs = (ctx->opcode >> 16) & 0x1f;
15928     rd = (ctx->opcode >> 11) & 0x1f;
15929     rr = (ctx->opcode >> 6) & 0x1f;
15930     imm = (int16_t) ctx->opcode;
15931
15932     op = (ctx->opcode >> 26) & 0x3f;
15933     switch (op) {
15934     case POOL32A:
15935         minor = ctx->opcode & 0x3f;
15936         switch (minor) {
15937         case 0x00:
15938             minor = (ctx->opcode >> 6) & 0xf;
15939             switch (minor) {
15940             case SLL32:
15941                 mips32_op = OPC_SLL;
15942                 goto do_shifti;
15943             case SRA:
15944                 mips32_op = OPC_SRA;
15945                 goto do_shifti;
15946             case SRL32:
15947                 mips32_op = OPC_SRL;
15948                 goto do_shifti;
15949             case ROTR:
15950                 mips32_op = OPC_ROTR;
15951             do_shifti:
15952                 gen_shift_imm(ctx, mips32_op, rt, rs, rd);
15953                 break;
15954             case SELEQZ:
15955                 check_insn(ctx, ISA_MIPS32R6);
15956                 gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
15957                 break;
15958             case SELNEZ:
15959                 check_insn(ctx, ISA_MIPS32R6);
15960                 gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
15961                 break;
15962             case R6_RDHWR:
15963                 check_insn(ctx, ISA_MIPS32R6);
15964                 gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
15965                 break;
15966             default:
15967                 goto pool32a_invalid;
15968             }
15969             break;
15970         case 0x10:
15971             minor = (ctx->opcode >> 6) & 0xf;
15972             switch (minor) {
15973                 /* Arithmetic */
15974             case ADD:
15975                 mips32_op = OPC_ADD;
15976                 goto do_arith;
15977             case ADDU32:
15978                 mips32_op = OPC_ADDU;
15979                 goto do_arith;
15980             case SUB:
15981                 mips32_op = OPC_SUB;
15982                 goto do_arith;
15983             case SUBU32:
15984                 mips32_op = OPC_SUBU;
15985                 goto do_arith;
15986             case MUL:
15987                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
15988                 mips32_op = OPC_MUL;
15989             do_arith:
15990                 gen_arith(ctx, mips32_op, rd, rs, rt);
15991                 break;
15992                 /* Shifts */
15993             case SLLV:
15994                 mips32_op = OPC_SLLV;
15995                 goto do_shift;
15996             case SRLV:
15997                 mips32_op = OPC_SRLV;
15998                 goto do_shift;
15999             case SRAV:
16000                 mips32_op = OPC_SRAV;
16001                 goto do_shift;
16002             case ROTRV:
16003                 mips32_op = OPC_ROTRV;
16004             do_shift:
16005                 gen_shift(ctx, mips32_op, rd, rs, rt);
16006                 break;
16007                 /* Logical operations */
16008             case AND:
16009                 mips32_op = OPC_AND;
16010                 goto do_logic;
16011             case OR32:
16012                 mips32_op = OPC_OR;
16013                 goto do_logic;
16014             case NOR:
16015                 mips32_op = OPC_NOR;
16016                 goto do_logic;
16017             case XOR32:
16018                 mips32_op = OPC_XOR;
16019             do_logic:
16020                 gen_logic(ctx, mips32_op, rd, rs, rt);
16021                 break;
16022                 /* Set less than */
16023             case SLT:
16024                 mips32_op = OPC_SLT;
16025                 goto do_slt;
16026             case SLTU:
16027                 mips32_op = OPC_SLTU;
16028             do_slt:
16029                 gen_slt(ctx, mips32_op, rd, rs, rt);
16030                 break;
16031             default:
16032                 goto pool32a_invalid;
16033             }
16034             break;
16035         case 0x18:
16036             minor = (ctx->opcode >> 6) & 0xf;
16037             switch (minor) {
16038                 /* Conditional moves */
16039             case MOVN: /* MUL */
16040                 if (ctx->insn_flags & ISA_MIPS32R6) {
16041                     /* MUL */
16042                     gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
16043                 } else {
16044                     /* MOVN */
16045                     gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
16046                 }
16047                 break;
16048             case MOVZ: /* MUH */
16049                 if (ctx->insn_flags & ISA_MIPS32R6) {
16050                     /* MUH */
16051                     gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
16052                 } else {
16053                     /* MOVZ */
16054                     gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
16055                 }
16056                 break;
16057             case MULU:
16058                 check_insn(ctx, ISA_MIPS32R6);
16059                 gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
16060                 break;
16061             case MUHU:
16062                 check_insn(ctx, ISA_MIPS32R6);
16063                 gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
16064                 break;
16065             case LWXS: /* DIV */
16066                 if (ctx->insn_flags & ISA_MIPS32R6) {
16067                     /* DIV */
16068                     gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
16069                 } else {
16070                     /* LWXS */
16071                     gen_ldxs(ctx, rs, rt, rd);
16072                 }
16073                 break;
16074             case MOD:
16075                 check_insn(ctx, ISA_MIPS32R6);
16076                 gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
16077                 break;
16078             case R6_DIVU:
16079                 check_insn(ctx, ISA_MIPS32R6);
16080                 gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
16081                 break;
16082             case MODU:
16083                 check_insn(ctx, ISA_MIPS32R6);
16084                 gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
16085                 break;
16086             default:
16087                 goto pool32a_invalid;
16088             }
16089             break;
16090         case INS:
16091             gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
16092             return;
16093         case LSA:
16094             check_insn(ctx, ISA_MIPS32R6);
16095             gen_lsa(ctx, OPC_LSA, rd, rs, rt,
16096                     extract32(ctx->opcode, 9, 2));
16097             break;
16098         case ALIGN:
16099             check_insn(ctx, ISA_MIPS32R6);
16100             gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
16101             break;
16102         case EXT:
16103             gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
16104             return;
16105         case POOL32AXF:
16106             gen_pool32axf(env, ctx, rt, rs);
16107             break;
16108         case BREAK32:
16109             generate_exception_end(ctx, EXCP_BREAK);
16110             break;
16111         case SIGRIE:
16112             check_insn(ctx, ISA_MIPS32R6);
16113             generate_exception_end(ctx, EXCP_RI);
16114             break;
16115         default:
16116         pool32a_invalid:
16117                 MIPS_INVAL("pool32a");
16118                 generate_exception_end(ctx, EXCP_RI);
16119                 break;
16120         }
16121         break;
16122     case POOL32B:
16123         minor = (ctx->opcode >> 12) & 0xf;
16124         switch (minor) {
16125         case CACHE:
16126             check_cp0_enabled(ctx);
16127             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16128                 gen_cache_operation(ctx, rt, rs, imm);
16129             }
16130             break;
16131         case LWC2:
16132         case SWC2:
16133             /* COP2: Not implemented. */
16134             generate_exception_err(ctx, EXCP_CpU, 2);
16135             break;
16136 #ifdef TARGET_MIPS64
16137         case LDP:
16138         case SDP:
16139             check_insn(ctx, ISA_MIPS3);
16140             check_mips_64(ctx);
16141 #endif
16142             /* fall through */
16143         case LWP:
16144         case SWP:
16145             gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16146             break;
16147 #ifdef TARGET_MIPS64
16148         case LDM:
16149         case SDM:
16150             check_insn(ctx, ISA_MIPS3);
16151             check_mips_64(ctx);
16152 #endif
16153             /* fall through */
16154         case LWM32:
16155         case SWM32:
16156             gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
16157             break;
16158         default:
16159             MIPS_INVAL("pool32b");
16160             generate_exception_end(ctx, EXCP_RI);
16161             break;
16162         }
16163         break;
16164     case POOL32F:
16165         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
16166             minor = ctx->opcode & 0x3f;
16167             check_cp1_enabled(ctx);
16168             switch (minor) {
16169             case ALNV_PS:
16170                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16171                 mips32_op = OPC_ALNV_PS;
16172                 goto do_madd;
16173             case MADD_S:
16174                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16175                 mips32_op = OPC_MADD_S;
16176                 goto do_madd;
16177             case MADD_D:
16178                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16179                 mips32_op = OPC_MADD_D;
16180                 goto do_madd;
16181             case MADD_PS:
16182                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16183                 mips32_op = OPC_MADD_PS;
16184                 goto do_madd;
16185             case MSUB_S:
16186                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16187                 mips32_op = OPC_MSUB_S;
16188                 goto do_madd;
16189             case MSUB_D:
16190                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16191                 mips32_op = OPC_MSUB_D;
16192                 goto do_madd;
16193             case MSUB_PS:
16194                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16195                 mips32_op = OPC_MSUB_PS;
16196                 goto do_madd;
16197             case NMADD_S:
16198                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16199                 mips32_op = OPC_NMADD_S;
16200                 goto do_madd;
16201             case NMADD_D:
16202                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16203                 mips32_op = OPC_NMADD_D;
16204                 goto do_madd;
16205             case NMADD_PS:
16206                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16207                 mips32_op = OPC_NMADD_PS;
16208                 goto do_madd;
16209             case NMSUB_S:
16210                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16211                 mips32_op = OPC_NMSUB_S;
16212                 goto do_madd;
16213             case NMSUB_D:
16214                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16215                 mips32_op = OPC_NMSUB_D;
16216                 goto do_madd;
16217             case NMSUB_PS:
16218                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16219                 mips32_op = OPC_NMSUB_PS;
16220             do_madd:
16221                 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
16222                 break;
16223             case CABS_COND_FMT:
16224                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16225                 cond = (ctx->opcode >> 6) & 0xf;
16226                 cc = (ctx->opcode >> 13) & 0x7;
16227                 fmt = (ctx->opcode >> 10) & 0x3;
16228                 switch (fmt) {
16229                 case 0x0:
16230                     gen_cmpabs_s(ctx, cond, rt, rs, cc);
16231                     break;
16232                 case 0x1:
16233                     gen_cmpabs_d(ctx, cond, rt, rs, cc);
16234                     break;
16235                 case 0x2:
16236                     gen_cmpabs_ps(ctx, cond, rt, rs, cc);
16237                     break;
16238                 default:
16239                     goto pool32f_invalid;
16240                 }
16241                 break;
16242             case C_COND_FMT:
16243                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16244                 cond = (ctx->opcode >> 6) & 0xf;
16245                 cc = (ctx->opcode >> 13) & 0x7;
16246                 fmt = (ctx->opcode >> 10) & 0x3;
16247                 switch (fmt) {
16248                 case 0x0:
16249                     gen_cmp_s(ctx, cond, rt, rs, cc);
16250                     break;
16251                 case 0x1:
16252                     gen_cmp_d(ctx, cond, rt, rs, cc);
16253                     break;
16254                 case 0x2:
16255                     gen_cmp_ps(ctx, cond, rt, rs, cc);
16256                     break;
16257                 default:
16258                     goto pool32f_invalid;
16259                 }
16260                 break;
16261             case CMP_CONDN_S:
16262                 check_insn(ctx, ISA_MIPS32R6);
16263                 gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16264                 break;
16265             case CMP_CONDN_D:
16266                 check_insn(ctx, ISA_MIPS32R6);
16267                 gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
16268                 break;
16269             case POOL32FXF:
16270                 gen_pool32fxf(ctx, rt, rs);
16271                 break;
16272             case 0x00:
16273                 /* PLL foo */
16274                 switch ((ctx->opcode >> 6) & 0x7) {
16275                 case PLL_PS:
16276                     mips32_op = OPC_PLL_PS;
16277                     goto do_ps;
16278                 case PLU_PS:
16279                     mips32_op = OPC_PLU_PS;
16280                     goto do_ps;
16281                 case PUL_PS:
16282                     mips32_op = OPC_PUL_PS;
16283                     goto do_ps;
16284                 case PUU_PS:
16285                     mips32_op = OPC_PUU_PS;
16286                     goto do_ps;
16287                 case CVT_PS_S:
16288                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16289                     mips32_op = OPC_CVT_PS_S;
16290                 do_ps:
16291                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16292                     break;
16293                 default:
16294                     goto pool32f_invalid;
16295                 }
16296                 break;
16297             case MIN_FMT:
16298                 check_insn(ctx, ISA_MIPS32R6);
16299                 switch ((ctx->opcode >> 9) & 0x3) {
16300                 case FMT_SDPS_S:
16301                     gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
16302                     break;
16303                 case FMT_SDPS_D:
16304                     gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
16305                     break;
16306                 default:
16307                     goto pool32f_invalid;
16308                 }
16309                 break;
16310             case 0x08:
16311                 /* [LS][WDU]XC1 */
16312                 switch ((ctx->opcode >> 6) & 0x7) {
16313                 case LWXC1:
16314                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16315                     mips32_op = OPC_LWXC1;
16316                     goto do_ldst_cp1;
16317                 case SWXC1:
16318                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16319                     mips32_op = OPC_SWXC1;
16320                     goto do_ldst_cp1;
16321                 case LDXC1:
16322                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16323                     mips32_op = OPC_LDXC1;
16324                     goto do_ldst_cp1;
16325                 case SDXC1:
16326                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16327                     mips32_op = OPC_SDXC1;
16328                     goto do_ldst_cp1;
16329                 case LUXC1:
16330                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16331                     mips32_op = OPC_LUXC1;
16332                     goto do_ldst_cp1;
16333                 case SUXC1:
16334                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16335                     mips32_op = OPC_SUXC1;
16336                 do_ldst_cp1:
16337                     gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
16338                     break;
16339                 default:
16340                     goto pool32f_invalid;
16341                 }
16342                 break;
16343             case MAX_FMT:
16344                 check_insn(ctx, ISA_MIPS32R6);
16345                 switch ((ctx->opcode >> 9) & 0x3) {
16346                 case FMT_SDPS_S:
16347                     gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
16348                     break;
16349                 case FMT_SDPS_D:
16350                     gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
16351                     break;
16352                 default:
16353                     goto pool32f_invalid;
16354                 }
16355                 break;
16356             case 0x18:
16357                 /* 3D insns */
16358                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16359                 fmt = (ctx->opcode >> 9) & 0x3;
16360                 switch ((ctx->opcode >> 6) & 0x7) {
16361                 case RSQRT2_FMT:
16362                     switch (fmt) {
16363                     case FMT_SDPS_S:
16364                         mips32_op = OPC_RSQRT2_S;
16365                         goto do_3d;
16366                     case FMT_SDPS_D:
16367                         mips32_op = OPC_RSQRT2_D;
16368                         goto do_3d;
16369                     case FMT_SDPS_PS:
16370                         mips32_op = OPC_RSQRT2_PS;
16371                         goto do_3d;
16372                     default:
16373                         goto pool32f_invalid;
16374                     }
16375                     break;
16376                 case RECIP2_FMT:
16377                     switch (fmt) {
16378                     case FMT_SDPS_S:
16379                         mips32_op = OPC_RECIP2_S;
16380                         goto do_3d;
16381                     case FMT_SDPS_D:
16382                         mips32_op = OPC_RECIP2_D;
16383                         goto do_3d;
16384                     case FMT_SDPS_PS:
16385                         mips32_op = OPC_RECIP2_PS;
16386                         goto do_3d;
16387                     default:
16388                         goto pool32f_invalid;
16389                     }
16390                     break;
16391                 case ADDR_PS:
16392                     mips32_op = OPC_ADDR_PS;
16393                     goto do_3d;
16394                 case MULR_PS:
16395                     mips32_op = OPC_MULR_PS;
16396                 do_3d:
16397                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16398                     break;
16399                 default:
16400                     goto pool32f_invalid;
16401                 }
16402                 break;
16403             case 0x20:
16404                 /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
16405                 cc = (ctx->opcode >> 13) & 0x7;
16406                 fmt = (ctx->opcode >> 9) & 0x3;
16407                 switch ((ctx->opcode >> 6) & 0x7) {
16408                 case MOVF_FMT: /* RINT_FMT */
16409                     if (ctx->insn_flags & ISA_MIPS32R6) {
16410                         /* RINT_FMT */
16411                         switch (fmt) {
16412                         case FMT_SDPS_S:
16413                             gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
16414                             break;
16415                         case FMT_SDPS_D:
16416                             gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
16417                             break;
16418                         default:
16419                             goto pool32f_invalid;
16420                         }
16421                     } else {
16422                         /* MOVF_FMT */
16423                         switch (fmt) {
16424                         case FMT_SDPS_S:
16425                             gen_movcf_s(ctx, rs, rt, cc, 0);
16426                             break;
16427                         case FMT_SDPS_D:
16428                             gen_movcf_d(ctx, rs, rt, cc, 0);
16429                             break;
16430                         case FMT_SDPS_PS:
16431                             check_ps(ctx);
16432                             gen_movcf_ps(ctx, rs, rt, cc, 0);
16433                             break;
16434                         default:
16435                             goto pool32f_invalid;
16436                         }
16437                     }
16438                     break;
16439                 case MOVT_FMT: /* CLASS_FMT */
16440                     if (ctx->insn_flags & ISA_MIPS32R6) {
16441                         /* CLASS_FMT */
16442                         switch (fmt) {
16443                         case FMT_SDPS_S:
16444                             gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
16445                             break;
16446                         case FMT_SDPS_D:
16447                             gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
16448                             break;
16449                         default:
16450                             goto pool32f_invalid;
16451                         }
16452                     } else {
16453                         /* MOVT_FMT */
16454                         switch (fmt) {
16455                         case FMT_SDPS_S:
16456                             gen_movcf_s(ctx, rs, rt, cc, 1);
16457                             break;
16458                         case FMT_SDPS_D:
16459                             gen_movcf_d(ctx, rs, rt, cc, 1);
16460                             break;
16461                         case FMT_SDPS_PS:
16462                             check_ps(ctx);
16463                             gen_movcf_ps(ctx, rs, rt, cc, 1);
16464                             break;
16465                         default:
16466                             goto pool32f_invalid;
16467                         }
16468                     }
16469                     break;
16470                 case PREFX:
16471                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16472                     break;
16473                 default:
16474                     goto pool32f_invalid;
16475                 }
16476                 break;
16477 #define FINSN_3ARG_SDPS(prfx)                           \
16478                 switch ((ctx->opcode >> 8) & 0x3) {     \
16479                 case FMT_SDPS_S:                        \
16480                     mips32_op = OPC_##prfx##_S;         \
16481                     goto do_fpop;                       \
16482                 case FMT_SDPS_D:                        \
16483                     mips32_op = OPC_##prfx##_D;         \
16484                     goto do_fpop;                       \
16485                 case FMT_SDPS_PS:                       \
16486                     check_ps(ctx);                      \
16487                     mips32_op = OPC_##prfx##_PS;        \
16488                     goto do_fpop;                       \
16489                 default:                                \
16490                     goto pool32f_invalid;               \
16491                 }
16492             case MINA_FMT:
16493                 check_insn(ctx, ISA_MIPS32R6);
16494                 switch ((ctx->opcode >> 9) & 0x3) {
16495                 case FMT_SDPS_S:
16496                     gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
16497                     break;
16498                 case FMT_SDPS_D:
16499                     gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
16500                     break;
16501                 default:
16502                     goto pool32f_invalid;
16503                 }
16504                 break;
16505             case MAXA_FMT:
16506                 check_insn(ctx, ISA_MIPS32R6);
16507                 switch ((ctx->opcode >> 9) & 0x3) {
16508                 case FMT_SDPS_S:
16509                     gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
16510                     break;
16511                 case FMT_SDPS_D:
16512                     gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
16513                     break;
16514                 default:
16515                     goto pool32f_invalid;
16516                 }
16517                 break;
16518             case 0x30:
16519                 /* regular FP ops */
16520                 switch ((ctx->opcode >> 6) & 0x3) {
16521                 case ADD_FMT:
16522                     FINSN_3ARG_SDPS(ADD);
16523                     break;
16524                 case SUB_FMT:
16525                     FINSN_3ARG_SDPS(SUB);
16526                     break;
16527                 case MUL_FMT:
16528                     FINSN_3ARG_SDPS(MUL);
16529                     break;
16530                 case DIV_FMT:
16531                     fmt = (ctx->opcode >> 8) & 0x3;
16532                     if (fmt == 1) {
16533                         mips32_op = OPC_DIV_D;
16534                     } else if (fmt == 0) {
16535                         mips32_op = OPC_DIV_S;
16536                     } else {
16537                         goto pool32f_invalid;
16538                     }
16539                     goto do_fpop;
16540                 default:
16541                     goto pool32f_invalid;
16542                 }
16543                 break;
16544             case 0x38:
16545                 /* cmovs */
16546                 switch ((ctx->opcode >> 6) & 0x7) {
16547                 case MOVN_FMT: /* SELEQZ_FMT */
16548                     if (ctx->insn_flags & ISA_MIPS32R6) {
16549                         /* SELEQZ_FMT */
16550                         switch ((ctx->opcode >> 9) & 0x3) {
16551                         case FMT_SDPS_S:
16552                             gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
16553                             break;
16554                         case FMT_SDPS_D:
16555                             gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
16556                             break;
16557                         default:
16558                             goto pool32f_invalid;
16559                         }
16560                     } else {
16561                         /* MOVN_FMT */
16562                         FINSN_3ARG_SDPS(MOVN);
16563                     }
16564                     break;
16565                 case MOVN_FMT_04:
16566                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16567                     FINSN_3ARG_SDPS(MOVN);
16568                     break;
16569                 case MOVZ_FMT: /* SELNEZ_FMT */
16570                     if (ctx->insn_flags & ISA_MIPS32R6) {
16571                         /* SELNEZ_FMT */
16572                         switch ((ctx->opcode >> 9) & 0x3) {
16573                         case FMT_SDPS_S:
16574                             gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
16575                             break;
16576                         case FMT_SDPS_D:
16577                             gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
16578                             break;
16579                         default:
16580                             goto pool32f_invalid;
16581                         }
16582                     } else {
16583                         /* MOVZ_FMT */
16584                         FINSN_3ARG_SDPS(MOVZ);
16585                     }
16586                     break;
16587                 case MOVZ_FMT_05:
16588                     check_insn_opc_removed(ctx, ISA_MIPS32R6);
16589                     FINSN_3ARG_SDPS(MOVZ);
16590                     break;
16591                 case SEL_FMT:
16592                     check_insn(ctx, ISA_MIPS32R6);
16593                     switch ((ctx->opcode >> 9) & 0x3) {
16594                     case FMT_SDPS_S:
16595                         gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
16596                         break;
16597                     case FMT_SDPS_D:
16598                         gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
16599                         break;
16600                     default:
16601                         goto pool32f_invalid;
16602                     }
16603                     break;
16604                 case MADDF_FMT:
16605                     check_insn(ctx, ISA_MIPS32R6);
16606                     switch ((ctx->opcode >> 9) & 0x3) {
16607                     case FMT_SDPS_S:
16608                         mips32_op = OPC_MADDF_S;
16609                         goto do_fpop;
16610                     case FMT_SDPS_D:
16611                         mips32_op = OPC_MADDF_D;
16612                         goto do_fpop;
16613                     default:
16614                         goto pool32f_invalid;
16615                     }
16616                     break;
16617                 case MSUBF_FMT:
16618                     check_insn(ctx, ISA_MIPS32R6);
16619                     switch ((ctx->opcode >> 9) & 0x3) {
16620                     case FMT_SDPS_S:
16621                         mips32_op = OPC_MSUBF_S;
16622                         goto do_fpop;
16623                     case FMT_SDPS_D:
16624                         mips32_op = OPC_MSUBF_D;
16625                         goto do_fpop;
16626                     default:
16627                         goto pool32f_invalid;
16628                     }
16629                     break;
16630                 default:
16631                     goto pool32f_invalid;
16632                 }
16633                 break;
16634             do_fpop:
16635                 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
16636                 break;
16637             default:
16638             pool32f_invalid:
16639                 MIPS_INVAL("pool32f");
16640                 generate_exception_end(ctx, EXCP_RI);
16641                 break;
16642             }
16643         } else {
16644             generate_exception_err(ctx, EXCP_CpU, 1);
16645         }
16646         break;
16647     case POOL32I:
16648         minor = (ctx->opcode >> 21) & 0x1f;
16649         switch (minor) {
16650         case BLTZ:
16651             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16652             gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
16653             break;
16654         case BLTZAL:
16655             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16656             gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
16657             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16658             break;
16659         case BLTZALS:
16660             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16661             gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
16662             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16663             break;
16664         case BGEZ:
16665             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16666             gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
16667             break;
16668         case BGEZAL:
16669             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16670             gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
16671             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16672             break;
16673         case BGEZALS:
16674             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16675             gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16676             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16677             break;
16678         case BLEZ:
16679             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16680             gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16681             break;
16682         case BGTZ:
16683             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16684             gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
16685             break;
16686
16687             /* Traps */
16688         case TLTI: /* BC1EQZC */
16689             if (ctx->insn_flags & ISA_MIPS32R6) {
16690                 /* BC1EQZC */
16691                 check_cp1_enabled(ctx);
16692                 gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16693             } else {
16694                 /* TLTI */
16695                 mips32_op = OPC_TLTI;
16696                 goto do_trapi;
16697             }
16698             break;
16699         case TGEI: /* BC1NEZC */
16700             if (ctx->insn_flags & ISA_MIPS32R6) {
16701                 /* BC1NEZC */
16702                 check_cp1_enabled(ctx);
16703                 gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16704             } else {
16705                 /* TGEI */
16706                 mips32_op = OPC_TGEI;
16707                 goto do_trapi;
16708             }
16709             break;
16710         case TLTIU:
16711             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16712             mips32_op = OPC_TLTIU;
16713             goto do_trapi;
16714         case TGEIU:
16715             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16716             mips32_op = OPC_TGEIU;
16717             goto do_trapi;
16718         case TNEI: /* SYNCI */
16719             if (ctx->insn_flags & ISA_MIPS32R6) {
16720                 /* SYNCI */
16721                 /* Break the TB to be able to sync copied instructions
16722                    immediately */
16723                 ctx->base.is_jmp = DISAS_STOP;
16724             } else {
16725                 /* TNEI */
16726                 mips32_op = OPC_TNEI;
16727                 goto do_trapi;
16728             }
16729             break;
16730         case TEQI:
16731             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16732             mips32_op = OPC_TEQI;
16733         do_trapi:
16734             gen_trap(ctx, mips32_op, rs, -1, imm);
16735             break;
16736
16737         case BNEZC:
16738         case BEQZC:
16739             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16740             gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
16741                                4, rs, 0, imm << 1, 0);
16742             /* Compact branches don't have a delay slot, so just let
16743                the normal delay slot handling take us to the branch
16744                target. */
16745             break;
16746         case LUI:
16747             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16748             gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
16749             break;
16750         case SYNCI:
16751             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16752             /* Break the TB to be able to sync copied instructions
16753                immediately */
16754             ctx->base.is_jmp = DISAS_STOP;
16755             break;
16756         case BC2F:
16757         case BC2T:
16758             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16759             /* COP2: Not implemented. */
16760             generate_exception_err(ctx, EXCP_CpU, 2);
16761             break;
16762         case BC1F:
16763             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16764             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
16765             goto do_cp1branch;
16766         case BC1T:
16767             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16768             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
16769             goto do_cp1branch;
16770         case BC1ANY4F:
16771             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16772             mips32_op = OPC_BC1FANY4;
16773             goto do_cp1mips3d;
16774         case BC1ANY4T:
16775             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16776             mips32_op = OPC_BC1TANY4;
16777         do_cp1mips3d:
16778             check_cop1x(ctx);
16779             check_insn(ctx, ASE_MIPS3D);
16780             /* Fall through */
16781         do_cp1branch:
16782             if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16783                 check_cp1_enabled(ctx);
16784                 gen_compute_branch1(ctx, mips32_op,
16785                                     (ctx->opcode >> 18) & 0x7, imm << 1);
16786             } else {
16787                 generate_exception_err(ctx, EXCP_CpU, 1);
16788             }
16789             break;
16790         case BPOSGE64:
16791         case BPOSGE32:
16792             /* MIPS DSP: not implemented */
16793             /* Fall through */
16794         default:
16795             MIPS_INVAL("pool32i");
16796             generate_exception_end(ctx, EXCP_RI);
16797             break;
16798         }
16799         break;
16800     case POOL32C:
16801         minor = (ctx->opcode >> 12) & 0xf;
16802         offset = sextract32(ctx->opcode, 0,
16803                             (ctx->insn_flags & ISA_MIPS32R6) ? 9 : 12);
16804         switch (minor) {
16805         case LWL:
16806             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16807             mips32_op = OPC_LWL;
16808             goto do_ld_lr;
16809         case SWL:
16810             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16811             mips32_op = OPC_SWL;
16812             goto do_st_lr;
16813         case LWR:
16814             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16815             mips32_op = OPC_LWR;
16816             goto do_ld_lr;
16817         case SWR:
16818             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16819             mips32_op = OPC_SWR;
16820             goto do_st_lr;
16821 #if defined(TARGET_MIPS64)
16822         case LDL:
16823             check_insn(ctx, ISA_MIPS3);
16824             check_mips_64(ctx);
16825             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16826             mips32_op = OPC_LDL;
16827             goto do_ld_lr;
16828         case SDL:
16829             check_insn(ctx, ISA_MIPS3);
16830             check_mips_64(ctx);
16831             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16832             mips32_op = OPC_SDL;
16833             goto do_st_lr;
16834         case LDR:
16835             check_insn(ctx, ISA_MIPS3);
16836             check_mips_64(ctx);
16837             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16838             mips32_op = OPC_LDR;
16839             goto do_ld_lr;
16840         case SDR:
16841             check_insn(ctx, ISA_MIPS3);
16842             check_mips_64(ctx);
16843             check_insn_opc_removed(ctx, ISA_MIPS32R6);
16844             mips32_op = OPC_SDR;
16845             goto do_st_lr;
16846         case LWU:
16847             check_insn(ctx, ISA_MIPS3);
16848             check_mips_64(ctx);
16849             mips32_op = OPC_LWU;
16850             goto do_ld_lr;
16851         case LLD:
16852             check_insn(ctx, ISA_MIPS3);
16853             check_mips_64(ctx);
16854             mips32_op = OPC_LLD;
16855             goto do_ld_lr;
16856 #endif
16857         case LL:
16858             mips32_op = OPC_LL;
16859             goto do_ld_lr;
16860         do_ld_lr:
16861             gen_ld(ctx, mips32_op, rt, rs, offset);
16862             break;
16863         do_st_lr:
16864             gen_st(ctx, mips32_op, rt, rs, offset);
16865             break;
16866         case SC:
16867             gen_st_cond(ctx, OPC_SC, rt, rs, offset);
16868             break;
16869 #if defined(TARGET_MIPS64)
16870         case SCD:
16871             check_insn(ctx, ISA_MIPS3);
16872             check_mips_64(ctx);
16873             gen_st_cond(ctx, OPC_SCD, rt, rs, offset);
16874             break;
16875 #endif
16876         case LD_EVA:
16877             if (!ctx->eva) {
16878                 MIPS_INVAL("pool32c ld-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 LBUE:
16888                 mips32_op = OPC_LBUE;
16889                 goto do_ld_lr;
16890             case LHUE:
16891                 mips32_op = OPC_LHUE;
16892                 goto do_ld_lr;
16893             case LWLE:
16894                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16895                 mips32_op = OPC_LWLE;
16896                 goto do_ld_lr;
16897             case LWRE:
16898                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16899                 mips32_op = OPC_LWRE;
16900                 goto do_ld_lr;
16901             case LBE:
16902                 mips32_op = OPC_LBE;
16903                 goto do_ld_lr;
16904             case LHE:
16905                 mips32_op = OPC_LHE;
16906                 goto do_ld_lr;
16907             case LLE:
16908                 mips32_op = OPC_LLE;
16909                 goto do_ld_lr;
16910             case LWE:
16911                 mips32_op = OPC_LWE;
16912                 goto do_ld_lr;
16913             };
16914             break;
16915         case ST_EVA:
16916             if (!ctx->eva) {
16917                 MIPS_INVAL("pool32c st-eva");
16918                 generate_exception_end(ctx, EXCP_RI);
16919                 break;
16920             }
16921             check_cp0_enabled(ctx);
16922
16923             minor2 = (ctx->opcode >> 9) & 0x7;
16924             offset = sextract32(ctx->opcode, 0, 9);
16925             switch (minor2) {
16926             case SWLE:
16927                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16928                 mips32_op = OPC_SWLE;
16929                 goto do_st_lr;
16930             case SWRE:
16931                 check_insn_opc_removed(ctx, ISA_MIPS32R6);
16932                 mips32_op = OPC_SWRE;
16933                 goto do_st_lr;
16934             case PREFE:
16935                 /* Treat as no-op */
16936                 if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16937                     /* hint codes 24-31 are reserved and signal RI */
16938                     generate_exception(ctx, EXCP_RI);
16939                 }
16940                 break;
16941             case CACHEE:
16942                 /* Treat as no-op */
16943                 if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16944                     gen_cache_operation(ctx, rt, rs, offset);
16945                 }
16946                 break;
16947             case SBE:
16948                 mips32_op = OPC_SBE;
16949                 goto do_st_lr;
16950             case SHE:
16951                 mips32_op = OPC_SHE;
16952                 goto do_st_lr;
16953             case SCE:
16954                 gen_st_cond(ctx, OPC_SCE, rt, rs, offset);
16955                 break;
16956             case SWE:
16957                 mips32_op = OPC_SWE;
16958                 goto do_st_lr;
16959             };
16960             break;
16961         case PREF:
16962             /* Treat as no-op */
16963             if ((ctx->insn_flags & ISA_MIPS32R6) && (rt >= 24)) {
16964                 /* hint codes 24-31 are reserved and signal RI */
16965                 generate_exception(ctx, EXCP_RI);
16966             }
16967             break;
16968         default:
16969             MIPS_INVAL("pool32c");
16970             generate_exception_end(ctx, EXCP_RI);
16971             break;
16972         }
16973         break;
16974     case ADDI32: /* AUI, LUI */
16975         if (ctx->insn_flags & ISA_MIPS32R6) {
16976             /* AUI, LUI */
16977             gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
16978         } else {
16979             /* ADDI32 */
16980             mips32_op = OPC_ADDI;
16981             goto do_addi;
16982         }
16983         break;
16984     case ADDIU32:
16985         mips32_op = OPC_ADDIU;
16986     do_addi:
16987         gen_arith_imm(ctx, mips32_op, rt, rs, imm);
16988         break;
16989
16990         /* Logical operations */
16991     case ORI32:
16992         mips32_op = OPC_ORI;
16993         goto do_logici;
16994     case XORI32:
16995         mips32_op = OPC_XORI;
16996         goto do_logici;
16997     case ANDI32:
16998         mips32_op = OPC_ANDI;
16999     do_logici:
17000         gen_logic_imm(ctx, mips32_op, rt, rs, imm);
17001         break;
17002
17003         /* Set less than immediate */
17004     case SLTI32:
17005         mips32_op = OPC_SLTI;
17006         goto do_slti;
17007     case SLTIU32:
17008         mips32_op = OPC_SLTIU;
17009     do_slti:
17010         gen_slt_imm(ctx, mips32_op, rt, rs, imm);
17011         break;
17012     case JALX32:
17013         check_insn_opc_removed(ctx, ISA_MIPS32R6);
17014         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
17015         gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
17016         ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17017         break;
17018     case JALS32: /* BOVC, BEQC, BEQZALC */
17019         if (ctx->insn_flags & ISA_MIPS32R6) {
17020             if (rs >= rt) {
17021                 /* BOVC */
17022                 mips32_op = OPC_BOVC;
17023             } else if (rs < rt && rs == 0) {
17024                 /* BEQZALC */
17025                 mips32_op = OPC_BEQZALC;
17026             } else {
17027                 /* BEQC */
17028                 mips32_op = OPC_BEQC;
17029             }
17030             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17031         } else {
17032             /* JALS32 */
17033             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
17034             gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
17035             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17036         }
17037         break;
17038     case BEQ32: /* BC */
17039         if (ctx->insn_flags & ISA_MIPS32R6) {
17040             /* BC */
17041             gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
17042                                        sextract32(ctx->opcode << 1, 0, 27));
17043         } else {
17044             /* BEQ32 */
17045             gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
17046         }
17047         break;
17048     case BNE32: /* BALC */
17049         if (ctx->insn_flags & ISA_MIPS32R6) {
17050             /* BALC */
17051             gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
17052                                        sextract32(ctx->opcode << 1, 0, 27));
17053         } else {
17054             /* BNE32 */
17055             gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
17056         }
17057         break;
17058     case J32: /* BGTZC, BLTZC, BLTC */
17059         if (ctx->insn_flags & ISA_MIPS32R6) {
17060             if (rs == 0 && rt != 0) {
17061                 /* BGTZC */
17062                 mips32_op = OPC_BGTZC;
17063             } else if (rs != 0 && rt != 0 && rs == rt) {
17064                 /* BLTZC */
17065                 mips32_op = OPC_BLTZC;
17066             } else {
17067                 /* BLTC */
17068                 mips32_op = OPC_BLTC;
17069             }
17070             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17071         } else {
17072             /* J32 */
17073             gen_compute_branch(ctx, OPC_J, 4, rt, rs,
17074                                (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17075         }
17076         break;
17077     case JAL32: /* BLEZC, BGEZC, BGEC */
17078         if (ctx->insn_flags & ISA_MIPS32R6) {
17079             if (rs == 0 && rt != 0) {
17080                 /* BLEZC */
17081                 mips32_op = OPC_BLEZC;
17082             } else if (rs != 0 && rt != 0 && rs == rt) {
17083                 /* BGEZC */
17084                 mips32_op = OPC_BGEZC;
17085             } else {
17086                 /* BGEC */
17087                 mips32_op = OPC_BGEC;
17088             }
17089             gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17090         } else {
17091             /* JAL32 */
17092             gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
17093                                (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
17094             ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
17095         }
17096         break;
17097         /* Floating point (COP1) */
17098     case LWC132:
17099         mips32_op = OPC_LWC1;
17100         goto do_cop1;
17101     case LDC132:
17102         mips32_op = OPC_LDC1;
17103         goto do_cop1;
17104     case SWC132:
17105         mips32_op = OPC_SWC1;
17106         goto do_cop1;
17107     case SDC132:
17108         mips32_op = OPC_SDC1;
17109     do_cop1:
17110         gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
17111         break;
17112     case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17113         if (ctx->insn_flags & ISA_MIPS32R6) {
17114             /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
17115             switch ((ctx->opcode >> 16) & 0x1f) {
17116             case ADDIUPC_00:
17117             case ADDIUPC_01:
17118             case ADDIUPC_02:
17119             case ADDIUPC_03:
17120             case ADDIUPC_04:
17121             case ADDIUPC_05:
17122             case ADDIUPC_06:
17123             case ADDIUPC_07:
17124                 gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
17125                 break;
17126             case AUIPC:
17127                 gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
17128                 break;
17129             case ALUIPC:
17130                 gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
17131                 break;
17132             case LWPC_08:
17133             case LWPC_09:
17134             case LWPC_0A:
17135             case LWPC_0B:
17136             case LWPC_0C:
17137             case LWPC_0D:
17138             case LWPC_0E:
17139             case LWPC_0F:
17140                 gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
17141                 break;
17142             default:
17143                 generate_exception(ctx, EXCP_RI);
17144                 break;
17145             }
17146         } else {
17147             /* ADDIUPC */
17148             int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
17149             offset = SIMM(ctx->opcode, 0, 23) << 2;
17150
17151             gen_addiupc(ctx, reg, offset, 0, 0);
17152         }
17153         break;
17154     case BNVC: /* BNEC, BNEZALC */
17155         check_insn(ctx, ISA_MIPS32R6);
17156         if (rs >= rt) {
17157             /* BNVC */
17158             mips32_op = OPC_BNVC;
17159         } else if (rs < rt && rs == 0) {
17160             /* BNEZALC */
17161             mips32_op = OPC_BNEZALC;
17162         } else {
17163             /* BNEC */
17164             mips32_op = OPC_BNEC;
17165         }
17166         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17167         break;
17168     case R6_BNEZC: /* JIALC */
17169         check_insn(ctx, ISA_MIPS32R6);
17170         if (rt != 0) {
17171             /* BNEZC */
17172             gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
17173                                        sextract32(ctx->opcode << 1, 0, 22));
17174         } else {
17175             /* JIALC */
17176             gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
17177         }
17178         break;
17179     case R6_BEQZC: /* JIC */
17180         check_insn(ctx, ISA_MIPS32R6);
17181         if (rt != 0) {
17182             /* BEQZC */
17183             gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
17184                                        sextract32(ctx->opcode << 1, 0, 22));
17185         } else {
17186             /* JIC */
17187             gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
17188         }
17189         break;
17190     case BLEZALC: /* BGEZALC, BGEUC */
17191         check_insn(ctx, ISA_MIPS32R6);
17192         if (rs == 0 && rt != 0) {
17193             /* BLEZALC */
17194             mips32_op = OPC_BLEZALC;
17195         } else if (rs != 0 && rt != 0 && rs == rt) {
17196             /* BGEZALC */
17197             mips32_op = OPC_BGEZALC;
17198         } else {
17199             /* BGEUC */
17200             mips32_op = OPC_BGEUC;
17201         }
17202         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17203         break;
17204     case BGTZALC: /* BLTZALC, BLTUC */
17205         check_insn(ctx, ISA_MIPS32R6);
17206         if (rs == 0 && rt != 0) {
17207             /* BGTZALC */
17208             mips32_op = OPC_BGTZALC;
17209         } else if (rs != 0 && rt != 0 && rs == rt) {
17210             /* BLTZALC */
17211             mips32_op = OPC_BLTZALC;
17212         } else {
17213             /* BLTUC */
17214             mips32_op = OPC_BLTUC;
17215         }
17216         gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
17217         break;
17218         /* Loads and stores */
17219     case LB32:
17220         mips32_op = OPC_LB;
17221         goto do_ld;
17222     case LBU32:
17223         mips32_op = OPC_LBU;
17224         goto do_ld;
17225     case LH32:
17226         mips32_op = OPC_LH;
17227         goto do_ld;
17228     case LHU32:
17229         mips32_op = OPC_LHU;
17230         goto do_ld;
17231     case LW32:
17232         mips32_op = OPC_LW;
17233         goto do_ld;
17234 #ifdef TARGET_MIPS64
17235     case LD32:
17236         check_insn(ctx, ISA_MIPS3);
17237         check_mips_64(ctx);
17238         mips32_op = OPC_LD;
17239         goto do_ld;
17240     case SD32:
17241         check_insn(ctx, ISA_MIPS3);
17242         check_mips_64(ctx);
17243         mips32_op = OPC_SD;
17244         goto do_st;
17245 #endif
17246     case SB32:
17247         mips32_op = OPC_SB;
17248         goto do_st;
17249     case SH32:
17250         mips32_op = OPC_SH;
17251         goto do_st;
17252     case SW32:
17253         mips32_op = OPC_SW;
17254         goto do_st;
17255     do_ld:
17256         gen_ld(ctx, mips32_op, rt, rs, imm);
17257         break;
17258     do_st:
17259         gen_st(ctx, mips32_op, rt, rs, imm);
17260         break;
17261     default:
17262         generate_exception_end(ctx, EXCP_RI);
17263         break;
17264     }
17265 }
17266
17267 static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
17268 {
17269     uint32_t op;
17270
17271     /* make sure instructions are on a halfword boundary */
17272     if (ctx->base.pc_next & 0x1) {
17273         env->CP0_BadVAddr = ctx->base.pc_next;
17274         generate_exception_end(ctx, EXCP_AdEL);
17275         return 2;
17276     }
17277
17278     op = (ctx->opcode >> 10) & 0x3f;
17279     /* Enforce properly-sized instructions in a delay slot */
17280     if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
17281         switch (op & 0x7) { /* MSB-3..MSB-5 */
17282         case 0:
17283         /* POOL32A, POOL32B, POOL32I, POOL32C */
17284         case 4:
17285         /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
17286         case 5:
17287         /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
17288         case 6:
17289         /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
17290         case 7:
17291         /* LB32, LH32, LWC132, LDC132, LW32 */
17292             if (ctx->hflags & MIPS_HFLAG_BDS16) {
17293                 generate_exception_end(ctx, EXCP_RI);
17294                 return 2;
17295             }
17296             break;
17297         case 1:
17298         /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
17299         case 2:
17300         /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
17301         case 3:
17302         /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
17303             if (ctx->hflags & MIPS_HFLAG_BDS32) {
17304                 generate_exception_end(ctx, EXCP_RI);
17305                 return 2;
17306             }
17307             break;
17308         }
17309     }
17310
17311     switch (op) {
17312     case POOL16A:
17313         {
17314             int rd = mmreg(uMIPS_RD(ctx->opcode));
17315             int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
17316             int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
17317             uint32_t opc = 0;
17318
17319             switch (ctx->opcode & 0x1) {
17320             case ADDU16:
17321                 opc = OPC_ADDU;
17322                 break;
17323             case SUBU16:
17324                 opc = OPC_SUBU;
17325                 break;
17326             }
17327             if (ctx->insn_flags & ISA_MIPS32R6) {
17328                 /* In the Release 6 the register number location in
17329                  * the instruction encoding has changed.
17330                  */
17331                 gen_arith(ctx, opc, rs1, rd, rs2);
17332             } else {
17333                 gen_arith(ctx, opc, rd, rs1, rs2);
17334             }
17335         }
17336         break;
17337     case POOL16B:
17338         {
17339             int rd = mmreg(uMIPS_RD(ctx->opcode));
17340             int rs = mmreg(uMIPS_RS(ctx->opcode));
17341             int amount = (ctx->opcode >> 1) & 0x7;
17342             uint32_t opc = 0;
17343             amount = amount == 0 ? 8 : amount;
17344
17345             switch (ctx->opcode & 0x1) {
17346             case SLL16:
17347                 opc = OPC_SLL;
17348                 break;
17349             case SRL16:
17350                 opc = OPC_SRL;
17351                 break;
17352             }
17353
17354             gen_shift_imm(ctx, opc, rd, rs, amount);
17355         }
17356         break;
17357     case POOL16C:
17358         if (ctx->insn_flags & ISA_MIPS32R6) {
17359             gen_pool16c_r6_insn(ctx);
17360         } else {
17361             gen_pool16c_insn(ctx);
17362         }
17363         break;
17364     case LWGP16:
17365         {
17366             int rd = mmreg(uMIPS_RD(ctx->opcode));
17367             int rb = 28;            /* GP */
17368             int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
17369
17370             gen_ld(ctx, OPC_LW, rd, rb, offset);
17371         }
17372         break;
17373     case POOL16F:
17374         check_insn_opc_removed(ctx, ISA_MIPS32R6);
17375         if (ctx->opcode & 1) {
17376             generate_exception_end(ctx, EXCP_RI);
17377         } else {
17378             /* MOVEP */
17379             int enc_dest = uMIPS_RD(ctx->opcode);
17380             int enc_rt = uMIPS_RS2(ctx->opcode);
17381             int enc_rs = uMIPS_RS1(ctx->opcode);
17382             gen_movep(ctx, enc_dest, enc_rt, enc_rs);
17383         }
17384         break;
17385     case LBU16:
17386         {
17387             int rd = mmreg(uMIPS_RD(ctx->opcode));
17388             int rb = mmreg(uMIPS_RS(ctx->opcode));
17389             int16_t offset = ZIMM(ctx->opcode, 0, 4);
17390             offset = (offset == 0xf ? -1 : offset);
17391
17392             gen_ld(ctx, OPC_LBU, rd, rb, offset);
17393         }
17394         break;
17395     case LHU16:
17396         {
17397             int rd = mmreg(uMIPS_RD(ctx->opcode));
17398             int rb = mmreg(uMIPS_RS(ctx->opcode));
17399             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17400
17401             gen_ld(ctx, OPC_LHU, rd, rb, offset);
17402         }
17403         break;
17404     case LWSP16:
17405         {
17406             int rd = (ctx->opcode >> 5) & 0x1f;
17407             int rb = 29;            /* SP */
17408             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17409
17410             gen_ld(ctx, OPC_LW, rd, rb, offset);
17411         }
17412         break;
17413     case LW16:
17414         {
17415             int rd = mmreg(uMIPS_RD(ctx->opcode));
17416             int rb = mmreg(uMIPS_RS(ctx->opcode));
17417             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17418
17419             gen_ld(ctx, OPC_LW, rd, rb, offset);
17420         }
17421         break;
17422     case SB16:
17423         {
17424             int rd = mmreg2(uMIPS_RD(ctx->opcode));
17425             int rb = mmreg(uMIPS_RS(ctx->opcode));
17426             int16_t offset = ZIMM(ctx->opcode, 0, 4);
17427
17428             gen_st(ctx, OPC_SB, rd, rb, offset);
17429         }
17430         break;
17431     case SH16:
17432         {
17433             int rd = mmreg2(uMIPS_RD(ctx->opcode));
17434             int rb = mmreg(uMIPS_RS(ctx->opcode));
17435             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
17436
17437             gen_st(ctx, OPC_SH, rd, rb, offset);
17438         }
17439         break;
17440     case SWSP16:
17441         {
17442             int rd = (ctx->opcode >> 5) & 0x1f;
17443             int rb = 29;            /* SP */
17444             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
17445
17446             gen_st(ctx, OPC_SW, rd, rb, offset);
17447         }
17448         break;
17449     case SW16:
17450         {
17451             int rd = mmreg2(uMIPS_RD(ctx->opcode));
17452             int rb = mmreg(uMIPS_RS(ctx->opcode));
17453             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
17454
17455             gen_st(ctx, OPC_SW, rd, rb, offset);
17456         }
17457         break;
17458     case MOVE16:
17459         {
17460             int rd = uMIPS_RD5(ctx->opcode);
17461             int rs = uMIPS_RS5(ctx->opcode);
17462
17463             gen_arith(ctx, OPC_ADDU, rd, rs, 0);
17464         }
17465         break;
17466     case ANDI16:
17467         gen_andi16(ctx);
17468         break;
17469     case POOL16D:
17470         switch (ctx->opcode & 0x1) {
17471         case ADDIUS5:
17472             gen_addius5(ctx);
17473             break;
17474         case ADDIUSP:
17475             gen_addiusp(ctx);
17476             break;
17477         }
17478         break;
17479     case POOL16E:
17480         switch (ctx->opcode & 0x1) {
17481         case ADDIUR2:
17482             gen_addiur2(ctx);
17483             break;
17484         case ADDIUR1SP:
17485             gen_addiur1sp(ctx);
17486             break;
17487         }
17488         break;
17489     case B16: /* BC16 */
17490         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
17491                            sextract32(ctx->opcode, 0, 10) << 1,
17492                            (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17493         break;
17494     case BNEZ16: /* BNEZC16 */
17495     case BEQZ16: /* BEQZC16 */
17496         gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
17497                            mmreg(uMIPS_RD(ctx->opcode)),
17498                            0, sextract32(ctx->opcode, 0, 7) << 1,
17499                            (ctx->insn_flags & ISA_MIPS32R6) ? 0 : 4);
17500
17501         break;
17502     case LI16:
17503         {
17504             int reg = mmreg(uMIPS_RD(ctx->opcode));
17505             int imm = ZIMM(ctx->opcode, 0, 7);
17506
17507             imm = (imm == 0x7f ? -1 : imm);
17508             tcg_gen_movi_tl(cpu_gpr[reg], imm);
17509         }
17510         break;
17511     case RES_29:
17512     case RES_31:
17513     case RES_39:
17514         generate_exception_end(ctx, EXCP_RI);
17515         break;
17516     default:
17517         decode_micromips32_opc(env, ctx);
17518         return 4;
17519     }
17520
17521     return 2;
17522 }
17523
17524 /*
17525  *
17526  * nanoMIPS opcodes
17527  *
17528  */
17529
17530 /* MAJOR, P16, and P32 pools opcodes */
17531 enum {
17532     NM_P_ADDIU      = 0x00,
17533     NM_ADDIUPC      = 0x01,
17534     NM_MOVE_BALC    = 0x02,
17535     NM_P16_MV       = 0x04,
17536     NM_LW16         = 0x05,
17537     NM_BC16         = 0x06,
17538     NM_P16_SR       = 0x07,
17539
17540     NM_POOL32A      = 0x08,
17541     NM_P_BAL        = 0x0a,
17542     NM_P16_SHIFT    = 0x0c,
17543     NM_LWSP16       = 0x0d,
17544     NM_BALC16       = 0x0e,
17545     NM_P16_4X4      = 0x0f,
17546
17547     NM_P_GP_W       = 0x10,
17548     NM_P_GP_BH      = 0x11,
17549     NM_P_J          = 0x12,
17550     NM_P16C         = 0x14,
17551     NM_LWGP16       = 0x15,
17552     NM_P16_LB       = 0x17,
17553
17554     NM_P48I         = 0x18,
17555     NM_P16_A1       = 0x1c,
17556     NM_LW4X4        = 0x1d,
17557     NM_P16_LH       = 0x1f,
17558
17559     NM_P_U12        = 0x20,
17560     NM_P_LS_U12     = 0x21,
17561     NM_P_BR1        = 0x22,
17562     NM_P16_A2       = 0x24,
17563     NM_SW16         = 0x25,
17564     NM_BEQZC16      = 0x26,
17565
17566     NM_POOL32F      = 0x28,
17567     NM_P_LS_S9      = 0x29,
17568     NM_P_BR2        = 0x2a,
17569
17570     NM_P16_ADDU     = 0x2c,
17571     NM_SWSP16       = 0x2d,
17572     NM_BNEZC16      = 0x2e,
17573     NM_MOVEP        = 0x2f,
17574
17575     NM_POOL32S      = 0x30,
17576     NM_P_BRI        = 0x32,
17577     NM_LI16         = 0x34,
17578     NM_SWGP16       = 0x35,
17579     NM_P16_BR       = 0x36,
17580
17581     NM_P_LUI        = 0x38,
17582     NM_ANDI16       = 0x3c,
17583     NM_SW4X4        = 0x3d,
17584     NM_MOVEPREV     = 0x3f,
17585 };
17586
17587 /* POOL32A instruction pool */
17588 enum {
17589     NM_POOL32A0    = 0x00,
17590     NM_SPECIAL2    = 0x01,
17591     NM_COP2_1      = 0x02,
17592     NM_UDI         = 0x03,
17593     NM_POOL32A5    = 0x05,
17594     NM_POOL32A7    = 0x07,
17595 };
17596
17597 /* P.GP.W instruction pool */
17598 enum {
17599     NM_ADDIUGP_W = 0x00,
17600     NM_LWGP      = 0x02,
17601     NM_SWGP      = 0x03,
17602 };
17603
17604 /* P48I instruction pool */
17605 enum {
17606     NM_LI48        = 0x00,
17607     NM_ADDIU48     = 0x01,
17608     NM_ADDIUGP48   = 0x02,
17609     NM_ADDIUPC48   = 0x03,
17610     NM_LWPC48      = 0x0b,
17611     NM_SWPC48      = 0x0f,
17612 };
17613
17614 /* P.U12 instruction pool */
17615 enum {
17616     NM_ORI      = 0x00,
17617     NM_XORI     = 0x01,
17618     NM_ANDI     = 0x02,
17619     NM_P_SR     = 0x03,
17620     NM_SLTI     = 0x04,
17621     NM_SLTIU    = 0x05,
17622     NM_SEQI     = 0x06,
17623     NM_ADDIUNEG = 0x08,
17624     NM_P_SHIFT  = 0x0c,
17625     NM_P_ROTX   = 0x0d,
17626     NM_P_INS    = 0x0e,
17627     NM_P_EXT    = 0x0f,
17628 };
17629
17630 /* POOL32F instruction pool */
17631 enum {
17632     NM_POOL32F_0   = 0x00,
17633     NM_POOL32F_3   = 0x03,
17634     NM_POOL32F_5   = 0x05,
17635 };
17636
17637 /* POOL32S instruction pool */
17638 enum {
17639     NM_POOL32S_0   = 0x00,
17640     NM_POOL32S_4   = 0x04,
17641 };
17642
17643 /* P.LUI instruction pool */
17644 enum {
17645     NM_LUI      = 0x00,
17646     NM_ALUIPC   = 0x01,
17647 };
17648
17649 /* P.GP.BH instruction pool */
17650 enum {
17651     NM_LBGP      = 0x00,
17652     NM_SBGP      = 0x01,
17653     NM_LBUGP     = 0x02,
17654     NM_ADDIUGP_B = 0x03,
17655     NM_P_GP_LH   = 0x04,
17656     NM_P_GP_SH   = 0x05,
17657     NM_P_GP_CP1  = 0x06,
17658 };
17659
17660 /* P.LS.U12 instruction pool */
17661 enum {
17662     NM_LB        = 0x00,
17663     NM_SB        = 0x01,
17664     NM_LBU       = 0x02,
17665     NM_P_PREFU12 = 0x03,
17666     NM_LH        = 0x04,
17667     NM_SH        = 0x05,
17668     NM_LHU       = 0x06,
17669     NM_LWU       = 0x07,
17670     NM_LW        = 0x08,
17671     NM_SW        = 0x09,
17672     NM_LWC1      = 0x0a,
17673     NM_SWC1      = 0x0b,
17674     NM_LDC1      = 0x0e,
17675     NM_SDC1      = 0x0f,
17676 };
17677
17678 /* P.LS.S9 instruction pool */
17679 enum {
17680     NM_P_LS_S0         = 0x00,
17681     NM_P_LS_S1         = 0x01,
17682     NM_P_LS_E0         = 0x02,
17683     NM_P_LS_WM         = 0x04,
17684     NM_P_LS_UAWM       = 0x05,
17685 };
17686
17687 /* P.BAL instruction pool */
17688 enum {
17689     NM_BC       = 0x00,
17690     NM_BALC     = 0x01,
17691 };
17692
17693 /* P.J instruction pool */
17694 enum {
17695     NM_JALRC    = 0x00,
17696     NM_JALRC_HB = 0x01,
17697     NM_P_BALRSC = 0x08,
17698 };
17699
17700 /* P.BR1 instruction pool */
17701 enum {
17702     NM_BEQC     = 0x00,
17703     NM_P_BR3A   = 0x01,
17704     NM_BGEC     = 0x02,
17705     NM_BGEUC    = 0x03,
17706 };
17707
17708 /* P.BR2 instruction pool */
17709 enum {
17710     NM_BNEC     = 0x00,
17711     NM_BLTC     = 0x02,
17712     NM_BLTUC    = 0x03,
17713 };
17714
17715 /* P.BRI instruction pool */
17716 enum {
17717     NM_BEQIC    = 0x00,
17718     NM_BBEQZC   = 0x01,
17719     NM_BGEIC    = 0x02,
17720     NM_BGEIUC   = 0x03,
17721     NM_BNEIC    = 0x04,
17722     NM_BBNEZC   = 0x05,
17723     NM_BLTIC    = 0x06,
17724     NM_BLTIUC   = 0x07,
17725 };
17726
17727 /* P16.SHIFT instruction pool */
17728 enum {
17729     NM_SLL16    = 0x00,
17730     NM_SRL16    = 0x01,
17731 };
17732
17733 /* POOL16C instruction pool */
17734 enum {
17735     NM_POOL16C_0  = 0x00,
17736     NM_LWXS16     = 0x01,
17737 };
17738
17739 /* P16.A1 instruction pool */
17740 enum {
17741     NM_ADDIUR1SP = 0x01,
17742 };
17743
17744 /* P16.A2 instruction pool */
17745 enum {
17746     NM_ADDIUR2  = 0x00,
17747     NM_P_ADDIURS5  = 0x01,
17748 };
17749
17750 /* P16.ADDU instruction pool */
17751 enum {
17752     NM_ADDU16     = 0x00,
17753     NM_SUBU16     = 0x01,
17754 };
17755
17756 /* P16.SR instruction pool */
17757 enum {
17758     NM_SAVE16        = 0x00,
17759     NM_RESTORE_JRC16 = 0x01,
17760 };
17761
17762 /* P16.4X4 instruction pool */
17763 enum {
17764     NM_ADDU4X4      = 0x00,
17765     NM_MUL4X4       = 0x01,
17766 };
17767
17768 /* P16.LB instruction pool */
17769 enum {
17770     NM_LB16       = 0x00,
17771     NM_SB16       = 0x01,
17772     NM_LBU16      = 0x02,
17773 };
17774
17775 /* P16.LH  instruction pool */
17776 enum {
17777     NM_LH16     = 0x00,
17778     NM_SH16     = 0x01,
17779     NM_LHU16    = 0x02,
17780 };
17781
17782 /* P.RI instruction pool */
17783 enum {
17784     NM_SIGRIE       = 0x00,
17785     NM_P_SYSCALL    = 0x01,
17786     NM_BREAK        = 0x02,
17787     NM_SDBBP        = 0x03,
17788 };
17789
17790 /* POOL32A0 instruction pool */
17791 enum {
17792     NM_P_TRAP   = 0x00,
17793     NM_SEB      = 0x01,
17794     NM_SLLV     = 0x02,
17795     NM_MUL      = 0x03,
17796     NM_MFC0     = 0x06,
17797     NM_MFHC0    = 0x07,
17798     NM_SEH      = 0x09,
17799     NM_SRLV     = 0x0a,
17800     NM_MUH      = 0x0b,
17801     NM_MTC0     = 0x0e,
17802     NM_MTHC0    = 0x0f,
17803     NM_SRAV     = 0x12,
17804     NM_MULU     = 0x13,
17805     NM_ROTRV    = 0x1a,
17806     NM_MUHU     = 0x1b,
17807     NM_ADD      = 0x22,
17808     NM_DIV      = 0x23,
17809     NM_ADDU     = 0x2a,
17810     NM_MOD      = 0x2b,
17811     NM_SUB      = 0x32,
17812     NM_DIVU     = 0x33,
17813     NM_RDHWR    = 0x38,
17814     NM_SUBU     = 0x3a,
17815     NM_MODU     = 0x3b,
17816     NM_P_CMOVE  = 0x42,
17817     NM_FORK     = 0x45,
17818     NM_MFTR     = 0x46,
17819     NM_MFHTR    = 0x47,
17820     NM_AND      = 0x4a,
17821     NM_YIELD    = 0x4d,
17822     NM_MTTR     = 0x4e,
17823     NM_MTHTR    = 0x4f,
17824     NM_OR       = 0x52,
17825     NM_D_E_MT_VPE = 0x56,
17826     NM_NOR      = 0x5a,
17827     NM_XOR      = 0x62,
17828     NM_SLT      = 0x6a,
17829     NM_P_SLTU   = 0x72,
17830     NM_SOV      = 0x7a,
17831 };
17832
17833 /* CRC32 instruction pool */
17834 enum {
17835     NM_CRC32B   = 0x00,
17836     NM_CRC32H   = 0x01,
17837     NM_CRC32W   = 0x02,
17838     NM_CRC32CB  = 0x04,
17839     NM_CRC32CH  = 0x05,
17840     NM_CRC32CW  = 0x06,
17841 };
17842
17843 /* POOL32A5 instruction pool */
17844 enum {
17845     NM_CMP_EQ_PH        = 0x00,
17846     NM_CMP_LT_PH        = 0x08,
17847     NM_CMP_LE_PH        = 0x10,
17848     NM_CMPGU_EQ_QB      = 0x18,
17849     NM_CMPGU_LT_QB      = 0x20,
17850     NM_CMPGU_LE_QB      = 0x28,
17851     NM_CMPGDU_EQ_QB     = 0x30,
17852     NM_CMPGDU_LT_QB     = 0x38,
17853     NM_CMPGDU_LE_QB     = 0x40,
17854     NM_CMPU_EQ_QB       = 0x48,
17855     NM_CMPU_LT_QB       = 0x50,
17856     NM_CMPU_LE_QB       = 0x58,
17857     NM_ADDQ_S_W         = 0x60,
17858     NM_SUBQ_S_W         = 0x68,
17859     NM_ADDSC            = 0x70,
17860     NM_ADDWC            = 0x78,
17861
17862     NM_ADDQ_S_PH   = 0x01,
17863     NM_ADDQH_R_PH  = 0x09,
17864     NM_ADDQH_R_W   = 0x11,
17865     NM_ADDU_S_QB   = 0x19,
17866     NM_ADDU_S_PH   = 0x21,
17867     NM_ADDUH_R_QB  = 0x29,
17868     NM_SHRAV_R_PH  = 0x31,
17869     NM_SHRAV_R_QB  = 0x39,
17870     NM_SUBQ_S_PH   = 0x41,
17871     NM_SUBQH_R_PH  = 0x49,
17872     NM_SUBQH_R_W   = 0x51,
17873     NM_SUBU_S_QB   = 0x59,
17874     NM_SUBU_S_PH   = 0x61,
17875     NM_SUBUH_R_QB  = 0x69,
17876     NM_SHLLV_S_PH  = 0x71,
17877     NM_PRECR_SRA_R_PH_W = 0x79,
17878
17879     NM_MULEU_S_PH_QBL   = 0x12,
17880     NM_MULEU_S_PH_QBR   = 0x1a,
17881     NM_MULQ_RS_PH       = 0x22,
17882     NM_MULQ_S_PH        = 0x2a,
17883     NM_MULQ_RS_W        = 0x32,
17884     NM_MULQ_S_W         = 0x3a,
17885     NM_APPEND           = 0x42,
17886     NM_MODSUB           = 0x52,
17887     NM_SHRAV_R_W        = 0x5a,
17888     NM_SHRLV_PH         = 0x62,
17889     NM_SHRLV_QB         = 0x6a,
17890     NM_SHLLV_QB         = 0x72,
17891     NM_SHLLV_S_W        = 0x7a,
17892
17893     NM_SHILO            = 0x03,
17894
17895     NM_MULEQ_S_W_PHL    = 0x04,
17896     NM_MULEQ_S_W_PHR    = 0x0c,
17897
17898     NM_MUL_S_PH         = 0x05,
17899     NM_PRECR_QB_PH      = 0x0d,
17900     NM_PRECRQ_QB_PH     = 0x15,
17901     NM_PRECRQ_PH_W      = 0x1d,
17902     NM_PRECRQ_RS_PH_W   = 0x25,
17903     NM_PRECRQU_S_QB_PH  = 0x2d,
17904     NM_PACKRL_PH        = 0x35,
17905     NM_PICK_QB          = 0x3d,
17906     NM_PICK_PH          = 0x45,
17907
17908     NM_SHRA_R_W         = 0x5e,
17909     NM_SHRA_R_PH        = 0x66,
17910     NM_SHLL_S_PH        = 0x76,
17911     NM_SHLL_S_W         = 0x7e,
17912
17913     NM_REPL_PH          = 0x07
17914 };
17915
17916 /* POOL32A7 instruction pool */
17917 enum {
17918     NM_P_LSX        = 0x00,
17919     NM_LSA          = 0x01,
17920     NM_EXTW         = 0x03,
17921     NM_POOL32AXF    = 0x07,
17922 };
17923
17924 /* P.SR instruction pool */
17925 enum {
17926     NM_PP_SR           = 0x00,
17927     NM_P_SR_F          = 0x01,
17928 };
17929
17930 /* P.SHIFT instruction pool */
17931 enum {
17932     NM_P_SLL        = 0x00,
17933     NM_SRL          = 0x02,
17934     NM_SRA          = 0x04,
17935     NM_ROTR         = 0x06,
17936 };
17937
17938 /* P.ROTX instruction pool */
17939 enum {
17940     NM_ROTX         = 0x00,
17941 };
17942
17943 /* P.INS instruction pool */
17944 enum {
17945     NM_INS          = 0x00,
17946 };
17947
17948 /* P.EXT instruction pool */
17949 enum {
17950     NM_EXT          = 0x00,
17951 };
17952
17953 /* POOL32F_0 (fmt) instruction pool */
17954 enum {
17955     NM_RINT_S              = 0x04,
17956     NM_RINT_D              = 0x44,
17957     NM_ADD_S               = 0x06,
17958     NM_SELEQZ_S            = 0x07,
17959     NM_SELEQZ_D            = 0x47,
17960     NM_CLASS_S             = 0x0c,
17961     NM_CLASS_D             = 0x4c,
17962     NM_SUB_S               = 0x0e,
17963     NM_SELNEZ_S            = 0x0f,
17964     NM_SELNEZ_D            = 0x4f,
17965     NM_MUL_S               = 0x16,
17966     NM_SEL_S               = 0x17,
17967     NM_SEL_D               = 0x57,
17968     NM_DIV_S               = 0x1e,
17969     NM_ADD_D               = 0x26,
17970     NM_SUB_D               = 0x2e,
17971     NM_MUL_D               = 0x36,
17972     NM_MADDF_S             = 0x37,
17973     NM_MADDF_D             = 0x77,
17974     NM_DIV_D               = 0x3e,
17975     NM_MSUBF_S             = 0x3f,
17976     NM_MSUBF_D             = 0x7f,
17977 };
17978
17979 /* POOL32F_3  instruction pool */
17980 enum {
17981     NM_MIN_FMT         = 0x00,
17982     NM_MAX_FMT         = 0x01,
17983     NM_MINA_FMT        = 0x04,
17984     NM_MAXA_FMT        = 0x05,
17985     NM_POOL32FXF       = 0x07,
17986 };
17987
17988 /* POOL32F_5  instruction pool */
17989 enum {
17990     NM_CMP_CONDN_S     = 0x00,
17991     NM_CMP_CONDN_D     = 0x02,
17992 };
17993
17994 /* P.GP.LH instruction pool */
17995 enum {
17996     NM_LHGP    = 0x00,
17997     NM_LHUGP   = 0x01,
17998 };
17999
18000 /* P.GP.SH instruction pool */
18001 enum {
18002     NM_SHGP    = 0x00,
18003 };
18004
18005 /* P.GP.CP1 instruction pool */
18006 enum {
18007     NM_LWC1GP       = 0x00,
18008     NM_SWC1GP       = 0x01,
18009     NM_LDC1GP       = 0x02,
18010     NM_SDC1GP       = 0x03,
18011 };
18012
18013 /* P.LS.S0 instruction pool */
18014 enum {
18015     NM_LBS9     = 0x00,
18016     NM_LHS9     = 0x04,
18017     NM_LWS9     = 0x08,
18018     NM_LDS9     = 0x0c,
18019
18020     NM_SBS9     = 0x01,
18021     NM_SHS9     = 0x05,
18022     NM_SWS9     = 0x09,
18023     NM_SDS9     = 0x0d,
18024
18025     NM_LBUS9    = 0x02,
18026     NM_LHUS9    = 0x06,
18027     NM_LWC1S9   = 0x0a,
18028     NM_LDC1S9   = 0x0e,
18029
18030     NM_P_PREFS9 = 0x03,
18031     NM_LWUS9    = 0x07,
18032     NM_SWC1S9   = 0x0b,
18033     NM_SDC1S9   = 0x0f,
18034 };
18035
18036 /* P.LS.S1 instruction pool */
18037 enum {
18038     NM_ASET_ACLR = 0x02,
18039     NM_UALH      = 0x04,
18040     NM_UASH      = 0x05,
18041     NM_CACHE     = 0x07,
18042     NM_P_LL      = 0x0a,
18043     NM_P_SC      = 0x0b,
18044 };
18045
18046 /* P.LS.E0 instruction pool */
18047 enum {
18048     NM_LBE      = 0x00,
18049     NM_SBE      = 0x01,
18050     NM_LBUE     = 0x02,
18051     NM_P_PREFE  = 0x03,
18052     NM_LHE      = 0x04,
18053     NM_SHE      = 0x05,
18054     NM_LHUE     = 0x06,
18055     NM_CACHEE   = 0x07,
18056     NM_LWE      = 0x08,
18057     NM_SWE      = 0x09,
18058     NM_P_LLE    = 0x0a,
18059     NM_P_SCE    = 0x0b,
18060 };
18061
18062 /* P.PREFE instruction pool */
18063 enum {
18064     NM_SYNCIE   = 0x00,
18065     NM_PREFE    = 0x01,
18066 };
18067
18068 /* P.LLE instruction pool */
18069 enum {
18070     NM_LLE      = 0x00,
18071     NM_LLWPE    = 0x01,
18072 };
18073
18074 /* P.SCE instruction pool */
18075 enum {
18076     NM_SCE      = 0x00,
18077     NM_SCWPE    = 0x01,
18078 };
18079
18080 /* P.LS.WM instruction pool */
18081 enum {
18082     NM_LWM       = 0x00,
18083     NM_SWM       = 0x01,
18084 };
18085
18086 /* P.LS.UAWM instruction pool */
18087 enum {
18088     NM_UALWM       = 0x00,
18089     NM_UASWM       = 0x01,
18090 };
18091
18092 /* P.BR3A instruction pool */
18093 enum {
18094     NM_BC1EQZC          = 0x00,
18095     NM_BC1NEZC          = 0x01,
18096     NM_BC2EQZC          = 0x02,
18097     NM_BC2NEZC          = 0x03,
18098     NM_BPOSGE32C        = 0x04,
18099 };
18100
18101 /* P16.RI instruction pool */
18102 enum {
18103     NM_P16_SYSCALL  = 0x01,
18104     NM_BREAK16      = 0x02,
18105     NM_SDBBP16      = 0x03,
18106 };
18107
18108 /* POOL16C_0 instruction pool */
18109 enum {
18110     NM_POOL16C_00      = 0x00,
18111 };
18112
18113 /* P16.JRC instruction pool */
18114 enum {
18115     NM_JRC          = 0x00,
18116     NM_JALRC16      = 0x01,
18117 };
18118
18119 /* P.SYSCALL instruction pool */
18120 enum {
18121     NM_SYSCALL      = 0x00,
18122     NM_HYPCALL      = 0x01,
18123 };
18124
18125 /* P.TRAP instruction pool */
18126 enum {
18127     NM_TEQ          = 0x00,
18128     NM_TNE          = 0x01,
18129 };
18130
18131 /* P.CMOVE instruction pool */
18132 enum {
18133     NM_MOVZ            = 0x00,
18134     NM_MOVN            = 0x01,
18135 };
18136
18137 /* POOL32Axf instruction pool */
18138 enum {
18139     NM_POOL32AXF_1 = 0x01,
18140     NM_POOL32AXF_2 = 0x02,
18141     NM_POOL32AXF_4 = 0x04,
18142     NM_POOL32AXF_5 = 0x05,
18143     NM_POOL32AXF_7 = 0x07,
18144 };
18145
18146 /* POOL32Axf_1 instruction pool */
18147 enum {
18148     NM_POOL32AXF_1_0 = 0x00,
18149     NM_POOL32AXF_1_1 = 0x01,
18150     NM_POOL32AXF_1_3 = 0x03,
18151     NM_POOL32AXF_1_4 = 0x04,
18152     NM_POOL32AXF_1_5 = 0x05,
18153     NM_POOL32AXF_1_7 = 0x07,
18154 };
18155
18156 /* POOL32Axf_2 instruction pool */
18157 enum {
18158     NM_POOL32AXF_2_0_7     = 0x00,
18159     NM_POOL32AXF_2_8_15    = 0x01,
18160     NM_POOL32AXF_2_16_23   = 0x02,
18161     NM_POOL32AXF_2_24_31   = 0x03,
18162 };
18163
18164 /* POOL32Axf_7 instruction pool */
18165 enum {
18166     NM_SHRA_R_QB    = 0x0,
18167     NM_SHRL_PH      = 0x1,
18168     NM_REPL_QB      = 0x2,
18169 };
18170
18171 /* POOL32Axf_1_0 instruction pool */
18172 enum {
18173     NM_MFHI = 0x0,
18174     NM_MFLO = 0x1,
18175     NM_MTHI = 0x2,
18176     NM_MTLO = 0x3,
18177 };
18178
18179 /* POOL32Axf_1_1 instruction pool */
18180 enum {
18181     NM_MTHLIP = 0x0,
18182     NM_SHILOV = 0x1,
18183 };
18184
18185 /* POOL32Axf_1_3 instruction pool */
18186 enum {
18187     NM_RDDSP    = 0x0,
18188     NM_WRDSP    = 0x1,
18189     NM_EXTP     = 0x2,
18190     NM_EXTPDP   = 0x3,
18191 };
18192
18193 /* POOL32Axf_1_4 instruction pool */
18194 enum {
18195     NM_SHLL_QB  = 0x0,
18196     NM_SHRL_QB  = 0x1,
18197 };
18198
18199 /* POOL32Axf_1_5 instruction pool */
18200 enum {
18201     NM_MAQ_S_W_PHR   = 0x0,
18202     NM_MAQ_S_W_PHL   = 0x1,
18203     NM_MAQ_SA_W_PHR  = 0x2,
18204     NM_MAQ_SA_W_PHL  = 0x3,
18205 };
18206
18207 /* POOL32Axf_1_7 instruction pool */
18208 enum {
18209     NM_EXTR_W       = 0x0,
18210     NM_EXTR_R_W     = 0x1,
18211     NM_EXTR_RS_W    = 0x2,
18212     NM_EXTR_S_H     = 0x3,
18213 };
18214
18215 /* POOL32Axf_2_0_7 instruction pool */
18216 enum {
18217     NM_DPA_W_PH     = 0x0,
18218     NM_DPAQ_S_W_PH  = 0x1,
18219     NM_DPS_W_PH     = 0x2,
18220     NM_DPSQ_S_W_PH  = 0x3,
18221     NM_BALIGN       = 0x4,
18222     NM_MADD         = 0x5,
18223     NM_MULT         = 0x6,
18224     NM_EXTRV_W      = 0x7,
18225 };
18226
18227 /* POOL32Axf_2_8_15 instruction pool */
18228 enum {
18229     NM_DPAX_W_PH    = 0x0,
18230     NM_DPAQ_SA_L_W  = 0x1,
18231     NM_DPSX_W_PH    = 0x2,
18232     NM_DPSQ_SA_L_W  = 0x3,
18233     NM_MADDU        = 0x5,
18234     NM_MULTU        = 0x6,
18235     NM_EXTRV_R_W    = 0x7,
18236 };
18237
18238 /* POOL32Axf_2_16_23 instruction pool */
18239 enum {
18240     NM_DPAU_H_QBL       = 0x0,
18241     NM_DPAQX_S_W_PH     = 0x1,
18242     NM_DPSU_H_QBL       = 0x2,
18243     NM_DPSQX_S_W_PH     = 0x3,
18244     NM_EXTPV            = 0x4,
18245     NM_MSUB             = 0x5,
18246     NM_MULSA_W_PH       = 0x6,
18247     NM_EXTRV_RS_W       = 0x7,
18248 };
18249
18250 /* POOL32Axf_2_24_31 instruction pool */
18251 enum {
18252     NM_DPAU_H_QBR       = 0x0,
18253     NM_DPAQX_SA_W_PH    = 0x1,
18254     NM_DPSU_H_QBR       = 0x2,
18255     NM_DPSQX_SA_W_PH    = 0x3,
18256     NM_EXTPDPV          = 0x4,
18257     NM_MSUBU            = 0x5,
18258     NM_MULSAQ_S_W_PH    = 0x6,
18259     NM_EXTRV_S_H        = 0x7,
18260 };
18261
18262 /* POOL32Axf_{4, 5} instruction pool */
18263 enum {
18264     NM_CLO      = 0x25,
18265     NM_CLZ      = 0x2d,
18266
18267     NM_TLBP     = 0x01,
18268     NM_TLBR     = 0x09,
18269     NM_TLBWI    = 0x11,
18270     NM_TLBWR    = 0x19,
18271     NM_TLBINV   = 0x03,
18272     NM_TLBINVF  = 0x0b,
18273     NM_DI       = 0x23,
18274     NM_EI       = 0x2b,
18275     NM_RDPGPR   = 0x70,
18276     NM_WRPGPR   = 0x78,
18277     NM_WAIT     = 0x61,
18278     NM_DERET    = 0x71,
18279     NM_ERETX    = 0x79,
18280
18281     /* nanoMIPS DSP instructions */
18282     NM_ABSQ_S_QB        = 0x00,
18283     NM_ABSQ_S_PH        = 0x08,
18284     NM_ABSQ_S_W         = 0x10,
18285     NM_PRECEQ_W_PHL     = 0x28,
18286     NM_PRECEQ_W_PHR     = 0x30,
18287     NM_PRECEQU_PH_QBL   = 0x38,
18288     NM_PRECEQU_PH_QBR   = 0x48,
18289     NM_PRECEU_PH_QBL    = 0x58,
18290     NM_PRECEU_PH_QBR    = 0x68,
18291     NM_PRECEQU_PH_QBLA  = 0x39,
18292     NM_PRECEQU_PH_QBRA  = 0x49,
18293     NM_PRECEU_PH_QBLA   = 0x59,
18294     NM_PRECEU_PH_QBRA   = 0x69,
18295     NM_REPLV_PH         = 0x01,
18296     NM_REPLV_QB         = 0x09,
18297     NM_BITREV           = 0x18,
18298     NM_INSV             = 0x20,
18299     NM_RADDU_W_QB       = 0x78,
18300
18301     NM_BITSWAP          = 0x05,
18302     NM_WSBH             = 0x3d,
18303 };
18304
18305 /* PP.SR instruction pool */
18306 enum {
18307     NM_SAVE         = 0x00,
18308     NM_RESTORE      = 0x02,
18309     NM_RESTORE_JRC  = 0x03,
18310 };
18311
18312 /* P.SR.F instruction pool */
18313 enum {
18314     NM_SAVEF        = 0x00,
18315     NM_RESTOREF     = 0x01,
18316 };
18317
18318 /* P16.SYSCALL  instruction pool */
18319 enum {
18320     NM_SYSCALL16     = 0x00,
18321     NM_HYPCALL16     = 0x01,
18322 };
18323
18324 /* POOL16C_00 instruction pool */
18325 enum {
18326     NM_NOT16           = 0x00,
18327     NM_XOR16           = 0x01,
18328     NM_AND16           = 0x02,
18329     NM_OR16            = 0x03,
18330 };
18331
18332 /* PP.LSX and PP.LSXS instruction pool */
18333 enum {
18334     NM_LBX      = 0x00,
18335     NM_LHX      = 0x04,
18336     NM_LWX      = 0x08,
18337     NM_LDX      = 0x0c,
18338
18339     NM_SBX      = 0x01,
18340     NM_SHX      = 0x05,
18341     NM_SWX      = 0x09,
18342     NM_SDX      = 0x0d,
18343
18344     NM_LBUX     = 0x02,
18345     NM_LHUX     = 0x06,
18346     NM_LWC1X    = 0x0a,
18347     NM_LDC1X    = 0x0e,
18348
18349     NM_LWUX     = 0x07,
18350     NM_SWC1X    = 0x0b,
18351     NM_SDC1X    = 0x0f,
18352
18353     NM_LHXS     = 0x04,
18354     NM_LWXS     = 0x08,
18355     NM_LDXS     = 0x0c,
18356
18357     NM_SHXS     = 0x05,
18358     NM_SWXS     = 0x09,
18359     NM_SDXS     = 0x0d,
18360
18361     NM_LHUXS    = 0x06,
18362     NM_LWC1XS   = 0x0a,
18363     NM_LDC1XS   = 0x0e,
18364
18365     NM_LWUXS    = 0x07,
18366     NM_SWC1XS   = 0x0b,
18367     NM_SDC1XS   = 0x0f,
18368 };
18369
18370 /* ERETx instruction pool */
18371 enum {
18372     NM_ERET     = 0x00,
18373     NM_ERETNC   = 0x01,
18374 };
18375
18376 /* POOL32FxF_{0, 1} insturction pool */
18377 enum {
18378     NM_CFC1     = 0x40,
18379     NM_CTC1     = 0x60,
18380     NM_MFC1     = 0x80,
18381     NM_MTC1     = 0xa0,
18382     NM_MFHC1    = 0xc0,
18383     NM_MTHC1    = 0xe0,
18384
18385     NM_CVT_S_PL = 0x84,
18386     NM_CVT_S_PU = 0xa4,
18387
18388     NM_CVT_L_S     = 0x004,
18389     NM_CVT_L_D     = 0x104,
18390     NM_CVT_W_S     = 0x024,
18391     NM_CVT_W_D     = 0x124,
18392
18393     NM_RSQRT_S     = 0x008,
18394     NM_RSQRT_D     = 0x108,
18395
18396     NM_SQRT_S      = 0x028,
18397     NM_SQRT_D      = 0x128,
18398
18399     NM_RECIP_S     = 0x048,
18400     NM_RECIP_D     = 0x148,
18401
18402     NM_FLOOR_L_S   = 0x00c,
18403     NM_FLOOR_L_D   = 0x10c,
18404
18405     NM_FLOOR_W_S   = 0x02c,
18406     NM_FLOOR_W_D   = 0x12c,
18407
18408     NM_CEIL_L_S    = 0x04c,
18409     NM_CEIL_L_D    = 0x14c,
18410     NM_CEIL_W_S    = 0x06c,
18411     NM_CEIL_W_D    = 0x16c,
18412     NM_TRUNC_L_S   = 0x08c,
18413     NM_TRUNC_L_D   = 0x18c,
18414     NM_TRUNC_W_S   = 0x0ac,
18415     NM_TRUNC_W_D   = 0x1ac,
18416     NM_ROUND_L_S   = 0x0cc,
18417     NM_ROUND_L_D   = 0x1cc,
18418     NM_ROUND_W_S   = 0x0ec,
18419     NM_ROUND_W_D   = 0x1ec,
18420
18421     NM_MOV_S       = 0x01,
18422     NM_MOV_D       = 0x81,
18423     NM_ABS_S       = 0x0d,
18424     NM_ABS_D       = 0x8d,
18425     NM_NEG_S       = 0x2d,
18426     NM_NEG_D       = 0xad,
18427     NM_CVT_D_S     = 0x04d,
18428     NM_CVT_D_W     = 0x0cd,
18429     NM_CVT_D_L     = 0x14d,
18430     NM_CVT_S_D     = 0x06d,
18431     NM_CVT_S_W     = 0x0ed,
18432     NM_CVT_S_L     = 0x16d,
18433 };
18434
18435 /* P.LL instruction pool */
18436 enum {
18437     NM_LL       = 0x00,
18438     NM_LLWP     = 0x01,
18439 };
18440
18441 /* P.SC instruction pool */
18442 enum {
18443     NM_SC       = 0x00,
18444     NM_SCWP     = 0x01,
18445 };
18446
18447 /* P.DVP instruction pool */
18448 enum {
18449     NM_DVP      = 0x00,
18450     NM_EVP      = 0x01,
18451 };
18452
18453
18454 /*
18455  *
18456  * nanoMIPS decoding engine
18457  *
18458  */
18459
18460
18461 /* extraction utilities */
18462
18463 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18464 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18465 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18466 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18467 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18468 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18469
18470 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
18471 static inline int decode_gpr_gpr3(int r)
18472 {
18473     static const int map[] = { 16, 17, 18, 19,  4,  5,  6,  7 };
18474
18475     return map[r & 0x7];
18476 }
18477
18478 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
18479 static inline int decode_gpr_gpr3_src_store(int r)
18480 {
18481     static const int map[] = {  0, 17, 18, 19,  4,  5,  6,  7 };
18482
18483     return map[r & 0x7];
18484 }
18485
18486 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
18487 static inline int decode_gpr_gpr4(int r)
18488 {
18489     static const int map[] = {  8,  9, 10, 11,  4,  5,  6,  7,
18490                                16, 17, 18, 19, 20, 21, 22, 23 };
18491
18492     return map[r & 0xf];
18493 }
18494
18495 /* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
18496 static inline int decode_gpr_gpr4_zero(int r)
18497 {
18498     static const int map[] = {  8,  9, 10,  0,  4,  5,  6,  7,
18499                                16, 17, 18, 19, 20, 21, 22, 23 };
18500
18501     return map[r & 0xf];
18502 }
18503
18504
18505 /* extraction utilities */
18506
18507 #define NANOMIPS_EXTRACT_RD(op) ((op >> 7) & 0x7)
18508 #define NANOMIPS_EXTRACT_RS(op) ((op >> 4) & 0x7)
18509 #define NANOMIPS_EXTRACT_RS2(op) uMIPS_RS(op)
18510 #define NANOMIPS_EXTRACT_RS1(op) ((op >> 1) & 0x7)
18511 #define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
18512 #define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
18513
18514
18515 static void gen_adjust_sp(DisasContext *ctx, int u)
18516 {
18517     gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
18518 }
18519
18520 static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
18521                      uint8_t gp, uint16_t u)
18522 {
18523     int counter = 0;
18524     TCGv va = tcg_temp_new();
18525     TCGv t0 = tcg_temp_new();
18526
18527     while (counter != count) {
18528         bool use_gp = gp && (counter == count - 1);
18529         int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18530         int this_offset = -((counter + 1) << 2);
18531         gen_base_offset_addr(ctx, va, 29, this_offset);
18532         gen_load_gpr(t0, this_rt);
18533         tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
18534                            (MO_TEUL | ctx->default_tcg_memop_mask));
18535         counter++;
18536     }
18537
18538     /* adjust stack pointer */
18539     gen_adjust_sp(ctx, -u);
18540
18541     tcg_temp_free(t0);
18542     tcg_temp_free(va);
18543 }
18544
18545 static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
18546                         uint8_t gp, uint16_t u)
18547 {
18548     int counter = 0;
18549     TCGv va = tcg_temp_new();
18550     TCGv t0 = tcg_temp_new();
18551
18552     while (counter != count) {
18553         bool use_gp = gp && (counter == count - 1);
18554         int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
18555         int this_offset = u - ((counter + 1) << 2);
18556         gen_base_offset_addr(ctx, va, 29, this_offset);
18557         tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
18558                         ctx->default_tcg_memop_mask);
18559         tcg_gen_ext32s_tl(t0, t0);
18560         gen_store_gpr(t0, this_rt);
18561         counter++;
18562     }
18563
18564     /* adjust stack pointer */
18565     gen_adjust_sp(ctx, u);
18566
18567     tcg_temp_free(t0);
18568     tcg_temp_free(va);
18569 }
18570
18571 static void gen_pool16c_nanomips_insn(DisasContext *ctx)
18572 {
18573     int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
18574     int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
18575
18576     switch (extract32(ctx->opcode, 2, 2)) {
18577     case NM_NOT16:
18578         gen_logic(ctx, OPC_NOR, rt, rs, 0);
18579         break;
18580     case NM_AND16:
18581         gen_logic(ctx, OPC_AND, rt, rt, rs);
18582         break;
18583     case NM_XOR16:
18584         gen_logic(ctx, OPC_XOR, rt, rt, rs);
18585         break;
18586     case NM_OR16:
18587         gen_logic(ctx, OPC_OR, rt, rt, rs);
18588         break;
18589     }
18590 }
18591
18592 static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18593 {
18594     int rt = extract32(ctx->opcode, 21, 5);
18595     int rs = extract32(ctx->opcode, 16, 5);
18596     int rd = extract32(ctx->opcode, 11, 5);
18597
18598     switch (extract32(ctx->opcode, 3, 7)) {
18599     case NM_P_TRAP:
18600         switch (extract32(ctx->opcode, 10, 1)) {
18601         case NM_TEQ:
18602             check_nms(ctx);
18603             gen_trap(ctx, OPC_TEQ, rs, rt, -1);
18604             break;
18605         case NM_TNE:
18606             check_nms(ctx);
18607             gen_trap(ctx, OPC_TNE, rs, rt, -1);
18608             break;
18609         }
18610         break;
18611     case NM_RDHWR:
18612         check_nms(ctx);
18613         gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
18614         break;
18615     case NM_SEB:
18616         check_nms(ctx);
18617         gen_bshfl(ctx, OPC_SEB, rs, rt);
18618         break;
18619     case NM_SEH:
18620         gen_bshfl(ctx, OPC_SEH, rs, rt);
18621         break;
18622     case NM_SLLV:
18623         gen_shift(ctx, OPC_SLLV, rd, rt, rs);
18624         break;
18625     case NM_SRLV:
18626         gen_shift(ctx, OPC_SRLV, rd, rt, rs);
18627         break;
18628     case NM_SRAV:
18629         gen_shift(ctx, OPC_SRAV, rd, rt, rs);
18630         break;
18631     case NM_ROTRV:
18632         gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
18633         break;
18634     case NM_ADD:
18635         gen_arith(ctx, OPC_ADD, rd, rs, rt);
18636         break;
18637     case NM_ADDU:
18638         gen_arith(ctx, OPC_ADDU, rd, rs, rt);
18639         break;
18640     case NM_SUB:
18641         check_nms(ctx);
18642         gen_arith(ctx, OPC_SUB, rd, rs, rt);
18643         break;
18644     case NM_SUBU:
18645         gen_arith(ctx, OPC_SUBU, rd, rs, rt);
18646         break;
18647     case NM_P_CMOVE:
18648         switch (extract32(ctx->opcode, 10, 1)) {
18649         case NM_MOVZ:
18650             gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
18651             break;
18652         case NM_MOVN:
18653             gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
18654             break;
18655         }
18656         break;
18657     case NM_AND:
18658         gen_logic(ctx, OPC_AND, rd, rs, rt);
18659         break;
18660     case NM_OR:
18661         gen_logic(ctx, OPC_OR, rd, rs, rt);
18662         break;
18663     case NM_NOR:
18664         gen_logic(ctx, OPC_NOR, rd, rs, rt);
18665         break;
18666     case NM_XOR:
18667         gen_logic(ctx, OPC_XOR, rd, rs, rt);
18668         break;
18669     case NM_SLT:
18670         gen_slt(ctx, OPC_SLT, rd, rs, rt);
18671         break;
18672     case NM_P_SLTU:
18673         if (rd == 0) {
18674             /* P_DVP */
18675 #ifndef CONFIG_USER_ONLY
18676             TCGv t0 = tcg_temp_new();
18677             switch (extract32(ctx->opcode, 10, 1)) {
18678             case NM_DVP:
18679                 if (ctx->vp) {
18680                     check_cp0_enabled(ctx);
18681                     gen_helper_dvp(t0, cpu_env);
18682                     gen_store_gpr(t0, rt);
18683                 }
18684                 break;
18685             case NM_EVP:
18686                 if (ctx->vp) {
18687                     check_cp0_enabled(ctx);
18688                     gen_helper_evp(t0, cpu_env);
18689                     gen_store_gpr(t0, rt);
18690                 }
18691                 break;
18692             }
18693             tcg_temp_free(t0);
18694 #endif
18695         } else {
18696             gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18697         }
18698         break;
18699     case NM_SOV:
18700         {
18701             TCGv t0 = tcg_temp_new();
18702             TCGv t1 = tcg_temp_new();
18703             TCGv t2 = tcg_temp_new();
18704
18705             gen_load_gpr(t1, rs);
18706             gen_load_gpr(t2, rt);
18707             tcg_gen_add_tl(t0, t1, t2);
18708             tcg_gen_ext32s_tl(t0, t0);
18709             tcg_gen_xor_tl(t1, t1, t2);
18710             tcg_gen_xor_tl(t2, t0, t2);
18711             tcg_gen_andc_tl(t1, t2, t1);
18712
18713             /* operands of same sign, result different sign */
18714             tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18715             gen_store_gpr(t0, rd);
18716
18717             tcg_temp_free(t0);
18718             tcg_temp_free(t1);
18719             tcg_temp_free(t2);
18720         }
18721         break;
18722     case NM_MUL:
18723         gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18724         break;
18725     case NM_MUH:
18726         gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18727         break;
18728     case NM_MULU:
18729         gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18730         break;
18731     case NM_MUHU:
18732         gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18733         break;
18734     case NM_DIV:
18735         gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18736         break;
18737     case NM_MOD:
18738         gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18739         break;
18740     case NM_DIVU:
18741         gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18742         break;
18743     case NM_MODU:
18744         gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
18745         break;
18746 #ifndef CONFIG_USER_ONLY
18747     case NM_MFC0:
18748         check_cp0_enabled(ctx);
18749         if (rt == 0) {
18750             /* Treat as NOP. */
18751             break;
18752         }
18753         gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
18754         break;
18755     case NM_MTC0:
18756         check_cp0_enabled(ctx);
18757         {
18758             TCGv t0 = tcg_temp_new();
18759
18760             gen_load_gpr(t0, rt);
18761             gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
18762             tcg_temp_free(t0);
18763         }
18764         break;
18765     case NM_D_E_MT_VPE:
18766         {
18767             uint8_t sc = extract32(ctx->opcode, 10, 1);
18768             TCGv t0 = tcg_temp_new();
18769
18770             switch (sc) {
18771             case 0:
18772                 if (rs == 1) {
18773                     /* DMT */
18774                     check_cp0_mt(ctx);
18775                     gen_helper_dmt(t0);
18776                     gen_store_gpr(t0, rt);
18777                 } else if (rs == 0) {
18778                     /* DVPE */
18779                     check_cp0_mt(ctx);
18780                     gen_helper_dvpe(t0, cpu_env);
18781                     gen_store_gpr(t0, rt);
18782                 } else {
18783                     generate_exception_end(ctx, EXCP_RI);
18784                 }
18785                 break;
18786             case 1:
18787                 if (rs == 1) {
18788                     /* EMT */
18789                     check_cp0_mt(ctx);
18790                     gen_helper_emt(t0);
18791                     gen_store_gpr(t0, rt);
18792                 } else if (rs == 0) {
18793                     /* EVPE */
18794                     check_cp0_mt(ctx);
18795                     gen_helper_evpe(t0, cpu_env);
18796                     gen_store_gpr(t0, rt);
18797                 } else {
18798                     generate_exception_end(ctx, EXCP_RI);
18799                 }
18800                 break;
18801             }
18802
18803             tcg_temp_free(t0);
18804         }
18805         break;
18806     case NM_FORK:
18807         check_mt(ctx);
18808         {
18809             TCGv t0 = tcg_temp_new();
18810             TCGv t1 = tcg_temp_new();
18811
18812             gen_load_gpr(t0, rt);
18813             gen_load_gpr(t1, rs);
18814             gen_helper_fork(t0, t1);
18815             tcg_temp_free(t0);
18816             tcg_temp_free(t1);
18817         }
18818         break;
18819     case NM_MFTR:
18820     case NM_MFHTR:
18821         check_cp0_enabled(ctx);
18822         if (rd == 0) {
18823             /* Treat as NOP. */
18824             return;
18825         }
18826         gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18827                  extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18828         break;
18829     case NM_MTTR:
18830     case NM_MTHTR:
18831         check_cp0_enabled(ctx);
18832         gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18833                  extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18834         break;
18835     case NM_YIELD:
18836         check_mt(ctx);
18837         {
18838             TCGv t0 = tcg_temp_new();
18839
18840             gen_load_gpr(t0, rs);
18841             gen_helper_yield(t0, cpu_env, t0);
18842             gen_store_gpr(t0, rt);
18843             tcg_temp_free(t0);
18844         }
18845         break;
18846 #endif
18847     default:
18848         generate_exception_end(ctx, EXCP_RI);
18849         break;
18850     }
18851 }
18852
18853 /* dsp */
18854 static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
18855                                             int ret, int v1, int v2)
18856 {
18857     TCGv_i32 t0;
18858     TCGv v0_t;
18859     TCGv v1_t;
18860
18861     t0 = tcg_temp_new_i32();
18862
18863     v0_t = tcg_temp_new();
18864     v1_t = tcg_temp_new();
18865
18866     tcg_gen_movi_i32(t0, v2 >> 3);
18867
18868     gen_load_gpr(v0_t, ret);
18869     gen_load_gpr(v1_t, v1);
18870
18871     switch (opc) {
18872     case NM_MAQ_S_W_PHR:
18873         check_dsp(ctx);
18874         gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
18875         break;
18876     case NM_MAQ_S_W_PHL:
18877         check_dsp(ctx);
18878         gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
18879         break;
18880     case NM_MAQ_SA_W_PHR:
18881         check_dsp(ctx);
18882         gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
18883         break;
18884     case NM_MAQ_SA_W_PHL:
18885         check_dsp(ctx);
18886         gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
18887         break;
18888     default:
18889         generate_exception_end(ctx, EXCP_RI);
18890         break;
18891     }
18892
18893     tcg_temp_free_i32(t0);
18894
18895     tcg_temp_free(v0_t);
18896     tcg_temp_free(v1_t);
18897 }
18898
18899
18900 static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
18901                                     int ret, int v1, int v2)
18902 {
18903     int16_t imm;
18904     TCGv t0 = tcg_temp_new();
18905     TCGv t1 = tcg_temp_new();
18906     TCGv v0_t = tcg_temp_new();
18907
18908     gen_load_gpr(v0_t, v1);
18909
18910     switch (opc) {
18911     case NM_POOL32AXF_1_0:
18912         check_dsp(ctx);
18913         switch (extract32(ctx->opcode, 12, 2)) {
18914         case NM_MFHI:
18915             gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
18916             break;
18917         case NM_MFLO:
18918             gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
18919             break;
18920         case NM_MTHI:
18921             gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
18922             break;
18923         case NM_MTLO:
18924             gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
18925             break;
18926         }
18927         break;
18928     case NM_POOL32AXF_1_1:
18929         check_dsp(ctx);
18930         switch (extract32(ctx->opcode, 12, 2)) {
18931         case NM_MTHLIP:
18932             tcg_gen_movi_tl(t0, v2);
18933             gen_helper_mthlip(t0, v0_t, cpu_env);
18934             break;
18935         case NM_SHILOV:
18936             tcg_gen_movi_tl(t0, v2 >> 3);
18937             gen_helper_shilo(t0, v0_t, cpu_env);
18938             break;
18939         default:
18940             generate_exception_end(ctx, EXCP_RI);
18941             break;
18942         }
18943         break;
18944     case NM_POOL32AXF_1_3:
18945         check_dsp(ctx);
18946         imm = extract32(ctx->opcode, 14, 7);
18947         switch (extract32(ctx->opcode, 12, 2)) {
18948         case NM_RDDSP:
18949             tcg_gen_movi_tl(t0, imm);
18950             gen_helper_rddsp(t0, t0, cpu_env);
18951             gen_store_gpr(t0, ret);
18952             break;
18953         case NM_WRDSP:
18954             gen_load_gpr(t0, ret);
18955             tcg_gen_movi_tl(t1, imm);
18956             gen_helper_wrdsp(t0, t1, cpu_env);
18957             break;
18958         case NM_EXTP:
18959             tcg_gen_movi_tl(t0, v2 >> 3);
18960             tcg_gen_movi_tl(t1, v1);
18961             gen_helper_extp(t0, t0, t1, cpu_env);
18962             gen_store_gpr(t0, ret);
18963             break;
18964         case NM_EXTPDP:
18965             tcg_gen_movi_tl(t0, v2 >> 3);
18966             tcg_gen_movi_tl(t1, v1);
18967             gen_helper_extpdp(t0, t0, t1, cpu_env);
18968             gen_store_gpr(t0, ret);
18969             break;
18970         }
18971         break;
18972     case NM_POOL32AXF_1_4:
18973         check_dsp(ctx);
18974         tcg_gen_movi_tl(t0, v2 >> 2);
18975         switch (extract32(ctx->opcode, 12, 1)) {
18976         case NM_SHLL_QB:
18977             gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
18978             gen_store_gpr(t0, ret);
18979             break;
18980         case NM_SHRL_QB:
18981             gen_helper_shrl_qb(t0, t0, v0_t);
18982             gen_store_gpr(t0, ret);
18983             break;
18984         }
18985         break;
18986     case NM_POOL32AXF_1_5:
18987         opc = extract32(ctx->opcode, 12, 2);
18988         gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
18989         break;
18990     case NM_POOL32AXF_1_7:
18991         check_dsp(ctx);
18992         tcg_gen_movi_tl(t0, v2 >> 3);
18993         tcg_gen_movi_tl(t1, v1);
18994         switch (extract32(ctx->opcode, 12, 2)) {
18995         case NM_EXTR_W:
18996             gen_helper_extr_w(t0, t0, t1, cpu_env);
18997             gen_store_gpr(t0, ret);
18998             break;
18999         case NM_EXTR_R_W:
19000             gen_helper_extr_r_w(t0, t0, t1, cpu_env);
19001             gen_store_gpr(t0, ret);
19002             break;
19003         case NM_EXTR_RS_W:
19004             gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
19005             gen_store_gpr(t0, ret);
19006             break;
19007         case NM_EXTR_S_H:
19008             gen_helper_extr_s_h(t0, t0, t1, cpu_env);
19009             gen_store_gpr(t0, ret);
19010             break;
19011         }
19012         break;
19013     default:
19014         generate_exception_end(ctx, EXCP_RI);
19015         break;
19016     }
19017
19018     tcg_temp_free(t0);
19019     tcg_temp_free(t1);
19020     tcg_temp_free(v0_t);
19021 }
19022
19023 static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
19024                                     TCGv v0, TCGv v1, int rd)
19025 {
19026     TCGv_i32 t0;
19027
19028     t0 = tcg_temp_new_i32();
19029
19030     tcg_gen_movi_i32(t0, rd >> 3);
19031
19032     switch (opc) {
19033     case NM_POOL32AXF_2_0_7:
19034         switch (extract32(ctx->opcode, 9, 3)) {
19035         case NM_DPA_W_PH:
19036             check_dsp_r2(ctx);
19037             gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
19038             break;
19039         case NM_DPAQ_S_W_PH:
19040             check_dsp(ctx);
19041             gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
19042             break;
19043         case NM_DPS_W_PH:
19044             check_dsp_r2(ctx);
19045             gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
19046             break;
19047         case NM_DPSQ_S_W_PH:
19048             check_dsp(ctx);
19049             gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
19050             break;
19051         default:
19052             generate_exception_end(ctx, EXCP_RI);
19053             break;
19054         }
19055         break;
19056     case NM_POOL32AXF_2_8_15:
19057         switch (extract32(ctx->opcode, 9, 3)) {
19058         case NM_DPAX_W_PH:
19059             check_dsp_r2(ctx);
19060             gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
19061             break;
19062         case NM_DPAQ_SA_L_W:
19063             check_dsp(ctx);
19064             gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
19065             break;
19066         case NM_DPSX_W_PH:
19067             check_dsp_r2(ctx);
19068             gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
19069             break;
19070         case NM_DPSQ_SA_L_W:
19071             check_dsp(ctx);
19072             gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
19073             break;
19074         default:
19075             generate_exception_end(ctx, EXCP_RI);
19076             break;
19077         }
19078         break;
19079     case NM_POOL32AXF_2_16_23:
19080         switch (extract32(ctx->opcode, 9, 3)) {
19081         case NM_DPAU_H_QBL:
19082             check_dsp(ctx);
19083             gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
19084             break;
19085         case NM_DPAQX_S_W_PH:
19086             check_dsp_r2(ctx);
19087             gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
19088             break;
19089         case NM_DPSU_H_QBL:
19090             check_dsp(ctx);
19091             gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
19092             break;
19093         case NM_DPSQX_S_W_PH:
19094             check_dsp_r2(ctx);
19095             gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
19096             break;
19097         case NM_MULSA_W_PH:
19098             check_dsp_r2(ctx);
19099             gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
19100             break;
19101         default:
19102             generate_exception_end(ctx, EXCP_RI);
19103             break;
19104         }
19105         break;
19106     case NM_POOL32AXF_2_24_31:
19107         switch (extract32(ctx->opcode, 9, 3)) {
19108         case NM_DPAU_H_QBR:
19109             check_dsp(ctx);
19110             gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
19111             break;
19112         case NM_DPAQX_SA_W_PH:
19113             check_dsp_r2(ctx);
19114             gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
19115             break;
19116         case NM_DPSU_H_QBR:
19117             check_dsp(ctx);
19118             gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
19119             break;
19120         case NM_DPSQX_SA_W_PH:
19121             check_dsp_r2(ctx);
19122             gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
19123             break;
19124         case NM_MULSAQ_S_W_PH:
19125             check_dsp(ctx);
19126             gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
19127             break;
19128         default:
19129             generate_exception_end(ctx, EXCP_RI);
19130             break;
19131         }
19132         break;
19133     default:
19134         generate_exception_end(ctx, EXCP_RI);
19135         break;
19136     }
19137
19138     tcg_temp_free_i32(t0);
19139 }
19140
19141 static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
19142                                           int rt, int rs, int rd)
19143 {
19144     int ret = rt;
19145     TCGv t0 = tcg_temp_new();
19146     TCGv t1 = tcg_temp_new();
19147     TCGv v0_t = tcg_temp_new();
19148     TCGv v1_t = tcg_temp_new();
19149
19150     gen_load_gpr(v0_t, rt);
19151     gen_load_gpr(v1_t, rs);
19152
19153     switch (opc) {
19154     case NM_POOL32AXF_2_0_7:
19155         switch (extract32(ctx->opcode, 9, 3)) {
19156         case NM_DPA_W_PH:
19157         case NM_DPAQ_S_W_PH:
19158         case NM_DPS_W_PH:
19159         case NM_DPSQ_S_W_PH:
19160             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19161             break;
19162         case NM_BALIGN:
19163             check_dsp_r2(ctx);
19164             if (rt != 0) {
19165                 gen_load_gpr(t0, rs);
19166                 rd &= 3;
19167                 if (rd != 0 && rd != 2) {
19168                     tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
19169                     tcg_gen_ext32u_tl(t0, t0);
19170                     tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
19171                     tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
19172                 }
19173                 tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
19174             }
19175             break;
19176         case NM_MADD:
19177             check_dsp(ctx);
19178             {
19179                 int acc = extract32(ctx->opcode, 14, 2);
19180                 TCGv_i64 t2 = tcg_temp_new_i64();
19181                 TCGv_i64 t3 = tcg_temp_new_i64();
19182
19183                 gen_load_gpr(t0, rt);
19184                 gen_load_gpr(t1, rs);
19185                 tcg_gen_ext_tl_i64(t2, t0);
19186                 tcg_gen_ext_tl_i64(t3, t1);
19187                 tcg_gen_mul_i64(t2, t2, t3);
19188                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19189                 tcg_gen_add_i64(t2, t2, t3);
19190                 tcg_temp_free_i64(t3);
19191                 gen_move_low32(cpu_LO[acc], t2);
19192                 gen_move_high32(cpu_HI[acc], t2);
19193                 tcg_temp_free_i64(t2);
19194             }
19195             break;
19196         case NM_MULT:
19197             check_dsp(ctx);
19198             {
19199                 int acc = extract32(ctx->opcode, 14, 2);
19200                 TCGv_i32 t2 = tcg_temp_new_i32();
19201                 TCGv_i32 t3 = tcg_temp_new_i32();
19202
19203                 gen_load_gpr(t0, rs);
19204                 gen_load_gpr(t1, rt);
19205                 tcg_gen_trunc_tl_i32(t2, t0);
19206                 tcg_gen_trunc_tl_i32(t3, t1);
19207                 tcg_gen_muls2_i32(t2, t3, t2, t3);
19208                 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19209                 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19210                 tcg_temp_free_i32(t2);
19211                 tcg_temp_free_i32(t3);
19212             }
19213             break;
19214         case NM_EXTRV_W:
19215             check_dsp(ctx);
19216             gen_load_gpr(v1_t, rs);
19217             tcg_gen_movi_tl(t0, rd >> 3);
19218             gen_helper_extr_w(t0, t0, v1_t, cpu_env);
19219             gen_store_gpr(t0, ret);
19220             break;
19221         }
19222         break;
19223     case NM_POOL32AXF_2_8_15:
19224         switch (extract32(ctx->opcode, 9, 3)) {
19225         case NM_DPAX_W_PH:
19226         case NM_DPAQ_SA_L_W:
19227         case NM_DPSX_W_PH:
19228         case NM_DPSQ_SA_L_W:
19229             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19230             break;
19231         case NM_MADDU:
19232             check_dsp(ctx);
19233             {
19234                 int acc = extract32(ctx->opcode, 14, 2);
19235                 TCGv_i64 t2 = tcg_temp_new_i64();
19236                 TCGv_i64 t3 = tcg_temp_new_i64();
19237
19238                 gen_load_gpr(t0, rs);
19239                 gen_load_gpr(t1, rt);
19240                 tcg_gen_ext32u_tl(t0, t0);
19241                 tcg_gen_ext32u_tl(t1, t1);
19242                 tcg_gen_extu_tl_i64(t2, t0);
19243                 tcg_gen_extu_tl_i64(t3, t1);
19244                 tcg_gen_mul_i64(t2, t2, t3);
19245                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19246                 tcg_gen_add_i64(t2, t2, t3);
19247                 tcg_temp_free_i64(t3);
19248                 gen_move_low32(cpu_LO[acc], t2);
19249                 gen_move_high32(cpu_HI[acc], t2);
19250                 tcg_temp_free_i64(t2);
19251             }
19252             break;
19253         case NM_MULTU:
19254             check_dsp(ctx);
19255             {
19256                 int acc = extract32(ctx->opcode, 14, 2);
19257                 TCGv_i32 t2 = tcg_temp_new_i32();
19258                 TCGv_i32 t3 = tcg_temp_new_i32();
19259
19260                 gen_load_gpr(t0, rs);
19261                 gen_load_gpr(t1, rt);
19262                 tcg_gen_trunc_tl_i32(t2, t0);
19263                 tcg_gen_trunc_tl_i32(t3, t1);
19264                 tcg_gen_mulu2_i32(t2, t3, t2, t3);
19265                 tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
19266                 tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
19267                 tcg_temp_free_i32(t2);
19268                 tcg_temp_free_i32(t3);
19269             }
19270             break;
19271         case NM_EXTRV_R_W:
19272             check_dsp(ctx);
19273             tcg_gen_movi_tl(t0, rd >> 3);
19274             gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
19275             gen_store_gpr(t0, ret);
19276             break;
19277         default:
19278             generate_exception_end(ctx, EXCP_RI);
19279             break;
19280         }
19281         break;
19282     case NM_POOL32AXF_2_16_23:
19283         switch (extract32(ctx->opcode, 9, 3)) {
19284         case NM_DPAU_H_QBL:
19285         case NM_DPAQX_S_W_PH:
19286         case NM_DPSU_H_QBL:
19287         case NM_DPSQX_S_W_PH:
19288         case NM_MULSA_W_PH:
19289             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19290             break;
19291         case NM_EXTPV:
19292             check_dsp(ctx);
19293             tcg_gen_movi_tl(t0, rd >> 3);
19294             gen_helper_extp(t0, t0, v1_t, cpu_env);
19295             gen_store_gpr(t0, ret);
19296             break;
19297         case NM_MSUB:
19298             check_dsp(ctx);
19299             {
19300                 int acc = extract32(ctx->opcode, 14, 2);
19301                 TCGv_i64 t2 = tcg_temp_new_i64();
19302                 TCGv_i64 t3 = tcg_temp_new_i64();
19303
19304                 gen_load_gpr(t0, rs);
19305                 gen_load_gpr(t1, rt);
19306                 tcg_gen_ext_tl_i64(t2, t0);
19307                 tcg_gen_ext_tl_i64(t3, t1);
19308                 tcg_gen_mul_i64(t2, t2, t3);
19309                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19310                 tcg_gen_sub_i64(t2, t3, t2);
19311                 tcg_temp_free_i64(t3);
19312                 gen_move_low32(cpu_LO[acc], t2);
19313                 gen_move_high32(cpu_HI[acc], t2);
19314                 tcg_temp_free_i64(t2);
19315             }
19316             break;
19317         case NM_EXTRV_RS_W:
19318             check_dsp(ctx);
19319             tcg_gen_movi_tl(t0, rd >> 3);
19320             gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
19321             gen_store_gpr(t0, ret);
19322             break;
19323         }
19324         break;
19325     case NM_POOL32AXF_2_24_31:
19326         switch (extract32(ctx->opcode, 9, 3)) {
19327         case NM_DPAU_H_QBR:
19328         case NM_DPAQX_SA_W_PH:
19329         case NM_DPSU_H_QBR:
19330         case NM_DPSQX_SA_W_PH:
19331         case NM_MULSAQ_S_W_PH:
19332             gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
19333             break;
19334         case NM_EXTPDPV:
19335             check_dsp(ctx);
19336             tcg_gen_movi_tl(t0, rd >> 3);
19337             gen_helper_extpdp(t0, t0, v1_t, cpu_env);
19338             gen_store_gpr(t0, ret);
19339             break;
19340         case NM_MSUBU:
19341             check_dsp(ctx);
19342             {
19343                 int acc = extract32(ctx->opcode, 14, 2);
19344                 TCGv_i64 t2 = tcg_temp_new_i64();
19345                 TCGv_i64 t3 = tcg_temp_new_i64();
19346
19347                 gen_load_gpr(t0, rs);
19348                 gen_load_gpr(t1, rt);
19349                 tcg_gen_ext32u_tl(t0, t0);
19350                 tcg_gen_ext32u_tl(t1, t1);
19351                 tcg_gen_extu_tl_i64(t2, t0);
19352                 tcg_gen_extu_tl_i64(t3, t1);
19353                 tcg_gen_mul_i64(t2, t2, t3);
19354                 tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
19355                 tcg_gen_sub_i64(t2, t3, t2);
19356                 tcg_temp_free_i64(t3);
19357                 gen_move_low32(cpu_LO[acc], t2);
19358                 gen_move_high32(cpu_HI[acc], t2);
19359                 tcg_temp_free_i64(t2);
19360             }
19361             break;
19362         case NM_EXTRV_S_H:
19363             check_dsp(ctx);
19364             tcg_gen_movi_tl(t0, rd >> 3);
19365             gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
19366             gen_store_gpr(t0, ret);
19367             break;
19368         }
19369         break;
19370     default:
19371         generate_exception_end(ctx, EXCP_RI);
19372         break;
19373     }
19374
19375     tcg_temp_free(t0);
19376     tcg_temp_free(t1);
19377
19378     tcg_temp_free(v0_t);
19379     tcg_temp_free(v1_t);
19380 }
19381
19382 static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
19383                                           int rt, int rs)
19384 {
19385     int ret = rt;
19386     TCGv t0 = tcg_temp_new();
19387     TCGv v0_t = tcg_temp_new();
19388
19389     gen_load_gpr(v0_t, rs);
19390
19391     switch (opc) {
19392     case NM_ABSQ_S_QB:
19393         check_dsp_r2(ctx);
19394         gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
19395         gen_store_gpr(v0_t, ret);
19396         break;
19397     case NM_ABSQ_S_PH:
19398         check_dsp(ctx);
19399         gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
19400         gen_store_gpr(v0_t, ret);
19401         break;
19402     case NM_ABSQ_S_W:
19403         check_dsp(ctx);
19404         gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
19405         gen_store_gpr(v0_t, ret);
19406         break;
19407     case NM_PRECEQ_W_PHL:
19408         check_dsp(ctx);
19409         tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
19410         tcg_gen_ext32s_tl(v0_t, v0_t);
19411         gen_store_gpr(v0_t, ret);
19412         break;
19413     case NM_PRECEQ_W_PHR:
19414         check_dsp(ctx);
19415         tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
19416         tcg_gen_shli_tl(v0_t, v0_t, 16);
19417         tcg_gen_ext32s_tl(v0_t, v0_t);
19418         gen_store_gpr(v0_t, ret);
19419         break;
19420     case NM_PRECEQU_PH_QBL:
19421         check_dsp(ctx);
19422         gen_helper_precequ_ph_qbl(v0_t, v0_t);
19423         gen_store_gpr(v0_t, ret);
19424         break;
19425     case NM_PRECEQU_PH_QBR:
19426         check_dsp(ctx);
19427         gen_helper_precequ_ph_qbr(v0_t, v0_t);
19428         gen_store_gpr(v0_t, ret);
19429         break;
19430     case NM_PRECEQU_PH_QBLA:
19431         check_dsp(ctx);
19432         gen_helper_precequ_ph_qbla(v0_t, v0_t);
19433         gen_store_gpr(v0_t, ret);
19434         break;
19435     case NM_PRECEQU_PH_QBRA:
19436         check_dsp(ctx);
19437         gen_helper_precequ_ph_qbra(v0_t, v0_t);
19438         gen_store_gpr(v0_t, ret);
19439         break;
19440     case NM_PRECEU_PH_QBL:
19441         check_dsp(ctx);
19442         gen_helper_preceu_ph_qbl(v0_t, v0_t);
19443         gen_store_gpr(v0_t, ret);
19444         break;
19445     case NM_PRECEU_PH_QBR:
19446         check_dsp(ctx);
19447         gen_helper_preceu_ph_qbr(v0_t, v0_t);
19448         gen_store_gpr(v0_t, ret);
19449         break;
19450     case NM_PRECEU_PH_QBLA:
19451         check_dsp(ctx);
19452         gen_helper_preceu_ph_qbla(v0_t, v0_t);
19453         gen_store_gpr(v0_t, ret);
19454         break;
19455     case NM_PRECEU_PH_QBRA:
19456         check_dsp(ctx);
19457         gen_helper_preceu_ph_qbra(v0_t, v0_t);
19458         gen_store_gpr(v0_t, ret);
19459         break;
19460     case NM_REPLV_PH:
19461         check_dsp(ctx);
19462         tcg_gen_ext16u_tl(v0_t, v0_t);
19463         tcg_gen_shli_tl(t0, v0_t, 16);
19464         tcg_gen_or_tl(v0_t, v0_t, t0);
19465         tcg_gen_ext32s_tl(v0_t, v0_t);
19466         gen_store_gpr(v0_t, ret);
19467         break;
19468     case NM_REPLV_QB:
19469         check_dsp(ctx);
19470         tcg_gen_ext8u_tl(v0_t, v0_t);
19471         tcg_gen_shli_tl(t0, v0_t, 8);
19472         tcg_gen_or_tl(v0_t, v0_t, t0);
19473         tcg_gen_shli_tl(t0, v0_t, 16);
19474         tcg_gen_or_tl(v0_t, v0_t, t0);
19475         tcg_gen_ext32s_tl(v0_t, v0_t);
19476         gen_store_gpr(v0_t, ret);
19477         break;
19478     case NM_BITREV:
19479         check_dsp(ctx);
19480         gen_helper_bitrev(v0_t, v0_t);
19481         gen_store_gpr(v0_t, ret);
19482         break;
19483     case NM_INSV:
19484         check_dsp(ctx);
19485         {
19486             TCGv tv0 = tcg_temp_new();
19487
19488             gen_load_gpr(tv0, rt);
19489             gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
19490             gen_store_gpr(v0_t, ret);
19491             tcg_temp_free(tv0);
19492         }
19493         break;
19494     case NM_RADDU_W_QB:
19495         check_dsp(ctx);
19496         gen_helper_raddu_w_qb(v0_t, v0_t);
19497         gen_store_gpr(v0_t, ret);
19498         break;
19499     case NM_BITSWAP:
19500         gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
19501         break;
19502     case NM_CLO:
19503         check_nms(ctx);
19504         gen_cl(ctx, OPC_CLO, ret, rs);
19505         break;
19506     case NM_CLZ:
19507         check_nms(ctx);
19508         gen_cl(ctx, OPC_CLZ, ret, rs);
19509         break;
19510     case NM_WSBH:
19511         gen_bshfl(ctx, OPC_WSBH, ret, rs);
19512         break;
19513     default:
19514         generate_exception_end(ctx, EXCP_RI);
19515         break;
19516     }
19517
19518     tcg_temp_free(v0_t);
19519     tcg_temp_free(t0);
19520 }
19521
19522 static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
19523                                           int rt, int rs, int rd)
19524 {
19525     TCGv t0 = tcg_temp_new();
19526     TCGv rs_t = tcg_temp_new();
19527
19528     gen_load_gpr(rs_t, rs);
19529
19530     switch (opc) {
19531     case NM_SHRA_R_QB:
19532         check_dsp_r2(ctx);
19533         tcg_gen_movi_tl(t0, rd >> 2);
19534         switch (extract32(ctx->opcode, 12, 1)) {
19535         case 0:
19536             /* NM_SHRA_QB */
19537             gen_helper_shra_qb(t0, t0, rs_t);
19538             gen_store_gpr(t0, rt);
19539             break;
19540         case 1:
19541             /* NM_SHRA_R_QB */
19542             gen_helper_shra_r_qb(t0, t0, rs_t);
19543             gen_store_gpr(t0, rt);
19544             break;
19545         }
19546         break;
19547     case NM_SHRL_PH:
19548         check_dsp_r2(ctx);
19549         tcg_gen_movi_tl(t0, rd >> 1);
19550         gen_helper_shrl_ph(t0, t0, rs_t);
19551         gen_store_gpr(t0, rt);
19552         break;
19553     case NM_REPL_QB:
19554         check_dsp(ctx);
19555         {
19556             int16_t imm;
19557             target_long result;
19558             imm = extract32(ctx->opcode, 13, 8);
19559             result = (uint32_t)imm << 24 |
19560                      (uint32_t)imm << 16 |
19561                      (uint32_t)imm << 8  |
19562                      (uint32_t)imm;
19563             result = (int32_t)result;
19564             tcg_gen_movi_tl(t0, result);
19565             gen_store_gpr(t0, rt);
19566         }
19567         break;
19568     default:
19569         generate_exception_end(ctx, EXCP_RI);
19570         break;
19571     }
19572     tcg_temp_free(t0);
19573     tcg_temp_free(rs_t);
19574 }
19575
19576
19577 static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
19578 {
19579     int rt = extract32(ctx->opcode, 21, 5);
19580     int rs = extract32(ctx->opcode, 16, 5);
19581     int rd = extract32(ctx->opcode, 11, 5);
19582
19583     switch (extract32(ctx->opcode, 6, 3)) {
19584     case NM_POOL32AXF_1:
19585         {
19586             int32_t op1 = extract32(ctx->opcode, 9, 3);
19587             gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
19588         }
19589         break;
19590     case NM_POOL32AXF_2:
19591         {
19592             int32_t op1 = extract32(ctx->opcode, 12, 2);
19593             gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
19594         }
19595         break;
19596     case NM_POOL32AXF_4:
19597         {
19598             int32_t op1 = extract32(ctx->opcode, 9, 7);
19599             gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
19600         }
19601         break;
19602     case NM_POOL32AXF_5:
19603         switch (extract32(ctx->opcode, 9, 7)) {
19604 #ifndef CONFIG_USER_ONLY
19605         case NM_TLBP:
19606             gen_cp0(env, ctx, OPC_TLBP, 0, 0);
19607             break;
19608         case NM_TLBR:
19609             gen_cp0(env, ctx, OPC_TLBR, 0, 0);
19610             break;
19611         case NM_TLBWI:
19612             gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
19613             break;
19614         case NM_TLBWR:
19615             gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
19616             break;
19617         case NM_TLBINV:
19618             gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
19619             break;
19620         case NM_TLBINVF:
19621             gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
19622             break;
19623         case NM_DI:
19624             check_cp0_enabled(ctx);
19625             {
19626                 TCGv t0 = tcg_temp_new();
19627
19628                 save_cpu_state(ctx, 1);
19629                 gen_helper_di(t0, cpu_env);
19630                 gen_store_gpr(t0, rt);
19631             /* Stop translation as we may have switched the execution mode */
19632                 ctx->base.is_jmp = DISAS_STOP;
19633                 tcg_temp_free(t0);
19634             }
19635             break;
19636         case NM_EI:
19637             check_cp0_enabled(ctx);
19638             {
19639                 TCGv t0 = tcg_temp_new();
19640
19641                 save_cpu_state(ctx, 1);
19642                 gen_helper_ei(t0, cpu_env);
19643                 gen_store_gpr(t0, rt);
19644             /* Stop translation as we may have switched the execution mode */
19645                 ctx->base.is_jmp = DISAS_STOP;
19646                 tcg_temp_free(t0);
19647             }
19648             break;
19649         case NM_RDPGPR:
19650             gen_load_srsgpr(rs, rt);
19651             break;
19652         case NM_WRPGPR:
19653             gen_store_srsgpr(rs, rt);
19654             break;
19655         case NM_WAIT:
19656             gen_cp0(env, ctx, OPC_WAIT, 0, 0);
19657             break;
19658         case NM_DERET:
19659             gen_cp0(env, ctx, OPC_DERET, 0, 0);
19660             break;
19661         case NM_ERETX:
19662             gen_cp0(env, ctx, OPC_ERET, 0, 0);
19663             break;
19664 #endif
19665         default:
19666             generate_exception_end(ctx, EXCP_RI);
19667             break;
19668         }
19669         break;
19670     case NM_POOL32AXF_7:
19671         {
19672             int32_t op1 = extract32(ctx->opcode, 9, 3);
19673             gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
19674         }
19675         break;
19676     default:
19677         generate_exception_end(ctx, EXCP_RI);
19678         break;
19679     }
19680 }
19681
19682 /* Immediate Value Compact Branches */
19683 static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19684                                    int rt, int32_t imm, int32_t offset)
19685 {
19686     TCGCond cond;
19687     int bcond_compute = 0;
19688     TCGv t0 = tcg_temp_new();
19689     TCGv t1 = tcg_temp_new();
19690
19691     gen_load_gpr(t0, rt);
19692     tcg_gen_movi_tl(t1, imm);
19693     ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19694
19695     /* Load needed operands and calculate btarget */
19696     switch (opc) {
19697     case NM_BEQIC:
19698         if (rt == 0 && imm == 0) {
19699             /* Unconditional branch */
19700         } else if (rt == 0 && imm != 0) {
19701             /* Treat as NOP */
19702             goto out;
19703         } else {
19704             bcond_compute = 1;
19705             cond = TCG_COND_EQ;
19706         }
19707         break;
19708     case NM_BBEQZC:
19709     case NM_BBNEZC:
19710         check_nms(ctx);
19711         if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19712             generate_exception_end(ctx, EXCP_RI);
19713             goto out;
19714         } else if (rt == 0 && opc == NM_BBEQZC) {
19715             /* Unconditional branch */
19716         } else if (rt == 0 && opc == NM_BBNEZC) {
19717             /* Treat as NOP */
19718             goto out;
19719         } else {
19720             tcg_gen_shri_tl(t0, t0, imm);
19721             tcg_gen_andi_tl(t0, t0, 1);
19722             tcg_gen_movi_tl(t1, 0);
19723             bcond_compute = 1;
19724             if (opc == NM_BBEQZC) {
19725                 cond = TCG_COND_EQ;
19726             } else {
19727                 cond = TCG_COND_NE;
19728             }
19729         }
19730         break;
19731     case NM_BNEIC:
19732         if (rt == 0 && imm == 0) {
19733             /* Treat as NOP */
19734             goto out;
19735         } else if (rt == 0 && imm != 0) {
19736             /* Unconditional branch */
19737         } else {
19738             bcond_compute = 1;
19739             cond = TCG_COND_NE;
19740         }
19741         break;
19742     case NM_BGEIC:
19743         if (rt == 0 && imm == 0) {
19744             /* Unconditional branch */
19745         } else  {
19746             bcond_compute = 1;
19747             cond = TCG_COND_GE;
19748         }
19749         break;
19750     case NM_BLTIC:
19751         bcond_compute = 1;
19752         cond = TCG_COND_LT;
19753         break;
19754     case NM_BGEIUC:
19755         if (rt == 0 && imm == 0) {
19756             /* Unconditional branch */
19757         } else  {
19758             bcond_compute = 1;
19759             cond = TCG_COND_GEU;
19760         }
19761         break;
19762     case NM_BLTIUC:
19763         bcond_compute = 1;
19764         cond = TCG_COND_LTU;
19765         break;
19766     default:
19767         MIPS_INVAL("Immediate Value Compact branch");
19768         generate_exception_end(ctx, EXCP_RI);
19769         goto out;
19770     }
19771
19772     if (bcond_compute == 0) {
19773         /* Uncoditional compact branch */
19774         gen_goto_tb(ctx, 0, ctx->btarget);
19775     } else {
19776         /* Conditional compact branch */
19777         TCGLabel *fs = gen_new_label();
19778
19779         tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
19780
19781         gen_goto_tb(ctx, 1, ctx->btarget);
19782         gen_set_label(fs);
19783
19784         gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19785     }
19786
19787 out:
19788     tcg_temp_free(t0);
19789     tcg_temp_free(t1);
19790 }
19791
19792 /* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19793 static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
19794                                                 int rt)
19795 {
19796     TCGv t0 = tcg_temp_new();
19797     TCGv t1 = tcg_temp_new();
19798
19799     /* load rs */
19800     gen_load_gpr(t0, rs);
19801
19802     /* link */
19803     if (rt != 0) {
19804         tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
19805     }
19806
19807     /* calculate btarget */
19808     tcg_gen_shli_tl(t0, t0, 1);
19809     tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
19810     gen_op_addr_add(ctx, btarget, t1, t0);
19811
19812     /* unconditional branch to register */
19813     tcg_gen_mov_tl(cpu_PC, btarget);
19814     tcg_gen_lookup_and_goto_ptr();
19815
19816     tcg_temp_free(t0);
19817     tcg_temp_free(t1);
19818 }
19819
19820 /* nanoMIPS Branches */
19821 static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
19822                                        int rs, int rt, int32_t offset)
19823 {
19824     int bcond_compute = 0;
19825     TCGv t0 = tcg_temp_new();
19826     TCGv t1 = tcg_temp_new();
19827
19828     /* Load needed operands and calculate btarget */
19829     switch (opc) {
19830     /* compact branch */
19831     case OPC_BGEC:
19832     case OPC_BLTC:
19833         gen_load_gpr(t0, rs);
19834         gen_load_gpr(t1, rt);
19835         bcond_compute = 1;
19836         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19837         break;
19838     case OPC_BGEUC:
19839     case OPC_BLTUC:
19840         if (rs == 0 || rs == rt) {
19841             /* OPC_BLEZALC, OPC_BGEZALC */
19842             /* OPC_BGTZALC, OPC_BLTZALC */
19843             tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
19844         }
19845         gen_load_gpr(t0, rs);
19846         gen_load_gpr(t1, rt);
19847         bcond_compute = 1;
19848         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19849         break;
19850     case OPC_BC:
19851         ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19852         break;
19853     case OPC_BEQZC:
19854         if (rs != 0) {
19855             /* OPC_BEQZC, OPC_BNEZC */
19856             gen_load_gpr(t0, rs);
19857             bcond_compute = 1;
19858             ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19859         } else {
19860             /* OPC_JIC, OPC_JIALC */
19861             TCGv tbase = tcg_temp_new();
19862             TCGv toffset = tcg_temp_new();
19863
19864             gen_load_gpr(tbase, rt);
19865             tcg_gen_movi_tl(toffset, offset);
19866             gen_op_addr_add(ctx, btarget, tbase, toffset);
19867             tcg_temp_free(tbase);
19868             tcg_temp_free(toffset);
19869         }
19870         break;
19871     default:
19872         MIPS_INVAL("Compact branch/jump");
19873         generate_exception_end(ctx, EXCP_RI);
19874         goto out;
19875     }
19876
19877     if (bcond_compute == 0) {
19878         /* Uncoditional compact branch */
19879         switch (opc) {
19880         case OPC_BC:
19881             gen_goto_tb(ctx, 0, ctx->btarget);
19882             break;
19883         default:
19884             MIPS_INVAL("Compact branch/jump");
19885             generate_exception_end(ctx, EXCP_RI);
19886             goto out;
19887         }
19888     } else {
19889         /* Conditional compact branch */
19890         TCGLabel *fs = gen_new_label();
19891
19892         switch (opc) {
19893         case OPC_BGEUC:
19894             if (rs == 0 && rt != 0) {
19895                 /* OPC_BLEZALC */
19896                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19897             } else if (rs != 0 && rt != 0 && rs == rt) {
19898                 /* OPC_BGEZALC */
19899                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19900             } else {
19901                 /* OPC_BGEUC */
19902                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
19903             }
19904             break;
19905         case OPC_BLTUC:
19906             if (rs == 0 && rt != 0) {
19907                 /* OPC_BGTZALC */
19908                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19909             } else if (rs != 0 && rt != 0 && rs == rt) {
19910                 /* OPC_BLTZALC */
19911                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19912             } else {
19913                 /* OPC_BLTUC */
19914                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
19915             }
19916             break;
19917         case OPC_BGEC:
19918             if (rs == 0 && rt != 0) {
19919                 /* OPC_BLEZC */
19920                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19921             } else if (rs != 0 && rt != 0 && rs == rt) {
19922                 /* OPC_BGEZC */
19923                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19924             } else {
19925                 /* OPC_BGEC */
19926                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
19927             }
19928             break;
19929         case OPC_BLTC:
19930             if (rs == 0 && rt != 0) {
19931                 /* OPC_BGTZC */
19932                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19933             } else if (rs != 0 && rt != 0 && rs == rt) {
19934                 /* OPC_BLTZC */
19935                 tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19936             } else {
19937                 /* OPC_BLTC */
19938                 tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
19939             }
19940             break;
19941         case OPC_BEQZC:
19942             tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
19943             break;
19944         default:
19945             MIPS_INVAL("Compact conditional branch/jump");
19946             generate_exception_end(ctx, EXCP_RI);
19947             goto out;
19948         }
19949
19950         /* Generating branch here as compact branches don't have delay slot */
19951         gen_goto_tb(ctx, 1, ctx->btarget);
19952         gen_set_label(fs);
19953
19954         gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19955     }
19956
19957 out:
19958     tcg_temp_free(t0);
19959     tcg_temp_free(t1);
19960 }
19961
19962
19963 /* nanoMIPS CP1 Branches */
19964 static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
19965                                    int32_t ft, int32_t offset)
19966 {
19967     target_ulong btarget;
19968     TCGv_i64 t0 = tcg_temp_new_i64();
19969
19970     gen_load_fpr64(ctx, t0, ft);
19971     tcg_gen_andi_i64(t0, t0, 1);
19972
19973     btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19974
19975     switch (op) {
19976     case NM_BC1EQZC:
19977         tcg_gen_xori_i64(t0, t0, 1);
19978         ctx->hflags |= MIPS_HFLAG_BC;
19979         break;
19980     case NM_BC1NEZC:
19981         /* t0 already set */
19982         ctx->hflags |= MIPS_HFLAG_BC;
19983         break;
19984     default:
19985         MIPS_INVAL("cp1 cond branch");
19986         generate_exception_end(ctx, EXCP_RI);
19987         goto out;
19988     }
19989
19990     tcg_gen_trunc_i64_tl(bcond, t0);
19991
19992     ctx->btarget = btarget;
19993
19994 out:
19995     tcg_temp_free_i64(t0);
19996 }
19997
19998
19999 static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
20000 {
20001     TCGv t0, t1;
20002     t0 = tcg_temp_new();
20003     t1 = tcg_temp_new();
20004
20005     gen_load_gpr(t0, rs);
20006     gen_load_gpr(t1, rt);
20007
20008     if ((extract32(ctx->opcode, 6, 1)) == 1) {
20009         /* PP.LSXS instructions require shifting */
20010         switch (extract32(ctx->opcode, 7, 4)) {
20011         case NM_SHXS:
20012             check_nms(ctx);
20013         case NM_LHXS:
20014         case NM_LHUXS:
20015             tcg_gen_shli_tl(t0, t0, 1);
20016             break;
20017         case NM_SWXS:
20018             check_nms(ctx);
20019         case NM_LWXS:
20020         case NM_LWC1XS:
20021         case NM_SWC1XS:
20022             tcg_gen_shli_tl(t0, t0, 2);
20023             break;
20024         case NM_LDC1XS:
20025         case NM_SDC1XS:
20026             tcg_gen_shli_tl(t0, t0, 3);
20027             break;
20028         }
20029     }
20030     gen_op_addr_add(ctx, t0, t0, t1);
20031
20032     switch (extract32(ctx->opcode, 7, 4)) {
20033     case NM_LBX:
20034         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20035                            MO_SB);
20036         gen_store_gpr(t0, rd);
20037         break;
20038     case NM_LHX:
20039     /*case NM_LHXS:*/
20040         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20041                            MO_TESW);
20042         gen_store_gpr(t0, rd);
20043         break;
20044     case NM_LWX:
20045     /*case NM_LWXS:*/
20046         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20047                            MO_TESL);
20048         gen_store_gpr(t0, rd);
20049         break;
20050     case NM_LBUX:
20051         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20052                            MO_UB);
20053         gen_store_gpr(t0, rd);
20054         break;
20055     case NM_LHUX:
20056     /*case NM_LHUXS:*/
20057         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
20058                            MO_TEUW);
20059         gen_store_gpr(t0, rd);
20060         break;
20061     case NM_SBX:
20062         check_nms(ctx);
20063         gen_load_gpr(t1, rd);
20064         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20065                            MO_8);
20066         break;
20067     case NM_SHX:
20068     /*case NM_SHXS:*/
20069         check_nms(ctx);
20070         gen_load_gpr(t1, rd);
20071         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20072                            MO_TEUW);
20073         break;
20074     case NM_SWX:
20075     /*case NM_SWXS:*/
20076         check_nms(ctx);
20077         gen_load_gpr(t1, rd);
20078         tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
20079                            MO_TEUL);
20080         break;
20081     case NM_LWC1X:
20082     /*case NM_LWC1XS:*/
20083     case NM_LDC1X:
20084     /*case NM_LDC1XS:*/
20085     case NM_SWC1X:
20086     /*case NM_SWC1XS:*/
20087     case NM_SDC1X:
20088     /*case NM_SDC1XS:*/
20089         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
20090             check_cp1_enabled(ctx);
20091             switch (extract32(ctx->opcode, 7, 4)) {
20092             case NM_LWC1X:
20093             /*case NM_LWC1XS:*/
20094                 gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
20095                 break;
20096             case NM_LDC1X:
20097             /*case NM_LDC1XS:*/
20098                 gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
20099                 break;
20100             case NM_SWC1X:
20101             /*case NM_SWC1XS:*/
20102                 gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
20103                 break;
20104             case NM_SDC1X:
20105             /*case NM_SDC1XS:*/
20106                 gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
20107                 break;
20108             }
20109         } else {
20110             generate_exception_err(ctx, EXCP_CpU, 1);
20111         }
20112         break;
20113     default:
20114         generate_exception_end(ctx, EXCP_RI);
20115         break;
20116     }
20117
20118     tcg_temp_free(t0);
20119     tcg_temp_free(t1);
20120 }
20121
20122 static void gen_pool32f_nanomips_insn(DisasContext *ctx)
20123 {
20124     int rt, rs, rd;
20125
20126     rt = extract32(ctx->opcode, 21, 5);
20127     rs = extract32(ctx->opcode, 16, 5);
20128     rd = extract32(ctx->opcode, 11, 5);
20129
20130     if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
20131         generate_exception_end(ctx, EXCP_RI);
20132         return;
20133     }
20134     check_cp1_enabled(ctx);
20135     switch (extract32(ctx->opcode, 0, 3)) {
20136     case NM_POOL32F_0:
20137         switch (extract32(ctx->opcode, 3, 7)) {
20138         case NM_RINT_S:
20139             gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
20140             break;
20141         case NM_RINT_D:
20142             gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
20143             break;
20144         case NM_CLASS_S:
20145             gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
20146             break;
20147         case NM_CLASS_D:
20148             gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
20149             break;
20150         case NM_ADD_S:
20151             gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
20152             break;
20153         case NM_ADD_D:
20154             gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
20155             break;
20156         case NM_SUB_S:
20157             gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
20158             break;
20159         case NM_SUB_D:
20160             gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
20161             break;
20162         case NM_MUL_S:
20163             gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
20164             break;
20165         case NM_MUL_D:
20166             gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
20167             break;
20168         case NM_DIV_S:
20169             gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
20170             break;
20171         case NM_DIV_D:
20172             gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
20173             break;
20174         case NM_SELEQZ_S:
20175             gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
20176             break;
20177         case NM_SELEQZ_D:
20178             gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
20179             break;
20180         case NM_SELNEZ_S:
20181             gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
20182             break;
20183         case NM_SELNEZ_D:
20184             gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
20185             break;
20186         case NM_SEL_S:
20187             gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
20188             break;
20189         case NM_SEL_D:
20190             gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
20191             break;
20192         case NM_MADDF_S:
20193             gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
20194             break;
20195         case NM_MADDF_D:
20196             gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
20197             break;
20198         case NM_MSUBF_S:
20199             gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
20200             break;
20201         case NM_MSUBF_D:
20202             gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
20203             break;
20204         default:
20205             generate_exception_end(ctx, EXCP_RI);
20206             break;
20207         }
20208         break;
20209     case NM_POOL32F_3:
20210         switch (extract32(ctx->opcode, 3, 3)) {
20211         case NM_MIN_FMT:
20212             switch (extract32(ctx->opcode, 9, 1)) {
20213             case FMT_SDPS_S:
20214                 gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
20215                 break;
20216             case FMT_SDPS_D:
20217                 gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
20218                 break;
20219             }
20220             break;
20221         case NM_MAX_FMT:
20222             switch (extract32(ctx->opcode, 9, 1)) {
20223             case FMT_SDPS_S:
20224                 gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
20225                 break;
20226             case FMT_SDPS_D:
20227                 gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
20228                 break;
20229             }
20230             break;
20231         case NM_MINA_FMT:
20232             switch (extract32(ctx->opcode, 9, 1)) {
20233             case FMT_SDPS_S:
20234                 gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
20235                 break;
20236             case FMT_SDPS_D:
20237                 gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
20238                 break;
20239             }
20240             break;
20241         case NM_MAXA_FMT:
20242             switch (extract32(ctx->opcode, 9, 1)) {
20243             case FMT_SDPS_S:
20244                 gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
20245                 break;
20246             case FMT_SDPS_D:
20247                 gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
20248                 break;
20249             }
20250             break;
20251         case NM_POOL32FXF:
20252             switch (extract32(ctx->opcode, 6, 8)) {
20253             case NM_CFC1:
20254                 gen_cp1(ctx, OPC_CFC1, rt, rs);
20255                 break;
20256             case NM_CTC1:
20257                 gen_cp1(ctx, OPC_CTC1, rt, rs);
20258                 break;
20259             case NM_MFC1:
20260                 gen_cp1(ctx, OPC_MFC1, rt, rs);
20261                 break;
20262             case NM_MTC1:
20263                 gen_cp1(ctx, OPC_MTC1, rt, rs);
20264                 break;
20265             case NM_MFHC1:
20266                 gen_cp1(ctx, OPC_MFHC1, rt, rs);
20267                 break;
20268             case NM_MTHC1:
20269                 gen_cp1(ctx, OPC_MTHC1, rt, rs);
20270                 break;
20271             case NM_CVT_S_PL:
20272                 gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
20273                 break;
20274             case NM_CVT_S_PU:
20275                 gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
20276                 break;
20277             default:
20278                 switch (extract32(ctx->opcode, 6, 9)) {
20279                 case NM_CVT_L_S:
20280                     gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
20281                     break;
20282                 case NM_CVT_L_D:
20283                     gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
20284                     break;
20285                 case NM_CVT_W_S:
20286                     gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
20287                     break;
20288                 case NM_CVT_W_D:
20289                     gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
20290                     break;
20291                 case NM_RSQRT_S:
20292                     gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
20293                     break;
20294                 case NM_RSQRT_D:
20295                     gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
20296                     break;
20297                 case NM_SQRT_S:
20298                     gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
20299                     break;
20300                 case NM_SQRT_D:
20301                     gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
20302                     break;
20303                 case NM_RECIP_S:
20304                     gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
20305                     break;
20306                 case NM_RECIP_D:
20307                     gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
20308                     break;
20309                 case NM_FLOOR_L_S:
20310                     gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
20311                     break;
20312                 case NM_FLOOR_L_D:
20313                     gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
20314                     break;
20315                 case NM_FLOOR_W_S:
20316                     gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
20317                     break;
20318                 case NM_FLOOR_W_D:
20319                     gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
20320                     break;
20321                 case NM_CEIL_L_S:
20322                     gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
20323                     break;
20324                 case NM_CEIL_L_D:
20325                     gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
20326                     break;
20327                 case NM_CEIL_W_S:
20328                     gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
20329                     break;
20330                 case NM_CEIL_W_D:
20331                     gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
20332                     break;
20333                 case NM_TRUNC_L_S:
20334                     gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
20335                     break;
20336                 case NM_TRUNC_L_D:
20337                     gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
20338                     break;
20339                 case NM_TRUNC_W_S:
20340                     gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
20341                     break;
20342                 case NM_TRUNC_W_D:
20343                     gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
20344                     break;
20345                 case NM_ROUND_L_S:
20346                     gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
20347                     break;
20348                 case NM_ROUND_L_D:
20349                     gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
20350                     break;
20351                 case NM_ROUND_W_S:
20352                     gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
20353                     break;
20354                 case NM_ROUND_W_D:
20355                     gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
20356                     break;
20357                 case NM_MOV_S:
20358                     gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
20359                     break;
20360                 case NM_MOV_D:
20361                     gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
20362                     break;
20363                 case NM_ABS_S:
20364                     gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
20365                     break;
20366                 case NM_ABS_D:
20367                     gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
20368                     break;
20369                 case NM_NEG_S:
20370                     gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
20371                     break;
20372                 case NM_NEG_D:
20373                     gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
20374                     break;
20375                 case NM_CVT_D_S:
20376                     gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
20377                     break;
20378                 case NM_CVT_D_W:
20379                     gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
20380                     break;
20381                 case NM_CVT_D_L:
20382                     gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
20383                     break;
20384                 case NM_CVT_S_D:
20385                     gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
20386                     break;
20387                 case NM_CVT_S_W:
20388                     gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
20389                     break;
20390                 case NM_CVT_S_L:
20391                     gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
20392                     break;
20393                 default:
20394                     generate_exception_end(ctx, EXCP_RI);
20395                     break;
20396                 }
20397                 break;
20398             }
20399             break;
20400         }
20401         break;
20402     case NM_POOL32F_5:
20403         switch (extract32(ctx->opcode, 3, 3)) {
20404         case NM_CMP_CONDN_S:
20405             gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20406             break;
20407         case NM_CMP_CONDN_D:
20408             gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
20409             break;
20410         default:
20411             generate_exception_end(ctx, EXCP_RI);
20412             break;
20413         }
20414         break;
20415     default:
20416         generate_exception_end(ctx, EXCP_RI);
20417         break;
20418     }
20419 }
20420
20421 static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
20422                                        int rd, int rs, int rt)
20423 {
20424     int ret = rd;
20425     TCGv t0 = tcg_temp_new();
20426     TCGv v1_t = tcg_temp_new();
20427     TCGv v2_t = tcg_temp_new();
20428
20429     gen_load_gpr(v1_t, rs);
20430     gen_load_gpr(v2_t, rt);
20431
20432     switch (opc) {
20433     case NM_CMP_EQ_PH:
20434         check_dsp(ctx);
20435         gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
20436         break;
20437     case NM_CMP_LT_PH:
20438         check_dsp(ctx);
20439         gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
20440         break;
20441     case NM_CMP_LE_PH:
20442         check_dsp(ctx);
20443         gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
20444         break;
20445     case NM_CMPU_EQ_QB:
20446         check_dsp(ctx);
20447         gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
20448         break;
20449     case NM_CMPU_LT_QB:
20450         check_dsp(ctx);
20451         gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
20452         break;
20453     case NM_CMPU_LE_QB:
20454         check_dsp(ctx);
20455         gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
20456         break;
20457     case NM_CMPGU_EQ_QB:
20458         check_dsp(ctx);
20459         gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20460         gen_store_gpr(v1_t, ret);
20461         break;
20462     case NM_CMPGU_LT_QB:
20463         check_dsp(ctx);
20464         gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20465         gen_store_gpr(v1_t, ret);
20466         break;
20467     case NM_CMPGU_LE_QB:
20468         check_dsp(ctx);
20469         gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20470         gen_store_gpr(v1_t, ret);
20471         break;
20472     case NM_CMPGDU_EQ_QB:
20473         check_dsp_r2(ctx);
20474         gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
20475         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20476         gen_store_gpr(v1_t, ret);
20477         break;
20478     case NM_CMPGDU_LT_QB:
20479         check_dsp_r2(ctx);
20480         gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
20481         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20482         gen_store_gpr(v1_t, ret);
20483         break;
20484     case NM_CMPGDU_LE_QB:
20485         check_dsp_r2(ctx);
20486         gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
20487         tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
20488         gen_store_gpr(v1_t, ret);
20489         break;
20490     case NM_PACKRL_PH:
20491         check_dsp(ctx);
20492         gen_helper_packrl_ph(v1_t, v1_t, v2_t);
20493         gen_store_gpr(v1_t, ret);
20494         break;
20495     case NM_PICK_QB:
20496         check_dsp(ctx);
20497         gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
20498         gen_store_gpr(v1_t, ret);
20499         break;
20500     case NM_PICK_PH:
20501         check_dsp(ctx);
20502         gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
20503         gen_store_gpr(v1_t, ret);
20504         break;
20505     case NM_ADDQ_S_W:
20506         check_dsp(ctx);
20507         gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
20508         gen_store_gpr(v1_t, ret);
20509         break;
20510     case NM_SUBQ_S_W:
20511         check_dsp(ctx);
20512         gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
20513         gen_store_gpr(v1_t, ret);
20514         break;
20515     case NM_ADDSC:
20516         check_dsp(ctx);
20517         gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
20518         gen_store_gpr(v1_t, ret);
20519         break;
20520     case NM_ADDWC:
20521         check_dsp(ctx);
20522         gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
20523         gen_store_gpr(v1_t, ret);
20524         break;
20525     case NM_ADDQ_S_PH:
20526         check_dsp(ctx);
20527         switch (extract32(ctx->opcode, 10, 1)) {
20528         case 0:
20529             /* ADDQ_PH */
20530             gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
20531             gen_store_gpr(v1_t, ret);
20532             break;
20533         case 1:
20534             /* ADDQ_S_PH */
20535             gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20536             gen_store_gpr(v1_t, ret);
20537             break;
20538         }
20539         break;
20540     case NM_ADDQH_R_PH:
20541         check_dsp_r2(ctx);
20542         switch (extract32(ctx->opcode, 10, 1)) {
20543         case 0:
20544             /* ADDQH_PH */
20545             gen_helper_addqh_ph(v1_t, v1_t, v2_t);
20546             gen_store_gpr(v1_t, ret);
20547             break;
20548         case 1:
20549             /* ADDQH_R_PH */
20550             gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
20551             gen_store_gpr(v1_t, ret);
20552             break;
20553         }
20554         break;
20555     case NM_ADDQH_R_W:
20556         check_dsp_r2(ctx);
20557         switch (extract32(ctx->opcode, 10, 1)) {
20558         case 0:
20559             /* ADDQH_W */
20560             gen_helper_addqh_w(v1_t, v1_t, v2_t);
20561             gen_store_gpr(v1_t, ret);
20562             break;
20563         case 1:
20564             /* ADDQH_R_W */
20565             gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
20566             gen_store_gpr(v1_t, ret);
20567             break;
20568         }
20569         break;
20570     case NM_ADDU_S_QB:
20571         check_dsp(ctx);
20572         switch (extract32(ctx->opcode, 10, 1)) {
20573         case 0:
20574             /* ADDU_QB */
20575             gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
20576             gen_store_gpr(v1_t, ret);
20577             break;
20578         case 1:
20579             /* ADDU_S_QB */
20580             gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20581             gen_store_gpr(v1_t, ret);
20582             break;
20583         }
20584         break;
20585     case NM_ADDU_S_PH:
20586         check_dsp_r2(ctx);
20587         switch (extract32(ctx->opcode, 10, 1)) {
20588         case 0:
20589             /* ADDU_PH */
20590             gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
20591             gen_store_gpr(v1_t, ret);
20592             break;
20593         case 1:
20594             /* ADDU_S_PH */
20595             gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20596             gen_store_gpr(v1_t, ret);
20597             break;
20598         }
20599         break;
20600     case NM_ADDUH_R_QB:
20601         check_dsp_r2(ctx);
20602         switch (extract32(ctx->opcode, 10, 1)) {
20603         case 0:
20604             /* ADDUH_QB */
20605             gen_helper_adduh_qb(v1_t, v1_t, v2_t);
20606             gen_store_gpr(v1_t, ret);
20607             break;
20608         case 1:
20609             /* ADDUH_R_QB */
20610             gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
20611             gen_store_gpr(v1_t, ret);
20612             break;
20613         }
20614         break;
20615     case NM_SHRAV_R_PH:
20616         check_dsp(ctx);
20617         switch (extract32(ctx->opcode, 10, 1)) {
20618         case 0:
20619             /* SHRAV_PH */
20620             gen_helper_shra_ph(v1_t, v1_t, v2_t);
20621             gen_store_gpr(v1_t, ret);
20622             break;
20623         case 1:
20624             /* SHRAV_R_PH */
20625             gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
20626             gen_store_gpr(v1_t, ret);
20627             break;
20628         }
20629         break;
20630     case NM_SHRAV_R_QB:
20631         check_dsp_r2(ctx);
20632         switch (extract32(ctx->opcode, 10, 1)) {
20633         case 0:
20634             /* SHRAV_QB */
20635             gen_helper_shra_qb(v1_t, v1_t, v2_t);
20636             gen_store_gpr(v1_t, ret);
20637             break;
20638         case 1:
20639             /* SHRAV_R_QB */
20640             gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
20641             gen_store_gpr(v1_t, ret);
20642             break;
20643         }
20644         break;
20645     case NM_SUBQ_S_PH:
20646         check_dsp(ctx);
20647         switch (extract32(ctx->opcode, 10, 1)) {
20648         case 0:
20649             /* SUBQ_PH */
20650             gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
20651             gen_store_gpr(v1_t, ret);
20652             break;
20653         case 1:
20654             /* SUBQ_S_PH */
20655             gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20656             gen_store_gpr(v1_t, ret);
20657             break;
20658         }
20659         break;
20660     case NM_SUBQH_R_PH:
20661         check_dsp_r2(ctx);
20662         switch (extract32(ctx->opcode, 10, 1)) {
20663         case 0:
20664             /* SUBQH_PH */
20665             gen_helper_subqh_ph(v1_t, v1_t, v2_t);
20666             gen_store_gpr(v1_t, ret);
20667             break;
20668         case 1:
20669             /* SUBQH_R_PH */
20670             gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
20671             gen_store_gpr(v1_t, ret);
20672             break;
20673         }
20674         break;
20675     case NM_SUBQH_R_W:
20676         check_dsp_r2(ctx);
20677         switch (extract32(ctx->opcode, 10, 1)) {
20678         case 0:
20679             /* SUBQH_W */
20680             gen_helper_subqh_w(v1_t, v1_t, v2_t);
20681             gen_store_gpr(v1_t, ret);
20682             break;
20683         case 1:
20684             /* SUBQH_R_W */
20685             gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20686             gen_store_gpr(v1_t, ret);
20687             break;
20688         }
20689         break;
20690     case NM_SUBU_S_QB:
20691         check_dsp(ctx);
20692         switch (extract32(ctx->opcode, 10, 1)) {
20693         case 0:
20694             /* SUBU_QB */
20695             gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20696             gen_store_gpr(v1_t, ret);
20697             break;
20698         case 1:
20699             /* SUBU_S_QB */
20700             gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20701             gen_store_gpr(v1_t, ret);
20702             break;
20703         }
20704         break;
20705     case NM_SUBU_S_PH:
20706         check_dsp_r2(ctx);
20707         switch (extract32(ctx->opcode, 10, 1)) {
20708         case 0:
20709             /* SUBU_PH */
20710             gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20711             gen_store_gpr(v1_t, ret);
20712             break;
20713         case 1:
20714             /* SUBU_S_PH */
20715             gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20716             gen_store_gpr(v1_t, ret);
20717             break;
20718         }
20719         break;
20720     case NM_SUBUH_R_QB:
20721         check_dsp_r2(ctx);
20722         switch (extract32(ctx->opcode, 10, 1)) {
20723         case 0:
20724             /* SUBUH_QB */
20725             gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20726             gen_store_gpr(v1_t, ret);
20727             break;
20728         case 1:
20729             /* SUBUH_R_QB */
20730             gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
20731             gen_store_gpr(v1_t, ret);
20732             break;
20733         }
20734         break;
20735     case NM_SHLLV_S_PH:
20736         check_dsp(ctx);
20737         switch (extract32(ctx->opcode, 10, 1)) {
20738         case 0:
20739             /* SHLLV_PH */
20740             gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
20741             gen_store_gpr(v1_t, ret);
20742             break;
20743         case 1:
20744             /* SHLLV_S_PH */
20745             gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
20746             gen_store_gpr(v1_t, ret);
20747             break;
20748         }
20749         break;
20750     case NM_PRECR_SRA_R_PH_W:
20751         check_dsp_r2(ctx);
20752         switch (extract32(ctx->opcode, 10, 1)) {
20753         case 0:
20754             /* PRECR_SRA_PH_W */
20755             {
20756                 TCGv_i32 sa_t = tcg_const_i32(rd);
20757                 gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
20758                                           cpu_gpr[rt]);
20759                 gen_store_gpr(v1_t, rt);
20760                 tcg_temp_free_i32(sa_t);
20761             }
20762             break;
20763         case 1:
20764             /* PRECR_SRA_R_PH_W */
20765             {
20766                 TCGv_i32 sa_t = tcg_const_i32(rd);
20767                 gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
20768                                             cpu_gpr[rt]);
20769                 gen_store_gpr(v1_t, rt);
20770                 tcg_temp_free_i32(sa_t);
20771             }
20772             break;
20773        }
20774         break;
20775     case NM_MULEU_S_PH_QBL:
20776         check_dsp(ctx);
20777         gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
20778         gen_store_gpr(v1_t, ret);
20779         break;
20780     case NM_MULEU_S_PH_QBR:
20781         check_dsp(ctx);
20782         gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
20783         gen_store_gpr(v1_t, ret);
20784         break;
20785     case NM_MULQ_RS_PH:
20786         check_dsp(ctx);
20787         gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
20788         gen_store_gpr(v1_t, ret);
20789         break;
20790     case NM_MULQ_S_PH:
20791         check_dsp_r2(ctx);
20792         gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20793         gen_store_gpr(v1_t, ret);
20794         break;
20795     case NM_MULQ_RS_W:
20796         check_dsp_r2(ctx);
20797         gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
20798         gen_store_gpr(v1_t, ret);
20799         break;
20800     case NM_MULQ_S_W:
20801         check_dsp_r2(ctx);
20802         gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
20803         gen_store_gpr(v1_t, ret);
20804         break;
20805     case NM_APPEND:
20806         check_dsp_r2(ctx);
20807         gen_load_gpr(t0, rs);
20808         if (rd != 0) {
20809             tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
20810         }
20811         tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20812         break;
20813     case NM_MODSUB:
20814         check_dsp(ctx);
20815         gen_helper_modsub(v1_t, v1_t, v2_t);
20816         gen_store_gpr(v1_t, ret);
20817         break;
20818     case NM_SHRAV_R_W:
20819         check_dsp(ctx);
20820         gen_helper_shra_r_w(v1_t, v1_t, v2_t);
20821         gen_store_gpr(v1_t, ret);
20822         break;
20823     case NM_SHRLV_PH:
20824         check_dsp_r2(ctx);
20825         gen_helper_shrl_ph(v1_t, v1_t, v2_t);
20826         gen_store_gpr(v1_t, ret);
20827         break;
20828     case NM_SHRLV_QB:
20829         check_dsp(ctx);
20830         gen_helper_shrl_qb(v1_t, v1_t, v2_t);
20831         gen_store_gpr(v1_t, ret);
20832         break;
20833     case NM_SHLLV_QB:
20834         check_dsp(ctx);
20835         gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
20836         gen_store_gpr(v1_t, ret);
20837         break;
20838     case NM_SHLLV_S_W:
20839         check_dsp(ctx);
20840         gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
20841         gen_store_gpr(v1_t, ret);
20842         break;
20843     case NM_SHILO:
20844         check_dsp(ctx);
20845         {
20846             TCGv tv0 = tcg_temp_new();
20847             TCGv tv1 = tcg_temp_new();
20848             int16_t imm = extract32(ctx->opcode, 16, 7);
20849
20850             tcg_gen_movi_tl(tv0, rd >> 3);
20851             tcg_gen_movi_tl(tv1, imm);
20852             gen_helper_shilo(tv0, tv1, cpu_env);
20853         }
20854         break;
20855     case NM_MULEQ_S_W_PHL:
20856         check_dsp(ctx);
20857         gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
20858         gen_store_gpr(v1_t, ret);
20859         break;
20860     case NM_MULEQ_S_W_PHR:
20861         check_dsp(ctx);
20862         gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
20863         gen_store_gpr(v1_t, ret);
20864         break;
20865     case NM_MUL_S_PH:
20866         check_dsp_r2(ctx);
20867         switch (extract32(ctx->opcode, 10, 1)) {
20868         case 0:
20869             /* MUL_PH */
20870             gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
20871             gen_store_gpr(v1_t, ret);
20872             break;
20873         case 1:
20874             /* MUL_S_PH */
20875             gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
20876             gen_store_gpr(v1_t, ret);
20877             break;
20878         }
20879         break;
20880     case NM_PRECR_QB_PH:
20881         check_dsp_r2(ctx);
20882         gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
20883         gen_store_gpr(v1_t, ret);
20884         break;
20885     case NM_PRECRQ_QB_PH:
20886         check_dsp(ctx);
20887         gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
20888         gen_store_gpr(v1_t, ret);
20889         break;
20890     case NM_PRECRQ_PH_W:
20891         check_dsp(ctx);
20892         gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
20893         gen_store_gpr(v1_t, ret);
20894         break;
20895     case NM_PRECRQ_RS_PH_W:
20896         check_dsp(ctx);
20897         gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
20898         gen_store_gpr(v1_t, ret);
20899         break;
20900     case NM_PRECRQU_S_QB_PH:
20901         check_dsp(ctx);
20902         gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
20903         gen_store_gpr(v1_t, ret);
20904         break;
20905     case NM_SHRA_R_W:
20906         check_dsp(ctx);
20907         tcg_gen_movi_tl(t0, rd);
20908         gen_helper_shra_r_w(v1_t, t0, v1_t);
20909         gen_store_gpr(v1_t, rt);
20910         break;
20911     case NM_SHRA_R_PH:
20912         check_dsp(ctx);
20913         tcg_gen_movi_tl(t0, rd >> 1);
20914         switch (extract32(ctx->opcode, 10, 1)) {
20915         case 0:
20916             /* SHRA_PH */
20917             gen_helper_shra_ph(v1_t, t0, v1_t);
20918             gen_store_gpr(v1_t, rt);
20919             break;
20920         case 1:
20921             /* SHRA_R_PH */
20922             gen_helper_shra_r_ph(v1_t, t0, v1_t);
20923             gen_store_gpr(v1_t, rt);
20924             break;
20925         }
20926         break;
20927     case NM_SHLL_S_PH:
20928         check_dsp(ctx);
20929         tcg_gen_movi_tl(t0, rd >> 1);
20930         switch (extract32(ctx->opcode, 10, 2)) {
20931         case 0:
20932             /* SHLL_PH */
20933             gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
20934             gen_store_gpr(v1_t, rt);
20935             break;
20936         case 2:
20937             /* SHLL_S_PH */
20938             gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
20939             gen_store_gpr(v1_t, rt);
20940             break;
20941         default:
20942             generate_exception_end(ctx, EXCP_RI);
20943             break;
20944         }
20945         break;
20946     case NM_SHLL_S_W:
20947         check_dsp(ctx);
20948         tcg_gen_movi_tl(t0, rd);
20949         gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
20950         gen_store_gpr(v1_t, rt);
20951         break;
20952     case NM_REPL_PH:
20953         check_dsp(ctx);
20954         {
20955             int16_t imm;
20956             imm = sextract32(ctx->opcode, 11, 11);
20957             imm = (int16_t)(imm << 6) >> 6;
20958             if (rt != 0) {
20959                 tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
20960             }
20961         }
20962         break;
20963     default:
20964         generate_exception_end(ctx, EXCP_RI);
20965         break;
20966     }
20967 }
20968
20969 static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
20970 {
20971     uint16_t insn;
20972     uint32_t op;
20973     int rt, rs, rd;
20974     int offset;
20975     int imm;
20976
20977     insn = cpu_lduw_code(env, ctx->base.pc_next + 2);
20978     ctx->opcode = (ctx->opcode << 16) | insn;
20979
20980     rt = extract32(ctx->opcode, 21, 5);
20981     rs = extract32(ctx->opcode, 16, 5);
20982     rd = extract32(ctx->opcode, 11, 5);
20983
20984     op = extract32(ctx->opcode, 26, 6);
20985     switch (op) {
20986     case NM_P_ADDIU:
20987         if (rt == 0) {
20988             /* P.RI */
20989             switch (extract32(ctx->opcode, 19, 2)) {
20990             case NM_SIGRIE:
20991             default:
20992                 generate_exception_end(ctx, EXCP_RI);
20993                 break;
20994             case NM_P_SYSCALL:
20995                 if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
20996                     generate_exception_end(ctx, EXCP_SYSCALL);
20997                 } else {
20998                     generate_exception_end(ctx, EXCP_RI);
20999                 }
21000                 break;
21001             case NM_BREAK:
21002                 generate_exception_end(ctx, EXCP_BREAK);
21003                 break;
21004             case NM_SDBBP:
21005                 if (is_uhi(extract32(ctx->opcode, 0, 19))) {
21006                     gen_helper_do_semihosting(cpu_env);
21007                 } else {
21008                     if (ctx->hflags & MIPS_HFLAG_SBRI) {
21009                         generate_exception_end(ctx, EXCP_RI);
21010                     } else {
21011                         generate_exception_end(ctx, EXCP_DBp);
21012                     }
21013                 }
21014                 break;
21015             }
21016         } else {
21017             /* NM_ADDIU */
21018             imm = extract32(ctx->opcode, 0, 16);
21019             if (rs != 0) {
21020                 tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
21021             } else {
21022                 tcg_gen_movi_tl(cpu_gpr[rt], imm);
21023             }
21024             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21025         }
21026         break;
21027     case NM_ADDIUPC:
21028         if (rt != 0) {
21029             offset = sextract32(ctx->opcode, 0, 1) << 21 |
21030                      extract32(ctx->opcode, 1, 20) << 1;
21031             target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
21032             tcg_gen_movi_tl(cpu_gpr[rt], addr);
21033         }
21034         break;
21035     case NM_POOL32A:
21036         switch (ctx->opcode & 0x07) {
21037         case NM_POOL32A0:
21038             gen_pool32a0_nanomips_insn(env, ctx);
21039             break;
21040         case NM_POOL32A5:
21041             {
21042                 int32_t op1 = extract32(ctx->opcode, 3, 7);
21043                 gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
21044             }
21045             break;
21046         case NM_POOL32A7:
21047             switch (extract32(ctx->opcode, 3, 3)) {
21048             case NM_P_LSX:
21049                 gen_p_lsx(ctx, rd, rs, rt);
21050                 break;
21051             case NM_LSA:
21052                 /* In nanoMIPS, the shift field directly encodes the shift
21053                  * amount, meaning that the supported shift values are in
21054                  * the range 0 to 3 (instead of 1 to 4 in MIPSR6). */
21055                 gen_lsa(ctx, OPC_LSA, rd, rs, rt,
21056                         extract32(ctx->opcode, 9, 2) - 1);
21057                 break;
21058             case NM_EXTW:
21059                 gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
21060                 break;
21061             case NM_POOL32AXF:
21062                 gen_pool32axf_nanomips_insn(env, ctx);
21063                 break;
21064             default:
21065                 generate_exception_end(ctx, EXCP_RI);
21066                 break;
21067             }
21068             break;
21069         default:
21070             generate_exception_end(ctx, EXCP_RI);
21071             break;
21072         }
21073         break;
21074     case NM_P_GP_W:
21075         switch (ctx->opcode & 0x03) {
21076         case NM_ADDIUGP_W:
21077             if (rt != 0) {
21078                 offset = extract32(ctx->opcode, 0, 21);
21079                 gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
21080             }
21081             break;
21082         case NM_LWGP:
21083             gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21084             break;
21085         case NM_SWGP:
21086             gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
21087             break;
21088         default:
21089             generate_exception_end(ctx, EXCP_RI);
21090             break;
21091         }
21092         break;
21093     case NM_P48I:
21094         {
21095             insn = cpu_lduw_code(env, ctx->base.pc_next + 4);
21096             target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
21097             switch (extract32(ctx->opcode, 16, 5)) {
21098             case NM_LI48:
21099                 check_nms(ctx);
21100                 if (rt != 0) {
21101                     tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
21102                 }
21103                 break;
21104             case NM_ADDIU48:
21105                 check_nms(ctx);
21106                 if (rt != 0) {
21107                     tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
21108                     tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
21109                 }
21110                 break;
21111             case NM_ADDIUGP48:
21112                 check_nms(ctx);
21113                 if (rt != 0) {
21114                     gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
21115                 }
21116                 break;
21117             case NM_ADDIUPC48:
21118                 check_nms(ctx);
21119                 if (rt != 0) {
21120                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21121                                                 addr_off);
21122
21123                     tcg_gen_movi_tl(cpu_gpr[rt], addr);
21124                 }
21125                 break;
21126             case NM_LWPC48:
21127                 check_nms(ctx);
21128                 if (rt != 0) {
21129                     TCGv t0;
21130                     t0 = tcg_temp_new();
21131
21132                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21133                                                 addr_off);
21134
21135                     tcg_gen_movi_tl(t0, addr);
21136                     tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
21137                     tcg_temp_free(t0);
21138                 }
21139                 break;
21140             case NM_SWPC48:
21141                 check_nms(ctx);
21142                 {
21143                     TCGv t0, t1;
21144                     t0 = tcg_temp_new();
21145                     t1 = tcg_temp_new();
21146
21147                     target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
21148                                                 addr_off);
21149
21150                     tcg_gen_movi_tl(t0, addr);
21151                     gen_load_gpr(t1, rt);
21152
21153                     tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
21154
21155                     tcg_temp_free(t0);
21156                     tcg_temp_free(t1);
21157                 }
21158                 break;
21159             default:
21160                 generate_exception_end(ctx, EXCP_RI);
21161                 break;
21162             }
21163             return 6;
21164         }
21165     case NM_P_U12:
21166         switch (extract32(ctx->opcode, 12, 4)) {
21167         case NM_ORI:
21168             gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
21169             break;
21170         case NM_XORI:
21171             gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
21172             break;
21173         case NM_ANDI:
21174             gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
21175             break;
21176         case NM_P_SR:
21177             switch (extract32(ctx->opcode, 20, 1)) {
21178             case NM_PP_SR:
21179                 switch (ctx->opcode & 3) {
21180                 case NM_SAVE:
21181                     gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
21182                              extract32(ctx->opcode, 2, 1),
21183                              extract32(ctx->opcode, 3, 9) << 3);
21184                     break;
21185                 case NM_RESTORE:
21186                 case NM_RESTORE_JRC:
21187                     gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
21188                                 extract32(ctx->opcode, 2, 1),
21189                                 extract32(ctx->opcode, 3, 9) << 3);
21190                     if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
21191                         gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21192                     }
21193                     break;
21194                 default:
21195                     generate_exception_end(ctx, EXCP_RI);
21196                     break;
21197                 }
21198                 break;
21199             case NM_P_SR_F:
21200                 generate_exception_end(ctx, EXCP_RI);
21201                 break;
21202             }
21203             break;
21204         case NM_SLTI:
21205             gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
21206             break;
21207         case NM_SLTIU:
21208             gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
21209             break;
21210         case NM_SEQI:
21211             {
21212                 TCGv t0 = tcg_temp_new();
21213
21214                 imm = extract32(ctx->opcode, 0, 12);
21215                 gen_load_gpr(t0, rs);
21216                 tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
21217                 gen_store_gpr(t0, rt);
21218
21219                 tcg_temp_free(t0);
21220             }
21221             break;
21222         case NM_ADDIUNEG:
21223             imm = (int16_t) extract32(ctx->opcode, 0, 12);
21224             gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
21225             break;
21226         case NM_P_SHIFT:
21227             {
21228                 int shift = extract32(ctx->opcode, 0, 5);
21229                 switch (extract32(ctx->opcode, 5, 4)) {
21230                 case NM_P_SLL:
21231                     if (rt == 0 && shift == 0) {
21232                         /* NOP */
21233                     } else if (rt == 0 && shift == 3) {
21234                         /* EHB - treat as NOP */
21235                     } else if (rt == 0 && shift == 5) {
21236                         /* PAUSE - treat as NOP */
21237                     } else if (rt == 0 && shift == 6) {
21238                         /* SYNC */
21239                         gen_sync(extract32(ctx->opcode, 16, 5));
21240                     } else {
21241                         /* SLL */
21242                         gen_shift_imm(ctx, OPC_SLL, rt, rs,
21243                                       extract32(ctx->opcode, 0, 5));
21244                     }
21245                     break;
21246                 case NM_SRL:
21247                     gen_shift_imm(ctx, OPC_SRL, rt, rs,
21248                                   extract32(ctx->opcode, 0, 5));
21249                     break;
21250                 case NM_SRA:
21251                     gen_shift_imm(ctx, OPC_SRA, rt, rs,
21252                                   extract32(ctx->opcode, 0, 5));
21253                     break;
21254                 case NM_ROTR:
21255                     gen_shift_imm(ctx, OPC_ROTR, rt, rs,
21256                                   extract32(ctx->opcode, 0, 5));
21257                     break;
21258                 }
21259             }
21260             break;
21261         case NM_P_ROTX:
21262             check_nms(ctx);
21263             if (rt != 0) {
21264                 TCGv t0 = tcg_temp_new();
21265                 TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
21266                 TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
21267                                                 << 1);
21268                 TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
21269
21270                 gen_load_gpr(t0, rs);
21271                 gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
21272                 tcg_temp_free(t0);
21273
21274                 tcg_temp_free_i32(shift);
21275                 tcg_temp_free_i32(shiftx);
21276                 tcg_temp_free_i32(stripe);
21277             }
21278             break;
21279         case NM_P_INS:
21280             switch (((ctx->opcode >> 10) & 2) |
21281                     (extract32(ctx->opcode, 5, 1))) {
21282             case NM_INS:
21283                 check_nms(ctx);
21284                 gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
21285                            extract32(ctx->opcode, 6, 5));
21286                 break;
21287             default:
21288                 generate_exception_end(ctx, EXCP_RI);
21289                 break;
21290             }
21291             break;
21292         case NM_P_EXT:
21293             switch (((ctx->opcode >> 10) & 2) |
21294                     (extract32(ctx->opcode, 5, 1))) {
21295             case NM_EXT:
21296                 check_nms(ctx);
21297                 gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
21298                            extract32(ctx->opcode, 6, 5));
21299                 break;
21300             default:
21301                 generate_exception_end(ctx, EXCP_RI);
21302                 break;
21303             }
21304             break;
21305         default:
21306             generate_exception_end(ctx, EXCP_RI);
21307             break;
21308         }
21309         break;
21310     case NM_POOL32F:
21311         gen_pool32f_nanomips_insn(ctx);
21312         break;
21313     case NM_POOL32S:
21314         break;
21315     case NM_P_LUI:
21316         switch (extract32(ctx->opcode, 1, 1)) {
21317         case NM_LUI:
21318             if (rt != 0) {
21319                 tcg_gen_movi_tl(cpu_gpr[rt],
21320                                 sextract32(ctx->opcode, 0, 1) << 31 |
21321                                 extract32(ctx->opcode, 2, 10) << 21 |
21322                                 extract32(ctx->opcode, 12, 9) << 12);
21323             }
21324             break;
21325         case NM_ALUIPC:
21326             if (rt != 0) {
21327                 offset = sextract32(ctx->opcode, 0, 1) << 31 |
21328                          extract32(ctx->opcode, 2, 10) << 21 |
21329                          extract32(ctx->opcode, 12, 9) << 12;
21330                 target_long addr;
21331                 addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
21332                 tcg_gen_movi_tl(cpu_gpr[rt], addr);
21333             }
21334             break;
21335         }
21336         break;
21337     case NM_P_GP_BH:
21338         {
21339             uint32_t u = extract32(ctx->opcode, 0, 18);
21340
21341             switch (extract32(ctx->opcode, 18, 3)) {
21342             case NM_LBGP:
21343                 gen_ld(ctx, OPC_LB, rt, 28, u);
21344                 break;
21345             case NM_SBGP:
21346                 gen_st(ctx, OPC_SB, rt, 28, u);
21347                 break;
21348             case NM_LBUGP:
21349                 gen_ld(ctx, OPC_LBU, rt, 28, u);
21350                 break;
21351             case NM_ADDIUGP_B:
21352                 if (rt != 0) {
21353                     gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
21354                 }
21355                 break;
21356             case NM_P_GP_LH:
21357                 u &= ~1;
21358                 switch (ctx->opcode & 1) {
21359                 case NM_LHGP:
21360                     gen_ld(ctx, OPC_LH, rt, 28, u);
21361                     break;
21362                 case NM_LHUGP:
21363                     gen_ld(ctx, OPC_LHU, rt, 28, u);
21364                     break;
21365                 }
21366                 break;
21367             case NM_P_GP_SH:
21368                 u &= ~1;
21369                 switch (ctx->opcode & 1) {
21370                 case NM_SHGP:
21371                     gen_st(ctx, OPC_SH, rt, 28, u);
21372                     break;
21373                 default:
21374                     generate_exception_end(ctx, EXCP_RI);
21375                     break;
21376                 }
21377                 break;
21378             case NM_P_GP_CP1:
21379                 u &= ~0x3;
21380                 switch (ctx->opcode & 0x3) {
21381                 case NM_LWC1GP:
21382                     gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
21383                     break;
21384                 case NM_LDC1GP:
21385                     gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
21386                     break;
21387                 case NM_SWC1GP:
21388                     gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
21389                     break;
21390                 case NM_SDC1GP:
21391                     gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
21392                     break;
21393                 }
21394                 break;
21395             default:
21396                 generate_exception_end(ctx, EXCP_RI);
21397                 break;
21398             }
21399         }
21400         break;
21401     case NM_P_LS_U12:
21402         {
21403             uint32_t u = extract32(ctx->opcode, 0, 12);
21404
21405             switch (extract32(ctx->opcode, 12, 4)) {
21406             case NM_P_PREFU12:
21407                 if (rt == 31) {
21408                     /* SYNCI */
21409                     /* Break the TB to be able to sync copied instructions
21410                        immediately */
21411                     ctx->base.is_jmp = DISAS_STOP;
21412                 } else {
21413                     /* PREF */
21414                     /* Treat as NOP. */
21415                 }
21416                 break;
21417             case NM_LB:
21418                 gen_ld(ctx, OPC_LB, rt, rs, u);
21419                 break;
21420             case NM_LH:
21421                 gen_ld(ctx, OPC_LH, rt, rs, u);
21422                 break;
21423             case NM_LW:
21424                 gen_ld(ctx, OPC_LW, rt, rs, u);
21425                 break;
21426             case NM_LBU:
21427                 gen_ld(ctx, OPC_LBU, rt, rs, u);
21428                 break;
21429             case NM_LHU:
21430                 gen_ld(ctx, OPC_LHU, rt, rs, u);
21431                 break;
21432             case NM_SB:
21433                 gen_st(ctx, OPC_SB, rt, rs, u);
21434                 break;
21435             case NM_SH:
21436                 gen_st(ctx, OPC_SH, rt, rs, u);
21437                 break;
21438             case NM_SW:
21439                 gen_st(ctx, OPC_SW, rt, rs, u);
21440                 break;
21441             case NM_LWC1:
21442                 gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
21443                 break;
21444             case NM_LDC1:
21445                 gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
21446                 break;
21447             case NM_SWC1:
21448                 gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
21449                 break;
21450             case NM_SDC1:
21451                 gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
21452                 break;
21453             default:
21454                 generate_exception_end(ctx, EXCP_RI);
21455                 break;
21456             }
21457         }
21458         break;
21459     case NM_P_LS_S9:
21460         {
21461             int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
21462                         extract32(ctx->opcode, 0, 8);
21463
21464             switch (extract32(ctx->opcode, 8, 3)) {
21465             case NM_P_LS_S0:
21466                 switch (extract32(ctx->opcode, 11, 4)) {
21467                 case NM_LBS9:
21468                     gen_ld(ctx, OPC_LB, rt, rs, s);
21469                     break;
21470                 case NM_LHS9:
21471                     gen_ld(ctx, OPC_LH, rt, rs, s);
21472                     break;
21473                 case NM_LWS9:
21474                     gen_ld(ctx, OPC_LW, rt, rs, s);
21475                     break;
21476                 case NM_LBUS9:
21477                     gen_ld(ctx, OPC_LBU, rt, rs, s);
21478                     break;
21479                 case NM_LHUS9:
21480                     gen_ld(ctx, OPC_LHU, rt, rs, s);
21481                     break;
21482                 case NM_SBS9:
21483                     gen_st(ctx, OPC_SB, rt, rs, s);
21484                     break;
21485                 case NM_SHS9:
21486                     gen_st(ctx, OPC_SH, rt, rs, s);
21487                     break;
21488                 case NM_SWS9:
21489                     gen_st(ctx, OPC_SW, rt, rs, s);
21490                     break;
21491                 case NM_LWC1S9:
21492                     gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
21493                     break;
21494                 case NM_LDC1S9:
21495                     gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
21496                     break;
21497                 case NM_SWC1S9:
21498                     gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
21499                     break;
21500                 case NM_SDC1S9:
21501                     gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
21502                     break;
21503                 case NM_P_PREFS9:
21504                     if (rt == 31) {
21505                         /* SYNCI */
21506                         /* Break the TB to be able to sync copied instructions
21507                            immediately */
21508                         ctx->base.is_jmp = DISAS_STOP;
21509                     } else {
21510                         /* PREF */
21511                         /* Treat as NOP. */
21512                     }
21513                     break;
21514                 default:
21515                     generate_exception_end(ctx, EXCP_RI);
21516                     break;
21517                 }
21518                 break;
21519             case NM_P_LS_S1:
21520                 switch (extract32(ctx->opcode, 11, 4)) {
21521                 case NM_UALH:
21522                 case NM_UASH:
21523                     check_nms(ctx);
21524                     {
21525                         TCGv t0 = tcg_temp_new();
21526                         TCGv t1 = tcg_temp_new();
21527
21528                         gen_base_offset_addr(ctx, t0, rs, s);
21529
21530                         switch (extract32(ctx->opcode, 11, 4)) {
21531                         case NM_UALH:
21532                             tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
21533                                                MO_UNALN);
21534                             gen_store_gpr(t0, rt);
21535                             break;
21536                         case NM_UASH:
21537                             gen_load_gpr(t1, rt);
21538                             tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
21539                                                MO_UNALN);
21540                             break;
21541                         }
21542                         tcg_temp_free(t0);
21543                         tcg_temp_free(t1);
21544                     }
21545                     break;
21546                 case NM_P_LL:
21547                     switch (ctx->opcode & 0x03) {
21548                     case NM_LL:
21549                         gen_ld(ctx, OPC_LL, rt, rs, s);
21550                         break;
21551                     case NM_LLWP:
21552                         check_xnp(ctx);
21553                         gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21554                         break;
21555                     }
21556                     break;
21557                 case NM_P_SC:
21558                     switch (ctx->opcode & 0x03) {
21559                     case NM_SC:
21560                         gen_st_cond(ctx, OPC_SC, rt, rs, s);
21561                         break;
21562                     case NM_SCWP:
21563                         check_xnp(ctx);
21564                         gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21565                         break;
21566                     }
21567                     break;
21568                 case NM_CACHE:
21569                     check_cp0_enabled(ctx);
21570                     if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
21571                         gen_cache_operation(ctx, rt, rs, s);
21572                     }
21573                     break;
21574                 }
21575                 break;
21576             case NM_P_LS_E0:
21577                 switch (extract32(ctx->opcode, 11, 4)) {
21578                 case NM_LBE:
21579                     check_eva(ctx);
21580                     check_cp0_enabled(ctx);
21581                     gen_ld(ctx, OPC_LBE, rt, rs, s);
21582                     break;
21583                 case NM_SBE:
21584                     check_eva(ctx);
21585                     check_cp0_enabled(ctx);
21586                     gen_st(ctx, OPC_SBE, rt, rs, s);
21587                     break;
21588                 case NM_LBUE:
21589                     check_eva(ctx);
21590                     check_cp0_enabled(ctx);
21591                     gen_ld(ctx, OPC_LBUE, rt, rs, s);
21592                     break;
21593                 case NM_P_PREFE:
21594                     if (rt == 31) {
21595                         /* case NM_SYNCIE */
21596                         check_eva(ctx);
21597                         check_cp0_enabled(ctx);
21598                         /* Break the TB to be able to sync copied instructions
21599                            immediately */
21600                         ctx->base.is_jmp = DISAS_STOP;
21601                     } else {
21602                         /* case NM_PREFE */
21603                         check_eva(ctx);
21604                         check_cp0_enabled(ctx);
21605                         /* Treat as NOP. */
21606                     }
21607                     break;
21608                 case NM_LHE:
21609                     check_eva(ctx);
21610                     check_cp0_enabled(ctx);
21611                     gen_ld(ctx, OPC_LHE, rt, rs, s);
21612                     break;
21613                 case NM_SHE:
21614                     check_eva(ctx);
21615                     check_cp0_enabled(ctx);
21616                     gen_st(ctx, OPC_SHE, rt, rs, s);
21617                     break;
21618                 case NM_LHUE:
21619                     check_eva(ctx);
21620                     check_cp0_enabled(ctx);
21621                     gen_ld(ctx, OPC_LHUE, rt, rs, s);
21622                     break;
21623                 case NM_CACHEE:
21624                     check_nms_dl_il_sl_tl_l2c(ctx);
21625                     gen_cache_operation(ctx, rt, rs, s);
21626                     break;
21627                 case NM_LWE:
21628                     check_eva(ctx);
21629                     check_cp0_enabled(ctx);
21630                     gen_ld(ctx, OPC_LWE, rt, rs, s);
21631                     break;
21632                 case NM_SWE:
21633                     check_eva(ctx);
21634                     check_cp0_enabled(ctx);
21635                     gen_st(ctx, OPC_SWE, rt, rs, s);
21636                     break;
21637                 case NM_P_LLE:
21638                     switch (extract32(ctx->opcode, 2, 2)) {
21639                     case NM_LLE:
21640                         check_xnp(ctx);
21641                         check_eva(ctx);
21642                         check_cp0_enabled(ctx);
21643                         gen_ld(ctx, OPC_LLE, rt, rs, s);
21644                         break;
21645                     case NM_LLWPE:
21646                         check_xnp(ctx);
21647                         check_eva(ctx);
21648                         check_cp0_enabled(ctx);
21649                         gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21650                         break;
21651                     default:
21652                         generate_exception_end(ctx, EXCP_RI);
21653                         break;
21654                     }
21655                     break;
21656                 case NM_P_SCE:
21657                     switch (extract32(ctx->opcode, 2, 2)) {
21658                     case NM_SCE:
21659                         check_xnp(ctx);
21660                         check_eva(ctx);
21661                         check_cp0_enabled(ctx);
21662                         gen_st_cond(ctx, OPC_SCE, rt, rs, s);
21663                         break;
21664                     case NM_SCWPE:
21665                         check_xnp(ctx);
21666                         check_eva(ctx);
21667                         check_cp0_enabled(ctx);
21668                         gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
21669                         break;
21670                     default:
21671                         generate_exception_end(ctx, EXCP_RI);
21672                         break;
21673                     }
21674                     break;
21675                 }
21676                 break;
21677             case NM_P_LS_WM:
21678             case NM_P_LS_UAWM:
21679                 check_nms(ctx);
21680                 {
21681                     int count = extract32(ctx->opcode, 12, 3);
21682                     int counter = 0;
21683
21684                     offset = sextract32(ctx->opcode, 15, 1) << 8 |
21685                              extract32(ctx->opcode, 0, 8);
21686                     TCGv va = tcg_temp_new();
21687                     TCGv t1 = tcg_temp_new();
21688                     TCGMemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21689                                       NM_P_LS_UAWM ? MO_UNALN : 0;
21690
21691                     count = (count == 0) ? 8 : count;
21692                     while (counter != count) {
21693                         int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21694                         int this_offset = offset + (counter << 2);
21695
21696                         gen_base_offset_addr(ctx, va, rs, this_offset);
21697
21698                         switch (extract32(ctx->opcode, 11, 1)) {
21699                         case NM_LWM:
21700                             tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21701                                                memop | MO_TESL);
21702                             gen_store_gpr(t1, this_rt);
21703                             if ((this_rt == rs) &&
21704                                 (counter != (count - 1))) {
21705                                 /* UNPREDICTABLE */
21706                             }
21707                             break;
21708                         case NM_SWM:
21709                             this_rt = (rt == 0) ? 0 : this_rt;
21710                             gen_load_gpr(t1, this_rt);
21711                             tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21712                                                memop | MO_TEUL);
21713                             break;
21714                         }
21715                         counter++;
21716                     }
21717                     tcg_temp_free(va);
21718                     tcg_temp_free(t1);
21719                 }
21720                 break;
21721             default:
21722                 generate_exception_end(ctx, EXCP_RI);
21723                 break;
21724             }
21725         }
21726         break;
21727     case NM_MOVE_BALC:
21728         check_nms(ctx);
21729         {
21730             TCGv t0 = tcg_temp_new();
21731             int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
21732                         extract32(ctx->opcode, 1, 20) << 1;
21733             rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
21734             rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
21735                             extract32(ctx->opcode, 21, 3));
21736             gen_load_gpr(t0, rt);
21737             tcg_gen_mov_tl(cpu_gpr[rd], t0);
21738             gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21739             tcg_temp_free(t0);
21740         }
21741         break;
21742     case NM_P_BAL:
21743         {
21744             int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
21745                         extract32(ctx->opcode, 1, 24) << 1;
21746
21747             if ((extract32(ctx->opcode, 25, 1)) == 0) {
21748                 /* BC */
21749                 gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
21750             } else {
21751                 /* BALC */
21752                 gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21753             }
21754         }
21755         break;
21756     case NM_P_J:
21757         switch (extract32(ctx->opcode, 12, 4)) {
21758         case NM_JALRC:
21759         case NM_JALRC_HB:
21760             gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
21761             break;
21762         case NM_P_BALRSC:
21763             gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
21764             break;
21765         default:
21766             generate_exception_end(ctx, EXCP_RI);
21767             break;
21768         }
21769         break;
21770     case NM_P_BR1:
21771         {
21772             int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21773                         extract32(ctx->opcode, 1, 13) << 1;
21774             switch (extract32(ctx->opcode, 14, 2)) {
21775             case NM_BEQC:
21776                 check_nms(ctx);
21777                 gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
21778                 break;
21779             case NM_P_BR3A:
21780                 s = sextract32(ctx->opcode, 0, 1) << 14 |
21781                     extract32(ctx->opcode, 1, 13) << 1;
21782                 check_cp1_enabled(ctx);
21783                 switch (extract32(ctx->opcode, 16, 5)) {
21784                 case NM_BC1EQZC:
21785                     gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
21786                     break;
21787                 case NM_BC1NEZC:
21788                     gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
21789                     break;
21790                 case NM_BPOSGE32C:
21791                     check_dsp_r3(ctx);
21792                     {
21793                         int32_t imm = extract32(ctx->opcode, 1, 13) |
21794                                       extract32(ctx->opcode, 0, 1) << 13;
21795
21796                         gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
21797                                               imm);
21798                     }
21799                     break;
21800                 default:
21801                     generate_exception_end(ctx, EXCP_RI);
21802                     break;
21803                 }
21804                 break;
21805             case NM_BGEC:
21806                 if (rs == rt) {
21807                     gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
21808                 } else {
21809                     gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
21810                 }
21811                 break;
21812             case NM_BGEUC:
21813                 if (rs == rt || rt == 0) {
21814                     gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
21815                 } else if (rs == 0) {
21816                     gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
21817                 } else {
21818                     gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
21819                 }
21820                 break;
21821             }
21822         }
21823         break;
21824     case NM_P_BR2:
21825         {
21826             int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21827                         extract32(ctx->opcode, 1, 13) << 1;
21828             switch (extract32(ctx->opcode, 14, 2)) {
21829             case NM_BNEC:
21830                 check_nms(ctx);
21831                 gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
21832                 break;
21833             case NM_BLTC:
21834                 if (rs != 0 && rt != 0 && rs == rt) {
21835                     /* NOP */
21836                     ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21837                 } else {
21838                     gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
21839                 }
21840                 break;
21841             case NM_BLTUC:
21842                 if (rs == 0 || rs == rt) {
21843                     /* NOP */
21844                     ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21845                 } else {
21846                     gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
21847                 }
21848                 break;
21849             default:
21850                 generate_exception_end(ctx, EXCP_RI);
21851                 break;
21852             }
21853         }
21854         break;
21855     case NM_P_BRI:
21856         {
21857             int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
21858                         extract32(ctx->opcode, 1, 10) << 1;
21859             uint32_t u = extract32(ctx->opcode, 11, 7);
21860
21861             gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
21862                                    rt, u, s);
21863         }
21864         break;
21865     default:
21866         generate_exception_end(ctx, EXCP_RI);
21867         break;
21868     }
21869     return 4;
21870 }
21871
21872 static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
21873 {
21874     uint32_t op;
21875     int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD(ctx->opcode));
21876     int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
21877     int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS1(ctx->opcode));
21878     int offset;
21879     int imm;
21880
21881     /* make sure instructions are on a halfword boundary */
21882     if (ctx->base.pc_next & 0x1) {
21883         TCGv tmp = tcg_const_tl(ctx->base.pc_next);
21884         tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
21885         tcg_temp_free(tmp);
21886         generate_exception_end(ctx, EXCP_AdEL);
21887         return 2;
21888     }
21889
21890     op = extract32(ctx->opcode, 10, 6);
21891     switch (op) {
21892     case NM_P16_MV:
21893         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21894         if (rt != 0) {
21895             /* MOVE */
21896             rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
21897             gen_arith(ctx, OPC_ADDU, rt, rs, 0);
21898         } else {
21899             /* P16.RI */
21900             switch (extract32(ctx->opcode, 3, 2)) {
21901             case NM_P16_SYSCALL:
21902                 if (extract32(ctx->opcode, 2, 1) == 0) {
21903                     generate_exception_end(ctx, EXCP_SYSCALL);
21904                 } else {
21905                     generate_exception_end(ctx, EXCP_RI);
21906                 }
21907                 break;
21908             case NM_BREAK16:
21909                 generate_exception_end(ctx, EXCP_BREAK);
21910                 break;
21911             case NM_SDBBP16:
21912                 if (is_uhi(extract32(ctx->opcode, 0, 3))) {
21913                     gen_helper_do_semihosting(cpu_env);
21914                 } else {
21915                     if (ctx->hflags & MIPS_HFLAG_SBRI) {
21916                         generate_exception_end(ctx, EXCP_RI);
21917                     } else {
21918                         generate_exception_end(ctx, EXCP_DBp);
21919                     }
21920                 }
21921                 break;
21922             default:
21923                 generate_exception_end(ctx, EXCP_RI);
21924                 break;
21925             }
21926         }
21927         break;
21928     case NM_P16_SHIFT:
21929         {
21930             int shift = extract32(ctx->opcode, 0, 3);
21931             uint32_t opc = 0;
21932             shift = (shift == 0) ? 8 : shift;
21933
21934             switch (extract32(ctx->opcode, 3, 1)) {
21935             case NM_SLL16:
21936                 opc = OPC_SLL;
21937                 break;
21938             case NM_SRL16:
21939                 opc = OPC_SRL;
21940                 break;
21941             }
21942             gen_shift_imm(ctx, opc, rt, rs, shift);
21943         }
21944         break;
21945     case NM_P16C:
21946         switch (ctx->opcode & 1) {
21947         case NM_POOL16C_0:
21948             gen_pool16c_nanomips_insn(ctx);
21949             break;
21950         case NM_LWXS16:
21951             gen_ldxs(ctx, rt, rs, rd);
21952             break;
21953         }
21954         break;
21955     case NM_P16_A1:
21956         switch (extract32(ctx->opcode, 6, 1)) {
21957         case NM_ADDIUR1SP:
21958             imm = extract32(ctx->opcode, 0, 6) << 2;
21959             gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
21960             break;
21961         default:
21962             generate_exception_end(ctx, EXCP_RI);
21963             break;
21964         }
21965         break;
21966     case NM_P16_A2:
21967         switch (extract32(ctx->opcode, 3, 1)) {
21968         case NM_ADDIUR2:
21969             imm = extract32(ctx->opcode, 0, 3) << 2;
21970             gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
21971             break;
21972         case NM_P_ADDIURS5:
21973             rt = extract32(ctx->opcode, 5, 5);
21974             if (rt != 0) {
21975                 /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21976                 imm = (sextract32(ctx->opcode, 4, 1) << 3) |
21977                       (extract32(ctx->opcode, 0, 3));
21978                 gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
21979             }
21980             break;
21981         }
21982         break;
21983     case NM_P16_ADDU:
21984         switch (ctx->opcode & 0x1) {
21985         case NM_ADDU16:
21986             gen_arith(ctx, OPC_ADDU, rd, rs, rt);
21987             break;
21988         case NM_SUBU16:
21989             gen_arith(ctx, OPC_SUBU, rd, rs, rt);
21990             break;
21991         }
21992         break;
21993     case NM_P16_4X4:
21994         rt = (extract32(ctx->opcode, 9, 1) << 3) |
21995               extract32(ctx->opcode, 5, 3);
21996         rs = (extract32(ctx->opcode, 4, 1) << 3) |
21997               extract32(ctx->opcode, 0, 3);
21998         rt = decode_gpr_gpr4(rt);
21999         rs = decode_gpr_gpr4(rs);
22000         switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
22001                 (extract32(ctx->opcode, 3, 1))) {
22002         case NM_ADDU4X4:
22003             check_nms(ctx);
22004             gen_arith(ctx, OPC_ADDU, rt, rs, rt);
22005             break;
22006         case NM_MUL4X4:
22007             check_nms(ctx);
22008             gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
22009             break;
22010         default:
22011             generate_exception_end(ctx, EXCP_RI);
22012             break;
22013         }
22014         break;
22015     case NM_LI16:
22016         {
22017             int imm = extract32(ctx->opcode, 0, 7);
22018             imm = (imm == 0x7f ? -1 : imm);
22019             if (rt != 0) {
22020                 tcg_gen_movi_tl(cpu_gpr[rt], imm);
22021             }
22022         }
22023         break;
22024     case NM_ANDI16:
22025         {
22026             uint32_t u = extract32(ctx->opcode, 0, 4);
22027             u = (u == 12) ? 0xff :
22028                 (u == 13) ? 0xffff : u;
22029             gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
22030         }
22031         break;
22032     case NM_P16_LB:
22033         offset = extract32(ctx->opcode, 0, 2);
22034         switch (extract32(ctx->opcode, 2, 2)) {
22035         case NM_LB16:
22036             gen_ld(ctx, OPC_LB, rt, rs, offset);
22037             break;
22038         case NM_SB16:
22039             rt = decode_gpr_gpr3_src_store(
22040                      NANOMIPS_EXTRACT_RD(ctx->opcode));
22041             gen_st(ctx, OPC_SB, rt, rs, offset);
22042             break;
22043         case NM_LBU16:
22044             gen_ld(ctx, OPC_LBU, rt, rs, offset);
22045             break;
22046         default:
22047             generate_exception_end(ctx, EXCP_RI);
22048             break;
22049         }
22050         break;
22051     case NM_P16_LH:
22052         offset = extract32(ctx->opcode, 1, 2) << 1;
22053         switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
22054         case NM_LH16:
22055             gen_ld(ctx, OPC_LH, rt, rs, offset);
22056             break;
22057         case NM_SH16:
22058             rt = decode_gpr_gpr3_src_store(
22059                      NANOMIPS_EXTRACT_RD(ctx->opcode));
22060             gen_st(ctx, OPC_SH, rt, rs, offset);
22061             break;
22062         case NM_LHU16:
22063             gen_ld(ctx, OPC_LHU, rt, rs, offset);
22064             break;
22065         default:
22066             generate_exception_end(ctx, EXCP_RI);
22067             break;
22068         }
22069         break;
22070     case NM_LW16:
22071         offset = extract32(ctx->opcode, 0, 4) << 2;
22072         gen_ld(ctx, OPC_LW, rt, rs, offset);
22073         break;
22074     case NM_LWSP16:
22075         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22076         offset = extract32(ctx->opcode, 0, 5) << 2;
22077         gen_ld(ctx, OPC_LW, rt, 29, offset);
22078         break;
22079     case NM_LW4X4:
22080         check_nms(ctx);
22081         rt = (extract32(ctx->opcode, 9, 1) << 3) |
22082              extract32(ctx->opcode, 5, 3);
22083         rs = (extract32(ctx->opcode, 4, 1) << 3) |
22084              extract32(ctx->opcode, 0, 3);
22085         offset = (extract32(ctx->opcode, 3, 1) << 3) |
22086                  (extract32(ctx->opcode, 8, 1) << 2);
22087         rt = decode_gpr_gpr4(rt);
22088         rs = decode_gpr_gpr4(rs);
22089         gen_ld(ctx, OPC_LW, rt, rs, offset);
22090         break;
22091     case NM_SW4X4:
22092         check_nms(ctx);
22093         rt = (extract32(ctx->opcode, 9, 1) << 3) |
22094              extract32(ctx->opcode, 5, 3);
22095         rs = (extract32(ctx->opcode, 4, 1) << 3) |
22096              extract32(ctx->opcode, 0, 3);
22097         offset = (extract32(ctx->opcode, 3, 1) << 3) |
22098                  (extract32(ctx->opcode, 8, 1) << 2);
22099         rt = decode_gpr_gpr4_zero(rt);
22100         rs = decode_gpr_gpr4(rs);
22101         gen_st(ctx, OPC_SW, rt, rs, offset);
22102         break;
22103     case NM_LWGP16:
22104         offset = extract32(ctx->opcode, 0, 7) << 2;
22105         gen_ld(ctx, OPC_LW, rt, 28, offset);
22106         break;
22107     case NM_SWSP16:
22108         rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
22109         offset = extract32(ctx->opcode, 0, 5) << 2;
22110         gen_st(ctx, OPC_SW, rt, 29, offset);
22111         break;
22112     case NM_SW16:
22113         rt = decode_gpr_gpr3_src_store(
22114                  NANOMIPS_EXTRACT_RD(ctx->opcode));
22115         rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS(ctx->opcode));
22116         offset = extract32(ctx->opcode, 0, 4) << 2;
22117         gen_st(ctx, OPC_SW, rt, rs, offset);
22118         break;
22119     case NM_SWGP16:
22120         rt = decode_gpr_gpr3_src_store(
22121                  NANOMIPS_EXTRACT_RD(ctx->opcode));
22122         offset = extract32(ctx->opcode, 0, 7) << 2;
22123         gen_st(ctx, OPC_SW, rt, 28, offset);
22124         break;
22125     case NM_BC16:
22126         gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
22127                            (sextract32(ctx->opcode, 0, 1) << 10) |
22128                            (extract32(ctx->opcode, 1, 9) << 1));
22129         break;
22130     case NM_BALC16:
22131         gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
22132                            (sextract32(ctx->opcode, 0, 1) << 10) |
22133                            (extract32(ctx->opcode, 1, 9) << 1));
22134         break;
22135     case NM_BEQZC16:
22136         gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
22137                            (sextract32(ctx->opcode, 0, 1) << 7) |
22138                            (extract32(ctx->opcode, 1, 6) << 1));
22139         break;
22140     case NM_BNEZC16:
22141         gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
22142                            (sextract32(ctx->opcode, 0, 1) << 7) |
22143                            (extract32(ctx->opcode, 1, 6) << 1));
22144         break;
22145     case NM_P16_BR:
22146         switch (ctx->opcode & 0xf) {
22147         case 0:
22148             /* P16.JRC */
22149             switch (extract32(ctx->opcode, 4, 1)) {
22150             case NM_JRC:
22151                 gen_compute_branch_nm(ctx, OPC_JR, 2,
22152                                    extract32(ctx->opcode, 5, 5), 0, 0);
22153                 break;
22154             case NM_JALRC16:
22155                 gen_compute_branch_nm(ctx, OPC_JALR, 2,
22156                                    extract32(ctx->opcode, 5, 5), 31, 0);
22157                 break;
22158             }
22159             break;
22160         default:
22161             {
22162                 /* P16.BRI */
22163                 uint32_t opc = extract32(ctx->opcode, 4, 3) <
22164                                extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
22165                 gen_compute_branch_nm(ctx, opc, 2, rs, rt,
22166                                    extract32(ctx->opcode, 0, 4) << 1);
22167             }
22168             break;
22169         }
22170         break;
22171     case NM_P16_SR:
22172         {
22173             int count = extract32(ctx->opcode, 0, 4);
22174             int u = extract32(ctx->opcode, 4, 4) << 4;
22175
22176             rt = 30 + extract32(ctx->opcode, 9, 1);
22177             switch (extract32(ctx->opcode, 8, 1)) {
22178             case NM_SAVE16:
22179                 gen_save(ctx, rt, count, 0, u);
22180                 break;
22181             case NM_RESTORE_JRC16:
22182                 gen_restore(ctx, rt, count, 0, u);
22183                 gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
22184                 break;
22185             }
22186         }
22187         break;
22188     case NM_MOVEP:
22189     case NM_MOVEPREV:
22190         check_nms(ctx);
22191         {
22192             static const int gpr2reg1[] = {4, 5, 6, 7};
22193             static const int gpr2reg2[] = {5, 6, 7, 8};
22194             int re;
22195             int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
22196                       extract32(ctx->opcode, 8, 1);
22197             int r1 = gpr2reg1[rd2];
22198             int r2 = gpr2reg2[rd2];
22199             int r3 = extract32(ctx->opcode, 4, 1) << 3 |
22200                      extract32(ctx->opcode, 0, 3);
22201             int r4 = extract32(ctx->opcode, 9, 1) << 3 |
22202                      extract32(ctx->opcode, 5, 3);
22203             TCGv t0 = tcg_temp_new();
22204             TCGv t1 = tcg_temp_new();
22205             if (op == NM_MOVEP) {
22206                 rd = r1;
22207                 re = r2;
22208                 rs = decode_gpr_gpr4_zero(r3);
22209                 rt = decode_gpr_gpr4_zero(r4);
22210             } else {
22211                 rd = decode_gpr_gpr4(r3);
22212                 re = decode_gpr_gpr4(r4);
22213                 rs = r1;
22214                 rt = r2;
22215             }
22216             gen_load_gpr(t0, rs);
22217             gen_load_gpr(t1, rt);
22218             tcg_gen_mov_tl(cpu_gpr[rd], t0);
22219             tcg_gen_mov_tl(cpu_gpr[re], t1);
22220             tcg_temp_free(t0);
22221             tcg_temp_free(t1);
22222         }
22223         break;
22224     default:
22225         return decode_nanomips_32_48_opc(env, ctx);
22226     }
22227
22228     return 2;
22229 }
22230
22231
22232 /* SmartMIPS extension to MIPS32 */
22233
22234 #if defined(TARGET_MIPS64)
22235
22236 /* MDMX extension to MIPS64 */
22237
22238 #endif
22239
22240 /* MIPSDSP functions. */
22241 static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
22242                            int rd, int base, int offset)
22243 {
22244     TCGv t0;
22245
22246     check_dsp(ctx);
22247     t0 = tcg_temp_new();
22248
22249     if (base == 0) {
22250         gen_load_gpr(t0, offset);
22251     } else if (offset == 0) {
22252         gen_load_gpr(t0, base);
22253     } else {
22254         gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
22255     }
22256
22257     switch (opc) {
22258     case OPC_LBUX:
22259         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
22260         gen_store_gpr(t0, rd);
22261         break;
22262     case OPC_LHX:
22263         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
22264         gen_store_gpr(t0, rd);
22265         break;
22266     case OPC_LWX:
22267         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
22268         gen_store_gpr(t0, rd);
22269         break;
22270 #if defined(TARGET_MIPS64)
22271     case OPC_LDX:
22272         tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
22273         gen_store_gpr(t0, rd);
22274         break;
22275 #endif
22276     }
22277     tcg_temp_free(t0);
22278 }
22279
22280 static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
22281                               int ret, int v1, int v2)
22282 {
22283     TCGv v1_t;
22284     TCGv v2_t;
22285
22286     if (ret == 0) {
22287         /* Treat as NOP. */
22288         return;
22289     }
22290
22291     v1_t = tcg_temp_new();
22292     v2_t = tcg_temp_new();
22293
22294     gen_load_gpr(v1_t, v1);
22295     gen_load_gpr(v2_t, v2);
22296
22297     switch (op1) {
22298     /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
22299     case OPC_MULT_G_2E:
22300         check_dsp_r2(ctx);
22301         switch (op2) {
22302         case OPC_ADDUH_QB:
22303             gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
22304             break;
22305         case OPC_ADDUH_R_QB:
22306             gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22307             break;
22308         case OPC_ADDQH_PH:
22309             gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
22310             break;
22311         case OPC_ADDQH_R_PH:
22312             gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22313             break;
22314         case OPC_ADDQH_W:
22315             gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
22316             break;
22317         case OPC_ADDQH_R_W:
22318             gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22319             break;
22320         case OPC_SUBUH_QB:
22321             gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
22322             break;
22323         case OPC_SUBUH_R_QB:
22324             gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
22325             break;
22326         case OPC_SUBQH_PH:
22327             gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
22328             break;
22329         case OPC_SUBQH_R_PH:
22330             gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
22331             break;
22332         case OPC_SUBQH_W:
22333             gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
22334             break;
22335         case OPC_SUBQH_R_W:
22336             gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
22337             break;
22338         }
22339         break;
22340     case OPC_ABSQ_S_PH_DSP:
22341         switch (op2) {
22342         case OPC_ABSQ_S_QB:
22343             check_dsp_r2(ctx);
22344             gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
22345             break;
22346         case OPC_ABSQ_S_PH:
22347             check_dsp(ctx);
22348             gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
22349             break;
22350         case OPC_ABSQ_S_W:
22351             check_dsp(ctx);
22352             gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
22353             break;
22354         case OPC_PRECEQ_W_PHL:
22355             check_dsp(ctx);
22356             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
22357             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22358             break;
22359         case OPC_PRECEQ_W_PHR:
22360             check_dsp(ctx);
22361             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
22362             tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
22363             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22364             break;
22365         case OPC_PRECEQU_PH_QBL:
22366             check_dsp(ctx);
22367             gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
22368             break;
22369         case OPC_PRECEQU_PH_QBR:
22370             check_dsp(ctx);
22371             gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
22372             break;
22373         case OPC_PRECEQU_PH_QBLA:
22374             check_dsp(ctx);
22375             gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
22376             break;
22377         case OPC_PRECEQU_PH_QBRA:
22378             check_dsp(ctx);
22379             gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
22380             break;
22381         case OPC_PRECEU_PH_QBL:
22382             check_dsp(ctx);
22383             gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
22384             break;
22385         case OPC_PRECEU_PH_QBR:
22386             check_dsp(ctx);
22387             gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
22388             break;
22389         case OPC_PRECEU_PH_QBLA:
22390             check_dsp(ctx);
22391             gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
22392             break;
22393         case OPC_PRECEU_PH_QBRA:
22394             check_dsp(ctx);
22395             gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
22396             break;
22397         }
22398         break;
22399     case OPC_ADDU_QB_DSP:
22400         switch (op2) {
22401         case OPC_ADDQ_PH:
22402             check_dsp(ctx);
22403             gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22404             break;
22405         case OPC_ADDQ_S_PH:
22406             check_dsp(ctx);
22407             gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22408             break;
22409         case OPC_ADDQ_S_W:
22410             check_dsp(ctx);
22411             gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22412             break;
22413         case OPC_ADDU_QB:
22414             check_dsp(ctx);
22415             gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22416             break;
22417         case OPC_ADDU_S_QB:
22418             check_dsp(ctx);
22419             gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22420             break;
22421         case OPC_ADDU_PH:
22422             check_dsp_r2(ctx);
22423             gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22424             break;
22425         case OPC_ADDU_S_PH:
22426             check_dsp_r2(ctx);
22427             gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22428             break;
22429         case OPC_SUBQ_PH:
22430             check_dsp(ctx);
22431             gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22432             break;
22433         case OPC_SUBQ_S_PH:
22434             check_dsp(ctx);
22435             gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22436             break;
22437         case OPC_SUBQ_S_W:
22438             check_dsp(ctx);
22439             gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22440             break;
22441         case OPC_SUBU_QB:
22442             check_dsp(ctx);
22443             gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22444             break;
22445         case OPC_SUBU_S_QB:
22446             check_dsp(ctx);
22447             gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22448             break;
22449         case OPC_SUBU_PH:
22450             check_dsp_r2(ctx);
22451             gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22452             break;
22453         case OPC_SUBU_S_PH:
22454             check_dsp_r2(ctx);
22455             gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22456             break;
22457         case OPC_ADDSC:
22458             check_dsp(ctx);
22459             gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22460             break;
22461         case OPC_ADDWC:
22462             check_dsp(ctx);
22463             gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22464             break;
22465         case OPC_MODSUB:
22466             check_dsp(ctx);
22467             gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
22468             break;
22469         case OPC_RADDU_W_QB:
22470             check_dsp(ctx);
22471             gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
22472             break;
22473         }
22474         break;
22475     case OPC_CMPU_EQ_QB_DSP:
22476         switch (op2) {
22477         case OPC_PRECR_QB_PH:
22478             check_dsp_r2(ctx);
22479             gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22480             break;
22481         case OPC_PRECRQ_QB_PH:
22482             check_dsp(ctx);
22483             gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
22484             break;
22485         case OPC_PRECR_SRA_PH_W:
22486             check_dsp_r2(ctx);
22487             {
22488                 TCGv_i32 sa_t = tcg_const_i32(v2);
22489                 gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
22490                                           cpu_gpr[ret]);
22491                 tcg_temp_free_i32(sa_t);
22492                 break;
22493             }
22494         case OPC_PRECR_SRA_R_PH_W:
22495             check_dsp_r2(ctx);
22496             {
22497                 TCGv_i32 sa_t = tcg_const_i32(v2);
22498                 gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
22499                                             cpu_gpr[ret]);
22500                 tcg_temp_free_i32(sa_t);
22501                 break;
22502             }
22503         case OPC_PRECRQ_PH_W:
22504             check_dsp(ctx);
22505             gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
22506             break;
22507         case OPC_PRECRQ_RS_PH_W:
22508             check_dsp(ctx);
22509             gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22510             break;
22511         case OPC_PRECRQU_S_QB_PH:
22512             check_dsp(ctx);
22513             gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22514             break;
22515         }
22516         break;
22517 #ifdef TARGET_MIPS64
22518     case OPC_ABSQ_S_QH_DSP:
22519         switch (op2) {
22520         case OPC_PRECEQ_L_PWL:
22521             check_dsp(ctx);
22522             tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
22523             break;
22524         case OPC_PRECEQ_L_PWR:
22525             check_dsp(ctx);
22526             tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
22527             break;
22528         case OPC_PRECEQ_PW_QHL:
22529             check_dsp(ctx);
22530             gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
22531             break;
22532         case OPC_PRECEQ_PW_QHR:
22533             check_dsp(ctx);
22534             gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
22535             break;
22536         case OPC_PRECEQ_PW_QHLA:
22537             check_dsp(ctx);
22538             gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
22539             break;
22540         case OPC_PRECEQ_PW_QHRA:
22541             check_dsp(ctx);
22542             gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
22543             break;
22544         case OPC_PRECEQU_QH_OBL:
22545             check_dsp(ctx);
22546             gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
22547             break;
22548         case OPC_PRECEQU_QH_OBR:
22549             check_dsp(ctx);
22550             gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
22551             break;
22552         case OPC_PRECEQU_QH_OBLA:
22553             check_dsp(ctx);
22554             gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
22555             break;
22556         case OPC_PRECEQU_QH_OBRA:
22557             check_dsp(ctx);
22558             gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
22559             break;
22560         case OPC_PRECEU_QH_OBL:
22561             check_dsp(ctx);
22562             gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
22563             break;
22564         case OPC_PRECEU_QH_OBR:
22565             check_dsp(ctx);
22566             gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
22567             break;
22568         case OPC_PRECEU_QH_OBLA:
22569             check_dsp(ctx);
22570             gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
22571             break;
22572         case OPC_PRECEU_QH_OBRA:
22573             check_dsp(ctx);
22574             gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
22575             break;
22576         case OPC_ABSQ_S_OB:
22577             check_dsp_r2(ctx);
22578             gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
22579             break;
22580         case OPC_ABSQ_S_PW:
22581             check_dsp(ctx);
22582             gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
22583             break;
22584         case OPC_ABSQ_S_QH:
22585             check_dsp(ctx);
22586             gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
22587             break;
22588         }
22589         break;
22590     case OPC_ADDU_OB_DSP:
22591         switch (op2) {
22592         case OPC_RADDU_L_OB:
22593             check_dsp(ctx);
22594             gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
22595             break;
22596         case OPC_SUBQ_PW:
22597             check_dsp(ctx);
22598             gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22599             break;
22600         case OPC_SUBQ_S_PW:
22601             check_dsp(ctx);
22602             gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22603             break;
22604         case OPC_SUBQ_QH:
22605             check_dsp(ctx);
22606             gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22607             break;
22608         case OPC_SUBQ_S_QH:
22609             check_dsp(ctx);
22610             gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22611             break;
22612         case OPC_SUBU_OB:
22613             check_dsp(ctx);
22614             gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22615             break;
22616         case OPC_SUBU_S_OB:
22617             check_dsp(ctx);
22618             gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22619             break;
22620         case OPC_SUBU_QH:
22621             check_dsp_r2(ctx);
22622             gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22623             break;
22624         case OPC_SUBU_S_QH:
22625             check_dsp_r2(ctx);
22626             gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22627             break;
22628         case OPC_SUBUH_OB:
22629             check_dsp_r2(ctx);
22630             gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
22631             break;
22632         case OPC_SUBUH_R_OB:
22633             check_dsp_r2(ctx);
22634             gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22635             break;
22636         case OPC_ADDQ_PW:
22637             check_dsp(ctx);
22638             gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22639             break;
22640         case OPC_ADDQ_S_PW:
22641             check_dsp(ctx);
22642             gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22643             break;
22644         case OPC_ADDQ_QH:
22645             check_dsp(ctx);
22646             gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22647             break;
22648         case OPC_ADDQ_S_QH:
22649             check_dsp(ctx);
22650             gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22651             break;
22652         case OPC_ADDU_OB:
22653             check_dsp(ctx);
22654             gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22655             break;
22656         case OPC_ADDU_S_OB:
22657             check_dsp(ctx);
22658             gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22659             break;
22660         case OPC_ADDU_QH:
22661             check_dsp_r2(ctx);
22662             gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22663             break;
22664         case OPC_ADDU_S_QH:
22665             check_dsp_r2(ctx);
22666             gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22667             break;
22668         case OPC_ADDUH_OB:
22669             check_dsp_r2(ctx);
22670             gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22671             break;
22672         case OPC_ADDUH_R_OB:
22673             check_dsp_r2(ctx);
22674             gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22675             break;
22676         }
22677         break;
22678     case OPC_CMPU_EQ_OB_DSP:
22679         switch (op2) {
22680         case OPC_PRECR_OB_QH:
22681             check_dsp_r2(ctx);
22682             gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22683             break;
22684         case OPC_PRECR_SRA_QH_PW:
22685             check_dsp_r2(ctx);
22686             {
22687                 TCGv_i32 ret_t = tcg_const_i32(ret);
22688                 gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22689                 tcg_temp_free_i32(ret_t);
22690                 break;
22691             }
22692         case OPC_PRECR_SRA_R_QH_PW:
22693             check_dsp_r2(ctx);
22694             {
22695                 TCGv_i32 sa_v = tcg_const_i32(ret);
22696                 gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22697                 tcg_temp_free_i32(sa_v);
22698                 break;
22699             }
22700         case OPC_PRECRQ_OB_QH:
22701             check_dsp(ctx);
22702             gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22703             break;
22704         case OPC_PRECRQ_PW_L:
22705             check_dsp(ctx);
22706             gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22707             break;
22708         case OPC_PRECRQ_QH_PW:
22709             check_dsp(ctx);
22710             gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22711             break;
22712         case OPC_PRECRQ_RS_QH_PW:
22713             check_dsp(ctx);
22714             gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22715             break;
22716         case OPC_PRECRQU_S_OB_QH:
22717             check_dsp(ctx);
22718             gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22719             break;
22720         }
22721         break;
22722 #endif
22723     }
22724
22725     tcg_temp_free(v1_t);
22726     tcg_temp_free(v2_t);
22727 }
22728
22729 static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
22730                               int ret, int v1, int v2)
22731 {
22732     uint32_t op2;
22733     TCGv t0;
22734     TCGv v1_t;
22735     TCGv v2_t;
22736
22737     if (ret == 0) {
22738         /* Treat as NOP. */
22739         return;
22740     }
22741
22742     t0 = tcg_temp_new();
22743     v1_t = tcg_temp_new();
22744     v2_t = tcg_temp_new();
22745
22746     tcg_gen_movi_tl(t0, v1);
22747     gen_load_gpr(v1_t, v1);
22748     gen_load_gpr(v2_t, v2);
22749
22750     switch (opc) {
22751     case OPC_SHLL_QB_DSP:
22752         {
22753             op2 = MASK_SHLL_QB(ctx->opcode);
22754             switch (op2) {
22755             case OPC_SHLL_QB:
22756                 check_dsp(ctx);
22757                 gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
22758                 break;
22759             case OPC_SHLLV_QB:
22760                 check_dsp(ctx);
22761                 gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22762                 break;
22763             case OPC_SHLL_PH:
22764                 check_dsp(ctx);
22765                 gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22766                 break;
22767             case OPC_SHLLV_PH:
22768                 check_dsp(ctx);
22769                 gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22770                 break;
22771             case OPC_SHLL_S_PH:
22772                 check_dsp(ctx);
22773                 gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22774                 break;
22775             case OPC_SHLLV_S_PH:
22776                 check_dsp(ctx);
22777                 gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22778                 break;
22779             case OPC_SHLL_S_W:
22780                 check_dsp(ctx);
22781                 gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
22782                 break;
22783             case OPC_SHLLV_S_W:
22784                 check_dsp(ctx);
22785                 gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22786                 break;
22787             case OPC_SHRL_QB:
22788                 check_dsp(ctx);
22789                 gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
22790                 break;
22791             case OPC_SHRLV_QB:
22792                 check_dsp(ctx);
22793                 gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
22794                 break;
22795             case OPC_SHRL_PH:
22796                 check_dsp_r2(ctx);
22797                 gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
22798                 break;
22799             case OPC_SHRLV_PH:
22800                 check_dsp_r2(ctx);
22801                 gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
22802                 break;
22803             case OPC_SHRA_QB:
22804                 check_dsp_r2(ctx);
22805                 gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
22806                 break;
22807             case OPC_SHRA_R_QB:
22808                 check_dsp_r2(ctx);
22809                 gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
22810                 break;
22811             case OPC_SHRAV_QB:
22812                 check_dsp_r2(ctx);
22813                 gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
22814                 break;
22815             case OPC_SHRAV_R_QB:
22816                 check_dsp_r2(ctx);
22817                 gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
22818                 break;
22819             case OPC_SHRA_PH:
22820                 check_dsp(ctx);
22821                 gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
22822                 break;
22823             case OPC_SHRA_R_PH:
22824                 check_dsp(ctx);
22825                 gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
22826                 break;
22827             case OPC_SHRAV_PH:
22828                 check_dsp(ctx);
22829                 gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
22830                 break;
22831             case OPC_SHRAV_R_PH:
22832                 check_dsp(ctx);
22833                 gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
22834                 break;
22835             case OPC_SHRA_R_W:
22836                 check_dsp(ctx);
22837                 gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
22838                 break;
22839             case OPC_SHRAV_R_W:
22840                 check_dsp(ctx);
22841                 gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
22842                 break;
22843             default:            /* Invalid */
22844                 MIPS_INVAL("MASK SHLL.QB");
22845                 generate_exception_end(ctx, EXCP_RI);
22846                 break;
22847             }
22848             break;
22849         }
22850 #ifdef TARGET_MIPS64
22851     case OPC_SHLL_OB_DSP:
22852         op2 = MASK_SHLL_OB(ctx->opcode);
22853         switch (op2) {
22854         case OPC_SHLL_PW:
22855             check_dsp(ctx);
22856             gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22857             break;
22858         case OPC_SHLLV_PW:
22859             check_dsp(ctx);
22860             gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22861             break;
22862         case OPC_SHLL_S_PW:
22863             check_dsp(ctx);
22864             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22865             break;
22866         case OPC_SHLLV_S_PW:
22867             check_dsp(ctx);
22868             gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22869             break;
22870         case OPC_SHLL_OB:
22871             check_dsp(ctx);
22872             gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
22873             break;
22874         case OPC_SHLLV_OB:
22875             check_dsp(ctx);
22876             gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22877             break;
22878         case OPC_SHLL_QH:
22879             check_dsp(ctx);
22880             gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22881             break;
22882         case OPC_SHLLV_QH:
22883             check_dsp(ctx);
22884             gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22885             break;
22886         case OPC_SHLL_S_QH:
22887             check_dsp(ctx);
22888             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22889             break;
22890         case OPC_SHLLV_S_QH:
22891             check_dsp(ctx);
22892             gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22893             break;
22894         case OPC_SHRA_OB:
22895             check_dsp_r2(ctx);
22896             gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
22897             break;
22898         case OPC_SHRAV_OB:
22899             check_dsp_r2(ctx);
22900             gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
22901             break;
22902         case OPC_SHRA_R_OB:
22903             check_dsp_r2(ctx);
22904             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
22905             break;
22906         case OPC_SHRAV_R_OB:
22907             check_dsp_r2(ctx);
22908             gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
22909             break;
22910         case OPC_SHRA_PW:
22911             check_dsp(ctx);
22912             gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
22913             break;
22914         case OPC_SHRAV_PW:
22915             check_dsp(ctx);
22916             gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
22917             break;
22918         case OPC_SHRA_R_PW:
22919             check_dsp(ctx);
22920             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
22921             break;
22922         case OPC_SHRAV_R_PW:
22923             check_dsp(ctx);
22924             gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
22925             break;
22926         case OPC_SHRA_QH:
22927             check_dsp(ctx);
22928             gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
22929             break;
22930         case OPC_SHRAV_QH:
22931             check_dsp(ctx);
22932             gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
22933             break;
22934         case OPC_SHRA_R_QH:
22935             check_dsp(ctx);
22936             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
22937             break;
22938         case OPC_SHRAV_R_QH:
22939             check_dsp(ctx);
22940             gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
22941             break;
22942         case OPC_SHRL_OB:
22943             check_dsp(ctx);
22944             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
22945             break;
22946         case OPC_SHRLV_OB:
22947             check_dsp(ctx);
22948             gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
22949             break;
22950         case OPC_SHRL_QH:
22951             check_dsp_r2(ctx);
22952             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
22953             break;
22954         case OPC_SHRLV_QH:
22955             check_dsp_r2(ctx);
22956             gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
22957             break;
22958         default:            /* Invalid */
22959             MIPS_INVAL("MASK SHLL.OB");
22960             generate_exception_end(ctx, EXCP_RI);
22961             break;
22962         }
22963         break;
22964 #endif
22965     }
22966
22967     tcg_temp_free(t0);
22968     tcg_temp_free(v1_t);
22969     tcg_temp_free(v2_t);
22970 }
22971
22972 static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
22973                                  int ret, int v1, int v2, int check_ret)
22974 {
22975     TCGv_i32 t0;
22976     TCGv v1_t;
22977     TCGv v2_t;
22978
22979     if ((ret == 0) && (check_ret == 1)) {
22980         /* Treat as NOP. */
22981         return;
22982     }
22983
22984     t0 = tcg_temp_new_i32();
22985     v1_t = tcg_temp_new();
22986     v2_t = tcg_temp_new();
22987
22988     tcg_gen_movi_i32(t0, ret);
22989     gen_load_gpr(v1_t, v1);
22990     gen_load_gpr(v2_t, v2);
22991
22992     switch (op1) {
22993     /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22994      * the same mask and op1. */
22995     case OPC_MULT_G_2E:
22996         check_dsp_r2(ctx);
22997         switch (op2) {
22998         case  OPC_MUL_PH:
22999             gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23000             break;
23001         case  OPC_MUL_S_PH:
23002             gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23003             break;
23004         case OPC_MULQ_S_W:
23005             gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23006             break;
23007         case OPC_MULQ_RS_W:
23008             gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23009             break;
23010         }
23011         break;
23012     case OPC_DPA_W_PH_DSP:
23013         switch (op2) {
23014         case OPC_DPAU_H_QBL:
23015             check_dsp(ctx);
23016             gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
23017             break;
23018         case OPC_DPAU_H_QBR:
23019             check_dsp(ctx);
23020             gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
23021             break;
23022         case OPC_DPSU_H_QBL:
23023             check_dsp(ctx);
23024             gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
23025             break;
23026         case OPC_DPSU_H_QBR:
23027             check_dsp(ctx);
23028             gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
23029             break;
23030         case OPC_DPA_W_PH:
23031             check_dsp_r2(ctx);
23032             gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
23033             break;
23034         case OPC_DPAX_W_PH:
23035             check_dsp_r2(ctx);
23036             gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
23037             break;
23038         case OPC_DPAQ_S_W_PH:
23039             check_dsp(ctx);
23040             gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23041             break;
23042         case OPC_DPAQX_S_W_PH:
23043             check_dsp_r2(ctx);
23044             gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23045             break;
23046         case OPC_DPAQX_SA_W_PH:
23047             check_dsp_r2(ctx);
23048             gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23049             break;
23050         case OPC_DPS_W_PH:
23051             check_dsp_r2(ctx);
23052             gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
23053             break;
23054         case OPC_DPSX_W_PH:
23055             check_dsp_r2(ctx);
23056             gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
23057             break;
23058         case OPC_DPSQ_S_W_PH:
23059             check_dsp(ctx);
23060             gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23061             break;
23062         case OPC_DPSQX_S_W_PH:
23063             check_dsp_r2(ctx);
23064             gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
23065             break;
23066         case OPC_DPSQX_SA_W_PH:
23067             check_dsp_r2(ctx);
23068             gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
23069             break;
23070         case OPC_MULSAQ_S_W_PH:
23071             check_dsp(ctx);
23072             gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
23073             break;
23074         case OPC_DPAQ_SA_L_W:
23075             check_dsp(ctx);
23076             gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23077             break;
23078         case OPC_DPSQ_SA_L_W:
23079             check_dsp(ctx);
23080             gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
23081             break;
23082         case OPC_MAQ_S_W_PHL:
23083             check_dsp(ctx);
23084             gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
23085             break;
23086         case OPC_MAQ_S_W_PHR:
23087             check_dsp(ctx);
23088             gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
23089             break;
23090         case OPC_MAQ_SA_W_PHL:
23091             check_dsp(ctx);
23092             gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
23093             break;
23094         case OPC_MAQ_SA_W_PHR:
23095             check_dsp(ctx);
23096             gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
23097             break;
23098         case OPC_MULSA_W_PH:
23099             check_dsp_r2(ctx);
23100             gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
23101             break;
23102         }
23103         break;
23104 #ifdef TARGET_MIPS64
23105     case OPC_DPAQ_W_QH_DSP:
23106         {
23107             int ac = ret & 0x03;
23108             tcg_gen_movi_i32(t0, ac);
23109
23110             switch (op2) {
23111             case OPC_DMADD:
23112                 check_dsp(ctx);
23113                 gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
23114                 break;
23115             case OPC_DMADDU:
23116                 check_dsp(ctx);
23117                 gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
23118                 break;
23119             case OPC_DMSUB:
23120                 check_dsp(ctx);
23121                 gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
23122                 break;
23123             case OPC_DMSUBU:
23124                 check_dsp(ctx);
23125                 gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
23126                 break;
23127             case OPC_DPA_W_QH:
23128                 check_dsp_r2(ctx);
23129                 gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
23130                 break;
23131             case OPC_DPAQ_S_W_QH:
23132                 check_dsp(ctx);
23133                 gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23134                 break;
23135             case OPC_DPAQ_SA_L_PW:
23136                 check_dsp(ctx);
23137                 gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23138                 break;
23139             case OPC_DPAU_H_OBL:
23140                 check_dsp(ctx);
23141                 gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
23142                 break;
23143             case OPC_DPAU_H_OBR:
23144                 check_dsp(ctx);
23145                 gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
23146                 break;
23147             case OPC_DPS_W_QH:
23148                 check_dsp_r2(ctx);
23149                 gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
23150                 break;
23151             case OPC_DPSQ_S_W_QH:
23152                 check_dsp(ctx);
23153                 gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23154                 break;
23155             case OPC_DPSQ_SA_L_PW:
23156                 check_dsp(ctx);
23157                 gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
23158                 break;
23159             case OPC_DPSU_H_OBL:
23160                 check_dsp(ctx);
23161                 gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
23162                 break;
23163             case OPC_DPSU_H_OBR:
23164                 check_dsp(ctx);
23165                 gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
23166                 break;
23167             case OPC_MAQ_S_L_PWL:
23168                 check_dsp(ctx);
23169                 gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
23170                 break;
23171             case OPC_MAQ_S_L_PWR:
23172                 check_dsp(ctx);
23173                 gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
23174                 break;
23175             case OPC_MAQ_S_W_QHLL:
23176                 check_dsp(ctx);
23177                 gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
23178                 break;
23179             case OPC_MAQ_SA_W_QHLL:
23180                 check_dsp(ctx);
23181                 gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
23182                 break;
23183             case OPC_MAQ_S_W_QHLR:
23184                 check_dsp(ctx);
23185                 gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
23186                 break;
23187             case OPC_MAQ_SA_W_QHLR:
23188                 check_dsp(ctx);
23189                 gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
23190                 break;
23191             case OPC_MAQ_S_W_QHRL:
23192                 check_dsp(ctx);
23193                 gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
23194                 break;
23195             case OPC_MAQ_SA_W_QHRL:
23196                 check_dsp(ctx);
23197                 gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
23198                 break;
23199             case OPC_MAQ_S_W_QHRR:
23200                 check_dsp(ctx);
23201                 gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
23202                 break;
23203             case OPC_MAQ_SA_W_QHRR:
23204                 check_dsp(ctx);
23205                 gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
23206                 break;
23207             case OPC_MULSAQ_S_L_PW:
23208                 check_dsp(ctx);
23209                 gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
23210                 break;
23211             case OPC_MULSAQ_S_W_QH:
23212                 check_dsp(ctx);
23213                 gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
23214                 break;
23215             }
23216         }
23217         break;
23218 #endif
23219     case OPC_ADDU_QB_DSP:
23220         switch (op2) {
23221         case OPC_MULEU_S_PH_QBL:
23222             check_dsp(ctx);
23223             gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23224             break;
23225         case OPC_MULEU_S_PH_QBR:
23226             check_dsp(ctx);
23227             gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23228             break;
23229         case OPC_MULQ_RS_PH:
23230             check_dsp(ctx);
23231             gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23232             break;
23233         case OPC_MULEQ_S_W_PHL:
23234             check_dsp(ctx);
23235             gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23236             break;
23237         case OPC_MULEQ_S_W_PHR:
23238             check_dsp(ctx);
23239             gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23240             break;
23241         case OPC_MULQ_S_PH:
23242             check_dsp_r2(ctx);
23243             gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23244             break;
23245         }
23246         break;
23247 #ifdef TARGET_MIPS64
23248     case OPC_ADDU_OB_DSP:
23249         switch (op2) {
23250         case OPC_MULEQ_S_PW_QHL:
23251             check_dsp(ctx);
23252             gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23253             break;
23254         case OPC_MULEQ_S_PW_QHR:
23255             check_dsp(ctx);
23256             gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23257             break;
23258         case OPC_MULEU_S_QH_OBL:
23259             check_dsp(ctx);
23260             gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23261             break;
23262         case OPC_MULEU_S_QH_OBR:
23263             check_dsp(ctx);
23264             gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23265             break;
23266         case OPC_MULQ_RS_QH:
23267             check_dsp(ctx);
23268             gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23269             break;
23270         }
23271         break;
23272 #endif
23273     }
23274
23275     tcg_temp_free_i32(t0);
23276     tcg_temp_free(v1_t);
23277     tcg_temp_free(v2_t);
23278 }
23279
23280 static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23281                                 int ret, int val)
23282 {
23283     int16_t imm;
23284     TCGv t0;
23285     TCGv val_t;
23286
23287     if (ret == 0) {
23288         /* Treat as NOP. */
23289         return;
23290     }
23291
23292     t0 = tcg_temp_new();
23293     val_t = tcg_temp_new();
23294     gen_load_gpr(val_t, val);
23295
23296     switch (op1) {
23297     case OPC_ABSQ_S_PH_DSP:
23298         switch (op2) {
23299         case OPC_BITREV:
23300             check_dsp(ctx);
23301             gen_helper_bitrev(cpu_gpr[ret], val_t);
23302             break;
23303         case OPC_REPL_QB:
23304             check_dsp(ctx);
23305             {
23306                 target_long result;
23307                 imm = (ctx->opcode >> 16) & 0xFF;
23308                 result = (uint32_t)imm << 24 |
23309                          (uint32_t)imm << 16 |
23310                          (uint32_t)imm << 8  |
23311                          (uint32_t)imm;
23312                 result = (int32_t)result;
23313                 tcg_gen_movi_tl(cpu_gpr[ret], result);
23314             }
23315             break;
23316         case OPC_REPLV_QB:
23317             check_dsp(ctx);
23318             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23319             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23320             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23321             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23322             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23323             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23324             break;
23325         case OPC_REPL_PH:
23326             check_dsp(ctx);
23327             {
23328                 imm = (ctx->opcode >> 16) & 0x03FF;
23329                 imm = (int16_t)(imm << 6) >> 6;
23330                 tcg_gen_movi_tl(cpu_gpr[ret], \
23331                                 (target_long)((int32_t)imm << 16 | \
23332                                 (uint16_t)imm));
23333             }
23334             break;
23335         case OPC_REPLV_PH:
23336             check_dsp(ctx);
23337             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23338             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23339             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23340             tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
23341             break;
23342         }
23343         break;
23344 #ifdef TARGET_MIPS64
23345     case OPC_ABSQ_S_QH_DSP:
23346         switch (op2) {
23347         case OPC_REPL_OB:
23348             check_dsp(ctx);
23349             {
23350                 target_long temp;
23351
23352                 imm = (ctx->opcode >> 16) & 0xFF;
23353                 temp = ((uint64_t)imm << 8) | (uint64_t)imm;
23354                 temp = (temp << 16) | temp;
23355                 temp = (temp << 32) | temp;
23356                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23357                 break;
23358             }
23359         case OPC_REPL_PW:
23360             check_dsp(ctx);
23361             {
23362                 target_long temp;
23363
23364                 imm = (ctx->opcode >> 16) & 0x03FF;
23365                 imm = (int16_t)(imm << 6) >> 6;
23366                 temp = ((target_long)imm << 32) \
23367                        | ((target_long)imm & 0xFFFFFFFF);
23368                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23369                 break;
23370             }
23371         case OPC_REPL_QH:
23372             check_dsp(ctx);
23373             {
23374                 target_long temp;
23375
23376                 imm = (ctx->opcode >> 16) & 0x03FF;
23377                 imm = (int16_t)(imm << 6) >> 6;
23378
23379                 temp = ((uint64_t)(uint16_t)imm << 48) |
23380                        ((uint64_t)(uint16_t)imm << 32) |
23381                        ((uint64_t)(uint16_t)imm << 16) |
23382                        (uint64_t)(uint16_t)imm;
23383                 tcg_gen_movi_tl(cpu_gpr[ret], temp);
23384                 break;
23385             }
23386         case OPC_REPLV_OB:
23387             check_dsp(ctx);
23388             tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
23389             tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
23390             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23391             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23392             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23393             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23394             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23395             break;
23396         case OPC_REPLV_PW:
23397             check_dsp(ctx);
23398             tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
23399             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23400             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23401             break;
23402         case OPC_REPLV_QH:
23403             check_dsp(ctx);
23404             tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
23405             tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
23406             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23407             tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
23408             tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
23409             break;
23410         }
23411         break;
23412 #endif
23413     }
23414     tcg_temp_free(t0);
23415     tcg_temp_free(val_t);
23416 }
23417
23418 static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
23419                                      uint32_t op1, uint32_t op2,
23420                                      int ret, int v1, int v2, int check_ret)
23421 {
23422     TCGv t1;
23423     TCGv v1_t;
23424     TCGv v2_t;
23425
23426     if ((ret == 0) && (check_ret == 1)) {
23427         /* Treat as NOP. */
23428         return;
23429     }
23430
23431     t1 = tcg_temp_new();
23432     v1_t = tcg_temp_new();
23433     v2_t = tcg_temp_new();
23434
23435     gen_load_gpr(v1_t, v1);
23436     gen_load_gpr(v2_t, v2);
23437
23438     switch (op1) {
23439     case OPC_CMPU_EQ_QB_DSP:
23440         switch (op2) {
23441         case OPC_CMPU_EQ_QB:
23442             check_dsp(ctx);
23443             gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
23444             break;
23445         case OPC_CMPU_LT_QB:
23446             check_dsp(ctx);
23447             gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
23448             break;
23449         case OPC_CMPU_LE_QB:
23450             check_dsp(ctx);
23451             gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
23452             break;
23453         case OPC_CMPGU_EQ_QB:
23454             check_dsp(ctx);
23455             gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
23456             break;
23457         case OPC_CMPGU_LT_QB:
23458             check_dsp(ctx);
23459             gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
23460             break;
23461         case OPC_CMPGU_LE_QB:
23462             check_dsp(ctx);
23463             gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
23464             break;
23465         case OPC_CMPGDU_EQ_QB:
23466             check_dsp_r2(ctx);
23467             gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
23468             tcg_gen_mov_tl(cpu_gpr[ret], t1);
23469             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23470             tcg_gen_shli_tl(t1, t1, 24);
23471             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23472             break;
23473         case OPC_CMPGDU_LT_QB:
23474             check_dsp_r2(ctx);
23475             gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
23476             tcg_gen_mov_tl(cpu_gpr[ret], t1);
23477             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23478             tcg_gen_shli_tl(t1, t1, 24);
23479             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23480             break;
23481         case OPC_CMPGDU_LE_QB:
23482             check_dsp_r2(ctx);
23483             gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
23484             tcg_gen_mov_tl(cpu_gpr[ret], t1);
23485             tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
23486             tcg_gen_shli_tl(t1, t1, 24);
23487             tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
23488             break;
23489         case OPC_CMP_EQ_PH:
23490             check_dsp(ctx);
23491             gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
23492             break;
23493         case OPC_CMP_LT_PH:
23494             check_dsp(ctx);
23495             gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
23496             break;
23497         case OPC_CMP_LE_PH:
23498             check_dsp(ctx);
23499             gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
23500             break;
23501         case OPC_PICK_QB:
23502             check_dsp(ctx);
23503             gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23504             break;
23505         case OPC_PICK_PH:
23506             check_dsp(ctx);
23507             gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23508             break;
23509         case OPC_PACKRL_PH:
23510             check_dsp(ctx);
23511             gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
23512             break;
23513         }
23514         break;
23515 #ifdef TARGET_MIPS64
23516     case OPC_CMPU_EQ_OB_DSP:
23517         switch (op2) {
23518         case OPC_CMP_EQ_PW:
23519             check_dsp(ctx);
23520             gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
23521             break;
23522         case OPC_CMP_LT_PW:
23523             check_dsp(ctx);
23524             gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
23525             break;
23526         case OPC_CMP_LE_PW:
23527             check_dsp(ctx);
23528             gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
23529             break;
23530         case OPC_CMP_EQ_QH:
23531             check_dsp(ctx);
23532             gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
23533             break;
23534         case OPC_CMP_LT_QH:
23535             check_dsp(ctx);
23536             gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
23537             break;
23538         case OPC_CMP_LE_QH:
23539             check_dsp(ctx);
23540             gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
23541             break;
23542         case OPC_CMPGDU_EQ_OB:
23543             check_dsp_r2(ctx);
23544             gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23545             break;
23546         case OPC_CMPGDU_LT_OB:
23547             check_dsp_r2(ctx);
23548             gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23549             break;
23550         case OPC_CMPGDU_LE_OB:
23551             check_dsp_r2(ctx);
23552             gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23553             break;
23554         case OPC_CMPGU_EQ_OB:
23555             check_dsp(ctx);
23556             gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
23557             break;
23558         case OPC_CMPGU_LT_OB:
23559             check_dsp(ctx);
23560             gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
23561             break;
23562         case OPC_CMPGU_LE_OB:
23563             check_dsp(ctx);
23564             gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
23565             break;
23566         case OPC_CMPU_EQ_OB:
23567             check_dsp(ctx);
23568             gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
23569             break;
23570         case OPC_CMPU_LT_OB:
23571             check_dsp(ctx);
23572             gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
23573             break;
23574         case OPC_CMPU_LE_OB:
23575             check_dsp(ctx);
23576             gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
23577             break;
23578         case OPC_PACKRL_PW:
23579             check_dsp(ctx);
23580             gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
23581             break;
23582         case OPC_PICK_OB:
23583             check_dsp(ctx);
23584             gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23585             break;
23586         case OPC_PICK_PW:
23587             check_dsp(ctx);
23588             gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23589             break;
23590         case OPC_PICK_QH:
23591             check_dsp(ctx);
23592             gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
23593             break;
23594         }
23595         break;
23596 #endif
23597     }
23598
23599     tcg_temp_free(t1);
23600     tcg_temp_free(v1_t);
23601     tcg_temp_free(v2_t);
23602 }
23603
23604 static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
23605                                uint32_t op1, int rt, int rs, int sa)
23606 {
23607     TCGv t0;
23608
23609     check_dsp_r2(ctx);
23610
23611     if (rt == 0) {
23612         /* Treat as NOP. */
23613         return;
23614     }
23615
23616     t0 = tcg_temp_new();
23617     gen_load_gpr(t0, rs);
23618
23619     switch (op1) {
23620     case OPC_APPEND_DSP:
23621         switch (MASK_APPEND(ctx->opcode)) {
23622         case OPC_APPEND:
23623             if (sa != 0) {
23624                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
23625             }
23626             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23627             break;
23628         case OPC_PREPEND:
23629             if (sa != 0) {
23630                 tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
23631                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23632                 tcg_gen_shli_tl(t0, t0, 32 - sa);
23633                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23634             }
23635             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23636             break;
23637         case OPC_BALIGN:
23638             sa &= 3;
23639             if (sa != 0 && sa != 2) {
23640                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23641                 tcg_gen_ext32u_tl(t0, t0);
23642                 tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
23643                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23644             }
23645             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
23646             break;
23647         default:            /* Invalid */
23648             MIPS_INVAL("MASK APPEND");
23649             generate_exception_end(ctx, EXCP_RI);
23650             break;
23651         }
23652         break;
23653 #ifdef TARGET_MIPS64
23654     case OPC_DAPPEND_DSP:
23655         switch (MASK_DAPPEND(ctx->opcode)) {
23656         case OPC_DAPPEND:
23657             if (sa != 0) {
23658                 tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
23659             }
23660             break;
23661         case OPC_PREPENDD:
23662             tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23663             tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23664             tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
23665             break;
23666         case OPC_PREPENDW:
23667             if (sa != 0) {
23668                 tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23669                 tcg_gen_shli_tl(t0, t0, 64 - sa);
23670                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23671             }
23672             break;
23673         case OPC_DBALIGN:
23674             sa &= 7;
23675             if (sa != 0 && sa != 2 && sa != 4) {
23676                 tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23677                 tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23678                 tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23679             }
23680             break;
23681         default:            /* Invalid */
23682             MIPS_INVAL("MASK DAPPEND");
23683             generate_exception_end(ctx, EXCP_RI);
23684             break;
23685         }
23686         break;
23687 #endif
23688     }
23689     tcg_temp_free(t0);
23690 }
23691
23692 static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23693                                 int ret, int v1, int v2, int check_ret)
23694
23695 {
23696     TCGv t0;
23697     TCGv t1;
23698     TCGv v1_t;
23699     TCGv v2_t;
23700     int16_t imm;
23701
23702     if ((ret == 0) && (check_ret == 1)) {
23703         /* Treat as NOP. */
23704         return;
23705     }
23706
23707     t0 = tcg_temp_new();
23708     t1 = tcg_temp_new();
23709     v1_t = tcg_temp_new();
23710     v2_t = tcg_temp_new();
23711
23712     gen_load_gpr(v1_t, v1);
23713     gen_load_gpr(v2_t, v2);
23714
23715     switch (op1) {
23716     case OPC_EXTR_W_DSP:
23717         check_dsp(ctx);
23718         switch (op2) {
23719         case OPC_EXTR_W:
23720             tcg_gen_movi_tl(t0, v2);
23721             tcg_gen_movi_tl(t1, v1);
23722             gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
23723             break;
23724         case OPC_EXTR_R_W:
23725             tcg_gen_movi_tl(t0, v2);
23726             tcg_gen_movi_tl(t1, v1);
23727             gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23728             break;
23729         case OPC_EXTR_RS_W:
23730             tcg_gen_movi_tl(t0, v2);
23731             tcg_gen_movi_tl(t1, v1);
23732             gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23733             break;
23734         case OPC_EXTR_S_H:
23735             tcg_gen_movi_tl(t0, v2);
23736             tcg_gen_movi_tl(t1, v1);
23737             gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23738             break;
23739         case OPC_EXTRV_S_H:
23740             tcg_gen_movi_tl(t0, v2);
23741             gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
23742             break;
23743         case OPC_EXTRV_W:
23744             tcg_gen_movi_tl(t0, v2);
23745             gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23746             break;
23747         case OPC_EXTRV_R_W:
23748             tcg_gen_movi_tl(t0, v2);
23749             gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23750             break;
23751         case OPC_EXTRV_RS_W:
23752             tcg_gen_movi_tl(t0, v2);
23753             gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23754             break;
23755         case OPC_EXTP:
23756             tcg_gen_movi_tl(t0, v2);
23757             tcg_gen_movi_tl(t1, v1);
23758             gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
23759             break;
23760         case OPC_EXTPV:
23761             tcg_gen_movi_tl(t0, v2);
23762             gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
23763             break;
23764         case OPC_EXTPDP:
23765             tcg_gen_movi_tl(t0, v2);
23766             tcg_gen_movi_tl(t1, v1);
23767             gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
23768             break;
23769         case OPC_EXTPDPV:
23770             tcg_gen_movi_tl(t0, v2);
23771             gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23772             break;
23773         case OPC_SHILO:
23774             imm = (ctx->opcode >> 20) & 0x3F;
23775             tcg_gen_movi_tl(t0, ret);
23776             tcg_gen_movi_tl(t1, imm);
23777             gen_helper_shilo(t0, t1, cpu_env);
23778             break;
23779         case OPC_SHILOV:
23780             tcg_gen_movi_tl(t0, ret);
23781             gen_helper_shilo(t0, v1_t, cpu_env);
23782             break;
23783         case OPC_MTHLIP:
23784             tcg_gen_movi_tl(t0, ret);
23785             gen_helper_mthlip(t0, v1_t, cpu_env);
23786             break;
23787         case OPC_WRDSP:
23788             imm = (ctx->opcode >> 11) & 0x3FF;
23789             tcg_gen_movi_tl(t0, imm);
23790             gen_helper_wrdsp(v1_t, t0, cpu_env);
23791             break;
23792         case OPC_RDDSP:
23793             imm = (ctx->opcode >> 16) & 0x03FF;
23794             tcg_gen_movi_tl(t0, imm);
23795             gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
23796             break;
23797         }
23798         break;
23799 #ifdef TARGET_MIPS64
23800     case OPC_DEXTR_W_DSP:
23801         check_dsp(ctx);
23802         switch (op2) {
23803         case OPC_DMTHLIP:
23804             tcg_gen_movi_tl(t0, ret);
23805             gen_helper_dmthlip(v1_t, t0, cpu_env);
23806             break;
23807         case OPC_DSHILO:
23808             {
23809                 int shift = (ctx->opcode >> 19) & 0x7F;
23810                 int ac = (ctx->opcode >> 11) & 0x03;
23811                 tcg_gen_movi_tl(t0, shift);
23812                 tcg_gen_movi_tl(t1, ac);
23813                 gen_helper_dshilo(t0, t1, cpu_env);
23814                 break;
23815             }
23816         case OPC_DSHILOV:
23817             {
23818                 int ac = (ctx->opcode >> 11) & 0x03;
23819                 tcg_gen_movi_tl(t0, ac);
23820                 gen_helper_dshilo(v1_t, t0, cpu_env);
23821                 break;
23822             }
23823         case OPC_DEXTP:
23824             tcg_gen_movi_tl(t0, v2);
23825             tcg_gen_movi_tl(t1, v1);
23826
23827             gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
23828             break;
23829         case OPC_DEXTPV:
23830             tcg_gen_movi_tl(t0, v2);
23831             gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
23832             break;
23833         case OPC_DEXTPDP:
23834             tcg_gen_movi_tl(t0, v2);
23835             tcg_gen_movi_tl(t1, v1);
23836             gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
23837             break;
23838         case OPC_DEXTPDPV:
23839             tcg_gen_movi_tl(t0, v2);
23840             gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23841             break;
23842         case OPC_DEXTR_L:
23843             tcg_gen_movi_tl(t0, v2);
23844             tcg_gen_movi_tl(t1, v1);
23845             gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
23846             break;
23847         case OPC_DEXTR_R_L:
23848             tcg_gen_movi_tl(t0, v2);
23849             tcg_gen_movi_tl(t1, v1);
23850             gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
23851             break;
23852         case OPC_DEXTR_RS_L:
23853             tcg_gen_movi_tl(t0, v2);
23854             tcg_gen_movi_tl(t1, v1);
23855             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
23856             break;
23857         case OPC_DEXTR_W:
23858             tcg_gen_movi_tl(t0, v2);
23859             tcg_gen_movi_tl(t1, v1);
23860             gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
23861             break;
23862         case OPC_DEXTR_R_W:
23863             tcg_gen_movi_tl(t0, v2);
23864             tcg_gen_movi_tl(t1, v1);
23865             gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23866             break;
23867         case OPC_DEXTR_RS_W:
23868             tcg_gen_movi_tl(t0, v2);
23869             tcg_gen_movi_tl(t1, v1);
23870             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23871             break;
23872         case OPC_DEXTR_S_H:
23873             tcg_gen_movi_tl(t0, v2);
23874             tcg_gen_movi_tl(t1, v1);
23875             gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23876             break;
23877         case OPC_DEXTRV_S_H:
23878             tcg_gen_movi_tl(t0, v2);
23879             tcg_gen_movi_tl(t1, v1);
23880             gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23881             break;
23882         case OPC_DEXTRV_L:
23883             tcg_gen_movi_tl(t0, v2);
23884             gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23885             break;
23886         case OPC_DEXTRV_R_L:
23887             tcg_gen_movi_tl(t0, v2);
23888             gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23889             break;
23890         case OPC_DEXTRV_RS_L:
23891             tcg_gen_movi_tl(t0, v2);
23892             gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23893             break;
23894         case OPC_DEXTRV_W:
23895             tcg_gen_movi_tl(t0, v2);
23896             gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23897             break;
23898         case OPC_DEXTRV_R_W:
23899             tcg_gen_movi_tl(t0, v2);
23900             gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23901             break;
23902         case OPC_DEXTRV_RS_W:
23903             tcg_gen_movi_tl(t0, v2);
23904             gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23905             break;
23906         }
23907         break;
23908 #endif
23909     }
23910
23911     tcg_temp_free(t0);
23912     tcg_temp_free(t1);
23913     tcg_temp_free(v1_t);
23914     tcg_temp_free(v2_t);
23915 }
23916
23917 /* End MIPSDSP functions. */
23918
23919 static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
23920 {
23921     int rs, rt, rd, sa;
23922     uint32_t op1, op2;
23923
23924     rs = (ctx->opcode >> 21) & 0x1f;
23925     rt = (ctx->opcode >> 16) & 0x1f;
23926     rd = (ctx->opcode >> 11) & 0x1f;
23927     sa = (ctx->opcode >> 6) & 0x1f;
23928
23929     op1 = MASK_SPECIAL(ctx->opcode);
23930     switch (op1) {
23931     case OPC_LSA:
23932         gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23933         break;
23934     case OPC_MULT:
23935     case OPC_MULTU:
23936     case OPC_DIV:
23937     case OPC_DIVU:
23938         op2 = MASK_R6_MULDIV(ctx->opcode);
23939         switch (op2) {
23940         case R6_OPC_MUL:
23941         case R6_OPC_MUH:
23942         case R6_OPC_MULU:
23943         case R6_OPC_MUHU:
23944         case R6_OPC_DIV:
23945         case R6_OPC_MOD:
23946         case R6_OPC_DIVU:
23947         case R6_OPC_MODU:
23948             gen_r6_muldiv(ctx, op2, rd, rs, rt);
23949             break;
23950         default:
23951             MIPS_INVAL("special_r6 muldiv");
23952             generate_exception_end(ctx, EXCP_RI);
23953             break;
23954         }
23955         break;
23956     case OPC_SELEQZ:
23957     case OPC_SELNEZ:
23958         gen_cond_move(ctx, op1, rd, rs, rt);
23959         break;
23960     case R6_OPC_CLO:
23961     case R6_OPC_CLZ:
23962         if (rt == 0 && sa == 1) {
23963             /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23964                We need additionally to check other fields */
23965             gen_cl(ctx, op1, rd, rs);
23966         } else {
23967             generate_exception_end(ctx, EXCP_RI);
23968         }
23969         break;
23970     case R6_OPC_SDBBP:
23971         if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23972             gen_helper_do_semihosting(cpu_env);
23973         } else {
23974             if (ctx->hflags & MIPS_HFLAG_SBRI) {
23975                 generate_exception_end(ctx, EXCP_RI);
23976             } else {
23977                 generate_exception_end(ctx, EXCP_DBp);
23978             }
23979         }
23980         break;
23981 #if defined(TARGET_MIPS64)
23982     case OPC_DLSA:
23983         check_mips_64(ctx);
23984         gen_lsa(ctx, op1, rd, rs, rt, extract32(ctx->opcode, 6, 2));
23985         break;
23986     case R6_OPC_DCLO:
23987     case R6_OPC_DCLZ:
23988         if (rt == 0 && sa == 1) {
23989             /* Major opcode and function field is shared with preR6 MFHI/MTHI.
23990                We need additionally to check other fields */
23991             check_mips_64(ctx);
23992             gen_cl(ctx, op1, rd, rs);
23993         } else {
23994             generate_exception_end(ctx, EXCP_RI);
23995         }
23996         break;
23997     case OPC_DMULT:
23998     case OPC_DMULTU:
23999     case OPC_DDIV:
24000     case OPC_DDIVU:
24001
24002         op2 = MASK_R6_MULDIV(ctx->opcode);
24003         switch (op2) {
24004         case R6_OPC_DMUL:
24005         case R6_OPC_DMUH:
24006         case R6_OPC_DMULU:
24007         case R6_OPC_DMUHU:
24008         case R6_OPC_DDIV:
24009         case R6_OPC_DMOD:
24010         case R6_OPC_DDIVU:
24011         case R6_OPC_DMODU:
24012             check_mips_64(ctx);
24013             gen_r6_muldiv(ctx, op2, rd, rs, rt);
24014             break;
24015         default:
24016             MIPS_INVAL("special_r6 muldiv");
24017             generate_exception_end(ctx, EXCP_RI);
24018             break;
24019         }
24020         break;
24021 #endif
24022     default:            /* Invalid */
24023         MIPS_INVAL("special_r6");
24024         generate_exception_end(ctx, EXCP_RI);
24025         break;
24026     }
24027 }
24028
24029 static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
24030 {
24031     int rs = extract32(ctx->opcode, 21, 5);
24032     int rt = extract32(ctx->opcode, 16, 5);
24033     int rd = extract32(ctx->opcode, 11, 5);
24034     uint32_t op1 = MASK_SPECIAL(ctx->opcode);
24035
24036     switch (op1) {
24037     case OPC_MOVN:         /* Conditional move */
24038     case OPC_MOVZ:
24039         gen_cond_move(ctx, op1, rd, rs, rt);
24040         break;
24041     case OPC_MFHI:          /* Move from HI/LO */
24042     case OPC_MFLO:
24043         gen_HILO(ctx, op1, 0, rd);
24044         break;
24045     case OPC_MTHI:
24046     case OPC_MTLO:          /* Move to HI/LO */
24047         gen_HILO(ctx, op1, 0, rs);
24048         break;
24049     case OPC_MULT:
24050     case OPC_MULTU:
24051         gen_mul_txx9(ctx, op1, rd, rs, rt);
24052         break;
24053     case OPC_DIV:
24054     case OPC_DIVU:
24055         gen_muldiv(ctx, op1, 0, rs, rt);
24056         break;
24057 #if defined(TARGET_MIPS64)
24058     case OPC_DMULT:
24059     case OPC_DMULTU:
24060     case OPC_DDIV:
24061     case OPC_DDIVU:
24062         check_insn_opc_user_only(ctx, INSN_R5900);
24063         gen_muldiv(ctx, op1, 0, rs, rt);
24064         break;
24065 #endif
24066     case OPC_JR:
24067         gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
24068         break;
24069     default:            /* Invalid */
24070         MIPS_INVAL("special_tx79");
24071         generate_exception_end(ctx, EXCP_RI);
24072         break;
24073     }
24074 }
24075
24076 static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
24077 {
24078     int rs, rt, rd, sa;
24079     uint32_t op1;
24080
24081     rs = (ctx->opcode >> 21) & 0x1f;
24082     rt = (ctx->opcode >> 16) & 0x1f;
24083     rd = (ctx->opcode >> 11) & 0x1f;
24084     sa = (ctx->opcode >> 6) & 0x1f;
24085
24086     op1 = MASK_SPECIAL(ctx->opcode);
24087     switch (op1) {
24088     case OPC_MOVN:         /* Conditional move */
24089     case OPC_MOVZ:
24090         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
24091                    INSN_LOONGSON2E | INSN_LOONGSON2F);
24092         gen_cond_move(ctx, op1, rd, rs, rt);
24093         break;
24094     case OPC_MFHI:          /* Move from HI/LO */
24095     case OPC_MFLO:
24096         gen_HILO(ctx, op1, rs & 3, rd);
24097         break;
24098     case OPC_MTHI:
24099     case OPC_MTLO:          /* Move to HI/LO */
24100         gen_HILO(ctx, op1, rd & 3, rs);
24101         break;
24102     case OPC_MOVCI:
24103         check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
24104         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
24105             check_cp1_enabled(ctx);
24106             gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
24107                       (ctx->opcode >> 16) & 1);
24108         } else {
24109             generate_exception_err(ctx, EXCP_CpU, 1);
24110         }
24111         break;
24112     case OPC_MULT:
24113     case OPC_MULTU:
24114         if (sa) {
24115             check_insn(ctx, INSN_VR54XX);
24116             op1 = MASK_MUL_VR54XX(ctx->opcode);
24117             gen_mul_vr54xx(ctx, op1, rd, rs, rt);
24118         } else {
24119             gen_muldiv(ctx, op1, rd & 3, rs, rt);
24120         }
24121         break;
24122     case OPC_DIV:
24123     case OPC_DIVU:
24124         gen_muldiv(ctx, op1, 0, rs, rt);
24125         break;
24126 #if defined(TARGET_MIPS64)
24127     case OPC_DMULT:
24128     case OPC_DMULTU:
24129     case OPC_DDIV:
24130     case OPC_DDIVU:
24131         check_insn(ctx, ISA_MIPS3);
24132         check_mips_64(ctx);
24133         gen_muldiv(ctx, op1, 0, rs, rt);
24134         break;
24135 #endif
24136     case OPC_JR:
24137         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24138         break;
24139     case OPC_SPIM:
24140 #ifdef MIPS_STRICT_STANDARD
24141         MIPS_INVAL("SPIM");
24142         generate_exception_end(ctx, EXCP_RI);
24143 #else
24144         /* Implemented as RI exception for now. */
24145         MIPS_INVAL("spim (unofficial)");
24146         generate_exception_end(ctx, EXCP_RI);
24147 #endif
24148         break;
24149     default:            /* Invalid */
24150         MIPS_INVAL("special_legacy");
24151         generate_exception_end(ctx, EXCP_RI);
24152         break;
24153     }
24154 }
24155
24156 static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
24157 {
24158     int rs, rt, rd, sa;
24159     uint32_t op1;
24160
24161     rs = (ctx->opcode >> 21) & 0x1f;
24162     rt = (ctx->opcode >> 16) & 0x1f;
24163     rd = (ctx->opcode >> 11) & 0x1f;
24164     sa = (ctx->opcode >> 6) & 0x1f;
24165
24166     op1 = MASK_SPECIAL(ctx->opcode);
24167     switch (op1) {
24168     case OPC_SLL:          /* Shift with immediate */
24169         if (sa == 5 && rd == 0 &&
24170             rs == 0 && rt == 0) { /* PAUSE */
24171             if ((ctx->insn_flags & ISA_MIPS32R6) &&
24172                 (ctx->hflags & MIPS_HFLAG_BMASK)) {
24173                 generate_exception_end(ctx, EXCP_RI);
24174                 break;
24175             }
24176         }
24177         /* Fallthrough */
24178     case OPC_SRA:
24179         gen_shift_imm(ctx, op1, rd, rt, sa);
24180         break;
24181     case OPC_SRL:
24182         switch ((ctx->opcode >> 21) & 0x1f) {
24183         case 1:
24184             /* rotr is decoded as srl on non-R2 CPUs */
24185             if (ctx->insn_flags & ISA_MIPS32R2) {
24186                 op1 = OPC_ROTR;
24187             }
24188             /* Fallthrough */
24189         case 0:
24190             gen_shift_imm(ctx, op1, rd, rt, sa);
24191             break;
24192         default:
24193             generate_exception_end(ctx, EXCP_RI);
24194             break;
24195         }
24196         break;
24197     case OPC_ADD:
24198     case OPC_ADDU:
24199     case OPC_SUB:
24200     case OPC_SUBU:
24201         gen_arith(ctx, op1, rd, rs, rt);
24202         break;
24203     case OPC_SLLV:         /* Shifts */
24204     case OPC_SRAV:
24205         gen_shift(ctx, op1, rd, rs, rt);
24206         break;
24207     case OPC_SRLV:
24208         switch ((ctx->opcode >> 6) & 0x1f) {
24209         case 1:
24210             /* rotrv is decoded as srlv on non-R2 CPUs */
24211             if (ctx->insn_flags & ISA_MIPS32R2) {
24212                 op1 = OPC_ROTRV;
24213             }
24214             /* Fallthrough */
24215         case 0:
24216             gen_shift(ctx, op1, rd, rs, rt);
24217             break;
24218         default:
24219             generate_exception_end(ctx, EXCP_RI);
24220             break;
24221         }
24222         break;
24223     case OPC_SLT:          /* Set on less than */
24224     case OPC_SLTU:
24225         gen_slt(ctx, op1, rd, rs, rt);
24226         break;
24227     case OPC_AND:          /* Logic*/
24228     case OPC_OR:
24229     case OPC_NOR:
24230     case OPC_XOR:
24231         gen_logic(ctx, op1, rd, rs, rt);
24232         break;
24233     case OPC_JALR:
24234         gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
24235         break;
24236     case OPC_TGE: /* Traps */
24237     case OPC_TGEU:
24238     case OPC_TLT:
24239     case OPC_TLTU:
24240     case OPC_TEQ:
24241     case OPC_TNE:
24242         check_insn(ctx, ISA_MIPS2);
24243         gen_trap(ctx, op1, rs, rt, -1);
24244         break;
24245     case OPC_LSA: /* OPC_PMON */
24246         if ((ctx->insn_flags & ISA_MIPS32R6) ||
24247             (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24248             decode_opc_special_r6(env, ctx);
24249         } else {
24250             /* Pmon entry point, also R4010 selsl */
24251 #ifdef MIPS_STRICT_STANDARD
24252             MIPS_INVAL("PMON / selsl");
24253             generate_exception_end(ctx, EXCP_RI);
24254 #else
24255             gen_helper_0e0i(pmon, sa);
24256 #endif
24257         }
24258         break;
24259     case OPC_SYSCALL:
24260         generate_exception_end(ctx, EXCP_SYSCALL);
24261         break;
24262     case OPC_BREAK:
24263         generate_exception_end(ctx, EXCP_BREAK);
24264         break;
24265     case OPC_SYNC:
24266         check_insn(ctx, ISA_MIPS2);
24267         gen_sync(extract32(ctx->opcode, 6, 5));
24268         break;
24269
24270 #if defined(TARGET_MIPS64)
24271         /* MIPS64 specific opcodes */
24272     case OPC_DSLL:
24273     case OPC_DSRA:
24274     case OPC_DSLL32:
24275     case OPC_DSRA32:
24276         check_insn(ctx, ISA_MIPS3);
24277         check_mips_64(ctx);
24278         gen_shift_imm(ctx, op1, rd, rt, sa);
24279         break;
24280     case OPC_DSRL:
24281         switch ((ctx->opcode >> 21) & 0x1f) {
24282         case 1:
24283             /* drotr is decoded as dsrl on non-R2 CPUs */
24284             if (ctx->insn_flags & ISA_MIPS32R2) {
24285                 op1 = OPC_DROTR;
24286             }
24287             /* Fallthrough */
24288         case 0:
24289             check_insn(ctx, ISA_MIPS3);
24290             check_mips_64(ctx);
24291             gen_shift_imm(ctx, op1, rd, rt, sa);
24292             break;
24293         default:
24294             generate_exception_end(ctx, EXCP_RI);
24295             break;
24296         }
24297         break;
24298     case OPC_DSRL32:
24299         switch ((ctx->opcode >> 21) & 0x1f) {
24300         case 1:
24301             /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
24302             if (ctx->insn_flags & ISA_MIPS32R2) {
24303                 op1 = OPC_DROTR32;
24304             }
24305             /* Fallthrough */
24306         case 0:
24307             check_insn(ctx, ISA_MIPS3);
24308             check_mips_64(ctx);
24309             gen_shift_imm(ctx, op1, rd, rt, sa);
24310             break;
24311         default:
24312             generate_exception_end(ctx, EXCP_RI);
24313             break;
24314         }
24315         break;
24316     case OPC_DADD:
24317     case OPC_DADDU:
24318     case OPC_DSUB:
24319     case OPC_DSUBU:
24320         check_insn(ctx, ISA_MIPS3);
24321         check_mips_64(ctx);
24322         gen_arith(ctx, op1, rd, rs, rt);
24323         break;
24324     case OPC_DSLLV:
24325     case OPC_DSRAV:
24326         check_insn(ctx, ISA_MIPS3);
24327         check_mips_64(ctx);
24328         gen_shift(ctx, op1, rd, rs, rt);
24329         break;
24330     case OPC_DSRLV:
24331         switch ((ctx->opcode >> 6) & 0x1f) {
24332         case 1:
24333             /* drotrv is decoded as dsrlv on non-R2 CPUs */
24334             if (ctx->insn_flags & ISA_MIPS32R2) {
24335                 op1 = OPC_DROTRV;
24336             }
24337             /* Fallthrough */
24338         case 0:
24339             check_insn(ctx, ISA_MIPS3);
24340             check_mips_64(ctx);
24341             gen_shift(ctx, op1, rd, rs, rt);
24342             break;
24343         default:
24344             generate_exception_end(ctx, EXCP_RI);
24345             break;
24346         }
24347         break;
24348     case OPC_DLSA:
24349         if ((ctx->insn_flags & ISA_MIPS32R6) ||
24350             (env->CP0_Config3 & (1 << CP0C3_MSAP))) {
24351             decode_opc_special_r6(env, ctx);
24352         }
24353         break;
24354 #endif
24355     default:
24356         if (ctx->insn_flags & ISA_MIPS32R6) {
24357             decode_opc_special_r6(env, ctx);
24358         } else if (ctx->insn_flags & INSN_R5900) {
24359             decode_opc_special_tx79(env, ctx);
24360         } else {
24361             decode_opc_special_legacy(env, ctx);
24362         }
24363     }
24364 }
24365
24366
24367 #if !defined(TARGET_MIPS64)
24368
24369 /* MXU accumulate add/subtract 1-bit pattern 'aptn1' */
24370 #define MXU_APTN1_A    0
24371 #define MXU_APTN1_S    1
24372
24373 /* MXU accumulate add/subtract 2-bit pattern 'aptn2' */
24374 #define MXU_APTN2_AA    0
24375 #define MXU_APTN2_AS    1
24376 #define MXU_APTN2_SA    2
24377 #define MXU_APTN2_SS    3
24378
24379 /* MXU execute add/subtract 2-bit pattern 'eptn2' */
24380 #define MXU_EPTN2_AA    0
24381 #define MXU_EPTN2_AS    1
24382 #define MXU_EPTN2_SA    2
24383 #define MXU_EPTN2_SS    3
24384
24385 /* MXU operand getting pattern 'optn2' */
24386 #define MXU_OPTN2_PTN0  0
24387 #define MXU_OPTN2_PTN1  1
24388 #define MXU_OPTN2_PTN2  2
24389 #define MXU_OPTN2_PTN3  3
24390 /* alternative naming scheme for 'optn2' */
24391 #define MXU_OPTN2_WW    0
24392 #define MXU_OPTN2_LW    1
24393 #define MXU_OPTN2_HW    2
24394 #define MXU_OPTN2_XW    3
24395
24396 /* MXU operand getting pattern 'optn3' */
24397 #define MXU_OPTN3_PTN0  0
24398 #define MXU_OPTN3_PTN1  1
24399 #define MXU_OPTN3_PTN2  2
24400 #define MXU_OPTN3_PTN3  3
24401 #define MXU_OPTN3_PTN4  4
24402 #define MXU_OPTN3_PTN5  5
24403 #define MXU_OPTN3_PTN6  6
24404 #define MXU_OPTN3_PTN7  7
24405
24406
24407 /*
24408  * S32I2M XRa, rb - Register move from GRF to XRF
24409  */
24410 static void gen_mxu_s32i2m(DisasContext *ctx)
24411 {
24412     TCGv t0;
24413     uint32_t XRa, Rb;
24414
24415     t0 = tcg_temp_new();
24416
24417     XRa = extract32(ctx->opcode, 6, 5);
24418     Rb = extract32(ctx->opcode, 16, 5);
24419
24420     gen_load_gpr(t0, Rb);
24421     if (XRa <= 15) {
24422         gen_store_mxu_gpr(t0, XRa);
24423     } else if (XRa == 16) {
24424         gen_store_mxu_cr(t0);
24425     }
24426
24427     tcg_temp_free(t0);
24428 }
24429
24430 /*
24431  * S32M2I XRa, rb - Register move from XRF to GRF
24432  */
24433 static void gen_mxu_s32m2i(DisasContext *ctx)
24434 {
24435     TCGv t0;
24436     uint32_t XRa, Rb;
24437
24438     t0 = tcg_temp_new();
24439
24440     XRa = extract32(ctx->opcode, 6, 5);
24441     Rb = extract32(ctx->opcode, 16, 5);
24442
24443     if (XRa <= 15) {
24444         gen_load_mxu_gpr(t0, XRa);
24445     } else if (XRa == 16) {
24446         gen_load_mxu_cr(t0);
24447     }
24448
24449     gen_store_gpr(t0, Rb);
24450
24451     tcg_temp_free(t0);
24452 }
24453
24454 /*
24455  * S8LDD XRa, Rb, s8, optn3 - Load a byte from memory to XRF
24456  */
24457 static void gen_mxu_s8ldd(DisasContext *ctx)
24458 {
24459     TCGv t0, t1;
24460     uint32_t XRa, Rb, s8, optn3;
24461
24462     t0 = tcg_temp_new();
24463     t1 = tcg_temp_new();
24464
24465     XRa = extract32(ctx->opcode, 6, 4);
24466     s8 = extract32(ctx->opcode, 10, 8);
24467     optn3 = extract32(ctx->opcode, 18, 3);
24468     Rb = extract32(ctx->opcode, 21, 5);
24469
24470     gen_load_gpr(t0, Rb);
24471     tcg_gen_addi_tl(t0, t0, (int8_t)s8);
24472
24473     switch (optn3) {
24474     /* XRa[7:0] = tmp8 */
24475     case MXU_OPTN3_PTN0:
24476         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24477         gen_load_mxu_gpr(t0, XRa);
24478         tcg_gen_deposit_tl(t0, t0, t1, 0, 8);
24479         break;
24480     /* XRa[15:8] = tmp8 */
24481     case MXU_OPTN3_PTN1:
24482         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24483         gen_load_mxu_gpr(t0, XRa);
24484         tcg_gen_deposit_tl(t0, t0, t1, 8, 8);
24485         break;
24486     /* XRa[23:16] = tmp8 */
24487     case MXU_OPTN3_PTN2:
24488         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24489         gen_load_mxu_gpr(t0, XRa);
24490         tcg_gen_deposit_tl(t0, t0, t1, 16, 8);
24491         break;
24492     /* XRa[31:24] = tmp8 */
24493     case MXU_OPTN3_PTN3:
24494         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24495         gen_load_mxu_gpr(t0, XRa);
24496         tcg_gen_deposit_tl(t0, t0, t1, 24, 8);
24497         break;
24498     /* XRa = {8'b0, tmp8, 8'b0, tmp8} */
24499     case MXU_OPTN3_PTN4:
24500         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24501         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24502         break;
24503     /* XRa = {tmp8, 8'b0, tmp8, 8'b0} */
24504     case MXU_OPTN3_PTN5:
24505         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24506         tcg_gen_shli_tl(t1, t1, 8);
24507         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24508         break;
24509     /* XRa = {{8{sign of tmp8}}, tmp8, {8{sign of tmp8}}, tmp8} */
24510     case MXU_OPTN3_PTN6:
24511         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_SB);
24512         tcg_gen_mov_tl(t0, t1);
24513         tcg_gen_andi_tl(t0, t0, 0xFF00FFFF);
24514         tcg_gen_shli_tl(t1, t1, 16);
24515         tcg_gen_or_tl(t0, t0, t1);
24516         break;
24517     /* XRa = {tmp8, tmp8, tmp8, tmp8} */
24518     case MXU_OPTN3_PTN7:
24519         tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
24520         tcg_gen_deposit_tl(t1, t1, t1, 8, 8);
24521         tcg_gen_deposit_tl(t0, t1, t1, 16, 16);
24522         break;
24523     }
24524
24525     gen_store_mxu_gpr(t0, XRa);
24526
24527     tcg_temp_free(t0);
24528     tcg_temp_free(t1);
24529 }
24530
24531 /*
24532  * D16MUL XRa, XRb, XRc, XRd, optn2 - Signed 16 bit pattern multiplication
24533  */
24534 static void gen_mxu_d16mul(DisasContext *ctx)
24535 {
24536     TCGv t0, t1, t2, t3;
24537     uint32_t XRa, XRb, XRc, XRd, optn2;
24538
24539     t0 = tcg_temp_new();
24540     t1 = tcg_temp_new();
24541     t2 = tcg_temp_new();
24542     t3 = tcg_temp_new();
24543
24544     XRa = extract32(ctx->opcode, 6, 4);
24545     XRb = extract32(ctx->opcode, 10, 4);
24546     XRc = extract32(ctx->opcode, 14, 4);
24547     XRd = extract32(ctx->opcode, 18, 4);
24548     optn2 = extract32(ctx->opcode, 22, 2);
24549
24550     gen_load_mxu_gpr(t1, XRb);
24551     tcg_gen_sextract_tl(t0, t1, 0, 16);
24552     tcg_gen_sextract_tl(t1, t1, 16, 16);
24553     gen_load_mxu_gpr(t3, XRc);
24554     tcg_gen_sextract_tl(t2, t3, 0, 16);
24555     tcg_gen_sextract_tl(t3, t3, 16, 16);
24556
24557     switch (optn2) {
24558     case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24559         tcg_gen_mul_tl(t3, t1, t3);
24560         tcg_gen_mul_tl(t2, t0, t2);
24561         break;
24562     case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24563         tcg_gen_mul_tl(t3, t0, t3);
24564         tcg_gen_mul_tl(t2, t0, t2);
24565         break;
24566     case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24567         tcg_gen_mul_tl(t3, t1, t3);
24568         tcg_gen_mul_tl(t2, t1, t2);
24569         break;
24570     case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24571         tcg_gen_mul_tl(t3, t0, t3);
24572         tcg_gen_mul_tl(t2, t1, t2);
24573         break;
24574     }
24575     gen_store_mxu_gpr(t3, XRa);
24576     gen_store_mxu_gpr(t2, XRd);
24577
24578     tcg_temp_free(t0);
24579     tcg_temp_free(t1);
24580     tcg_temp_free(t2);
24581     tcg_temp_free(t3);
24582 }
24583
24584 /*
24585  * D16MAC XRa, XRb, XRc, XRd, aptn2, optn2 - Signed 16 bit pattern multiply
24586  *                                           and accumulate
24587  */
24588 static void gen_mxu_d16mac(DisasContext *ctx)
24589 {
24590     TCGv t0, t1, t2, t3;
24591     uint32_t XRa, XRb, XRc, XRd, optn2, aptn2;
24592
24593     t0 = tcg_temp_new();
24594     t1 = tcg_temp_new();
24595     t2 = tcg_temp_new();
24596     t3 = tcg_temp_new();
24597
24598     XRa = extract32(ctx->opcode, 6, 4);
24599     XRb = extract32(ctx->opcode, 10, 4);
24600     XRc = extract32(ctx->opcode, 14, 4);
24601     XRd = extract32(ctx->opcode, 18, 4);
24602     optn2 = extract32(ctx->opcode, 22, 2);
24603     aptn2 = extract32(ctx->opcode, 24, 2);
24604
24605     gen_load_mxu_gpr(t1, XRb);
24606     tcg_gen_sextract_tl(t0, t1, 0, 16);
24607     tcg_gen_sextract_tl(t1, t1, 16, 16);
24608
24609     gen_load_mxu_gpr(t3, XRc);
24610     tcg_gen_sextract_tl(t2, t3, 0, 16);
24611     tcg_gen_sextract_tl(t3, t3, 16, 16);
24612
24613     switch (optn2) {
24614     case MXU_OPTN2_WW: /* XRB.H*XRC.H == lop, XRB.L*XRC.L == rop */
24615         tcg_gen_mul_tl(t3, t1, t3);
24616         tcg_gen_mul_tl(t2, t0, t2);
24617         break;
24618     case MXU_OPTN2_LW: /* XRB.L*XRC.H == lop, XRB.L*XRC.L == rop */
24619         tcg_gen_mul_tl(t3, t0, t3);
24620         tcg_gen_mul_tl(t2, t0, t2);
24621         break;
24622     case MXU_OPTN2_HW: /* XRB.H*XRC.H == lop, XRB.H*XRC.L == rop */
24623         tcg_gen_mul_tl(t3, t1, t3);
24624         tcg_gen_mul_tl(t2, t1, t2);
24625         break;
24626     case MXU_OPTN2_XW: /* XRB.L*XRC.H == lop, XRB.H*XRC.L == rop */
24627         tcg_gen_mul_tl(t3, t0, t3);
24628         tcg_gen_mul_tl(t2, t1, t2);
24629         break;
24630     }
24631     gen_load_mxu_gpr(t0, XRa);
24632     gen_load_mxu_gpr(t1, XRd);
24633
24634     switch (aptn2) {
24635     case MXU_APTN2_AA:
24636         tcg_gen_add_tl(t3, t0, t3);
24637         tcg_gen_add_tl(t2, t1, t2);
24638         break;
24639     case MXU_APTN2_AS:
24640         tcg_gen_add_tl(t3, t0, t3);
24641         tcg_gen_sub_tl(t2, t1, t2);
24642         break;
24643     case MXU_APTN2_SA:
24644         tcg_gen_sub_tl(t3, t0, t3);
24645         tcg_gen_add_tl(t2, t1, t2);
24646         break;
24647     case MXU_APTN2_SS:
24648         tcg_gen_sub_tl(t3, t0, t3);
24649         tcg_gen_sub_tl(t2, t1, t2);
24650         break;
24651     }
24652     gen_store_mxu_gpr(t3, XRa);
24653     gen_store_mxu_gpr(t2, XRd);
24654
24655     tcg_temp_free(t0);
24656     tcg_temp_free(t1);
24657     tcg_temp_free(t2);
24658     tcg_temp_free(t3);
24659 }
24660
24661 /*
24662  * Q8MUL   XRa, XRb, XRc, XRd - Parallel unsigned 8 bit pattern multiply
24663  * Q8MULSU XRa, XRb, XRc, XRd - Parallel signed 8 bit pattern multiply
24664  */
24665 static void gen_mxu_q8mul_q8mulsu(DisasContext *ctx)
24666 {
24667     TCGv t0, t1, t2, t3, t4, t5, t6, t7;
24668     uint32_t XRa, XRb, XRc, XRd, sel;
24669
24670     t0 = tcg_temp_new();
24671     t1 = tcg_temp_new();
24672     t2 = tcg_temp_new();
24673     t3 = tcg_temp_new();
24674     t4 = tcg_temp_new();
24675     t5 = tcg_temp_new();
24676     t6 = tcg_temp_new();
24677     t7 = tcg_temp_new();
24678
24679     XRa = extract32(ctx->opcode, 6, 4);
24680     XRb = extract32(ctx->opcode, 10, 4);
24681     XRc = extract32(ctx->opcode, 14, 4);
24682     XRd = extract32(ctx->opcode, 18, 4);
24683     sel = extract32(ctx->opcode, 22, 2);
24684
24685     gen_load_mxu_gpr(t3, XRb);
24686     gen_load_mxu_gpr(t7, XRc);
24687
24688     if (sel == 0x2) {
24689         /* Q8MULSU */
24690         tcg_gen_ext8s_tl(t0, t3);
24691         tcg_gen_shri_tl(t3, t3, 8);
24692         tcg_gen_ext8s_tl(t1, t3);
24693         tcg_gen_shri_tl(t3, t3, 8);
24694         tcg_gen_ext8s_tl(t2, t3);
24695         tcg_gen_shri_tl(t3, t3, 8);
24696         tcg_gen_ext8s_tl(t3, t3);
24697     } else {
24698         /* Q8MUL */
24699         tcg_gen_ext8u_tl(t0, t3);
24700         tcg_gen_shri_tl(t3, t3, 8);
24701         tcg_gen_ext8u_tl(t1, t3);
24702         tcg_gen_shri_tl(t3, t3, 8);
24703         tcg_gen_ext8u_tl(t2, t3);
24704         tcg_gen_shri_tl(t3, t3, 8);
24705         tcg_gen_ext8u_tl(t3, t3);
24706     }
24707
24708     tcg_gen_ext8u_tl(t4, t7);
24709     tcg_gen_shri_tl(t7, t7, 8);
24710     tcg_gen_ext8u_tl(t5, t7);
24711     tcg_gen_shri_tl(t7, t7, 8);
24712     tcg_gen_ext8u_tl(t6, t7);
24713     tcg_gen_shri_tl(t7, t7, 8);
24714     tcg_gen_ext8u_tl(t7, t7);
24715
24716     tcg_gen_mul_tl(t0, t0, t4);
24717     tcg_gen_mul_tl(t1, t1, t5);
24718     tcg_gen_mul_tl(t2, t2, t6);
24719     tcg_gen_mul_tl(t3, t3, t7);
24720
24721     tcg_gen_andi_tl(t0, t0, 0xFFFF);
24722     tcg_gen_andi_tl(t1, t1, 0xFFFF);
24723     tcg_gen_andi_tl(t2, t2, 0xFFFF);
24724     tcg_gen_andi_tl(t3, t3, 0xFFFF);
24725
24726     tcg_gen_shli_tl(t1, t1, 16);
24727     tcg_gen_shli_tl(t3, t3, 16);
24728
24729     tcg_gen_or_tl(t0, t0, t1);
24730     tcg_gen_or_tl(t1, t2, t3);
24731
24732     gen_store_mxu_gpr(t0, XRd);
24733     gen_store_mxu_gpr(t1, XRa);
24734
24735     tcg_temp_free(t0);
24736     tcg_temp_free(t1);
24737     tcg_temp_free(t2);
24738     tcg_temp_free(t3);
24739     tcg_temp_free(t4);
24740     tcg_temp_free(t5);
24741     tcg_temp_free(t6);
24742     tcg_temp_free(t7);
24743 }
24744
24745 /*
24746  * S32LDD  XRa, Rb, S12 - Load a word from memory to XRF
24747  * S32LDDR XRa, Rb, S12 - Load a word from memory to XRF, reversed byte seq.
24748  */
24749 static void gen_mxu_s32ldd_s32lddr(DisasContext *ctx)
24750 {
24751     TCGv t0, t1;
24752     uint32_t XRa, Rb, s12, sel;
24753
24754     t0 = tcg_temp_new();
24755     t1 = tcg_temp_new();
24756
24757     XRa = extract32(ctx->opcode, 6, 4);
24758     s12 = extract32(ctx->opcode, 10, 10);
24759     sel = extract32(ctx->opcode, 20, 1);
24760     Rb = extract32(ctx->opcode, 21, 5);
24761
24762     gen_load_gpr(t0, Rb);
24763
24764     tcg_gen_movi_tl(t1, s12);
24765     tcg_gen_shli_tl(t1, t1, 2);
24766     if (s12 & 0x200) {
24767         tcg_gen_ori_tl(t1, t1, 0xFFFFF000);
24768     }
24769     tcg_gen_add_tl(t1, t0, t1);
24770     tcg_gen_qemu_ld_tl(t1, t1, ctx->mem_idx, MO_SL);
24771
24772     if (sel == 1) {
24773         /* S32LDDR */
24774         tcg_gen_bswap32_tl(t1, t1);
24775     }
24776     gen_store_mxu_gpr(t1, XRa);
24777
24778     tcg_temp_free(t0);
24779     tcg_temp_free(t1);
24780 }
24781
24782
24783 /*
24784  *                 MXU instruction category: logic
24785  *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24786  *
24787  *               S32NOR    S32AND    S32OR    S32XOR
24788  */
24789
24790 /*
24791  *  S32NOR XRa, XRb, XRc
24792  *    Update XRa with the result of logical bitwise 'nor' operation
24793  *    applied to the content of XRb and XRc.
24794  *
24795  *   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
24796  *  +-----------+---------+-----+-------+-------+-------+-----------+
24797  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
24798  *  +-----------+---------+-----+-------+-------+-------+-----------+
24799  */
24800 static void gen_mxu_S32NOR(DisasContext *ctx)
24801 {
24802     uint32_t pad, XRc, XRb, XRa;
24803
24804     pad = extract32(ctx->opcode, 21, 5);
24805     XRc = extract32(ctx->opcode, 14, 4);
24806     XRb = extract32(ctx->opcode, 10, 4);
24807     XRa = extract32(ctx->opcode,  6, 4);
24808
24809     if (unlikely(pad != 0)) {
24810         /* opcode padding incorrect -> do nothing */
24811     } else if (unlikely(XRa == 0)) {
24812         /* destination is zero register -> do nothing */
24813     } else if (unlikely((XRb == 0) && (XRc == 0))) {
24814         /* both operands zero registers -> just set destination to all 1s */
24815         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0xFFFFFFFF);
24816     } else if (unlikely(XRb == 0)) {
24817         /* XRb zero register -> just set destination to the negation of XRc */
24818         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24819     } else if (unlikely(XRc == 0)) {
24820         /* XRa zero register -> just set destination to the negation of XRb */
24821         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24822     } else if (unlikely(XRb == XRc)) {
24823         /* both operands same -> just set destination to the negation of XRb */
24824         tcg_gen_not_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24825     } else {
24826         /* the most general case */
24827         tcg_gen_nor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24828     }
24829 }
24830
24831 /*
24832  *  S32AND XRa, XRb, XRc
24833  *    Update XRa with the result of logical bitwise 'and' operation
24834  *    applied to the content of XRb and XRc.
24835  *
24836  *   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
24837  *  +-----------+---------+-----+-------+-------+-------+-----------+
24838  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
24839  *  +-----------+---------+-----+-------+-------+-------+-----------+
24840  */
24841 static void gen_mxu_S32AND(DisasContext *ctx)
24842 {
24843     uint32_t pad, XRc, XRb, XRa;
24844
24845     pad = extract32(ctx->opcode, 21, 5);
24846     XRc = extract32(ctx->opcode, 14, 4);
24847     XRb = extract32(ctx->opcode, 10, 4);
24848     XRa = extract32(ctx->opcode,  6, 4);
24849
24850     if (unlikely(pad != 0)) {
24851         /* opcode padding incorrect -> do nothing */
24852     } else if (unlikely(XRa == 0)) {
24853         /* destination is zero register -> do nothing */
24854     } else if (unlikely((XRb == 0) || (XRc == 0))) {
24855         /* one of operands zero register -> just set destination to all 0s */
24856         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24857     } else if (unlikely(XRb == XRc)) {
24858         /* both operands same -> just set destination to one of them */
24859         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24860     } else {
24861         /* the most general case */
24862         tcg_gen_and_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24863     }
24864 }
24865
24866 /*
24867  *  S32OR XRa, XRb, XRc
24868  *    Update XRa with the result of logical bitwise 'or' operation
24869  *    applied to the content of XRb and XRc.
24870  *
24871  *   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
24872  *  +-----------+---------+-----+-------+-------+-------+-----------+
24873  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
24874  *  +-----------+---------+-----+-------+-------+-------+-----------+
24875  */
24876 static void gen_mxu_S32OR(DisasContext *ctx)
24877 {
24878     uint32_t pad, XRc, XRb, XRa;
24879
24880     pad = extract32(ctx->opcode, 21, 5);
24881     XRc = extract32(ctx->opcode, 14, 4);
24882     XRb = extract32(ctx->opcode, 10, 4);
24883     XRa = extract32(ctx->opcode,  6, 4);
24884
24885     if (unlikely(pad != 0)) {
24886         /* opcode padding incorrect -> do nothing */
24887     } else if (unlikely(XRa == 0)) {
24888         /* destination is zero register -> do nothing */
24889     } else if (unlikely((XRb == 0) && (XRc == 0))) {
24890         /* both operands zero registers -> just set destination to all 0s */
24891         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24892     } else if (unlikely(XRb == 0)) {
24893         /* XRb zero register -> just set destination to the content of XRc */
24894         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24895     } else if (unlikely(XRc == 0)) {
24896         /* XRc zero register -> just set destination to the content of XRb */
24897         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24898     } else if (unlikely(XRb == XRc)) {
24899         /* both operands same -> just set destination to one of them */
24900         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24901     } else {
24902         /* the most general case */
24903         tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24904     }
24905 }
24906
24907 /*
24908  *  S32XOR XRa, XRb, XRc
24909  *    Update XRa with the result of logical bitwise 'xor' operation
24910  *    applied to the content of XRb and XRc.
24911  *
24912  *   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
24913  *  +-----------+---------+-----+-------+-------+-------+-----------+
24914  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL16|
24915  *  +-----------+---------+-----+-------+-------+-------+-----------+
24916  */
24917 static void gen_mxu_S32XOR(DisasContext *ctx)
24918 {
24919     uint32_t pad, XRc, XRb, XRa;
24920
24921     pad = extract32(ctx->opcode, 21, 5);
24922     XRc = extract32(ctx->opcode, 14, 4);
24923     XRb = extract32(ctx->opcode, 10, 4);
24924     XRa = extract32(ctx->opcode,  6, 4);
24925
24926     if (unlikely(pad != 0)) {
24927         /* opcode padding incorrect -> do nothing */
24928     } else if (unlikely(XRa == 0)) {
24929         /* destination is zero register -> do nothing */
24930     } else if (unlikely((XRb == 0) && (XRc == 0))) {
24931         /* both operands zero registers -> just set destination to all 0s */
24932         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24933     } else if (unlikely(XRb == 0)) {
24934         /* XRb zero register -> just set destination to the content of XRc */
24935         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
24936     } else if (unlikely(XRc == 0)) {
24937         /* XRc zero register -> just set destination to the content of XRb */
24938         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
24939     } else if (unlikely(XRb == XRc)) {
24940         /* both operands same -> just set destination to all 0s */
24941         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24942     } else {
24943         /* the most general case */
24944         tcg_gen_xor_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], mxu_gpr[XRc - 1]);
24945     }
24946 }
24947
24948
24949 /*
24950  *                   MXU instruction category max/min
24951  *                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24952  *
24953  *                     S32MAX     D16MAX     Q8MAX
24954  *                     S32MIN     D16MIN     Q8MIN
24955  */
24956
24957 /*
24958  *  S32MAX XRa, XRb, XRc
24959  *    Update XRa with the maximum of signed 32-bit integers contained
24960  *    in XRb and XRc.
24961  *
24962  *  S32MIN XRa, XRb, XRc
24963  *    Update XRa with the minimum of signed 32-bit integers contained
24964  *    in XRb and XRc.
24965  *
24966  *   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
24967  *  +-----------+---------+-----+-------+-------+-------+-----------+
24968  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
24969  *  +-----------+---------+-----+-------+-------+-------+-----------+
24970  */
24971 static void gen_mxu_S32MAX_S32MIN(DisasContext *ctx)
24972 {
24973     uint32_t pad, opc, XRc, XRb, XRa;
24974
24975     pad = extract32(ctx->opcode, 21, 5);
24976     opc = extract32(ctx->opcode, 18, 3);
24977     XRc = extract32(ctx->opcode, 14, 4);
24978     XRb = extract32(ctx->opcode, 10, 4);
24979     XRa = extract32(ctx->opcode,  6, 4);
24980
24981     if (unlikely(pad != 0)) {
24982         /* opcode padding incorrect -> do nothing */
24983     } else if (unlikely(XRa == 0)) {
24984         /* destination is zero register -> do nothing */
24985     } else if (unlikely((XRb == 0) && (XRc == 0))) {
24986         /* both operands zero registers -> just set destination to zero */
24987         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
24988     } else if (unlikely((XRb == 0) || (XRc == 0))) {
24989         /* exactly one operand is zero register - find which one is not...*/
24990         uint32_t XRx = XRb ? XRb : XRc;
24991         /* ...and do max/min operation with one operand 0 */
24992         if (opc == OPC_MXU_S32MAX) {
24993             tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
24994         } else {
24995             tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRx - 1], 0);
24996         }
24997     } else if (unlikely(XRb == XRc)) {
24998         /* both operands same -> just set destination to one of them */
24999         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25000     } else {
25001         /* the most general case */
25002         if (opc == OPC_MXU_S32MAX) {
25003             tcg_gen_smax_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25004                                                mxu_gpr[XRc - 1]);
25005         } else {
25006             tcg_gen_smin_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1],
25007                                                mxu_gpr[XRc - 1]);
25008         }
25009     }
25010 }
25011
25012 /*
25013  *  D16MAX
25014  *    Update XRa with the 16-bit-wise maximums of signed integers
25015  *    contained in XRb and XRc.
25016  *
25017  *  D16MIN
25018  *    Update XRa with the 16-bit-wise minimums of signed integers
25019  *    contained in XRb and XRc.
25020  *
25021  *   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
25022  *  +-----------+---------+-----+-------+-------+-------+-----------+
25023  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
25024  *  +-----------+---------+-----+-------+-------+-------+-----------+
25025  */
25026 static void gen_mxu_D16MAX_D16MIN(DisasContext *ctx)
25027 {
25028     uint32_t pad, opc, XRc, XRb, XRa;
25029
25030     pad = extract32(ctx->opcode, 21, 5);
25031     opc = extract32(ctx->opcode, 18, 3);
25032     XRc = extract32(ctx->opcode, 14, 4);
25033     XRb = extract32(ctx->opcode, 10, 4);
25034     XRa = extract32(ctx->opcode,  6, 4);
25035
25036     if (unlikely(pad != 0)) {
25037         /* opcode padding incorrect -> do nothing */
25038     } else if (unlikely(XRc == 0)) {
25039         /* destination is zero register -> do nothing */
25040     } else if (unlikely((XRb == 0) && (XRa == 0))) {
25041         /* both operands zero registers -> just set destination to zero */
25042         tcg_gen_movi_i32(mxu_gpr[XRc - 1], 0);
25043     } else if (unlikely((XRb == 0) || (XRa == 0))) {
25044         /* exactly one operand is zero register - find which one is not...*/
25045         uint32_t XRx = XRb ? XRb : XRc;
25046         /* ...and do half-word-wise max/min with one operand 0 */
25047         TCGv_i32 t0 = tcg_temp_new();
25048         TCGv_i32 t1 = tcg_const_i32(0);
25049
25050         /* the left half-word first */
25051         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFFFF0000);
25052         if (opc == OPC_MXU_D16MAX) {
25053             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25054         } else {
25055             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25056         }
25057
25058         /* the right half-word */
25059         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0x0000FFFF);
25060         /* move half-words to the leftmost position */
25061         tcg_gen_shli_i32(t0, t0, 16);
25062         /* t0 will be max/min of t0 and t1 */
25063         if (opc == OPC_MXU_D16MAX) {
25064             tcg_gen_smax_i32(t0, t0, t1);
25065         } else {
25066             tcg_gen_smin_i32(t0, t0, t1);
25067         }
25068         /* return resulting half-words to its original position */
25069         tcg_gen_shri_i32(t0, t0, 16);
25070         /* finaly update the destination */
25071         tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25072
25073         tcg_temp_free(t1);
25074         tcg_temp_free(t0);
25075     } else if (unlikely(XRb == XRc)) {
25076         /* both operands same -> just set destination to one of them */
25077         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25078     } else {
25079         /* the most general case */
25080         TCGv_i32 t0 = tcg_temp_new();
25081         TCGv_i32 t1 = tcg_temp_new();
25082
25083         /* the left half-word first */
25084         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFFFF0000);
25085         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25086         if (opc == OPC_MXU_D16MAX) {
25087             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25088         } else {
25089             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25090         }
25091
25092         /* the right half-word */
25093         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25094         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0x0000FFFF);
25095         /* move half-words to the leftmost position */
25096         tcg_gen_shli_i32(t0, t0, 16);
25097         tcg_gen_shli_i32(t1, t1, 16);
25098         /* t0 will be max/min of t0 and t1 */
25099         if (opc == OPC_MXU_D16MAX) {
25100             tcg_gen_smax_i32(t0, t0, t1);
25101         } else {
25102             tcg_gen_smin_i32(t0, t0, t1);
25103         }
25104         /* return resulting half-words to its original position */
25105         tcg_gen_shri_i32(t0, t0, 16);
25106         /* finaly update the destination */
25107         tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25108
25109         tcg_temp_free(t1);
25110         tcg_temp_free(t0);
25111     }
25112 }
25113
25114 /*
25115  *  Q8MAX
25116  *    Update XRa with the 8-bit-wise maximums of signed integers
25117  *    contained in XRb and XRc.
25118  *
25119  *  Q8MIN
25120  *    Update XRa with the 8-bit-wise minimums of signed integers
25121  *    contained in XRb and XRc.
25122  *
25123  *   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
25124  *  +-----------+---------+-----+-------+-------+-------+-----------+
25125  *  |  SPECIAL2 |0 0 0 0 0| opc |  XRc  |  XRb  |  XRa  |MXU__POOL00|
25126  *  +-----------+---------+-----+-------+-------+-------+-----------+
25127  */
25128 static void gen_mxu_Q8MAX_Q8MIN(DisasContext *ctx)
25129 {
25130     uint32_t pad, opc, XRc, XRb, XRa;
25131
25132     pad = extract32(ctx->opcode, 21, 5);
25133     opc = extract32(ctx->opcode, 18, 3);
25134     XRc = extract32(ctx->opcode, 14, 4);
25135     XRb = extract32(ctx->opcode, 10, 4);
25136     XRa = extract32(ctx->opcode,  6, 4);
25137
25138     if (unlikely(pad != 0)) {
25139         /* opcode padding incorrect -> do nothing */
25140     } else if (unlikely(XRa == 0)) {
25141         /* destination is zero register -> do nothing */
25142     } else if (unlikely((XRb == 0) && (XRc == 0))) {
25143         /* both operands zero registers -> just set destination to zero */
25144         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25145     } else if (unlikely((XRb == 0) || (XRc == 0))) {
25146         /* exactly one operand is zero register - make it be the first...*/
25147         uint32_t XRx = XRb ? XRb : XRc;
25148         /* ...and do byte-wise max/min with one operand 0 */
25149         TCGv_i32 t0 = tcg_temp_new();
25150         TCGv_i32 t1 = tcg_const_i32(0);
25151         int32_t i;
25152
25153         /* the leftmost byte (byte 3) first */
25154         tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF000000);
25155         if (opc == OPC_MXU_Q8MAX) {
25156             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25157         } else {
25158             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25159         }
25160
25161         /* bytes 2, 1, 0 */
25162         for (i = 2; i >= 0; i--) {
25163             /* extract the byte */
25164             tcg_gen_andi_i32(t0, mxu_gpr[XRx - 1], 0xFF << (8 * i));
25165             /* move the byte to the leftmost position */
25166             tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25167             /* t0 will be max/min of t0 and t1 */
25168             if (opc == OPC_MXU_Q8MAX) {
25169                 tcg_gen_smax_i32(t0, t0, t1);
25170             } else {
25171                 tcg_gen_smin_i32(t0, t0, t1);
25172             }
25173             /* return resulting byte to its original position */
25174             tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25175             /* finaly update the destination */
25176             tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25177         }
25178
25179         tcg_temp_free(t1);
25180         tcg_temp_free(t0);
25181     } else if (unlikely(XRb == XRc)) {
25182         /* both operands same -> just set destination to one of them */
25183         tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25184     } else {
25185         /* the most general case */
25186         TCGv_i32 t0 = tcg_temp_new();
25187         TCGv_i32 t1 = tcg_temp_new();
25188         int32_t i;
25189
25190         /* the leftmost bytes (bytes 3) first */
25191         tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF000000);
25192         tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25193         if (opc == OPC_MXU_Q8MAX) {
25194             tcg_gen_smax_i32(mxu_gpr[XRa - 1], t0, t1);
25195         } else {
25196             tcg_gen_smin_i32(mxu_gpr[XRa - 1], t0, t1);
25197         }
25198
25199         /* bytes 2, 1, 0 */
25200         for (i = 2; i >= 0; i--) {
25201             /* extract corresponding bytes */
25202             tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0xFF << (8 * i));
25203             tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF << (8 * i));
25204             /* move the bytes to the leftmost position */
25205             tcg_gen_shli_i32(t0, t0, 8 * (3 - i));
25206             tcg_gen_shli_i32(t1, t1, 8 * (3 - i));
25207             /* t0 will be max/min of t0 and t1 */
25208             if (opc == OPC_MXU_Q8MAX) {
25209                 tcg_gen_smax_i32(t0, t0, t1);
25210             } else {
25211                 tcg_gen_smin_i32(t0, t0, t1);
25212             }
25213             /* return resulting byte to its original position */
25214             tcg_gen_shri_i32(t0, t0, 8 * (3 - i));
25215             /* finaly update the destination */
25216             tcg_gen_or_i32(mxu_gpr[XRa - 1], mxu_gpr[XRa - 1], t0);
25217         }
25218
25219         tcg_temp_free(t1);
25220         tcg_temp_free(t0);
25221     }
25222 }
25223
25224
25225 /*
25226  *                 MXU instruction category: align
25227  *                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25228  *
25229  *                       S32ALN     S32ALNI
25230  */
25231
25232 /*
25233  *  S32ALNI XRc, XRb, XRa, optn3
25234  *    Arrange bytes from XRb and XRc according to one of five sets of
25235  *    rules determined by optn3, and place the result in XRa.
25236  *
25237  *   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
25238  *  +-----------+-----+---+-----+-------+-------+-------+-----------+
25239  *  |  SPECIAL2 |optn3|0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
25240  *  +-----------+-----+---+-----+-------+-------+-------+-----------+
25241  *
25242  */
25243 static void gen_mxu_S32ALNI(DisasContext *ctx)
25244 {
25245     uint32_t optn3, pad, XRc, XRb, XRa;
25246
25247     optn3 = extract32(ctx->opcode,  23, 3);
25248     pad   = extract32(ctx->opcode,  21, 2);
25249     XRc   = extract32(ctx->opcode, 14, 4);
25250     XRb   = extract32(ctx->opcode, 10, 4);
25251     XRa   = extract32(ctx->opcode,  6, 4);
25252
25253     if (unlikely(pad != 0)) {
25254         /* opcode padding incorrect -> do nothing */
25255     } else if (unlikely(XRa == 0)) {
25256         /* destination is zero register -> do nothing */
25257     } else if (unlikely((XRb == 0) && (XRc == 0))) {
25258         /* both operands zero registers -> just set destination to all 0s */
25259         tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25260     } else if (unlikely(XRb == 0)) {
25261         /* XRb zero register -> just appropriatelly shift XRc into XRa */
25262         switch (optn3) {
25263         case MXU_OPTN3_PTN0:
25264             tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25265             break;
25266         case MXU_OPTN3_PTN1:
25267         case MXU_OPTN3_PTN2:
25268         case MXU_OPTN3_PTN3:
25269             tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1],
25270                              8 * (4 - optn3));
25271             break;
25272         case MXU_OPTN3_PTN4:
25273             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25274             break;
25275         }
25276     } else if (unlikely(XRc == 0)) {
25277         /* XRc zero register -> just appropriatelly shift XRb into XRa */
25278         switch (optn3) {
25279         case MXU_OPTN3_PTN0:
25280             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25281             break;
25282         case MXU_OPTN3_PTN1:
25283         case MXU_OPTN3_PTN2:
25284         case MXU_OPTN3_PTN3:
25285             tcg_gen_shri_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25286             break;
25287         case MXU_OPTN3_PTN4:
25288             tcg_gen_movi_i32(mxu_gpr[XRa - 1], 0);
25289             break;
25290         }
25291     } else if (unlikely(XRb == XRc)) {
25292         /* both operands same -> just rotation or moving from any of them */
25293         switch (optn3) {
25294         case MXU_OPTN3_PTN0:
25295         case MXU_OPTN3_PTN4:
25296             tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25297             break;
25298         case MXU_OPTN3_PTN1:
25299         case MXU_OPTN3_PTN2:
25300         case MXU_OPTN3_PTN3:
25301             tcg_gen_rotli_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1], 8 * optn3);
25302             break;
25303         }
25304     } else {
25305         /* the most general case */
25306         switch (optn3) {
25307         case MXU_OPTN3_PTN0:
25308             {
25309                 /*                                         */
25310                 /*         XRb                XRc          */
25311                 /*  +---------------+                      */
25312                 /*  | A   B   C   D |    E   F   G   H     */
25313                 /*  +-------+-------+                      */
25314                 /*          |                              */
25315                 /*         XRa                             */
25316                 /*                                         */
25317
25318                 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRb - 1]);
25319             }
25320             break;
25321         case MXU_OPTN3_PTN1:
25322             {
25323                 /*                                         */
25324                 /*         XRb                 XRc         */
25325                 /*      +-------------------+              */
25326                 /*    A | B   C   D       E | F   G   H    */
25327                 /*      +---------+---------+              */
25328                 /*                |                        */
25329                 /*               XRa                       */
25330                 /*                                         */
25331
25332                 TCGv_i32 t0 = tcg_temp_new();
25333                 TCGv_i32 t1 = tcg_temp_new();
25334
25335                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x00FFFFFF);
25336                 tcg_gen_shli_i32(t0, t0, 8);
25337
25338                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFF000000);
25339                 tcg_gen_shri_i32(t1, t1, 24);
25340
25341                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25342
25343                 tcg_temp_free(t1);
25344                 tcg_temp_free(t0);
25345             }
25346             break;
25347         case MXU_OPTN3_PTN2:
25348             {
25349                 /*                                         */
25350                 /*         XRb                 XRc         */
25351                 /*          +-------------------+          */
25352                 /*    A   B | C   D       E   F | G   H    */
25353                 /*          +---------+---------+          */
25354                 /*                    |                    */
25355                 /*                   XRa                   */
25356                 /*                                         */
25357
25358                 TCGv_i32 t0 = tcg_temp_new();
25359                 TCGv_i32 t1 = tcg_temp_new();
25360
25361                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x0000FFFF);
25362                 tcg_gen_shli_i32(t0, t0, 16);
25363
25364                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFF0000);
25365                 tcg_gen_shri_i32(t1, t1, 16);
25366
25367                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25368
25369                 tcg_temp_free(t1);
25370                 tcg_temp_free(t0);
25371             }
25372             break;
25373         case MXU_OPTN3_PTN3:
25374             {
25375                 /*                                         */
25376                 /*         XRb                 XRc         */
25377                 /*              +-------------------+      */
25378                 /*    A   B   C | D       E   F   G | H    */
25379                 /*              +---------+---------+      */
25380                 /*                        |                */
25381                 /*                       XRa               */
25382                 /*                                         */
25383
25384                 TCGv_i32 t0 = tcg_temp_new();
25385                 TCGv_i32 t1 = tcg_temp_new();
25386
25387                 tcg_gen_andi_i32(t0, mxu_gpr[XRb - 1], 0x000000FF);
25388                 tcg_gen_shli_i32(t0, t0, 24);
25389
25390                 tcg_gen_andi_i32(t1, mxu_gpr[XRc - 1], 0xFFFFFF00);
25391                 tcg_gen_shri_i32(t1, t1, 8);
25392
25393                 tcg_gen_or_i32(mxu_gpr[XRa - 1], t0, t1);
25394
25395                 tcg_temp_free(t1);
25396                 tcg_temp_free(t0);
25397             }
25398             break;
25399         case MXU_OPTN3_PTN4:
25400             {
25401                 /*                                         */
25402                 /*         XRb                 XRc         */
25403                 /*                     +---------------+   */
25404                 /*    A   B   C   D    | E   F   G   H |   */
25405                 /*                     +-------+-------+   */
25406                 /*                             |           */
25407                 /*                            XRa          */
25408                 /*                                         */
25409
25410                 tcg_gen_mov_i32(mxu_gpr[XRa - 1], mxu_gpr[XRc - 1]);
25411             }
25412             break;
25413         }
25414     }
25415 }
25416
25417
25418 /*
25419  * Decoding engine for MXU
25420  * =======================
25421  */
25422
25423 /*
25424  *
25425  * Decode MXU pool00
25426  *
25427  *   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
25428  *  +-----------+---------+-----+-------+-------+-------+-----------+
25429  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL00|
25430  *  +-----------+---------+-----+-------+-------+-------+-----------+
25431  *
25432  */
25433 static void decode_opc_mxu__pool00(CPUMIPSState *env, DisasContext *ctx)
25434 {
25435     uint32_t opcode = extract32(ctx->opcode, 18, 3);
25436
25437     switch (opcode) {
25438     case OPC_MXU_S32MAX:
25439     case OPC_MXU_S32MIN:
25440         gen_mxu_S32MAX_S32MIN(ctx);
25441         break;
25442     case OPC_MXU_D16MAX:
25443     case OPC_MXU_D16MIN:
25444         gen_mxu_D16MAX_D16MIN(ctx);
25445         break;
25446     case OPC_MXU_Q8MAX:
25447     case OPC_MXU_Q8MIN:
25448         gen_mxu_Q8MAX_Q8MIN(ctx);
25449         break;
25450     case OPC_MXU_Q8SLT:
25451         /* TODO: Implement emulation of Q8SLT instruction. */
25452         MIPS_INVAL("OPC_MXU_Q8SLT");
25453         generate_exception_end(ctx, EXCP_RI);
25454         break;
25455     case OPC_MXU_Q8SLTU:
25456         /* TODO: Implement emulation of Q8SLTU instruction. */
25457         MIPS_INVAL("OPC_MXU_Q8SLTU");
25458         generate_exception_end(ctx, EXCP_RI);
25459         break;
25460     default:
25461         MIPS_INVAL("decode_opc_mxu");
25462         generate_exception_end(ctx, EXCP_RI);
25463         break;
25464     }
25465 }
25466
25467 /*
25468  *
25469  * Decode MXU pool01
25470  *
25471  *  S32SLT, D16SLT, D16AVG, D16AVGR, Q8AVG, Q8AVGR:
25472  *   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
25473  *  +-----------+---------+-----+-------+-------+-------+-----------+
25474  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
25475  *  +-----------+---------+-----+-------+-------+-------+-----------+
25476  *
25477  *  Q8ADD:
25478  *   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
25479  *  +-----------+---+-----+-----+-------+-------+-------+-----------+
25480  *  |  SPECIAL2 |en2|0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL01|
25481  *  +-----------+---+-----+-----+-------+-------+-------+-----------+
25482  *
25483  */
25484 static void decode_opc_mxu__pool01(CPUMIPSState *env, DisasContext *ctx)
25485 {
25486     uint32_t opcode = extract32(ctx->opcode, 18, 3);
25487
25488     switch (opcode) {
25489     case OPC_MXU_S32SLT:
25490         /* TODO: Implement emulation of S32SLT instruction. */
25491         MIPS_INVAL("OPC_MXU_S32SLT");
25492         generate_exception_end(ctx, EXCP_RI);
25493         break;
25494     case OPC_MXU_D16SLT:
25495         /* TODO: Implement emulation of D16SLT instruction. */
25496         MIPS_INVAL("OPC_MXU_D16SLT");
25497         generate_exception_end(ctx, EXCP_RI);
25498         break;
25499     case OPC_MXU_D16AVG:
25500         /* TODO: Implement emulation of D16AVG instruction. */
25501         MIPS_INVAL("OPC_MXU_D16AVG");
25502         generate_exception_end(ctx, EXCP_RI);
25503         break;
25504     case OPC_MXU_D16AVGR:
25505         /* TODO: Implement emulation of D16AVGR instruction. */
25506         MIPS_INVAL("OPC_MXU_D16AVGR");
25507         generate_exception_end(ctx, EXCP_RI);
25508         break;
25509     case OPC_MXU_Q8AVG:
25510         /* TODO: Implement emulation of Q8AVG instruction. */
25511         MIPS_INVAL("OPC_MXU_Q8AVG");
25512         generate_exception_end(ctx, EXCP_RI);
25513         break;
25514     case OPC_MXU_Q8AVGR:
25515         /* TODO: Implement emulation of Q8AVGR instruction. */
25516         MIPS_INVAL("OPC_MXU_Q8AVGR");
25517         generate_exception_end(ctx, EXCP_RI);
25518         break;
25519     case OPC_MXU_Q8ADD:
25520         /* TODO: Implement emulation of Q8ADD instruction. */
25521         MIPS_INVAL("OPC_MXU_Q8ADD");
25522         generate_exception_end(ctx, EXCP_RI);
25523         break;
25524     default:
25525         MIPS_INVAL("decode_opc_mxu");
25526         generate_exception_end(ctx, EXCP_RI);
25527         break;
25528     }
25529 }
25530
25531 /*
25532  *
25533  * Decode MXU pool02
25534  *
25535  *   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
25536  *  +-----------+---------+-----+-------+-------+-------+-----------+
25537  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL02|
25538  *  +-----------+---------+-----+-------+-------+-------+-----------+
25539  *
25540  */
25541 static void decode_opc_mxu__pool02(CPUMIPSState *env, DisasContext *ctx)
25542 {
25543     uint32_t opcode = extract32(ctx->opcode, 18, 3);
25544
25545     switch (opcode) {
25546     case OPC_MXU_S32CPS:
25547         /* TODO: Implement emulation of S32CPS instruction. */
25548         MIPS_INVAL("OPC_MXU_S32CPS");
25549         generate_exception_end(ctx, EXCP_RI);
25550         break;
25551     case OPC_MXU_D16CPS:
25552         /* TODO: Implement emulation of D16CPS instruction. */
25553         MIPS_INVAL("OPC_MXU_D16CPS");
25554         generate_exception_end(ctx, EXCP_RI);
25555         break;
25556     case OPC_MXU_Q8ABD:
25557         /* TODO: Implement emulation of Q8ABD instruction. */
25558         MIPS_INVAL("OPC_MXU_Q8ABD");
25559         generate_exception_end(ctx, EXCP_RI);
25560         break;
25561     case OPC_MXU_Q16SAT:
25562         /* TODO: Implement emulation of Q16SAT instruction. */
25563         MIPS_INVAL("OPC_MXU_Q16SAT");
25564         generate_exception_end(ctx, EXCP_RI);
25565         break;
25566     default:
25567         MIPS_INVAL("decode_opc_mxu");
25568         generate_exception_end(ctx, EXCP_RI);
25569         break;
25570     }
25571 }
25572
25573 /*
25574  *
25575  * Decode MXU pool03
25576  *
25577  *  D16MULF:
25578  *   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
25579  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25580  *  |  SPECIAL2 |x x|on2|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL03|
25581  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25582  *
25583  *  D16MULE:
25584  *   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
25585  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25586  *  |  SPECIAL2 |x x|on2|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL03|
25587  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25588  *
25589  */
25590 static void decode_opc_mxu__pool03(CPUMIPSState *env, DisasContext *ctx)
25591 {
25592     uint32_t opcode = extract32(ctx->opcode, 24, 2);
25593
25594     switch (opcode) {
25595     case OPC_MXU_D16MULF:
25596         /* TODO: Implement emulation of D16MULF instruction. */
25597         MIPS_INVAL("OPC_MXU_D16MULF");
25598         generate_exception_end(ctx, EXCP_RI);
25599         break;
25600     case OPC_MXU_D16MULE:
25601         /* TODO: Implement emulation of D16MULE instruction. */
25602         MIPS_INVAL("OPC_MXU_D16MULE");
25603         generate_exception_end(ctx, EXCP_RI);
25604         break;
25605     default:
25606         MIPS_INVAL("decode_opc_mxu");
25607         generate_exception_end(ctx, EXCP_RI);
25608         break;
25609     }
25610 }
25611
25612 /*
25613  *
25614  * Decode MXU pool04
25615  *
25616  *   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
25617  *  +-----------+---------+-+-------------------+-------+-----------+
25618  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL04|
25619  *  +-----------+---------+-+-------------------+-------+-----------+
25620  *
25621  */
25622 static void decode_opc_mxu__pool04(CPUMIPSState *env, DisasContext *ctx)
25623 {
25624     uint32_t opcode = extract32(ctx->opcode, 20, 1);
25625
25626     switch (opcode) {
25627     case OPC_MXU_S32LDD:
25628     case OPC_MXU_S32LDDR:
25629         gen_mxu_s32ldd_s32lddr(ctx);
25630         break;
25631     default:
25632         MIPS_INVAL("decode_opc_mxu");
25633         generate_exception_end(ctx, EXCP_RI);
25634         break;
25635     }
25636 }
25637
25638 /*
25639  *
25640  * Decode MXU pool05
25641  *
25642  *   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
25643  *  +-----------+---------+-+-------------------+-------+-----------+
25644  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL05|
25645  *  +-----------+---------+-+-------------------+-------+-----------+
25646  *
25647  */
25648 static void decode_opc_mxu__pool05(CPUMIPSState *env, DisasContext *ctx)
25649 {
25650     uint32_t opcode = extract32(ctx->opcode, 20, 1);
25651
25652     switch (opcode) {
25653     case OPC_MXU_S32STD:
25654         /* TODO: Implement emulation of S32STD instruction. */
25655         MIPS_INVAL("OPC_MXU_S32STD");
25656         generate_exception_end(ctx, EXCP_RI);
25657         break;
25658     case OPC_MXU_S32STDR:
25659         /* TODO: Implement emulation of S32STDR instruction. */
25660         MIPS_INVAL("OPC_MXU_S32STDR");
25661         generate_exception_end(ctx, EXCP_RI);
25662         break;
25663     default:
25664         MIPS_INVAL("decode_opc_mxu");
25665         generate_exception_end(ctx, EXCP_RI);
25666         break;
25667     }
25668 }
25669
25670 /*
25671  *
25672  * Decode MXU pool06
25673  *
25674  *   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
25675  *  +-----------+---------+---------+---+-------+-------+-----------+
25676  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL06|
25677  *  +-----------+---------+---------+---+-------+-------+-----------+
25678  *
25679  */
25680 static void decode_opc_mxu__pool06(CPUMIPSState *env, DisasContext *ctx)
25681 {
25682     uint32_t opcode = extract32(ctx->opcode, 10, 4);
25683
25684     switch (opcode) {
25685     case OPC_MXU_S32LDDV:
25686         /* TODO: Implement emulation of S32LDDV instruction. */
25687         MIPS_INVAL("OPC_MXU_S32LDDV");
25688         generate_exception_end(ctx, EXCP_RI);
25689         break;
25690     case OPC_MXU_S32LDDVR:
25691         /* TODO: Implement emulation of S32LDDVR instruction. */
25692         MIPS_INVAL("OPC_MXU_S32LDDVR");
25693         generate_exception_end(ctx, EXCP_RI);
25694         break;
25695     default:
25696         MIPS_INVAL("decode_opc_mxu");
25697         generate_exception_end(ctx, EXCP_RI);
25698         break;
25699     }
25700 }
25701
25702 /*
25703  *
25704  * Decode MXU pool07
25705  *
25706  *   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
25707  *  +-----------+---------+---------+---+-------+-------+-----------+
25708  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL07|
25709  *  +-----------+---------+---------+---+-------+-------+-----------+
25710  *
25711  */
25712 static void decode_opc_mxu__pool07(CPUMIPSState *env, DisasContext *ctx)
25713 {
25714     uint32_t opcode = extract32(ctx->opcode, 10, 4);
25715
25716     switch (opcode) {
25717     case OPC_MXU_S32STDV:
25718         /* TODO: Implement emulation of S32TDV instruction. */
25719         MIPS_INVAL("OPC_MXU_S32TDV");
25720         generate_exception_end(ctx, EXCP_RI);
25721         break;
25722     case OPC_MXU_S32STDVR:
25723         /* TODO: Implement emulation of S32TDVR instruction. */
25724         MIPS_INVAL("OPC_MXU_S32TDVR");
25725         generate_exception_end(ctx, EXCP_RI);
25726         break;
25727     default:
25728         MIPS_INVAL("decode_opc_mxu");
25729         generate_exception_end(ctx, EXCP_RI);
25730         break;
25731     }
25732 }
25733
25734 /*
25735  *
25736  * Decode MXU pool08
25737  *
25738  *   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
25739  *  +-----------+---------+-+-------------------+-------+-----------+
25740  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL08|
25741  *  +-----------+---------+-+-------------------+-------+-----------+
25742  *
25743 */
25744 static void decode_opc_mxu__pool08(CPUMIPSState *env, DisasContext *ctx)
25745 {
25746     uint32_t opcode = extract32(ctx->opcode, 20, 1);
25747
25748     switch (opcode) {
25749     case OPC_MXU_S32LDI:
25750         /* TODO: Implement emulation of S32LDI instruction. */
25751         MIPS_INVAL("OPC_MXU_S32LDI");
25752         generate_exception_end(ctx, EXCP_RI);
25753         break;
25754     case OPC_MXU_S32LDIR:
25755         /* TODO: Implement emulation of S32LDIR instruction. */
25756         MIPS_INVAL("OPC_MXU_S32LDIR");
25757         generate_exception_end(ctx, EXCP_RI);
25758         break;
25759     default:
25760         MIPS_INVAL("decode_opc_mxu");
25761         generate_exception_end(ctx, EXCP_RI);
25762         break;
25763     }
25764 }
25765
25766 /*
25767  *
25768  * Decode MXU pool09
25769  *
25770  *   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
25771  *  +-----------+---------+-+-------------------+-------+-----------+
25772  *  |  SPECIAL2 |    rb   |x|        s12        |  XRa  |MXU__POOL09|
25773  *  +-----------+---------+-+-------------------+-------+-----------+
25774  *
25775  */
25776 static void decode_opc_mxu__pool09(CPUMIPSState *env, DisasContext *ctx)
25777 {
25778     uint32_t opcode = extract32(ctx->opcode, 5, 0);
25779
25780     switch (opcode) {
25781     case OPC_MXU_S32SDI:
25782         /* TODO: Implement emulation of S32SDI instruction. */
25783         MIPS_INVAL("OPC_MXU_S32SDI");
25784         generate_exception_end(ctx, EXCP_RI);
25785         break;
25786     case OPC_MXU_S32SDIR:
25787         /* TODO: Implement emulation of S32SDIR instruction. */
25788         MIPS_INVAL("OPC_MXU_S32SDIR");
25789         generate_exception_end(ctx, EXCP_RI);
25790         break;
25791     default:
25792         MIPS_INVAL("decode_opc_mxu");
25793         generate_exception_end(ctx, EXCP_RI);
25794         break;
25795     }
25796 }
25797
25798 /*
25799  *
25800  * Decode MXU pool10
25801  *
25802  *   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
25803  *  +-----------+---------+---------+---+-------+-------+-----------+
25804  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL10|
25805  *  +-----------+---------+---------+---+-------+-------+-----------+
25806  *
25807  */
25808 static void decode_opc_mxu__pool10(CPUMIPSState *env, DisasContext *ctx)
25809 {
25810     uint32_t opcode = extract32(ctx->opcode, 5, 0);
25811
25812     switch (opcode) {
25813     case OPC_MXU_S32LDIV:
25814         /* TODO: Implement emulation of S32LDIV instruction. */
25815         MIPS_INVAL("OPC_MXU_S32LDIV");
25816         generate_exception_end(ctx, EXCP_RI);
25817         break;
25818     case OPC_MXU_S32LDIVR:
25819         /* TODO: Implement emulation of S32LDIVR instruction. */
25820         MIPS_INVAL("OPC_MXU_S32LDIVR");
25821         generate_exception_end(ctx, EXCP_RI);
25822         break;
25823     default:
25824         MIPS_INVAL("decode_opc_mxu");
25825         generate_exception_end(ctx, EXCP_RI);
25826         break;
25827     }
25828 }
25829
25830 /*
25831  *
25832  * Decode MXU pool11
25833  *
25834  *   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
25835  *  +-----------+---------+---------+---+-------+-------+-----------+
25836  *  |  SPECIAL2 |    rb   |    rc   |st2|x x x x|  XRa  |MXU__POOL11|
25837  *  +-----------+---------+---------+---+-------+-------+-----------+
25838  *
25839  */
25840 static void decode_opc_mxu__pool11(CPUMIPSState *env, DisasContext *ctx)
25841 {
25842     uint32_t opcode = extract32(ctx->opcode, 10, 4);
25843
25844     switch (opcode) {
25845     case OPC_MXU_S32SDIV:
25846         /* TODO: Implement emulation of S32SDIV instruction. */
25847         MIPS_INVAL("OPC_MXU_S32SDIV");
25848         generate_exception_end(ctx, EXCP_RI);
25849         break;
25850     case OPC_MXU_S32SDIVR:
25851         /* TODO: Implement emulation of S32SDIVR instruction. */
25852         MIPS_INVAL("OPC_MXU_S32SDIVR");
25853         generate_exception_end(ctx, EXCP_RI);
25854         break;
25855     default:
25856         MIPS_INVAL("decode_opc_mxu");
25857         generate_exception_end(ctx, EXCP_RI);
25858         break;
25859     }
25860 }
25861
25862 /*
25863  *
25864  * Decode MXU pool12
25865  *
25866  *   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
25867  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25868  *  |  SPECIAL2 |an2|x x|   Xd  |  XRc  |  XRb  |  XRa  |MXU__POOL12|
25869  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25870  *
25871  */
25872 static void decode_opc_mxu__pool12(CPUMIPSState *env, DisasContext *ctx)
25873 {
25874     uint32_t opcode = extract32(ctx->opcode, 22, 2);
25875
25876     switch (opcode) {
25877     case OPC_MXU_D32ACC:
25878         /* TODO: Implement emulation of D32ACC instruction. */
25879         MIPS_INVAL("OPC_MXU_D32ACC");
25880         generate_exception_end(ctx, EXCP_RI);
25881         break;
25882     case OPC_MXU_D32ACCM:
25883         /* TODO: Implement emulation of D32ACCM instruction. */
25884         MIPS_INVAL("OPC_MXU_D32ACCM");
25885         generate_exception_end(ctx, EXCP_RI);
25886         break;
25887     case OPC_MXU_D32ASUM:
25888         /* TODO: Implement emulation of D32ASUM instruction. */
25889         MIPS_INVAL("OPC_MXU_D32ASUM");
25890         generate_exception_end(ctx, EXCP_RI);
25891         break;
25892     default:
25893         MIPS_INVAL("decode_opc_mxu");
25894         generate_exception_end(ctx, EXCP_RI);
25895         break;
25896     }
25897 }
25898
25899 /*
25900  *
25901  * Decode MXU pool13
25902  *
25903  *   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
25904  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25905  *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL13|
25906  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25907  *
25908  */
25909 static void decode_opc_mxu__pool13(CPUMIPSState *env, DisasContext *ctx)
25910 {
25911     uint32_t opcode = extract32(ctx->opcode, 22, 2);
25912
25913     switch (opcode) {
25914     case OPC_MXU_Q16ACC:
25915         /* TODO: Implement emulation of Q16ACC instruction. */
25916         MIPS_INVAL("OPC_MXU_Q16ACC");
25917         generate_exception_end(ctx, EXCP_RI);
25918         break;
25919     case OPC_MXU_Q16ACCM:
25920         /* TODO: Implement emulation of Q16ACCM instruction. */
25921         MIPS_INVAL("OPC_MXU_Q16ACCM");
25922         generate_exception_end(ctx, EXCP_RI);
25923         break;
25924     case OPC_MXU_Q16ASUM:
25925         /* TODO: Implement emulation of Q16ASUM instruction. */
25926         MIPS_INVAL("OPC_MXU_Q16ASUM");
25927         generate_exception_end(ctx, EXCP_RI);
25928         break;
25929     default:
25930         MIPS_INVAL("decode_opc_mxu");
25931         generate_exception_end(ctx, EXCP_RI);
25932         break;
25933     }
25934 }
25935
25936 /*
25937  *
25938  * Decode MXU pool14
25939  *
25940  *  Q8ADDE, Q8ACCE:
25941  *   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
25942  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25943  *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL14|
25944  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25945  *
25946  *  D8SUM, D8SUMC:
25947  *   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
25948  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25949  *  |  SPECIAL2 |en2|x x|0 0 0 0|  XRc  |  XRb  |  XRa  |MXU__POOL14|
25950  *  +-----------+---+---+-------+-------+-------+-------+-----------+
25951  *
25952  */
25953 static void decode_opc_mxu__pool14(CPUMIPSState *env, DisasContext *ctx)
25954 {
25955     uint32_t opcode = extract32(ctx->opcode, 22, 2);
25956
25957     switch (opcode) {
25958     case OPC_MXU_Q8ADDE:
25959         /* TODO: Implement emulation of Q8ADDE instruction. */
25960         MIPS_INVAL("OPC_MXU_Q8ADDE");
25961         generate_exception_end(ctx, EXCP_RI);
25962         break;
25963     case OPC_MXU_D8SUM:
25964         /* TODO: Implement emulation of D8SUM instruction. */
25965         MIPS_INVAL("OPC_MXU_D8SUM");
25966         generate_exception_end(ctx, EXCP_RI);
25967         break;
25968     case OPC_MXU_D8SUMC:
25969         /* TODO: Implement emulation of D8SUMC instruction. */
25970         MIPS_INVAL("OPC_MXU_D8SUMC");
25971         generate_exception_end(ctx, EXCP_RI);
25972         break;
25973     default:
25974         MIPS_INVAL("decode_opc_mxu");
25975         generate_exception_end(ctx, EXCP_RI);
25976         break;
25977     }
25978 }
25979
25980 /*
25981  *
25982  * Decode MXU pool15
25983  *
25984  *  S32MUL, S32MULU, S32EXTRV:
25985  *   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
25986  *  +-----------+---------+---------+---+-------+-------+-----------+
25987  *  |  SPECIAL2 |    rs   |    rt   |x x|  XRd  |  XRa  |MXU__POOL15|
25988  *  +-----------+---------+---------+---+-------+-------+-----------+
25989  *
25990  *  S32EXTR:
25991  *   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
25992  *  +-----------+---------+---------+---+-------+-------+-----------+
25993  *  |  SPECIAL2 |    rb   |   sft5  |x x|  XRd  |  XRa  |MXU__POOL15|
25994  *  +-----------+---------+---------+---+-------+-------+-----------+
25995  *
25996  */
25997 static void decode_opc_mxu__pool15(CPUMIPSState *env, DisasContext *ctx)
25998 {
25999     uint32_t opcode = extract32(ctx->opcode, 14, 2);
26000
26001     switch (opcode) {
26002     case OPC_MXU_S32MUL:
26003         /* TODO: Implement emulation of S32MUL instruction. */
26004         MIPS_INVAL("OPC_MXU_S32MUL");
26005         generate_exception_end(ctx, EXCP_RI);
26006         break;
26007     case OPC_MXU_S32MULU:
26008         /* TODO: Implement emulation of S32MULU instruction. */
26009         MIPS_INVAL("OPC_MXU_S32MULU");
26010         generate_exception_end(ctx, EXCP_RI);
26011         break;
26012     case OPC_MXU_S32EXTR:
26013         /* TODO: Implement emulation of S32EXTR instruction. */
26014         MIPS_INVAL("OPC_MXU_S32EXTR");
26015         generate_exception_end(ctx, EXCP_RI);
26016         break;
26017     case OPC_MXU_S32EXTRV:
26018         /* TODO: Implement emulation of S32EXTRV instruction. */
26019         MIPS_INVAL("OPC_MXU_S32EXTRV");
26020         generate_exception_end(ctx, EXCP_RI);
26021         break;
26022     default:
26023         MIPS_INVAL("decode_opc_mxu");
26024         generate_exception_end(ctx, EXCP_RI);
26025         break;
26026     }
26027 }
26028
26029 /*
26030  *
26031  * Decode MXU pool16
26032  *
26033  *  D32SARW:
26034  *   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
26035  *  +-----------+---------+-----+-------+-------+-------+-----------+
26036  *  |  SPECIAL2 |    rb   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26037  *  +-----------+---------+-----+-------+-------+-------+-----------+
26038  *
26039  *  S32ALN:
26040  *   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
26041  *  +-----------+---------+-----+-------+-------+-------+-----------+
26042  *  |  SPECIAL2 |    rs   |x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26043  *  +-----------+---------+-----+-------+-------+-------+-----------+
26044  *
26045  *  S32ALNI:
26046  *   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
26047  *  +-----------+-----+---+-----+-------+-------+-------+-----------+
26048  *  |  SPECIAL2 |  s3 |0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26049  *  +-----------+-----+---+-----+-------+-------+-------+-----------+
26050  *
26051  *  S32LUI:
26052  *   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
26053  *  +-----------+-----+---+-----+-------+---------------+-----------+
26054  *  |  SPECIAL2 |optn3|0 0|x x x|  XRc  |       s8      |MXU__POOL16|
26055  *  +-----------+-----+---+-----+-------+---------------+-----------+
26056  *
26057  *  S32NOR, S32AND, S32OR, S32XOR:
26058  *   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
26059  *  +-----------+---------+-----+-------+-------+-------+-----------+
26060  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL16|
26061  *  +-----------+---------+-----+-------+-------+-------+-----------+
26062  *
26063  */
26064 static void decode_opc_mxu__pool16(CPUMIPSState *env, DisasContext *ctx)
26065 {
26066     uint32_t opcode = extract32(ctx->opcode, 18, 3);
26067
26068     switch (opcode) {
26069     case OPC_MXU_D32SARW:
26070         /* TODO: Implement emulation of D32SARW instruction. */
26071         MIPS_INVAL("OPC_MXU_D32SARW");
26072         generate_exception_end(ctx, EXCP_RI);
26073         break;
26074     case OPC_MXU_S32ALN:
26075         /* TODO: Implement emulation of S32ALN instruction. */
26076         MIPS_INVAL("OPC_MXU_S32ALN");
26077         generate_exception_end(ctx, EXCP_RI);
26078         break;
26079     case OPC_MXU_S32ALNI:
26080         gen_mxu_S32ALNI(ctx);
26081         break;
26082     case OPC_MXU_S32LUI:
26083         /* TODO: Implement emulation of S32LUI instruction. */
26084         MIPS_INVAL("OPC_MXU_S32LUI");
26085         generate_exception_end(ctx, EXCP_RI);
26086         break;
26087     case OPC_MXU_S32NOR:
26088         gen_mxu_S32NOR(ctx);
26089         break;
26090     case OPC_MXU_S32AND:
26091         gen_mxu_S32AND(ctx);
26092         break;
26093     case OPC_MXU_S32OR:
26094         gen_mxu_S32OR(ctx);
26095         break;
26096     case OPC_MXU_S32XOR:
26097         gen_mxu_S32XOR(ctx);
26098         break;
26099     default:
26100         MIPS_INVAL("decode_opc_mxu");
26101         generate_exception_end(ctx, EXCP_RI);
26102         break;
26103     }
26104 }
26105
26106 /*
26107  *
26108  * Decode MXU pool17
26109  *
26110  *   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
26111  *  +-----------+---------+---------+---+---------+-----+-----------+
26112  *  |  SPECIAL2 |    rs   |    rt   |0 0|    rd   |x x x|MXU__POOL15|
26113  *  +-----------+---------+---------+---+---------+-----+-----------+
26114  *
26115  */
26116 static void decode_opc_mxu__pool17(CPUMIPSState *env, DisasContext *ctx)
26117 {
26118     uint32_t opcode = extract32(ctx->opcode, 6, 2);
26119
26120     switch (opcode) {
26121     case OPC_MXU_LXW:
26122         /* TODO: Implement emulation of LXW instruction. */
26123         MIPS_INVAL("OPC_MXU_LXW");
26124         generate_exception_end(ctx, EXCP_RI);
26125         break;
26126     case OPC_MXU_LXH:
26127         /* TODO: Implement emulation of LXH instruction. */
26128         MIPS_INVAL("OPC_MXU_LXH");
26129         generate_exception_end(ctx, EXCP_RI);
26130         break;
26131     case OPC_MXU_LXHU:
26132         /* TODO: Implement emulation of LXHU instruction. */
26133         MIPS_INVAL("OPC_MXU_LXHU");
26134         generate_exception_end(ctx, EXCP_RI);
26135         break;
26136     case OPC_MXU_LXB:
26137         /* TODO: Implement emulation of LXB instruction. */
26138         MIPS_INVAL("OPC_MXU_LXB");
26139         generate_exception_end(ctx, EXCP_RI);
26140         break;
26141     case OPC_MXU_LXBU:
26142         /* TODO: Implement emulation of LXBU instruction. */
26143         MIPS_INVAL("OPC_MXU_LXBU");
26144         generate_exception_end(ctx, EXCP_RI);
26145         break;
26146     default:
26147         MIPS_INVAL("decode_opc_mxu");
26148         generate_exception_end(ctx, EXCP_RI);
26149         break;
26150     }
26151 }
26152 /*
26153  *
26154  * Decode MXU pool18
26155  *
26156  *   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
26157  *  +-----------+---------+-----+-------+-------+-------+-----------+
26158  *  |  SPECIAL2 |    rb   |x x x|  XRd  |  XRa  |0 0 0 0|MXU__POOL18|
26159  *  +-----------+---------+-----+-------+-------+-------+-----------+
26160  *
26161  */
26162 static void decode_opc_mxu__pool18(CPUMIPSState *env, DisasContext *ctx)
26163 {
26164     uint32_t opcode = extract32(ctx->opcode, 18, 3);
26165
26166     switch (opcode) {
26167     case OPC_MXU_D32SLLV:
26168         /* TODO: Implement emulation of D32SLLV instruction. */
26169         MIPS_INVAL("OPC_MXU_D32SLLV");
26170         generate_exception_end(ctx, EXCP_RI);
26171         break;
26172     case OPC_MXU_D32SLRV:
26173         /* TODO: Implement emulation of D32SLRV instruction. */
26174         MIPS_INVAL("OPC_MXU_D32SLRV");
26175         generate_exception_end(ctx, EXCP_RI);
26176         break;
26177     case OPC_MXU_D32SARV:
26178         /* TODO: Implement emulation of D32SARV instruction. */
26179         MIPS_INVAL("OPC_MXU_D32SARV");
26180         generate_exception_end(ctx, EXCP_RI);
26181         break;
26182     case OPC_MXU_Q16SLLV:
26183         /* TODO: Implement emulation of Q16SLLV instruction. */
26184         MIPS_INVAL("OPC_MXU_Q16SLLV");
26185         generate_exception_end(ctx, EXCP_RI);
26186         break;
26187     case OPC_MXU_Q16SLRV:
26188         /* TODO: Implement emulation of Q16SLRV instruction. */
26189         MIPS_INVAL("OPC_MXU_Q16SLRV");
26190         generate_exception_end(ctx, EXCP_RI);
26191         break;
26192     case OPC_MXU_Q16SARV:
26193         /* TODO: Implement emulation of Q16SARV instruction. */
26194         MIPS_INVAL("OPC_MXU_Q16SARV");
26195         generate_exception_end(ctx, EXCP_RI);
26196         break;
26197     default:
26198         MIPS_INVAL("decode_opc_mxu");
26199         generate_exception_end(ctx, EXCP_RI);
26200         break;
26201     }
26202 }
26203
26204 /*
26205  *
26206  * Decode MXU pool19
26207  *
26208  *   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
26209  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26210  *  |  SPECIAL2 |0 0|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL19|
26211  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26212  *
26213  */
26214 static void decode_opc_mxu__pool19(CPUMIPSState *env, DisasContext *ctx)
26215 {
26216     uint32_t opcode = extract32(ctx->opcode, 22, 2);
26217
26218     switch (opcode) {
26219     case OPC_MXU_Q8MUL:
26220     case OPC_MXU_Q8MULSU:
26221         gen_mxu_q8mul_q8mulsu(ctx);
26222         break;
26223     default:
26224         MIPS_INVAL("decode_opc_mxu");
26225         generate_exception_end(ctx, EXCP_RI);
26226         break;
26227     }
26228 }
26229
26230 /*
26231  *
26232  * Decode MXU pool20
26233  *
26234  *   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
26235  *  +-----------+---------+-----+-------+-------+-------+-----------+
26236  *  |  SPECIAL2 |0 0 0 0 0|x x x|  XRc  |  XRb  |  XRa  |MXU__POOL20|
26237  *  +-----------+---------+-----+-------+-------+-------+-----------+
26238  *
26239  */
26240 static void decode_opc_mxu__pool20(CPUMIPSState *env, DisasContext *ctx)
26241 {
26242     uint32_t opcode = extract32(ctx->opcode, 18, 3);
26243
26244     switch (opcode) {
26245     case OPC_MXU_Q8MOVZ:
26246         /* TODO: Implement emulation of Q8MOVZ instruction. */
26247         MIPS_INVAL("OPC_MXU_Q8MOVZ");
26248         generate_exception_end(ctx, EXCP_RI);
26249         break;
26250     case OPC_MXU_Q8MOVN:
26251         /* TODO: Implement emulation of Q8MOVN instruction. */
26252         MIPS_INVAL("OPC_MXU_Q8MOVN");
26253         generate_exception_end(ctx, EXCP_RI);
26254         break;
26255     case OPC_MXU_D16MOVZ:
26256         /* TODO: Implement emulation of D16MOVZ instruction. */
26257         MIPS_INVAL("OPC_MXU_D16MOVZ");
26258         generate_exception_end(ctx, EXCP_RI);
26259         break;
26260     case OPC_MXU_D16MOVN:
26261         /* TODO: Implement emulation of D16MOVN instruction. */
26262         MIPS_INVAL("OPC_MXU_D16MOVN");
26263         generate_exception_end(ctx, EXCP_RI);
26264         break;
26265     case OPC_MXU_S32MOVZ:
26266         /* TODO: Implement emulation of S32MOVZ instruction. */
26267         MIPS_INVAL("OPC_MXU_S32MOVZ");
26268         generate_exception_end(ctx, EXCP_RI);
26269         break;
26270     case OPC_MXU_S32MOVN:
26271         /* TODO: Implement emulation of S32MOVN instruction. */
26272         MIPS_INVAL("OPC_MXU_S32MOVN");
26273         generate_exception_end(ctx, EXCP_RI);
26274         break;
26275     default:
26276         MIPS_INVAL("decode_opc_mxu");
26277         generate_exception_end(ctx, EXCP_RI);
26278         break;
26279     }
26280 }
26281
26282 /*
26283  *
26284  * Decode MXU pool21
26285  *
26286  *   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
26287  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26288  *  |  SPECIAL2 |an2|x x|  XRd  |  XRc  |  XRb  |  XRa  |MXU__POOL21|
26289  *  +-----------+---+---+-------+-------+-------+-------+-----------+
26290  *
26291  */
26292 static void decode_opc_mxu__pool21(CPUMIPSState *env, DisasContext *ctx)
26293 {
26294     uint32_t opcode = extract32(ctx->opcode, 22, 2);
26295
26296     switch (opcode) {
26297     case OPC_MXU_Q8MAC:
26298         /* TODO: Implement emulation of Q8MAC instruction. */
26299         MIPS_INVAL("OPC_MXU_Q8MAC");
26300         generate_exception_end(ctx, EXCP_RI);
26301         break;
26302     case OPC_MXU_Q8MACSU:
26303         /* TODO: Implement emulation of Q8MACSU instruction. */
26304         MIPS_INVAL("OPC_MXU_Q8MACSU");
26305         generate_exception_end(ctx, EXCP_RI);
26306         break;
26307     default:
26308         MIPS_INVAL("decode_opc_mxu");
26309         generate_exception_end(ctx, EXCP_RI);
26310         break;
26311     }
26312 }
26313
26314
26315 /*
26316  * Main MXU decoding function
26317  *
26318  *   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
26319  *  +-----------+---------------------------------------+-----------+
26320  *  |  SPECIAL2 |                                       |x x x x x x|
26321  *  +-----------+---------------------------------------+-----------+
26322  *
26323  */
26324 static void decode_opc_mxu(CPUMIPSState *env, DisasContext *ctx)
26325 {
26326     /*
26327      * TODO: Investigate necessity of including handling of
26328      * CLZ, CLO, SDBB in this function, as they belong to
26329      * SPECIAL2 opcode space for regular pre-R6 MIPS ISAs.
26330      */
26331     uint32_t opcode = extract32(ctx->opcode, 0, 6);
26332
26333     if (opcode == OPC__MXU_MUL) {
26334         uint32_t  rs, rt, rd, op1;
26335
26336         rs = extract32(ctx->opcode, 21, 5);
26337         rt = extract32(ctx->opcode, 16, 5);
26338         rd = extract32(ctx->opcode, 11, 5);
26339         op1 = MASK_SPECIAL2(ctx->opcode);
26340
26341         gen_arith(ctx, op1, rd, rs, rt);
26342
26343         return;
26344     }
26345
26346     if (opcode == OPC_MXU_S32M2I) {
26347         gen_mxu_s32m2i(ctx);
26348         return;
26349     }
26350
26351     if (opcode == OPC_MXU_S32I2M) {
26352         gen_mxu_s32i2m(ctx);
26353         return;
26354     }
26355
26356     {
26357         TCGv t_mxu_cr = tcg_temp_new();
26358         TCGLabel *l_exit = gen_new_label();
26359
26360         gen_load_mxu_cr(t_mxu_cr);
26361         tcg_gen_andi_tl(t_mxu_cr, t_mxu_cr, MXU_CR_MXU_EN);
26362         tcg_gen_brcondi_tl(TCG_COND_NE, t_mxu_cr, MXU_CR_MXU_EN, l_exit);
26363
26364         switch (opcode) {
26365         case OPC_MXU_S32MADD:
26366             /* TODO: Implement emulation of S32MADD instruction. */
26367             MIPS_INVAL("OPC_MXU_S32MADD");
26368             generate_exception_end(ctx, EXCP_RI);
26369             break;
26370         case OPC_MXU_S32MADDU:
26371             /* TODO: Implement emulation of S32MADDU instruction. */
26372             MIPS_INVAL("OPC_MXU_S32MADDU");
26373             generate_exception_end(ctx, EXCP_RI);
26374             break;
26375         case OPC_MXU__POOL00:
26376             decode_opc_mxu__pool00(env, ctx);
26377             break;
26378         case OPC_MXU_S32MSUB:
26379             /* TODO: Implement emulation of S32MSUB instruction. */
26380             MIPS_INVAL("OPC_MXU_S32MSUB");
26381             generate_exception_end(ctx, EXCP_RI);
26382             break;
26383         case OPC_MXU_S32MSUBU:
26384             /* TODO: Implement emulation of S32MSUBU instruction. */
26385             MIPS_INVAL("OPC_MXU_S32MSUBU");
26386             generate_exception_end(ctx, EXCP_RI);
26387             break;
26388         case OPC_MXU__POOL01:
26389             decode_opc_mxu__pool01(env, ctx);
26390             break;
26391         case OPC_MXU__POOL02:
26392             decode_opc_mxu__pool02(env, ctx);
26393             break;
26394         case OPC_MXU_D16MUL:
26395             gen_mxu_d16mul(ctx);
26396             break;
26397         case OPC_MXU__POOL03:
26398             decode_opc_mxu__pool03(env, ctx);
26399             break;
26400         case OPC_MXU_D16MAC:
26401             gen_mxu_d16mac(ctx);
26402             break;
26403         case OPC_MXU_D16MACF:
26404             /* TODO: Implement emulation of D16MACF instruction. */
26405             MIPS_INVAL("OPC_MXU_D16MACF");
26406             generate_exception_end(ctx, EXCP_RI);
26407             break;
26408         case OPC_MXU_D16MADL:
26409             /* TODO: Implement emulation of D16MADL instruction. */
26410             MIPS_INVAL("OPC_MXU_D16MADL");
26411             generate_exception_end(ctx, EXCP_RI);
26412             break;
26413         case OPC_MXU_S16MAD:
26414             /* TODO: Implement emulation of S16MAD instruction. */
26415             MIPS_INVAL("OPC_MXU_S16MAD");
26416             generate_exception_end(ctx, EXCP_RI);
26417             break;
26418         case OPC_MXU_Q16ADD:
26419             /* TODO: Implement emulation of Q16ADD instruction. */
26420             MIPS_INVAL("OPC_MXU_Q16ADD");
26421             generate_exception_end(ctx, EXCP_RI);
26422             break;
26423         case OPC_MXU_D16MACE:
26424             /* TODO: Implement emulation of D16MACE instruction. */
26425             MIPS_INVAL("OPC_MXU_D16MACE");
26426             generate_exception_end(ctx, EXCP_RI);
26427             break;
26428         case OPC_MXU__POOL04:
26429             decode_opc_mxu__pool04(env, ctx);
26430             break;
26431         case OPC_MXU__POOL05:
26432             decode_opc_mxu__pool05(env, ctx);
26433             break;
26434         case OPC_MXU__POOL06:
26435             decode_opc_mxu__pool06(env, ctx);
26436             break;
26437         case OPC_MXU__POOL07:
26438             decode_opc_mxu__pool07(env, ctx);
26439             break;
26440         case OPC_MXU__POOL08:
26441             decode_opc_mxu__pool08(env, ctx);
26442             break;
26443         case OPC_MXU__POOL09:
26444             decode_opc_mxu__pool09(env, ctx);
26445             break;
26446         case OPC_MXU__POOL10:
26447             decode_opc_mxu__pool10(env, ctx);
26448             break;
26449         case OPC_MXU__POOL11:
26450             decode_opc_mxu__pool11(env, ctx);
26451             break;
26452         case OPC_MXU_D32ADD:
26453             /* TODO: Implement emulation of D32ADD instruction. */
26454             MIPS_INVAL("OPC_MXU_D32ADD");
26455             generate_exception_end(ctx, EXCP_RI);
26456             break;
26457         case OPC_MXU__POOL12:
26458             decode_opc_mxu__pool12(env, ctx);
26459             break;
26460         case OPC_MXU__POOL13:
26461             decode_opc_mxu__pool13(env, ctx);
26462             break;
26463         case OPC_MXU__POOL14:
26464             decode_opc_mxu__pool14(env, ctx);
26465             break;
26466         case OPC_MXU_Q8ACCE:
26467             /* TODO: Implement emulation of Q8ACCE instruction. */
26468             MIPS_INVAL("OPC_MXU_Q8ACCE");
26469             generate_exception_end(ctx, EXCP_RI);
26470             break;
26471         case OPC_MXU_S8LDD:
26472             gen_mxu_s8ldd(ctx);
26473             break;
26474         case OPC_MXU_S8STD:
26475             /* TODO: Implement emulation of S8STD instruction. */
26476             MIPS_INVAL("OPC_MXU_S8STD");
26477             generate_exception_end(ctx, EXCP_RI);
26478             break;
26479         case OPC_MXU_S8LDI:
26480             /* TODO: Implement emulation of S8LDI instruction. */
26481             MIPS_INVAL("OPC_MXU_S8LDI");
26482             generate_exception_end(ctx, EXCP_RI);
26483             break;
26484         case OPC_MXU_S8SDI:
26485             /* TODO: Implement emulation of S8SDI instruction. */
26486             MIPS_INVAL("OPC_MXU_S8SDI");
26487             generate_exception_end(ctx, EXCP_RI);
26488             break;
26489         case OPC_MXU__POOL15:
26490             decode_opc_mxu__pool15(env, ctx);
26491             break;
26492         case OPC_MXU__POOL16:
26493             decode_opc_mxu__pool16(env, ctx);
26494             break;
26495         case OPC_MXU__POOL17:
26496             decode_opc_mxu__pool17(env, ctx);
26497             break;
26498         case OPC_MXU_S16LDD:
26499             /* TODO: Implement emulation of S16LDD instruction. */
26500             MIPS_INVAL("OPC_MXU_S16LDD");
26501             generate_exception_end(ctx, EXCP_RI);
26502             break;
26503         case OPC_MXU_S16STD:
26504             /* TODO: Implement emulation of S16STD instruction. */
26505             MIPS_INVAL("OPC_MXU_S16STD");
26506             generate_exception_end(ctx, EXCP_RI);
26507             break;
26508         case OPC_MXU_S16LDI:
26509             /* TODO: Implement emulation of S16LDI instruction. */
26510             MIPS_INVAL("OPC_MXU_S16LDI");
26511             generate_exception_end(ctx, EXCP_RI);
26512             break;
26513         case OPC_MXU_S16SDI:
26514             /* TODO: Implement emulation of S16SDI instruction. */
26515             MIPS_INVAL("OPC_MXU_S16SDI");
26516             generate_exception_end(ctx, EXCP_RI);
26517             break;
26518         case OPC_MXU_D32SLL:
26519             /* TODO: Implement emulation of D32SLL instruction. */
26520             MIPS_INVAL("OPC_MXU_D32SLL");
26521             generate_exception_end(ctx, EXCP_RI);
26522             break;
26523         case OPC_MXU_D32SLR:
26524             /* TODO: Implement emulation of D32SLR instruction. */
26525             MIPS_INVAL("OPC_MXU_D32SLR");
26526             generate_exception_end(ctx, EXCP_RI);
26527             break;
26528         case OPC_MXU_D32SARL:
26529             /* TODO: Implement emulation of D32SARL instruction. */
26530             MIPS_INVAL("OPC_MXU_D32SARL");
26531             generate_exception_end(ctx, EXCP_RI);
26532             break;
26533         case OPC_MXU_D32SAR:
26534             /* TODO: Implement emulation of D32SAR instruction. */
26535             MIPS_INVAL("OPC_MXU_D32SAR");
26536             generate_exception_end(ctx, EXCP_RI);
26537             break;
26538         case OPC_MXU_Q16SLL:
26539             /* TODO: Implement emulation of Q16SLL instruction. */
26540             MIPS_INVAL("OPC_MXU_Q16SLL");
26541             generate_exception_end(ctx, EXCP_RI);
26542             break;
26543         case OPC_MXU_Q16SLR:
26544             /* TODO: Implement emulation of Q16SLR instruction. */
26545             MIPS_INVAL("OPC_MXU_Q16SLR");
26546             generate_exception_end(ctx, EXCP_RI);
26547             break;
26548         case OPC_MXU__POOL18:
26549             decode_opc_mxu__pool18(env, ctx);
26550             break;
26551         case OPC_MXU_Q16SAR:
26552             /* TODO: Implement emulation of Q16SAR instruction. */
26553             MIPS_INVAL("OPC_MXU_Q16SAR");
26554             generate_exception_end(ctx, EXCP_RI);
26555             break;
26556         case OPC_MXU__POOL19:
26557             decode_opc_mxu__pool19(env, ctx);
26558             break;
26559         case OPC_MXU__POOL20:
26560             decode_opc_mxu__pool20(env, ctx);
26561             break;
26562         case OPC_MXU__POOL21:
26563             decode_opc_mxu__pool21(env, ctx);
26564             break;
26565         case OPC_MXU_Q16SCOP:
26566             /* TODO: Implement emulation of Q16SCOP instruction. */
26567             MIPS_INVAL("OPC_MXU_Q16SCOP");
26568             generate_exception_end(ctx, EXCP_RI);
26569             break;
26570         case OPC_MXU_Q8MADL:
26571             /* TODO: Implement emulation of Q8MADL instruction. */
26572             MIPS_INVAL("OPC_MXU_Q8MADL");
26573             generate_exception_end(ctx, EXCP_RI);
26574             break;
26575         case OPC_MXU_S32SFL:
26576             /* TODO: Implement emulation of S32SFL instruction. */
26577             MIPS_INVAL("OPC_MXU_S32SFL");
26578             generate_exception_end(ctx, EXCP_RI);
26579             break;
26580         case OPC_MXU_Q8SAD:
26581             /* TODO: Implement emulation of Q8SAD instruction. */
26582             MIPS_INVAL("OPC_MXU_Q8SAD");
26583             generate_exception_end(ctx, EXCP_RI);
26584             break;
26585         default:
26586             MIPS_INVAL("decode_opc_mxu");
26587             generate_exception_end(ctx, EXCP_RI);
26588         }
26589
26590         gen_set_label(l_exit);
26591         tcg_temp_free(t_mxu_cr);
26592     }
26593 }
26594
26595 #endif /* !defined(TARGET_MIPS64) */
26596
26597
26598 static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
26599 {
26600     int rs, rt, rd;
26601     uint32_t op1;
26602
26603     check_insn_opc_removed(ctx, ISA_MIPS32R6);
26604
26605     rs = (ctx->opcode >> 21) & 0x1f;
26606     rt = (ctx->opcode >> 16) & 0x1f;
26607     rd = (ctx->opcode >> 11) & 0x1f;
26608
26609     op1 = MASK_SPECIAL2(ctx->opcode);
26610     switch (op1) {
26611     case OPC_MADD: /* Multiply and add/sub */
26612     case OPC_MADDU:
26613     case OPC_MSUB:
26614     case OPC_MSUBU:
26615         check_insn(ctx, ISA_MIPS32);
26616         gen_muldiv(ctx, op1, rd & 3, rs, rt);
26617         break;
26618     case OPC_MUL:
26619         gen_arith(ctx, op1, rd, rs, rt);
26620         break;
26621     case OPC_DIV_G_2F:
26622     case OPC_DIVU_G_2F:
26623     case OPC_MULT_G_2F:
26624     case OPC_MULTU_G_2F:
26625     case OPC_MOD_G_2F:
26626     case OPC_MODU_G_2F:
26627         check_insn(ctx, INSN_LOONGSON2F);
26628         gen_loongson_integer(ctx, op1, rd, rs, rt);
26629         break;
26630     case OPC_CLO:
26631     case OPC_CLZ:
26632         check_insn(ctx, ISA_MIPS32);
26633         gen_cl(ctx, op1, rd, rs);
26634         break;
26635     case OPC_SDBBP:
26636         if (is_uhi(extract32(ctx->opcode, 6, 20))) {
26637             gen_helper_do_semihosting(cpu_env);
26638         } else {
26639             /* XXX: not clear which exception should be raised
26640              *      when in debug mode...
26641              */
26642             check_insn(ctx, ISA_MIPS32);
26643             generate_exception_end(ctx, EXCP_DBp);
26644         }
26645         break;
26646 #if defined(TARGET_MIPS64)
26647     case OPC_DCLO:
26648     case OPC_DCLZ:
26649         check_insn(ctx, ISA_MIPS64);
26650         check_mips_64(ctx);
26651         gen_cl(ctx, op1, rd, rs);
26652         break;
26653     case OPC_DMULT_G_2F:
26654     case OPC_DMULTU_G_2F:
26655     case OPC_DDIV_G_2F:
26656     case OPC_DDIVU_G_2F:
26657     case OPC_DMOD_G_2F:
26658     case OPC_DMODU_G_2F:
26659         check_insn(ctx, INSN_LOONGSON2F);
26660         gen_loongson_integer(ctx, op1, rd, rs, rt);
26661         break;
26662 #endif
26663     default:            /* Invalid */
26664         MIPS_INVAL("special2_legacy");
26665         generate_exception_end(ctx, EXCP_RI);
26666         break;
26667     }
26668 }
26669
26670 static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
26671 {
26672     int rs, rt, rd, sa;
26673     uint32_t op1, op2;
26674     int16_t imm;
26675
26676     rs = (ctx->opcode >> 21) & 0x1f;
26677     rt = (ctx->opcode >> 16) & 0x1f;
26678     rd = (ctx->opcode >> 11) & 0x1f;
26679     sa = (ctx->opcode >> 6) & 0x1f;
26680     imm = (int16_t)ctx->opcode >> 7;
26681
26682     op1 = MASK_SPECIAL3(ctx->opcode);
26683     switch (op1) {
26684     case R6_OPC_PREF:
26685         if (rt >= 24) {
26686             /* hint codes 24-31 are reserved and signal RI */
26687             generate_exception_end(ctx, EXCP_RI);
26688         }
26689         /* Treat as NOP. */
26690         break;
26691     case R6_OPC_CACHE:
26692         check_cp0_enabled(ctx);
26693         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
26694             gen_cache_operation(ctx, rt, rs, imm);
26695         }
26696         break;
26697     case R6_OPC_SC:
26698         gen_st_cond(ctx, op1, rt, rs, imm);
26699         break;
26700     case R6_OPC_LL:
26701         gen_ld(ctx, op1, rt, rs, imm);
26702         break;
26703     case OPC_BSHFL:
26704         {
26705             if (rd == 0) {
26706                 /* Treat as NOP. */
26707                 break;
26708             }
26709             op2 = MASK_BSHFL(ctx->opcode);
26710             switch (op2) {
26711             case OPC_ALIGN:
26712             case OPC_ALIGN_1:
26713             case OPC_ALIGN_2:
26714             case OPC_ALIGN_3:
26715                 gen_align(ctx, 32, rd, rs, rt, sa & 3);
26716                 break;
26717             case OPC_BITSWAP:
26718                 gen_bitswap(ctx, op2, rd, rt);
26719                 break;
26720             }
26721         }
26722         break;
26723 #if defined(TARGET_MIPS64)
26724     case R6_OPC_SCD:
26725         gen_st_cond(ctx, op1, rt, rs, imm);
26726         break;
26727     case R6_OPC_LLD:
26728         gen_ld(ctx, op1, rt, rs, imm);
26729         break;
26730     case OPC_DBSHFL:
26731         check_mips_64(ctx);
26732         {
26733             if (rd == 0) {
26734                 /* Treat as NOP. */
26735                 break;
26736             }
26737             op2 = MASK_DBSHFL(ctx->opcode);
26738             switch (op2) {
26739             case OPC_DALIGN:
26740             case OPC_DALIGN_1:
26741             case OPC_DALIGN_2:
26742             case OPC_DALIGN_3:
26743             case OPC_DALIGN_4:
26744             case OPC_DALIGN_5:
26745             case OPC_DALIGN_6:
26746             case OPC_DALIGN_7:
26747                 gen_align(ctx, 64, rd, rs, rt, sa & 7);
26748                 break;
26749             case OPC_DBITSWAP:
26750                 gen_bitswap(ctx, op2, rd, rt);
26751                 break;
26752             }
26753
26754         }
26755         break;
26756 #endif
26757     default:            /* Invalid */
26758         MIPS_INVAL("special3_r6");
26759         generate_exception_end(ctx, EXCP_RI);
26760         break;
26761     }
26762 }
26763
26764 static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
26765 {
26766     int rs, rt, rd;
26767     uint32_t op1, op2;
26768
26769     rs = (ctx->opcode >> 21) & 0x1f;
26770     rt = (ctx->opcode >> 16) & 0x1f;
26771     rd = (ctx->opcode >> 11) & 0x1f;
26772
26773     op1 = MASK_SPECIAL3(ctx->opcode);
26774     switch (op1) {
26775     case OPC_DIV_G_2E:
26776     case OPC_DIVU_G_2E:
26777     case OPC_MOD_G_2E:
26778     case OPC_MODU_G_2E:
26779     case OPC_MULT_G_2E:
26780     case OPC_MULTU_G_2E:
26781         /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
26782          * the same mask and op1. */
26783         if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
26784             op2 = MASK_ADDUH_QB(ctx->opcode);
26785             switch (op2) {
26786             case OPC_ADDUH_QB:
26787             case OPC_ADDUH_R_QB:
26788             case OPC_ADDQH_PH:
26789             case OPC_ADDQH_R_PH:
26790             case OPC_ADDQH_W:
26791             case OPC_ADDQH_R_W:
26792             case OPC_SUBUH_QB:
26793             case OPC_SUBUH_R_QB:
26794             case OPC_SUBQH_PH:
26795             case OPC_SUBQH_R_PH:
26796             case OPC_SUBQH_W:
26797             case OPC_SUBQH_R_W:
26798                 gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26799                 break;
26800             case OPC_MUL_PH:
26801             case OPC_MUL_S_PH:
26802             case OPC_MULQ_S_W:
26803             case OPC_MULQ_RS_W:
26804                 gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
26805                 break;
26806             default:
26807                 MIPS_INVAL("MASK ADDUH.QB");
26808                 generate_exception_end(ctx, EXCP_RI);
26809                 break;
26810             }
26811         } else if (ctx->insn_flags & INSN_LOONGSON2E) {
26812             gen_loongson_integer(ctx, op1, rd, rs, rt);
26813         } else {
26814             generate_exception_end(ctx, EXCP_RI);
26815         }
26816         break;
26817     case OPC_LX_DSP:
26818         op2 = MASK_LX(ctx->opcode);
26819         switch (op2) {
26820 #if defined(TARGET_MIPS64)
26821         case OPC_LDX:
26822 #endif
26823         case OPC_LBUX:
26824         case OPC_LHX:
26825         case OPC_LWX:
26826             gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
26827             break;
26828         default:            /* Invalid */
26829             MIPS_INVAL("MASK LX");
26830             generate_exception_end(ctx, EXCP_RI);
26831             break;
26832         }
26833         break;
26834     case OPC_ABSQ_S_PH_DSP:
26835         op2 = MASK_ABSQ_S_PH(ctx->opcode);
26836         switch (op2) {
26837         case OPC_ABSQ_S_QB:
26838         case OPC_ABSQ_S_PH:
26839         case OPC_ABSQ_S_W:
26840         case OPC_PRECEQ_W_PHL:
26841         case OPC_PRECEQ_W_PHR:
26842         case OPC_PRECEQU_PH_QBL:
26843         case OPC_PRECEQU_PH_QBR:
26844         case OPC_PRECEQU_PH_QBLA:
26845         case OPC_PRECEQU_PH_QBRA:
26846         case OPC_PRECEU_PH_QBL:
26847         case OPC_PRECEU_PH_QBR:
26848         case OPC_PRECEU_PH_QBLA:
26849         case OPC_PRECEU_PH_QBRA:
26850             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26851             break;
26852         case OPC_BITREV:
26853         case OPC_REPL_QB:
26854         case OPC_REPLV_QB:
26855         case OPC_REPL_PH:
26856         case OPC_REPLV_PH:
26857             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
26858             break;
26859         default:
26860             MIPS_INVAL("MASK ABSQ_S.PH");
26861             generate_exception_end(ctx, EXCP_RI);
26862             break;
26863         }
26864         break;
26865     case OPC_ADDU_QB_DSP:
26866         op2 = MASK_ADDU_QB(ctx->opcode);
26867         switch (op2) {
26868         case OPC_ADDQ_PH:
26869         case OPC_ADDQ_S_PH:
26870         case OPC_ADDQ_S_W:
26871         case OPC_ADDU_QB:
26872         case OPC_ADDU_S_QB:
26873         case OPC_ADDU_PH:
26874         case OPC_ADDU_S_PH:
26875         case OPC_SUBQ_PH:
26876         case OPC_SUBQ_S_PH:
26877         case OPC_SUBQ_S_W:
26878         case OPC_SUBU_QB:
26879         case OPC_SUBU_S_QB:
26880         case OPC_SUBU_PH:
26881         case OPC_SUBU_S_PH:
26882         case OPC_ADDSC:
26883         case OPC_ADDWC:
26884         case OPC_MODSUB:
26885         case OPC_RADDU_W_QB:
26886             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26887             break;
26888         case OPC_MULEU_S_PH_QBL:
26889         case OPC_MULEU_S_PH_QBR:
26890         case OPC_MULQ_RS_PH:
26891         case OPC_MULEQ_S_W_PHL:
26892         case OPC_MULEQ_S_W_PHR:
26893         case OPC_MULQ_S_PH:
26894             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
26895             break;
26896         default:            /* Invalid */
26897             MIPS_INVAL("MASK ADDU.QB");
26898             generate_exception_end(ctx, EXCP_RI);
26899             break;
26900
26901         }
26902         break;
26903     case OPC_CMPU_EQ_QB_DSP:
26904         op2 = MASK_CMPU_EQ_QB(ctx->opcode);
26905         switch (op2) {
26906         case OPC_PRECR_SRA_PH_W:
26907         case OPC_PRECR_SRA_R_PH_W:
26908             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
26909             break;
26910         case OPC_PRECR_QB_PH:
26911         case OPC_PRECRQ_QB_PH:
26912         case OPC_PRECRQ_PH_W:
26913         case OPC_PRECRQ_RS_PH_W:
26914         case OPC_PRECRQU_S_QB_PH:
26915             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
26916             break;
26917         case OPC_CMPU_EQ_QB:
26918         case OPC_CMPU_LT_QB:
26919         case OPC_CMPU_LE_QB:
26920         case OPC_CMP_EQ_PH:
26921         case OPC_CMP_LT_PH:
26922         case OPC_CMP_LE_PH:
26923             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
26924             break;
26925         case OPC_CMPGU_EQ_QB:
26926         case OPC_CMPGU_LT_QB:
26927         case OPC_CMPGU_LE_QB:
26928         case OPC_CMPGDU_EQ_QB:
26929         case OPC_CMPGDU_LT_QB:
26930         case OPC_CMPGDU_LE_QB:
26931         case OPC_PICK_QB:
26932         case OPC_PICK_PH:
26933         case OPC_PACKRL_PH:
26934             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
26935             break;
26936         default:            /* Invalid */
26937             MIPS_INVAL("MASK CMPU.EQ.QB");
26938             generate_exception_end(ctx, EXCP_RI);
26939             break;
26940         }
26941         break;
26942     case OPC_SHLL_QB_DSP:
26943         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
26944         break;
26945     case OPC_DPA_W_PH_DSP:
26946         op2 = MASK_DPA_W_PH(ctx->opcode);
26947         switch (op2) {
26948         case OPC_DPAU_H_QBL:
26949         case OPC_DPAU_H_QBR:
26950         case OPC_DPSU_H_QBL:
26951         case OPC_DPSU_H_QBR:
26952         case OPC_DPA_W_PH:
26953         case OPC_DPAX_W_PH:
26954         case OPC_DPAQ_S_W_PH:
26955         case OPC_DPAQX_S_W_PH:
26956         case OPC_DPAQX_SA_W_PH:
26957         case OPC_DPS_W_PH:
26958         case OPC_DPSX_W_PH:
26959         case OPC_DPSQ_S_W_PH:
26960         case OPC_DPSQX_S_W_PH:
26961         case OPC_DPSQX_SA_W_PH:
26962         case OPC_MULSAQ_S_W_PH:
26963         case OPC_DPAQ_SA_L_W:
26964         case OPC_DPSQ_SA_L_W:
26965         case OPC_MAQ_S_W_PHL:
26966         case OPC_MAQ_S_W_PHR:
26967         case OPC_MAQ_SA_W_PHL:
26968         case OPC_MAQ_SA_W_PHR:
26969         case OPC_MULSA_W_PH:
26970             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
26971             break;
26972         default:            /* Invalid */
26973             MIPS_INVAL("MASK DPAW.PH");
26974             generate_exception_end(ctx, EXCP_RI);
26975             break;
26976         }
26977         break;
26978     case OPC_INSV_DSP:
26979         op2 = MASK_INSV(ctx->opcode);
26980         switch (op2) {
26981         case OPC_INSV:
26982             check_dsp(ctx);
26983             {
26984                 TCGv t0, t1;
26985
26986                 if (rt == 0) {
26987                     break;
26988                 }
26989
26990                 t0 = tcg_temp_new();
26991                 t1 = tcg_temp_new();
26992
26993                 gen_load_gpr(t0, rt);
26994                 gen_load_gpr(t1, rs);
26995
26996                 gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
26997
26998                 tcg_temp_free(t0);
26999                 tcg_temp_free(t1);
27000                 break;
27001             }
27002         default:            /* Invalid */
27003             MIPS_INVAL("MASK INSV");
27004             generate_exception_end(ctx, EXCP_RI);
27005             break;
27006         }
27007         break;
27008     case OPC_APPEND_DSP:
27009         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27010         break;
27011     case OPC_EXTR_W_DSP:
27012         op2 = MASK_EXTR_W(ctx->opcode);
27013         switch (op2) {
27014         case OPC_EXTR_W:
27015         case OPC_EXTR_R_W:
27016         case OPC_EXTR_RS_W:
27017         case OPC_EXTR_S_H:
27018         case OPC_EXTRV_S_H:
27019         case OPC_EXTRV_W:
27020         case OPC_EXTRV_R_W:
27021         case OPC_EXTRV_RS_W:
27022         case OPC_EXTP:
27023         case OPC_EXTPV:
27024         case OPC_EXTPDP:
27025         case OPC_EXTPDPV:
27026             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27027             break;
27028         case OPC_RDDSP:
27029             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
27030             break;
27031         case OPC_SHILO:
27032         case OPC_SHILOV:
27033         case OPC_MTHLIP:
27034         case OPC_WRDSP:
27035             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27036             break;
27037         default:            /* Invalid */
27038             MIPS_INVAL("MASK EXTR.W");
27039             generate_exception_end(ctx, EXCP_RI);
27040             break;
27041         }
27042         break;
27043 #if defined(TARGET_MIPS64)
27044     case OPC_DDIV_G_2E:
27045     case OPC_DDIVU_G_2E:
27046     case OPC_DMULT_G_2E:
27047     case OPC_DMULTU_G_2E:
27048     case OPC_DMOD_G_2E:
27049     case OPC_DMODU_G_2E:
27050         check_insn(ctx, INSN_LOONGSON2E);
27051         gen_loongson_integer(ctx, op1, rd, rs, rt);
27052         break;
27053     case OPC_ABSQ_S_QH_DSP:
27054         op2 = MASK_ABSQ_S_QH(ctx->opcode);
27055         switch (op2) {
27056         case OPC_PRECEQ_L_PWL:
27057         case OPC_PRECEQ_L_PWR:
27058         case OPC_PRECEQ_PW_QHL:
27059         case OPC_PRECEQ_PW_QHR:
27060         case OPC_PRECEQ_PW_QHLA:
27061         case OPC_PRECEQ_PW_QHRA:
27062         case OPC_PRECEQU_QH_OBL:
27063         case OPC_PRECEQU_QH_OBR:
27064         case OPC_PRECEQU_QH_OBLA:
27065         case OPC_PRECEQU_QH_OBRA:
27066         case OPC_PRECEU_QH_OBL:
27067         case OPC_PRECEU_QH_OBR:
27068         case OPC_PRECEU_QH_OBLA:
27069         case OPC_PRECEU_QH_OBRA:
27070         case OPC_ABSQ_S_OB:
27071         case OPC_ABSQ_S_PW:
27072         case OPC_ABSQ_S_QH:
27073             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27074             break;
27075         case OPC_REPL_OB:
27076         case OPC_REPL_PW:
27077         case OPC_REPL_QH:
27078         case OPC_REPLV_OB:
27079         case OPC_REPLV_PW:
27080         case OPC_REPLV_QH:
27081             gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
27082             break;
27083         default:            /* Invalid */
27084             MIPS_INVAL("MASK ABSQ_S.QH");
27085             generate_exception_end(ctx, EXCP_RI);
27086             break;
27087         }
27088         break;
27089     case OPC_ADDU_OB_DSP:
27090         op2 = MASK_ADDU_OB(ctx->opcode);
27091         switch (op2) {
27092         case OPC_RADDU_L_OB:
27093         case OPC_SUBQ_PW:
27094         case OPC_SUBQ_S_PW:
27095         case OPC_SUBQ_QH:
27096         case OPC_SUBQ_S_QH:
27097         case OPC_SUBU_OB:
27098         case OPC_SUBU_S_OB:
27099         case OPC_SUBU_QH:
27100         case OPC_SUBU_S_QH:
27101         case OPC_SUBUH_OB:
27102         case OPC_SUBUH_R_OB:
27103         case OPC_ADDQ_PW:
27104         case OPC_ADDQ_S_PW:
27105         case OPC_ADDQ_QH:
27106         case OPC_ADDQ_S_QH:
27107         case OPC_ADDU_OB:
27108         case OPC_ADDU_S_OB:
27109         case OPC_ADDU_QH:
27110         case OPC_ADDU_S_QH:
27111         case OPC_ADDUH_OB:
27112         case OPC_ADDUH_R_OB:
27113             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27114             break;
27115         case OPC_MULEQ_S_PW_QHL:
27116         case OPC_MULEQ_S_PW_QHR:
27117         case OPC_MULEU_S_QH_OBL:
27118         case OPC_MULEU_S_QH_OBR:
27119         case OPC_MULQ_RS_QH:
27120             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
27121             break;
27122         default:            /* Invalid */
27123             MIPS_INVAL("MASK ADDU.OB");
27124             generate_exception_end(ctx, EXCP_RI);
27125             break;
27126         }
27127         break;
27128     case OPC_CMPU_EQ_OB_DSP:
27129         op2 = MASK_CMPU_EQ_OB(ctx->opcode);
27130         switch (op2) {
27131         case OPC_PRECR_SRA_QH_PW:
27132         case OPC_PRECR_SRA_R_QH_PW:
27133             /* Return value is rt. */
27134             gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
27135             break;
27136         case OPC_PRECR_OB_QH:
27137         case OPC_PRECRQ_OB_QH:
27138         case OPC_PRECRQ_PW_L:
27139         case OPC_PRECRQ_QH_PW:
27140         case OPC_PRECRQ_RS_QH_PW:
27141         case OPC_PRECRQU_S_OB_QH:
27142             gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
27143             break;
27144         case OPC_CMPU_EQ_OB:
27145         case OPC_CMPU_LT_OB:
27146         case OPC_CMPU_LE_OB:
27147         case OPC_CMP_EQ_QH:
27148         case OPC_CMP_LT_QH:
27149         case OPC_CMP_LE_QH:
27150         case OPC_CMP_EQ_PW:
27151         case OPC_CMP_LT_PW:
27152         case OPC_CMP_LE_PW:
27153             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
27154             break;
27155         case OPC_CMPGDU_EQ_OB:
27156         case OPC_CMPGDU_LT_OB:
27157         case OPC_CMPGDU_LE_OB:
27158         case OPC_CMPGU_EQ_OB:
27159         case OPC_CMPGU_LT_OB:
27160         case OPC_CMPGU_LE_OB:
27161         case OPC_PACKRL_PW:
27162         case OPC_PICK_OB:
27163         case OPC_PICK_PW:
27164         case OPC_PICK_QH:
27165             gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
27166             break;
27167         default:            /* Invalid */
27168             MIPS_INVAL("MASK CMPU_EQ.OB");
27169             generate_exception_end(ctx, EXCP_RI);
27170             break;
27171         }
27172         break;
27173     case OPC_DAPPEND_DSP:
27174         gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
27175         break;
27176     case OPC_DEXTR_W_DSP:
27177         op2 = MASK_DEXTR_W(ctx->opcode);
27178         switch (op2) {
27179         case OPC_DEXTP:
27180         case OPC_DEXTPDP:
27181         case OPC_DEXTPDPV:
27182         case OPC_DEXTPV:
27183         case OPC_DEXTR_L:
27184         case OPC_DEXTR_R_L:
27185         case OPC_DEXTR_RS_L:
27186         case OPC_DEXTR_W:
27187         case OPC_DEXTR_R_W:
27188         case OPC_DEXTR_RS_W:
27189         case OPC_DEXTR_S_H:
27190         case OPC_DEXTRV_L:
27191         case OPC_DEXTRV_R_L:
27192         case OPC_DEXTRV_RS_L:
27193         case OPC_DEXTRV_S_H:
27194         case OPC_DEXTRV_W:
27195         case OPC_DEXTRV_R_W:
27196         case OPC_DEXTRV_RS_W:
27197             gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
27198             break;
27199         case OPC_DMTHLIP:
27200         case OPC_DSHILO:
27201         case OPC_DSHILOV:
27202             gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
27203             break;
27204         default:            /* Invalid */
27205             MIPS_INVAL("MASK EXTR.W");
27206             generate_exception_end(ctx, EXCP_RI);
27207             break;
27208         }
27209         break;
27210     case OPC_DPAQ_W_QH_DSP:
27211         op2 = MASK_DPAQ_W_QH(ctx->opcode);
27212         switch (op2) {
27213         case OPC_DPAU_H_OBL:
27214         case OPC_DPAU_H_OBR:
27215         case OPC_DPSU_H_OBL:
27216         case OPC_DPSU_H_OBR:
27217         case OPC_DPA_W_QH:
27218         case OPC_DPAQ_S_W_QH:
27219         case OPC_DPS_W_QH:
27220         case OPC_DPSQ_S_W_QH:
27221         case OPC_MULSAQ_S_W_QH:
27222         case OPC_DPAQ_SA_L_PW:
27223         case OPC_DPSQ_SA_L_PW:
27224         case OPC_MULSAQ_S_L_PW:
27225             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27226             break;
27227         case OPC_MAQ_S_W_QHLL:
27228         case OPC_MAQ_S_W_QHLR:
27229         case OPC_MAQ_S_W_QHRL:
27230         case OPC_MAQ_S_W_QHRR:
27231         case OPC_MAQ_SA_W_QHLL:
27232         case OPC_MAQ_SA_W_QHLR:
27233         case OPC_MAQ_SA_W_QHRL:
27234         case OPC_MAQ_SA_W_QHRR:
27235         case OPC_MAQ_S_L_PWL:
27236         case OPC_MAQ_S_L_PWR:
27237         case OPC_DMADD:
27238         case OPC_DMADDU:
27239         case OPC_DMSUB:
27240         case OPC_DMSUBU:
27241             gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
27242             break;
27243         default:            /* Invalid */
27244             MIPS_INVAL("MASK DPAQ.W.QH");
27245             generate_exception_end(ctx, EXCP_RI);
27246             break;
27247         }
27248         break;
27249     case OPC_DINSV_DSP:
27250         op2 = MASK_INSV(ctx->opcode);
27251         switch (op2) {
27252         case OPC_DINSV:
27253         {
27254             TCGv t0, t1;
27255
27256             if (rt == 0) {
27257                 break;
27258             }
27259             check_dsp(ctx);
27260
27261             t0 = tcg_temp_new();
27262             t1 = tcg_temp_new();
27263
27264             gen_load_gpr(t0, rt);
27265             gen_load_gpr(t1, rs);
27266
27267             gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
27268
27269             tcg_temp_free(t0);
27270             tcg_temp_free(t1);
27271             break;
27272         }
27273         default:            /* Invalid */
27274             MIPS_INVAL("MASK DINSV");
27275             generate_exception_end(ctx, EXCP_RI);
27276             break;
27277         }
27278         break;
27279     case OPC_SHLL_OB_DSP:
27280         gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
27281         break;
27282 #endif
27283     default:            /* Invalid */
27284         MIPS_INVAL("special3_legacy");
27285         generate_exception_end(ctx, EXCP_RI);
27286         break;
27287     }
27288 }
27289
27290 static void decode_mmi0(CPUMIPSState *env, DisasContext *ctx)
27291 {
27292     uint32_t opc = MASK_MMI0(ctx->opcode);
27293
27294     switch (opc) {
27295     case MMI_OPC_0_PADDW:     /* TODO: MMI_OPC_0_PADDW */
27296     case MMI_OPC_0_PSUBW:     /* TODO: MMI_OPC_0_PSUBW */
27297     case MMI_OPC_0_PCGTW:     /* TODO: MMI_OPC_0_PCGTW */
27298     case MMI_OPC_0_PMAXW:     /* TODO: MMI_OPC_0_PMAXW */
27299     case MMI_OPC_0_PADDH:     /* TODO: MMI_OPC_0_PADDH */
27300     case MMI_OPC_0_PSUBH:     /* TODO: MMI_OPC_0_PSUBH */
27301     case MMI_OPC_0_PCGTH:     /* TODO: MMI_OPC_0_PCGTH */
27302     case MMI_OPC_0_PMAXH:     /* TODO: MMI_OPC_0_PMAXH */
27303     case MMI_OPC_0_PADDB:     /* TODO: MMI_OPC_0_PADDB */
27304     case MMI_OPC_0_PSUBB:     /* TODO: MMI_OPC_0_PSUBB */
27305     case MMI_OPC_0_PCGTB:     /* TODO: MMI_OPC_0_PCGTB */
27306     case MMI_OPC_0_PADDSW:    /* TODO: MMI_OPC_0_PADDSW */
27307     case MMI_OPC_0_PSUBSW:    /* TODO: MMI_OPC_0_PSUBSW */
27308     case MMI_OPC_0_PEXTLW:    /* TODO: MMI_OPC_0_PEXTLW */
27309     case MMI_OPC_0_PPACW:     /* TODO: MMI_OPC_0_PPACW */
27310     case MMI_OPC_0_PADDSH:    /* TODO: MMI_OPC_0_PADDSH */
27311     case MMI_OPC_0_PSUBSH:    /* TODO: MMI_OPC_0_PSUBSH */
27312     case MMI_OPC_0_PEXTLH:    /* TODO: MMI_OPC_0_PEXTLH */
27313     case MMI_OPC_0_PPACH:     /* TODO: MMI_OPC_0_PPACH */
27314     case MMI_OPC_0_PADDSB:    /* TODO: MMI_OPC_0_PADDSB */
27315     case MMI_OPC_0_PSUBSB:    /* TODO: MMI_OPC_0_PSUBSB */
27316     case MMI_OPC_0_PEXTLB:    /* TODO: MMI_OPC_0_PEXTLB */
27317     case MMI_OPC_0_PPACB:     /* TODO: MMI_OPC_0_PPACB */
27318     case MMI_OPC_0_PEXT5:     /* TODO: MMI_OPC_0_PEXT5 */
27319     case MMI_OPC_0_PPAC5:     /* TODO: MMI_OPC_0_PPAC5 */
27320         generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI0 */
27321         break;
27322     default:
27323         MIPS_INVAL("TX79 MMI class MMI0");
27324         generate_exception_end(ctx, EXCP_RI);
27325         break;
27326     }
27327 }
27328
27329 static void decode_mmi1(CPUMIPSState *env, DisasContext *ctx)
27330 {
27331     uint32_t opc = MASK_MMI1(ctx->opcode);
27332
27333     switch (opc) {
27334     case MMI_OPC_1_PABSW:     /* TODO: MMI_OPC_1_PABSW */
27335     case MMI_OPC_1_PCEQW:     /* TODO: MMI_OPC_1_PCEQW */
27336     case MMI_OPC_1_PMINW:     /* TODO: MMI_OPC_1_PMINW */
27337     case MMI_OPC_1_PADSBH:    /* TODO: MMI_OPC_1_PADSBH */
27338     case MMI_OPC_1_PABSH:     /* TODO: MMI_OPC_1_PABSH */
27339     case MMI_OPC_1_PCEQH:     /* TODO: MMI_OPC_1_PCEQH */
27340     case MMI_OPC_1_PMINH:     /* TODO: MMI_OPC_1_PMINH */
27341     case MMI_OPC_1_PCEQB:     /* TODO: MMI_OPC_1_PCEQB */
27342     case MMI_OPC_1_PADDUW:    /* TODO: MMI_OPC_1_PADDUW */
27343     case MMI_OPC_1_PSUBUW:    /* TODO: MMI_OPC_1_PSUBUW */
27344     case MMI_OPC_1_PEXTUW:    /* TODO: MMI_OPC_1_PEXTUW */
27345     case MMI_OPC_1_PADDUH:    /* TODO: MMI_OPC_1_PADDUH */
27346     case MMI_OPC_1_PSUBUH:    /* TODO: MMI_OPC_1_PSUBUH */
27347     case MMI_OPC_1_PEXTUH:    /* TODO: MMI_OPC_1_PEXTUH */
27348     case MMI_OPC_1_PADDUB:    /* TODO: MMI_OPC_1_PADDUB */
27349     case MMI_OPC_1_PSUBUB:    /* TODO: MMI_OPC_1_PSUBUB */
27350     case MMI_OPC_1_PEXTUB:    /* TODO: MMI_OPC_1_PEXTUB */
27351     case MMI_OPC_1_QFSRV:     /* TODO: MMI_OPC_1_QFSRV */
27352         generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI1 */
27353         break;
27354     default:
27355         MIPS_INVAL("TX79 MMI class MMI1");
27356         generate_exception_end(ctx, EXCP_RI);
27357         break;
27358     }
27359 }
27360
27361 static void decode_mmi2(CPUMIPSState *env, DisasContext *ctx)
27362 {
27363     uint32_t opc = MASK_MMI2(ctx->opcode);
27364
27365     switch (opc) {
27366     case MMI_OPC_2_PMADDW:    /* TODO: MMI_OPC_2_PMADDW */
27367     case MMI_OPC_2_PSLLVW:    /* TODO: MMI_OPC_2_PSLLVW */
27368     case MMI_OPC_2_PSRLVW:    /* TODO: MMI_OPC_2_PSRLVW */
27369     case MMI_OPC_2_PMSUBW:    /* TODO: MMI_OPC_2_PMSUBW */
27370     case MMI_OPC_2_PMFHI:     /* TODO: MMI_OPC_2_PMFHI */
27371     case MMI_OPC_2_PMFLO:     /* TODO: MMI_OPC_2_PMFLO */
27372     case MMI_OPC_2_PINTH:     /* TODO: MMI_OPC_2_PINTH */
27373     case MMI_OPC_2_PMULTW:    /* TODO: MMI_OPC_2_PMULTW */
27374     case MMI_OPC_2_PDIVW:     /* TODO: MMI_OPC_2_PDIVW */
27375     case MMI_OPC_2_PCPYLD:    /* TODO: MMI_OPC_2_PCPYLD */
27376     case MMI_OPC_2_PMADDH:    /* TODO: MMI_OPC_2_PMADDH */
27377     case MMI_OPC_2_PHMADH:    /* TODO: MMI_OPC_2_PHMADH */
27378     case MMI_OPC_2_PAND:      /* TODO: MMI_OPC_2_PAND */
27379     case MMI_OPC_2_PXOR:      /* TODO: MMI_OPC_2_PXOR */
27380     case MMI_OPC_2_PMSUBH:    /* TODO: MMI_OPC_2_PMSUBH */
27381     case MMI_OPC_2_PHMSBH:    /* TODO: MMI_OPC_2_PHMSBH */
27382     case MMI_OPC_2_PEXEH:     /* TODO: MMI_OPC_2_PEXEH */
27383     case MMI_OPC_2_PREVH:     /* TODO: MMI_OPC_2_PREVH */
27384     case MMI_OPC_2_PMULTH:    /* TODO: MMI_OPC_2_PMULTH */
27385     case MMI_OPC_2_PDIVBW:    /* TODO: MMI_OPC_2_PDIVBW */
27386     case MMI_OPC_2_PEXEW:     /* TODO: MMI_OPC_2_PEXEW */
27387     case MMI_OPC_2_PROT3W:    /* TODO: MMI_OPC_2_PROT3W */
27388         generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI2 */
27389         break;
27390     default:
27391         MIPS_INVAL("TX79 MMI class MMI2");
27392         generate_exception_end(ctx, EXCP_RI);
27393         break;
27394     }
27395 }
27396
27397 static void decode_mmi3(CPUMIPSState *env, DisasContext *ctx)
27398 {
27399     uint32_t opc = MASK_MMI3(ctx->opcode);
27400
27401     switch (opc) {
27402     case MMI_OPC_3_PMADDUW:    /* TODO: MMI_OPC_3_PMADDUW */
27403     case MMI_OPC_3_PSRAVW:     /* TODO: MMI_OPC_3_PSRAVW */
27404     case MMI_OPC_3_PMTHI:      /* TODO: MMI_OPC_3_PMTHI */
27405     case MMI_OPC_3_PMTLO:      /* TODO: MMI_OPC_3_PMTLO */
27406     case MMI_OPC_3_PINTEH:     /* TODO: MMI_OPC_3_PINTEH */
27407     case MMI_OPC_3_PMULTUW:    /* TODO: MMI_OPC_3_PMULTUW */
27408     case MMI_OPC_3_PDIVUW:     /* TODO: MMI_OPC_3_PDIVUW */
27409     case MMI_OPC_3_PCPYUD:     /* TODO: MMI_OPC_3_PCPYUD */
27410     case MMI_OPC_3_POR:        /* TODO: MMI_OPC_3_POR */
27411     case MMI_OPC_3_PNOR:       /* TODO: MMI_OPC_3_PNOR */
27412     case MMI_OPC_3_PEXCH:      /* TODO: MMI_OPC_3_PEXCH */
27413     case MMI_OPC_3_PCPYH:      /* TODO: MMI_OPC_3_PCPYH */
27414     case MMI_OPC_3_PEXCW:      /* TODO: MMI_OPC_3_PEXCW */
27415         generate_exception_end(ctx, EXCP_RI); /* TODO: MMI_OPC_CLASS_MMI3 */
27416         break;
27417     default:
27418         MIPS_INVAL("TX79 MMI class MMI3");
27419         generate_exception_end(ctx, EXCP_RI);
27420         break;
27421     }
27422 }
27423
27424 static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
27425 {
27426     uint32_t opc = MASK_MMI(ctx->opcode);
27427     int rs = extract32(ctx->opcode, 21, 5);
27428     int rt = extract32(ctx->opcode, 16, 5);
27429     int rd = extract32(ctx->opcode, 11, 5);
27430
27431     switch (opc) {
27432     case MMI_OPC_CLASS_MMI0:
27433         decode_mmi0(env, ctx);
27434         break;
27435     case MMI_OPC_CLASS_MMI1:
27436         decode_mmi1(env, ctx);
27437         break;
27438     case MMI_OPC_CLASS_MMI2:
27439         decode_mmi2(env, ctx);
27440         break;
27441     case MMI_OPC_CLASS_MMI3:
27442         decode_mmi3(env, ctx);
27443         break;
27444     case MMI_OPC_MULT1:
27445     case MMI_OPC_MULTU1:
27446     case MMI_OPC_MADD:
27447     case MMI_OPC_MADDU:
27448     case MMI_OPC_MADD1:
27449     case MMI_OPC_MADDU1:
27450         gen_mul_txx9(ctx, opc, rd, rs, rt);
27451         break;
27452     case MMI_OPC_DIV1:
27453     case MMI_OPC_DIVU1:
27454         gen_div1_tx79(ctx, opc, rs, rt);
27455         break;
27456     case MMI_OPC_MTLO1:
27457     case MMI_OPC_MTHI1:
27458         gen_HILO1_tx79(ctx, opc, rs);
27459         break;
27460     case MMI_OPC_MFLO1:
27461     case MMI_OPC_MFHI1:
27462         gen_HILO1_tx79(ctx, opc, rd);
27463         break;
27464     case MMI_OPC_PLZCW:         /* TODO: MMI_OPC_PLZCW */
27465     case MMI_OPC_PMFHL:         /* TODO: MMI_OPC_PMFHL */
27466     case MMI_OPC_PMTHL:         /* TODO: MMI_OPC_PMTHL */
27467     case MMI_OPC_PSLLH:         /* TODO: MMI_OPC_PSLLH */
27468     case MMI_OPC_PSRLH:         /* TODO: MMI_OPC_PSRLH */
27469     case MMI_OPC_PSRAH:         /* TODO: MMI_OPC_PSRAH */
27470     case MMI_OPC_PSLLW:         /* TODO: MMI_OPC_PSLLW */
27471     case MMI_OPC_PSRLW:         /* TODO: MMI_OPC_PSRLW */
27472     case MMI_OPC_PSRAW:         /* TODO: MMI_OPC_PSRAW */
27473         generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_CLASS_MMI */
27474         break;
27475     default:
27476         MIPS_INVAL("TX79 MMI class");
27477         generate_exception_end(ctx, EXCP_RI);
27478         break;
27479     }
27480 }
27481
27482 static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx)
27483 {
27484     generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_LQ */
27485 }
27486
27487 static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
27488 {
27489     generate_exception_end(ctx, EXCP_RI);    /* TODO: MMI_OPC_SQ */
27490 }
27491
27492 /*
27493  * The TX79-specific instruction Store Quadword
27494  *
27495  * +--------+-------+-------+------------------------+
27496  * | 011111 |  base |   rt  |           offset       | SQ
27497  * +--------+-------+-------+------------------------+
27498  *      6       5       5                 16
27499  *
27500  * has the same opcode as the Read Hardware Register instruction
27501  *
27502  * +--------+-------+-------+-------+-------+--------+
27503  * | 011111 | 00000 |   rt  |   rd  | 00000 | 111011 | RDHWR
27504  * +--------+-------+-------+-------+-------+--------+
27505  *      6       5       5       5       5        6
27506  *
27507  * that is required, trapped and emulated by the Linux kernel. However, all
27508  * RDHWR encodings yield address error exceptions on the TX79 since the SQ
27509  * offset is odd. Therefore all valid SQ instructions can execute normally.
27510  * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
27511  * between SQ and RDHWR, as the Linux kernel does.
27512  */
27513 static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
27514 {
27515     int base = extract32(ctx->opcode, 21, 5);
27516     int rt = extract32(ctx->opcode, 16, 5);
27517     int offset = extract32(ctx->opcode, 0, 16);
27518
27519 #ifdef CONFIG_USER_ONLY
27520     uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
27521     uint32_t op2 = extract32(ctx->opcode, 6, 5);
27522
27523     if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
27524         int rd = extract32(ctx->opcode, 11, 5);
27525
27526         gen_rdhwr(ctx, rt, rd, 0);
27527         return;
27528     }
27529 #endif
27530
27531     gen_mmi_sq(ctx, base, rt, offset);
27532 }
27533
27534 static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
27535 {
27536     int rs, rt, rd, sa;
27537     uint32_t op1, op2;
27538     int16_t imm;
27539
27540     rs = (ctx->opcode >> 21) & 0x1f;
27541     rt = (ctx->opcode >> 16) & 0x1f;
27542     rd = (ctx->opcode >> 11) & 0x1f;
27543     sa = (ctx->opcode >> 6) & 0x1f;
27544     imm = sextract32(ctx->opcode, 7, 9);
27545
27546     op1 = MASK_SPECIAL3(ctx->opcode);
27547
27548     /*
27549      * EVA loads and stores overlap Loongson 2E instructions decoded by
27550      * decode_opc_special3_legacy(), so be careful to allow their decoding when
27551      * EVA is absent.
27552      */
27553     if (ctx->eva) {
27554         switch (op1) {
27555         case OPC_LWLE:
27556         case OPC_LWRE:
27557             check_insn_opc_removed(ctx, ISA_MIPS32R6);
27558             /* fall through */
27559         case OPC_LBUE:
27560         case OPC_LHUE:
27561         case OPC_LBE:
27562         case OPC_LHE:
27563         case OPC_LLE:
27564         case OPC_LWE:
27565             check_cp0_enabled(ctx);
27566             gen_ld(ctx, op1, rt, rs, imm);
27567             return;
27568         case OPC_SWLE:
27569         case OPC_SWRE:
27570             check_insn_opc_removed(ctx, ISA_MIPS32R6);
27571             /* fall through */
27572         case OPC_SBE:
27573         case OPC_SHE:
27574         case OPC_SWE:
27575             check_cp0_enabled(ctx);
27576             gen_st(ctx, op1, rt, rs, imm);
27577             return;
27578         case OPC_SCE:
27579             check_cp0_enabled(ctx);
27580             gen_st_cond(ctx, op1, rt, rs, imm);
27581             return;
27582         case OPC_CACHEE:
27583             check_cp0_enabled(ctx);
27584             if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
27585                 gen_cache_operation(ctx, rt, rs, imm);
27586             }
27587             /* Treat as NOP. */
27588             return;
27589         case OPC_PREFE:
27590             check_cp0_enabled(ctx);
27591             /* Treat as NOP. */
27592             return;
27593         }
27594     }
27595
27596     switch (op1) {
27597     case OPC_EXT:
27598     case OPC_INS:
27599         check_insn(ctx, ISA_MIPS32R2);
27600         gen_bitops(ctx, op1, rt, rs, sa, rd);
27601         break;
27602     case OPC_BSHFL:
27603         op2 = MASK_BSHFL(ctx->opcode);
27604         switch (op2) {
27605         case OPC_ALIGN:
27606         case OPC_ALIGN_1:
27607         case OPC_ALIGN_2:
27608         case OPC_ALIGN_3:
27609         case OPC_BITSWAP:
27610             check_insn(ctx, ISA_MIPS32R6);
27611             decode_opc_special3_r6(env, ctx);
27612             break;
27613         default:
27614             check_insn(ctx, ISA_MIPS32R2);
27615             gen_bshfl(ctx, op2, rt, rd);
27616             break;
27617         }
27618         break;
27619 #if defined(TARGET_MIPS64)
27620     case OPC_DEXTM:
27621     case OPC_DEXTU:
27622     case OPC_DEXT:
27623     case OPC_DINSM:
27624     case OPC_DINSU:
27625     case OPC_DINS:
27626         check_insn(ctx, ISA_MIPS64R2);
27627         check_mips_64(ctx);
27628         gen_bitops(ctx, op1, rt, rs, sa, rd);
27629         break;
27630     case OPC_DBSHFL:
27631         op2 = MASK_DBSHFL(ctx->opcode);
27632         switch (op2) {
27633         case OPC_DALIGN:
27634         case OPC_DALIGN_1:
27635         case OPC_DALIGN_2:
27636         case OPC_DALIGN_3:
27637         case OPC_DALIGN_4:
27638         case OPC_DALIGN_5:
27639         case OPC_DALIGN_6:
27640         case OPC_DALIGN_7:
27641         case OPC_DBITSWAP:
27642             check_insn(ctx, ISA_MIPS32R6);
27643             decode_opc_special3_r6(env, ctx);
27644             break;
27645         default:
27646             check_insn(ctx, ISA_MIPS64R2);
27647             check_mips_64(ctx);
27648             op2 = MASK_DBSHFL(ctx->opcode);
27649             gen_bshfl(ctx, op2, rt, rd);
27650             break;
27651         }
27652         break;
27653 #endif
27654     case OPC_RDHWR:
27655         gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
27656         break;
27657     case OPC_FORK:
27658         check_mt(ctx);
27659         {
27660             TCGv t0 = tcg_temp_new();
27661             TCGv t1 = tcg_temp_new();
27662
27663             gen_load_gpr(t0, rt);
27664             gen_load_gpr(t1, rs);
27665             gen_helper_fork(t0, t1);
27666             tcg_temp_free(t0);
27667             tcg_temp_free(t1);
27668         }
27669         break;
27670     case OPC_YIELD:
27671         check_mt(ctx);
27672         {
27673             TCGv t0 = tcg_temp_new();
27674
27675             gen_load_gpr(t0, rs);
27676             gen_helper_yield(t0, cpu_env, t0);
27677             gen_store_gpr(t0, rd);
27678             tcg_temp_free(t0);
27679         }
27680         break;
27681     default:
27682         if (ctx->insn_flags & ISA_MIPS32R6) {
27683             decode_opc_special3_r6(env, ctx);
27684         } else {
27685             decode_opc_special3_legacy(env, ctx);
27686         }
27687     }
27688 }
27689
27690 /* MIPS SIMD Architecture (MSA)  */
27691 static inline int check_msa_access(DisasContext *ctx)
27692 {
27693     if (unlikely((ctx->hflags & MIPS_HFLAG_FPU) &&
27694                  !(ctx->hflags & MIPS_HFLAG_F64))) {
27695         generate_exception_end(ctx, EXCP_RI);
27696         return 0;
27697     }
27698
27699     if (unlikely(!(ctx->hflags & MIPS_HFLAG_MSA))) {
27700         if (ctx->insn_flags & ASE_MSA) {
27701             generate_exception_end(ctx, EXCP_MSADIS);
27702             return 0;
27703         } else {
27704             generate_exception_end(ctx, EXCP_RI);
27705             return 0;
27706         }
27707     }
27708     return 1;
27709 }
27710
27711 static void gen_check_zero_element(TCGv tresult, uint8_t df, uint8_t wt)
27712 {
27713     /* generates tcg ops to check if any element is 0 */
27714     /* Note this function only works with MSA_WRLEN = 128 */
27715     uint64_t eval_zero_or_big = 0;
27716     uint64_t eval_big = 0;
27717     TCGv_i64 t0 = tcg_temp_new_i64();
27718     TCGv_i64 t1 = tcg_temp_new_i64();
27719     switch (df) {
27720     case DF_BYTE:
27721         eval_zero_or_big = 0x0101010101010101ULL;
27722         eval_big = 0x8080808080808080ULL;
27723         break;
27724     case DF_HALF:
27725         eval_zero_or_big = 0x0001000100010001ULL;
27726         eval_big = 0x8000800080008000ULL;
27727         break;
27728     case DF_WORD:
27729         eval_zero_or_big = 0x0000000100000001ULL;
27730         eval_big = 0x8000000080000000ULL;
27731         break;
27732     case DF_DOUBLE:
27733         eval_zero_or_big = 0x0000000000000001ULL;
27734         eval_big = 0x8000000000000000ULL;
27735         break;
27736     }
27737     tcg_gen_subi_i64(t0, msa_wr_d[wt<<1], eval_zero_or_big);
27738     tcg_gen_andc_i64(t0, t0, msa_wr_d[wt<<1]);
27739     tcg_gen_andi_i64(t0, t0, eval_big);
27740     tcg_gen_subi_i64(t1, msa_wr_d[(wt<<1)+1], eval_zero_or_big);
27741     tcg_gen_andc_i64(t1, t1, msa_wr_d[(wt<<1)+1]);
27742     tcg_gen_andi_i64(t1, t1, eval_big);
27743     tcg_gen_or_i64(t0, t0, t1);
27744     /* if all bits are zero then all elements are not zero */
27745     /* if some bit is non-zero then some element is zero */
27746     tcg_gen_setcondi_i64(TCG_COND_NE, t0, t0, 0);
27747     tcg_gen_trunc_i64_tl(tresult, t0);
27748     tcg_temp_free_i64(t0);
27749     tcg_temp_free_i64(t1);
27750 }
27751
27752 static void gen_msa_branch(CPUMIPSState *env, DisasContext *ctx, uint32_t op1)
27753 {
27754     uint8_t df = (ctx->opcode >> 21) & 0x3;
27755     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
27756     int64_t s16 = (int16_t)ctx->opcode;
27757
27758     check_msa_access(ctx);
27759
27760     if (ctx->hflags & MIPS_HFLAG_BMASK) {
27761         generate_exception_end(ctx, EXCP_RI);
27762         return;
27763     }
27764     switch (op1) {
27765     case OPC_BZ_V:
27766     case OPC_BNZ_V:
27767         {
27768             TCGv_i64 t0 = tcg_temp_new_i64();
27769             tcg_gen_or_i64(t0, msa_wr_d[wt<<1], msa_wr_d[(wt<<1)+1]);
27770             tcg_gen_setcondi_i64((op1 == OPC_BZ_V) ?
27771                     TCG_COND_EQ : TCG_COND_NE, t0, t0, 0);
27772             tcg_gen_trunc_i64_tl(bcond, t0);
27773             tcg_temp_free_i64(t0);
27774         }
27775         break;
27776     case OPC_BZ_B:
27777     case OPC_BZ_H:
27778     case OPC_BZ_W:
27779     case OPC_BZ_D:
27780         gen_check_zero_element(bcond, df, wt);
27781         break;
27782     case OPC_BNZ_B:
27783     case OPC_BNZ_H:
27784     case OPC_BNZ_W:
27785     case OPC_BNZ_D:
27786         gen_check_zero_element(bcond, df, wt);
27787         tcg_gen_setcondi_tl(TCG_COND_EQ, bcond, bcond, 0);
27788         break;
27789     }
27790
27791     ctx->btarget = ctx->base.pc_next + (s16 << 2) + 4;
27792
27793     ctx->hflags |= MIPS_HFLAG_BC;
27794     ctx->hflags |= MIPS_HFLAG_BDS32;
27795 }
27796
27797 static void gen_msa_i8(CPUMIPSState *env, DisasContext *ctx)
27798 {
27799 #define MASK_MSA_I8(op)    (MASK_MSA_MINOR(op) | (op & (0x03 << 24)))
27800     uint8_t i8 = (ctx->opcode >> 16) & 0xff;
27801     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27802     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27803
27804     TCGv_i32 twd = tcg_const_i32(wd);
27805     TCGv_i32 tws = tcg_const_i32(ws);
27806     TCGv_i32 ti8 = tcg_const_i32(i8);
27807
27808     switch (MASK_MSA_I8(ctx->opcode)) {
27809     case OPC_ANDI_B:
27810         gen_helper_msa_andi_b(cpu_env, twd, tws, ti8);
27811         break;
27812     case OPC_ORI_B:
27813         gen_helper_msa_ori_b(cpu_env, twd, tws, ti8);
27814         break;
27815     case OPC_NORI_B:
27816         gen_helper_msa_nori_b(cpu_env, twd, tws, ti8);
27817         break;
27818     case OPC_XORI_B:
27819         gen_helper_msa_xori_b(cpu_env, twd, tws, ti8);
27820         break;
27821     case OPC_BMNZI_B:
27822         gen_helper_msa_bmnzi_b(cpu_env, twd, tws, ti8);
27823         break;
27824     case OPC_BMZI_B:
27825         gen_helper_msa_bmzi_b(cpu_env, twd, tws, ti8);
27826         break;
27827     case OPC_BSELI_B:
27828         gen_helper_msa_bseli_b(cpu_env, twd, tws, ti8);
27829         break;
27830     case OPC_SHF_B:
27831     case OPC_SHF_H:
27832     case OPC_SHF_W:
27833         {
27834             uint8_t df = (ctx->opcode >> 24) & 0x3;
27835             if (df == DF_DOUBLE) {
27836                 generate_exception_end(ctx, EXCP_RI);
27837             } else {
27838                 TCGv_i32 tdf = tcg_const_i32(df);
27839                 gen_helper_msa_shf_df(cpu_env, tdf, twd, tws, ti8);
27840                 tcg_temp_free_i32(tdf);
27841             }
27842         }
27843         break;
27844     default:
27845         MIPS_INVAL("MSA instruction");
27846         generate_exception_end(ctx, EXCP_RI);
27847         break;
27848     }
27849
27850     tcg_temp_free_i32(twd);
27851     tcg_temp_free_i32(tws);
27852     tcg_temp_free_i32(ti8);
27853 }
27854
27855 static void gen_msa_i5(CPUMIPSState *env, DisasContext *ctx)
27856 {
27857 #define MASK_MSA_I5(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27858     uint8_t df = (ctx->opcode >> 21) & 0x3;
27859     int8_t s5 = (int8_t) sextract32(ctx->opcode, 16, 5);
27860     uint8_t u5 = (ctx->opcode >> 16) & 0x1f;
27861     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27862     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27863
27864     TCGv_i32 tdf = tcg_const_i32(df);
27865     TCGv_i32 twd = tcg_const_i32(wd);
27866     TCGv_i32 tws = tcg_const_i32(ws);
27867     TCGv_i32 timm = tcg_temp_new_i32();
27868     tcg_gen_movi_i32(timm, u5);
27869
27870     switch (MASK_MSA_I5(ctx->opcode)) {
27871     case OPC_ADDVI_df:
27872         gen_helper_msa_addvi_df(cpu_env, tdf, twd, tws, timm);
27873         break;
27874     case OPC_SUBVI_df:
27875         gen_helper_msa_subvi_df(cpu_env, tdf, twd, tws, timm);
27876         break;
27877     case OPC_MAXI_S_df:
27878         tcg_gen_movi_i32(timm, s5);
27879         gen_helper_msa_maxi_s_df(cpu_env, tdf, twd, tws, timm);
27880         break;
27881     case OPC_MAXI_U_df:
27882         gen_helper_msa_maxi_u_df(cpu_env, tdf, twd, tws, timm);
27883         break;
27884     case OPC_MINI_S_df:
27885         tcg_gen_movi_i32(timm, s5);
27886         gen_helper_msa_mini_s_df(cpu_env, tdf, twd, tws, timm);
27887         break;
27888     case OPC_MINI_U_df:
27889         gen_helper_msa_mini_u_df(cpu_env, tdf, twd, tws, timm);
27890         break;
27891     case OPC_CEQI_df:
27892         tcg_gen_movi_i32(timm, s5);
27893         gen_helper_msa_ceqi_df(cpu_env, tdf, twd, tws, timm);
27894         break;
27895     case OPC_CLTI_S_df:
27896         tcg_gen_movi_i32(timm, s5);
27897         gen_helper_msa_clti_s_df(cpu_env, tdf, twd, tws, timm);
27898         break;
27899     case OPC_CLTI_U_df:
27900         gen_helper_msa_clti_u_df(cpu_env, tdf, twd, tws, timm);
27901         break;
27902     case OPC_CLEI_S_df:
27903         tcg_gen_movi_i32(timm, s5);
27904         gen_helper_msa_clei_s_df(cpu_env, tdf, twd, tws, timm);
27905         break;
27906     case OPC_CLEI_U_df:
27907         gen_helper_msa_clei_u_df(cpu_env, tdf, twd, tws, timm);
27908         break;
27909     case OPC_LDI_df:
27910         {
27911             int32_t s10 = sextract32(ctx->opcode, 11, 10);
27912             tcg_gen_movi_i32(timm, s10);
27913             gen_helper_msa_ldi_df(cpu_env, tdf, twd, timm);
27914         }
27915         break;
27916     default:
27917         MIPS_INVAL("MSA instruction");
27918         generate_exception_end(ctx, EXCP_RI);
27919         break;
27920     }
27921
27922     tcg_temp_free_i32(tdf);
27923     tcg_temp_free_i32(twd);
27924     tcg_temp_free_i32(tws);
27925     tcg_temp_free_i32(timm);
27926 }
27927
27928 static void gen_msa_bit(CPUMIPSState *env, DisasContext *ctx)
27929 {
27930 #define MASK_MSA_BIT(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
27931     uint8_t dfm = (ctx->opcode >> 16) & 0x7f;
27932     uint32_t df = 0, m = 0;
27933     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
27934     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
27935
27936     TCGv_i32 tdf;
27937     TCGv_i32 tm;
27938     TCGv_i32 twd;
27939     TCGv_i32 tws;
27940
27941     if ((dfm & 0x40) == 0x00) {
27942         m = dfm & 0x3f;
27943         df = DF_DOUBLE;
27944     } else if ((dfm & 0x60) == 0x40) {
27945         m = dfm & 0x1f;
27946         df = DF_WORD;
27947     } else if ((dfm & 0x70) == 0x60) {
27948         m = dfm & 0x0f;
27949         df = DF_HALF;
27950     } else if ((dfm & 0x78) == 0x70) {
27951         m = dfm & 0x7;
27952         df = DF_BYTE;
27953     } else {
27954         generate_exception_end(ctx, EXCP_RI);
27955         return;
27956     }
27957
27958     tdf = tcg_const_i32(df);
27959     tm  = tcg_const_i32(m);
27960     twd = tcg_const_i32(wd);
27961     tws = tcg_const_i32(ws);
27962
27963     switch (MASK_MSA_BIT(ctx->opcode)) {
27964     case OPC_SLLI_df:
27965         gen_helper_msa_slli_df(cpu_env, tdf, twd, tws, tm);
27966         break;
27967     case OPC_SRAI_df:
27968         gen_helper_msa_srai_df(cpu_env, tdf, twd, tws, tm);
27969         break;
27970     case OPC_SRLI_df:
27971         gen_helper_msa_srli_df(cpu_env, tdf, twd, tws, tm);
27972         break;
27973     case OPC_BCLRI_df:
27974         gen_helper_msa_bclri_df(cpu_env, tdf, twd, tws, tm);
27975         break;
27976     case OPC_BSETI_df:
27977         gen_helper_msa_bseti_df(cpu_env, tdf, twd, tws, tm);
27978         break;
27979     case OPC_BNEGI_df:
27980         gen_helper_msa_bnegi_df(cpu_env, tdf, twd, tws, tm);
27981         break;
27982     case OPC_BINSLI_df:
27983         gen_helper_msa_binsli_df(cpu_env, tdf, twd, tws, tm);
27984         break;
27985     case OPC_BINSRI_df:
27986         gen_helper_msa_binsri_df(cpu_env, tdf, twd, tws, tm);
27987         break;
27988     case OPC_SAT_S_df:
27989         gen_helper_msa_sat_s_df(cpu_env, tdf, twd, tws, tm);
27990         break;
27991     case OPC_SAT_U_df:
27992         gen_helper_msa_sat_u_df(cpu_env, tdf, twd, tws, tm);
27993         break;
27994     case OPC_SRARI_df:
27995         gen_helper_msa_srari_df(cpu_env, tdf, twd, tws, tm);
27996         break;
27997     case OPC_SRLRI_df:
27998         gen_helper_msa_srlri_df(cpu_env, tdf, twd, tws, tm);
27999         break;
28000     default:
28001         MIPS_INVAL("MSA instruction");
28002         generate_exception_end(ctx, EXCP_RI);
28003         break;
28004     }
28005
28006     tcg_temp_free_i32(tdf);
28007     tcg_temp_free_i32(tm);
28008     tcg_temp_free_i32(twd);
28009     tcg_temp_free_i32(tws);
28010 }
28011
28012 static void gen_msa_3r(CPUMIPSState *env, DisasContext *ctx)
28013 {
28014 #define MASK_MSA_3R(op)    (MASK_MSA_MINOR(op) | (op & (0x7 << 23)))
28015     uint8_t df = (ctx->opcode >> 21) & 0x3;
28016     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28017     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28018     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28019
28020     TCGv_i32 tdf = tcg_const_i32(df);
28021     TCGv_i32 twd = tcg_const_i32(wd);
28022     TCGv_i32 tws = tcg_const_i32(ws);
28023     TCGv_i32 twt = tcg_const_i32(wt);
28024
28025     switch (MASK_MSA_3R(ctx->opcode)) {
28026     case OPC_SLL_df:
28027         gen_helper_msa_sll_df(cpu_env, tdf, twd, tws, twt);
28028         break;
28029     case OPC_ADDV_df:
28030         gen_helper_msa_addv_df(cpu_env, tdf, twd, tws, twt);
28031         break;
28032     case OPC_CEQ_df:
28033         gen_helper_msa_ceq_df(cpu_env, tdf, twd, tws, twt);
28034         break;
28035     case OPC_ADD_A_df:
28036         gen_helper_msa_add_a_df(cpu_env, tdf, twd, tws, twt);
28037         break;
28038     case OPC_SUBS_S_df:
28039         gen_helper_msa_subs_s_df(cpu_env, tdf, twd, tws, twt);
28040         break;
28041     case OPC_MULV_df:
28042         gen_helper_msa_mulv_df(cpu_env, tdf, twd, tws, twt);
28043         break;
28044     case OPC_SLD_df:
28045         gen_helper_msa_sld_df(cpu_env, tdf, twd, tws, twt);
28046         break;
28047     case OPC_VSHF_df:
28048         gen_helper_msa_vshf_df(cpu_env, tdf, twd, tws, twt);
28049         break;
28050     case OPC_SRA_df:
28051         gen_helper_msa_sra_df(cpu_env, tdf, twd, tws, twt);
28052         break;
28053     case OPC_SUBV_df:
28054         gen_helper_msa_subv_df(cpu_env, tdf, twd, tws, twt);
28055         break;
28056     case OPC_ADDS_A_df:
28057         gen_helper_msa_adds_a_df(cpu_env, tdf, twd, tws, twt);
28058         break;
28059     case OPC_SUBS_U_df:
28060         gen_helper_msa_subs_u_df(cpu_env, tdf, twd, tws, twt);
28061         break;
28062     case OPC_MADDV_df:
28063         gen_helper_msa_maddv_df(cpu_env, tdf, twd, tws, twt);
28064         break;
28065     case OPC_SPLAT_df:
28066         gen_helper_msa_splat_df(cpu_env, tdf, twd, tws, twt);
28067         break;
28068     case OPC_SRAR_df:
28069         gen_helper_msa_srar_df(cpu_env, tdf, twd, tws, twt);
28070         break;
28071     case OPC_SRL_df:
28072         gen_helper_msa_srl_df(cpu_env, tdf, twd, tws, twt);
28073         break;
28074     case OPC_MAX_S_df:
28075         gen_helper_msa_max_s_df(cpu_env, tdf, twd, tws, twt);
28076         break;
28077     case OPC_CLT_S_df:
28078         gen_helper_msa_clt_s_df(cpu_env, tdf, twd, tws, twt);
28079         break;
28080     case OPC_ADDS_S_df:
28081         gen_helper_msa_adds_s_df(cpu_env, tdf, twd, tws, twt);
28082         break;
28083     case OPC_SUBSUS_U_df:
28084         gen_helper_msa_subsus_u_df(cpu_env, tdf, twd, tws, twt);
28085         break;
28086     case OPC_MSUBV_df:
28087         gen_helper_msa_msubv_df(cpu_env, tdf, twd, tws, twt);
28088         break;
28089     case OPC_PCKEV_df:
28090         gen_helper_msa_pckev_df(cpu_env, tdf, twd, tws, twt);
28091         break;
28092     case OPC_SRLR_df:
28093         gen_helper_msa_srlr_df(cpu_env, tdf, twd, tws, twt);
28094         break;
28095     case OPC_BCLR_df:
28096         gen_helper_msa_bclr_df(cpu_env, tdf, twd, tws, twt);
28097         break;
28098     case OPC_MAX_U_df:
28099         gen_helper_msa_max_u_df(cpu_env, tdf, twd, tws, twt);
28100         break;
28101     case OPC_CLT_U_df:
28102         gen_helper_msa_clt_u_df(cpu_env, tdf, twd, tws, twt);
28103         break;
28104     case OPC_ADDS_U_df:
28105         gen_helper_msa_adds_u_df(cpu_env, tdf, twd, tws, twt);
28106         break;
28107     case OPC_SUBSUU_S_df:
28108         gen_helper_msa_subsuu_s_df(cpu_env, tdf, twd, tws, twt);
28109         break;
28110     case OPC_PCKOD_df:
28111         gen_helper_msa_pckod_df(cpu_env, tdf, twd, tws, twt);
28112         break;
28113     case OPC_BSET_df:
28114         gen_helper_msa_bset_df(cpu_env, tdf, twd, tws, twt);
28115         break;
28116     case OPC_MIN_S_df:
28117         gen_helper_msa_min_s_df(cpu_env, tdf, twd, tws, twt);
28118         break;
28119     case OPC_CLE_S_df:
28120         gen_helper_msa_cle_s_df(cpu_env, tdf, twd, tws, twt);
28121         break;
28122     case OPC_AVE_S_df:
28123         gen_helper_msa_ave_s_df(cpu_env, tdf, twd, tws, twt);
28124         break;
28125     case OPC_ASUB_S_df:
28126         gen_helper_msa_asub_s_df(cpu_env, tdf, twd, tws, twt);
28127         break;
28128     case OPC_DIV_S_df:
28129         gen_helper_msa_div_s_df(cpu_env, tdf, twd, tws, twt);
28130         break;
28131     case OPC_ILVL_df:
28132         gen_helper_msa_ilvl_df(cpu_env, tdf, twd, tws, twt);
28133         break;
28134     case OPC_BNEG_df:
28135         gen_helper_msa_bneg_df(cpu_env, tdf, twd, tws, twt);
28136         break;
28137     case OPC_MIN_U_df:
28138         gen_helper_msa_min_u_df(cpu_env, tdf, twd, tws, twt);
28139         break;
28140     case OPC_CLE_U_df:
28141         gen_helper_msa_cle_u_df(cpu_env, tdf, twd, tws, twt);
28142         break;
28143     case OPC_AVE_U_df:
28144         gen_helper_msa_ave_u_df(cpu_env, tdf, twd, tws, twt);
28145         break;
28146     case OPC_ASUB_U_df:
28147         gen_helper_msa_asub_u_df(cpu_env, tdf, twd, tws, twt);
28148         break;
28149     case OPC_DIV_U_df:
28150         gen_helper_msa_div_u_df(cpu_env, tdf, twd, tws, twt);
28151         break;
28152     case OPC_ILVR_df:
28153         gen_helper_msa_ilvr_df(cpu_env, tdf, twd, tws, twt);
28154         break;
28155     case OPC_BINSL_df:
28156         gen_helper_msa_binsl_df(cpu_env, tdf, twd, tws, twt);
28157         break;
28158     case OPC_MAX_A_df:
28159         gen_helper_msa_max_a_df(cpu_env, tdf, twd, tws, twt);
28160         break;
28161     case OPC_AVER_S_df:
28162         gen_helper_msa_aver_s_df(cpu_env, tdf, twd, tws, twt);
28163         break;
28164     case OPC_MOD_S_df:
28165         gen_helper_msa_mod_s_df(cpu_env, tdf, twd, tws, twt);
28166         break;
28167     case OPC_ILVEV_df:
28168         gen_helper_msa_ilvev_df(cpu_env, tdf, twd, tws, twt);
28169         break;
28170     case OPC_BINSR_df:
28171         gen_helper_msa_binsr_df(cpu_env, tdf, twd, tws, twt);
28172         break;
28173     case OPC_MIN_A_df:
28174         gen_helper_msa_min_a_df(cpu_env, tdf, twd, tws, twt);
28175         break;
28176     case OPC_AVER_U_df:
28177         gen_helper_msa_aver_u_df(cpu_env, tdf, twd, tws, twt);
28178         break;
28179     case OPC_MOD_U_df:
28180         gen_helper_msa_mod_u_df(cpu_env, tdf, twd, tws, twt);
28181         break;
28182     case OPC_ILVOD_df:
28183         gen_helper_msa_ilvod_df(cpu_env, tdf, twd, tws, twt);
28184         break;
28185
28186     case OPC_DOTP_S_df:
28187     case OPC_DOTP_U_df:
28188     case OPC_DPADD_S_df:
28189     case OPC_DPADD_U_df:
28190     case OPC_DPSUB_S_df:
28191     case OPC_HADD_S_df:
28192     case OPC_DPSUB_U_df:
28193     case OPC_HADD_U_df:
28194     case OPC_HSUB_S_df:
28195     case OPC_HSUB_U_df:
28196         if (df == DF_BYTE) {
28197             generate_exception_end(ctx, EXCP_RI);
28198             break;
28199         }
28200         switch (MASK_MSA_3R(ctx->opcode)) {
28201         case OPC_DOTP_S_df:
28202             gen_helper_msa_dotp_s_df(cpu_env, tdf, twd, tws, twt);
28203             break;
28204         case OPC_DOTP_U_df:
28205             gen_helper_msa_dotp_u_df(cpu_env, tdf, twd, tws, twt);
28206             break;
28207         case OPC_DPADD_S_df:
28208             gen_helper_msa_dpadd_s_df(cpu_env, tdf, twd, tws, twt);
28209             break;
28210         case OPC_DPADD_U_df:
28211             gen_helper_msa_dpadd_u_df(cpu_env, tdf, twd, tws, twt);
28212             break;
28213         case OPC_DPSUB_S_df:
28214             gen_helper_msa_dpsub_s_df(cpu_env, tdf, twd, tws, twt);
28215             break;
28216         case OPC_HADD_S_df:
28217             gen_helper_msa_hadd_s_df(cpu_env, tdf, twd, tws, twt);
28218             break;
28219         case OPC_DPSUB_U_df:
28220             gen_helper_msa_dpsub_u_df(cpu_env, tdf, twd, tws, twt);
28221             break;
28222         case OPC_HADD_U_df:
28223             gen_helper_msa_hadd_u_df(cpu_env, tdf, twd, tws, twt);
28224             break;
28225         case OPC_HSUB_S_df:
28226             gen_helper_msa_hsub_s_df(cpu_env, tdf, twd, tws, twt);
28227             break;
28228         case OPC_HSUB_U_df:
28229             gen_helper_msa_hsub_u_df(cpu_env, tdf, twd, tws, twt);
28230             break;
28231         }
28232         break;
28233     default:
28234         MIPS_INVAL("MSA instruction");
28235         generate_exception_end(ctx, EXCP_RI);
28236         break;
28237     }
28238     tcg_temp_free_i32(twd);
28239     tcg_temp_free_i32(tws);
28240     tcg_temp_free_i32(twt);
28241     tcg_temp_free_i32(tdf);
28242 }
28243
28244 static void gen_msa_elm_3e(CPUMIPSState *env, DisasContext *ctx)
28245 {
28246 #define MASK_MSA_ELM_DF3E(op)   (MASK_MSA_MINOR(op) | (op & (0x3FF << 16)))
28247     uint8_t source = (ctx->opcode >> 11) & 0x1f;
28248     uint8_t dest = (ctx->opcode >> 6) & 0x1f;
28249     TCGv telm = tcg_temp_new();
28250     TCGv_i32 tsr = tcg_const_i32(source);
28251     TCGv_i32 tdt = tcg_const_i32(dest);
28252
28253     switch (MASK_MSA_ELM_DF3E(ctx->opcode)) {
28254     case OPC_CTCMSA:
28255         gen_load_gpr(telm, source);
28256         gen_helper_msa_ctcmsa(cpu_env, telm, tdt);
28257         break;
28258     case OPC_CFCMSA:
28259         gen_helper_msa_cfcmsa(telm, cpu_env, tsr);
28260         gen_store_gpr(telm, dest);
28261         break;
28262     case OPC_MOVE_V:
28263         gen_helper_msa_move_v(cpu_env, tdt, tsr);
28264         break;
28265     default:
28266         MIPS_INVAL("MSA instruction");
28267         generate_exception_end(ctx, EXCP_RI);
28268         break;
28269     }
28270
28271     tcg_temp_free(telm);
28272     tcg_temp_free_i32(tdt);
28273     tcg_temp_free_i32(tsr);
28274 }
28275
28276 static void gen_msa_elm_df(CPUMIPSState *env, DisasContext *ctx, uint32_t df,
28277         uint32_t n)
28278 {
28279 #define MASK_MSA_ELM(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28280     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28281     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28282
28283     TCGv_i32 tws = tcg_const_i32(ws);
28284     TCGv_i32 twd = tcg_const_i32(wd);
28285     TCGv_i32 tn  = tcg_const_i32(n);
28286     TCGv_i32 tdf = tcg_const_i32(df);
28287
28288     switch (MASK_MSA_ELM(ctx->opcode)) {
28289     case OPC_SLDI_df:
28290         gen_helper_msa_sldi_df(cpu_env, tdf, twd, tws, tn);
28291         break;
28292     case OPC_SPLATI_df:
28293         gen_helper_msa_splati_df(cpu_env, tdf, twd, tws, tn);
28294         break;
28295     case OPC_INSVE_df:
28296         gen_helper_msa_insve_df(cpu_env, tdf, twd, tws, tn);
28297         break;
28298     case OPC_COPY_S_df:
28299     case OPC_COPY_U_df:
28300     case OPC_INSERT_df:
28301 #if !defined(TARGET_MIPS64)
28302         /* Double format valid only for MIPS64 */
28303         if (df == DF_DOUBLE) {
28304             generate_exception_end(ctx, EXCP_RI);
28305             break;
28306         }
28307 #endif
28308         switch (MASK_MSA_ELM(ctx->opcode)) {
28309         case OPC_COPY_S_df:
28310             if (likely(wd != 0)) {
28311                 gen_helper_msa_copy_s_df(cpu_env, tdf, twd, tws, tn);
28312             }
28313             break;
28314         case OPC_COPY_U_df:
28315             if (likely(wd != 0)) {
28316                 gen_helper_msa_copy_u_df(cpu_env, tdf, twd, tws, tn);
28317             }
28318             break;
28319         case OPC_INSERT_df:
28320             gen_helper_msa_insert_df(cpu_env, tdf, twd, tws, tn);
28321             break;
28322         }
28323         break;
28324     default:
28325         MIPS_INVAL("MSA instruction");
28326         generate_exception_end(ctx, EXCP_RI);
28327     }
28328     tcg_temp_free_i32(twd);
28329     tcg_temp_free_i32(tws);
28330     tcg_temp_free_i32(tn);
28331     tcg_temp_free_i32(tdf);
28332 }
28333
28334 static void gen_msa_elm(CPUMIPSState *env, DisasContext *ctx)
28335 {
28336     uint8_t dfn = (ctx->opcode >> 16) & 0x3f;
28337     uint32_t df = 0, n = 0;
28338
28339     if ((dfn & 0x30) == 0x00) {
28340         n = dfn & 0x0f;
28341         df = DF_BYTE;
28342     } else if ((dfn & 0x38) == 0x20) {
28343         n = dfn & 0x07;
28344         df = DF_HALF;
28345     } else if ((dfn & 0x3c) == 0x30) {
28346         n = dfn & 0x03;
28347         df = DF_WORD;
28348     } else if ((dfn & 0x3e) == 0x38) {
28349         n = dfn & 0x01;
28350         df = DF_DOUBLE;
28351     } else if (dfn == 0x3E) {
28352         /* CTCMSA, CFCMSA, MOVE.V */
28353         gen_msa_elm_3e(env, ctx);
28354         return;
28355     } else {
28356         generate_exception_end(ctx, EXCP_RI);
28357         return;
28358     }
28359
28360     gen_msa_elm_df(env, ctx, df, n);
28361 }
28362
28363 static void gen_msa_3rf(CPUMIPSState *env, DisasContext *ctx)
28364 {
28365 #define MASK_MSA_3RF(op)    (MASK_MSA_MINOR(op) | (op & (0xf << 22)))
28366     uint8_t df = (ctx->opcode >> 21) & 0x1;
28367     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28368     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28369     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28370
28371     TCGv_i32 twd = tcg_const_i32(wd);
28372     TCGv_i32 tws = tcg_const_i32(ws);
28373     TCGv_i32 twt = tcg_const_i32(wt);
28374     TCGv_i32 tdf = tcg_temp_new_i32();
28375
28376     /* adjust df value for floating-point instruction */
28377     tcg_gen_movi_i32(tdf, df + 2);
28378
28379     switch (MASK_MSA_3RF(ctx->opcode)) {
28380     case OPC_FCAF_df:
28381         gen_helper_msa_fcaf_df(cpu_env, tdf, twd, tws, twt);
28382         break;
28383     case OPC_FADD_df:
28384         gen_helper_msa_fadd_df(cpu_env, tdf, twd, tws, twt);
28385         break;
28386     case OPC_FCUN_df:
28387         gen_helper_msa_fcun_df(cpu_env, tdf, twd, tws, twt);
28388         break;
28389     case OPC_FSUB_df:
28390         gen_helper_msa_fsub_df(cpu_env, tdf, twd, tws, twt);
28391         break;
28392     case OPC_FCOR_df:
28393         gen_helper_msa_fcor_df(cpu_env, tdf, twd, tws, twt);
28394         break;
28395     case OPC_FCEQ_df:
28396         gen_helper_msa_fceq_df(cpu_env, tdf, twd, tws, twt);
28397         break;
28398     case OPC_FMUL_df:
28399         gen_helper_msa_fmul_df(cpu_env, tdf, twd, tws, twt);
28400         break;
28401     case OPC_FCUNE_df:
28402         gen_helper_msa_fcune_df(cpu_env, tdf, twd, tws, twt);
28403         break;
28404     case OPC_FCUEQ_df:
28405         gen_helper_msa_fcueq_df(cpu_env, tdf, twd, tws, twt);
28406         break;
28407     case OPC_FDIV_df:
28408         gen_helper_msa_fdiv_df(cpu_env, tdf, twd, tws, twt);
28409         break;
28410     case OPC_FCNE_df:
28411         gen_helper_msa_fcne_df(cpu_env, tdf, twd, tws, twt);
28412         break;
28413     case OPC_FCLT_df:
28414         gen_helper_msa_fclt_df(cpu_env, tdf, twd, tws, twt);
28415         break;
28416     case OPC_FMADD_df:
28417         gen_helper_msa_fmadd_df(cpu_env, tdf, twd, tws, twt);
28418         break;
28419     case OPC_MUL_Q_df:
28420         tcg_gen_movi_i32(tdf, df + 1);
28421         gen_helper_msa_mul_q_df(cpu_env, tdf, twd, tws, twt);
28422         break;
28423     case OPC_FCULT_df:
28424         gen_helper_msa_fcult_df(cpu_env, tdf, twd, tws, twt);
28425         break;
28426     case OPC_FMSUB_df:
28427         gen_helper_msa_fmsub_df(cpu_env, tdf, twd, tws, twt);
28428         break;
28429     case OPC_MADD_Q_df:
28430         tcg_gen_movi_i32(tdf, df + 1);
28431         gen_helper_msa_madd_q_df(cpu_env, tdf, twd, tws, twt);
28432         break;
28433     case OPC_FCLE_df:
28434         gen_helper_msa_fcle_df(cpu_env, tdf, twd, tws, twt);
28435         break;
28436     case OPC_MSUB_Q_df:
28437         tcg_gen_movi_i32(tdf, df + 1);
28438         gen_helper_msa_msub_q_df(cpu_env, tdf, twd, tws, twt);
28439         break;
28440     case OPC_FCULE_df:
28441         gen_helper_msa_fcule_df(cpu_env, tdf, twd, tws, twt);
28442         break;
28443     case OPC_FEXP2_df:
28444         gen_helper_msa_fexp2_df(cpu_env, tdf, twd, tws, twt);
28445         break;
28446     case OPC_FSAF_df:
28447         gen_helper_msa_fsaf_df(cpu_env, tdf, twd, tws, twt);
28448         break;
28449     case OPC_FEXDO_df:
28450         gen_helper_msa_fexdo_df(cpu_env, tdf, twd, tws, twt);
28451         break;
28452     case OPC_FSUN_df:
28453         gen_helper_msa_fsun_df(cpu_env, tdf, twd, tws, twt);
28454         break;
28455     case OPC_FSOR_df:
28456         gen_helper_msa_fsor_df(cpu_env, tdf, twd, tws, twt);
28457         break;
28458     case OPC_FSEQ_df:
28459         gen_helper_msa_fseq_df(cpu_env, tdf, twd, tws, twt);
28460         break;
28461     case OPC_FTQ_df:
28462         gen_helper_msa_ftq_df(cpu_env, tdf, twd, tws, twt);
28463         break;
28464     case OPC_FSUNE_df:
28465         gen_helper_msa_fsune_df(cpu_env, tdf, twd, tws, twt);
28466         break;
28467     case OPC_FSUEQ_df:
28468         gen_helper_msa_fsueq_df(cpu_env, tdf, twd, tws, twt);
28469         break;
28470     case OPC_FSNE_df:
28471         gen_helper_msa_fsne_df(cpu_env, tdf, twd, tws, twt);
28472         break;
28473     case OPC_FSLT_df:
28474         gen_helper_msa_fslt_df(cpu_env, tdf, twd, tws, twt);
28475         break;
28476     case OPC_FMIN_df:
28477         gen_helper_msa_fmin_df(cpu_env, tdf, twd, tws, twt);
28478         break;
28479     case OPC_MULR_Q_df:
28480         tcg_gen_movi_i32(tdf, df + 1);
28481         gen_helper_msa_mulr_q_df(cpu_env, tdf, twd, tws, twt);
28482         break;
28483     case OPC_FSULT_df:
28484         gen_helper_msa_fsult_df(cpu_env, tdf, twd, tws, twt);
28485         break;
28486     case OPC_FMIN_A_df:
28487         gen_helper_msa_fmin_a_df(cpu_env, tdf, twd, tws, twt);
28488         break;
28489     case OPC_MADDR_Q_df:
28490         tcg_gen_movi_i32(tdf, df + 1);
28491         gen_helper_msa_maddr_q_df(cpu_env, tdf, twd, tws, twt);
28492         break;
28493     case OPC_FSLE_df:
28494         gen_helper_msa_fsle_df(cpu_env, tdf, twd, tws, twt);
28495         break;
28496     case OPC_FMAX_df:
28497         gen_helper_msa_fmax_df(cpu_env, tdf, twd, tws, twt);
28498         break;
28499     case OPC_MSUBR_Q_df:
28500         tcg_gen_movi_i32(tdf, df + 1);
28501         gen_helper_msa_msubr_q_df(cpu_env, tdf, twd, tws, twt);
28502         break;
28503     case OPC_FSULE_df:
28504         gen_helper_msa_fsule_df(cpu_env, tdf, twd, tws, twt);
28505         break;
28506     case OPC_FMAX_A_df:
28507         gen_helper_msa_fmax_a_df(cpu_env, tdf, twd, tws, twt);
28508         break;
28509     default:
28510         MIPS_INVAL("MSA instruction");
28511         generate_exception_end(ctx, EXCP_RI);
28512         break;
28513     }
28514
28515     tcg_temp_free_i32(twd);
28516     tcg_temp_free_i32(tws);
28517     tcg_temp_free_i32(twt);
28518     tcg_temp_free_i32(tdf);
28519 }
28520
28521 static void gen_msa_2r(CPUMIPSState *env, DisasContext *ctx)
28522 {
28523 #define MASK_MSA_2R(op)     (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28524                             (op & (0x7 << 18)))
28525     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28526     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28527     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28528     uint8_t df = (ctx->opcode >> 16) & 0x3;
28529     TCGv_i32 twd = tcg_const_i32(wd);
28530     TCGv_i32 tws = tcg_const_i32(ws);
28531     TCGv_i32 twt = tcg_const_i32(wt);
28532     TCGv_i32 tdf = tcg_const_i32(df);
28533
28534     switch (MASK_MSA_2R(ctx->opcode)) {
28535     case OPC_FILL_df:
28536 #if !defined(TARGET_MIPS64)
28537         /* Double format valid only for MIPS64 */
28538         if (df == DF_DOUBLE) {
28539             generate_exception_end(ctx, EXCP_RI);
28540             break;
28541         }
28542 #endif
28543         gen_helper_msa_fill_df(cpu_env, tdf, twd, tws); /* trs */
28544         break;
28545     case OPC_PCNT_df:
28546         gen_helper_msa_pcnt_df(cpu_env, tdf, twd, tws);
28547         break;
28548     case OPC_NLOC_df:
28549         gen_helper_msa_nloc_df(cpu_env, tdf, twd, tws);
28550         break;
28551     case OPC_NLZC_df:
28552         gen_helper_msa_nlzc_df(cpu_env, tdf, twd, tws);
28553         break;
28554     default:
28555         MIPS_INVAL("MSA instruction");
28556         generate_exception_end(ctx, EXCP_RI);
28557         break;
28558     }
28559
28560     tcg_temp_free_i32(twd);
28561     tcg_temp_free_i32(tws);
28562     tcg_temp_free_i32(twt);
28563     tcg_temp_free_i32(tdf);
28564 }
28565
28566 static void gen_msa_2rf(CPUMIPSState *env, DisasContext *ctx)
28567 {
28568 #define MASK_MSA_2RF(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)) | \
28569                             (op & (0xf << 17)))
28570     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28571     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28572     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28573     uint8_t df = (ctx->opcode >> 16) & 0x1;
28574     TCGv_i32 twd = tcg_const_i32(wd);
28575     TCGv_i32 tws = tcg_const_i32(ws);
28576     TCGv_i32 twt = tcg_const_i32(wt);
28577     /* adjust df value for floating-point instruction */
28578     TCGv_i32 tdf = tcg_const_i32(df + 2);
28579
28580     switch (MASK_MSA_2RF(ctx->opcode)) {
28581     case OPC_FCLASS_df:
28582         gen_helper_msa_fclass_df(cpu_env, tdf, twd, tws);
28583         break;
28584     case OPC_FTRUNC_S_df:
28585         gen_helper_msa_ftrunc_s_df(cpu_env, tdf, twd, tws);
28586         break;
28587     case OPC_FTRUNC_U_df:
28588         gen_helper_msa_ftrunc_u_df(cpu_env, tdf, twd, tws);
28589         break;
28590     case OPC_FSQRT_df:
28591         gen_helper_msa_fsqrt_df(cpu_env, tdf, twd, tws);
28592         break;
28593     case OPC_FRSQRT_df:
28594         gen_helper_msa_frsqrt_df(cpu_env, tdf, twd, tws);
28595         break;
28596     case OPC_FRCP_df:
28597         gen_helper_msa_frcp_df(cpu_env, tdf, twd, tws);
28598         break;
28599     case OPC_FRINT_df:
28600         gen_helper_msa_frint_df(cpu_env, tdf, twd, tws);
28601         break;
28602     case OPC_FLOG2_df:
28603         gen_helper_msa_flog2_df(cpu_env, tdf, twd, tws);
28604         break;
28605     case OPC_FEXUPL_df:
28606         gen_helper_msa_fexupl_df(cpu_env, tdf, twd, tws);
28607         break;
28608     case OPC_FEXUPR_df:
28609         gen_helper_msa_fexupr_df(cpu_env, tdf, twd, tws);
28610         break;
28611     case OPC_FFQL_df:
28612         gen_helper_msa_ffql_df(cpu_env, tdf, twd, tws);
28613         break;
28614     case OPC_FFQR_df:
28615         gen_helper_msa_ffqr_df(cpu_env, tdf, twd, tws);
28616         break;
28617     case OPC_FTINT_S_df:
28618         gen_helper_msa_ftint_s_df(cpu_env, tdf, twd, tws);
28619         break;
28620     case OPC_FTINT_U_df:
28621         gen_helper_msa_ftint_u_df(cpu_env, tdf, twd, tws);
28622         break;
28623     case OPC_FFINT_S_df:
28624         gen_helper_msa_ffint_s_df(cpu_env, tdf, twd, tws);
28625         break;
28626     case OPC_FFINT_U_df:
28627         gen_helper_msa_ffint_u_df(cpu_env, tdf, twd, tws);
28628         break;
28629     }
28630
28631     tcg_temp_free_i32(twd);
28632     tcg_temp_free_i32(tws);
28633     tcg_temp_free_i32(twt);
28634     tcg_temp_free_i32(tdf);
28635 }
28636
28637 static void gen_msa_vec_v(CPUMIPSState *env, DisasContext *ctx)
28638 {
28639 #define MASK_MSA_VEC(op)    (MASK_MSA_MINOR(op) | (op & (0x1f << 21)))
28640     uint8_t wt = (ctx->opcode >> 16) & 0x1f;
28641     uint8_t ws = (ctx->opcode >> 11) & 0x1f;
28642     uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28643     TCGv_i32 twd = tcg_const_i32(wd);
28644     TCGv_i32 tws = tcg_const_i32(ws);
28645     TCGv_i32 twt = tcg_const_i32(wt);
28646
28647     switch (MASK_MSA_VEC(ctx->opcode)) {
28648     case OPC_AND_V:
28649         gen_helper_msa_and_v(cpu_env, twd, tws, twt);
28650         break;
28651     case OPC_OR_V:
28652         gen_helper_msa_or_v(cpu_env, twd, tws, twt);
28653         break;
28654     case OPC_NOR_V:
28655         gen_helper_msa_nor_v(cpu_env, twd, tws, twt);
28656         break;
28657     case OPC_XOR_V:
28658         gen_helper_msa_xor_v(cpu_env, twd, tws, twt);
28659         break;
28660     case OPC_BMNZ_V:
28661         gen_helper_msa_bmnz_v(cpu_env, twd, tws, twt);
28662         break;
28663     case OPC_BMZ_V:
28664         gen_helper_msa_bmz_v(cpu_env, twd, tws, twt);
28665         break;
28666     case OPC_BSEL_V:
28667         gen_helper_msa_bsel_v(cpu_env, twd, tws, twt);
28668         break;
28669     default:
28670         MIPS_INVAL("MSA instruction");
28671         generate_exception_end(ctx, EXCP_RI);
28672         break;
28673     }
28674
28675     tcg_temp_free_i32(twd);
28676     tcg_temp_free_i32(tws);
28677     tcg_temp_free_i32(twt);
28678 }
28679
28680 static void gen_msa_vec(CPUMIPSState *env, DisasContext *ctx)
28681 {
28682     switch (MASK_MSA_VEC(ctx->opcode)) {
28683     case OPC_AND_V:
28684     case OPC_OR_V:
28685     case OPC_NOR_V:
28686     case OPC_XOR_V:
28687     case OPC_BMNZ_V:
28688     case OPC_BMZ_V:
28689     case OPC_BSEL_V:
28690         gen_msa_vec_v(env, ctx);
28691         break;
28692     case OPC_MSA_2R:
28693         gen_msa_2r(env, ctx);
28694         break;
28695     case OPC_MSA_2RF:
28696         gen_msa_2rf(env, ctx);
28697         break;
28698     default:
28699         MIPS_INVAL("MSA instruction");
28700         generate_exception_end(ctx, EXCP_RI);
28701         break;
28702     }
28703 }
28704
28705 static void gen_msa(CPUMIPSState *env, DisasContext *ctx)
28706 {
28707     uint32_t opcode = ctx->opcode;
28708     check_insn(ctx, ASE_MSA);
28709     check_msa_access(ctx);
28710
28711     switch (MASK_MSA_MINOR(opcode)) {
28712     case OPC_MSA_I8_00:
28713     case OPC_MSA_I8_01:
28714     case OPC_MSA_I8_02:
28715         gen_msa_i8(env, ctx);
28716         break;
28717     case OPC_MSA_I5_06:
28718     case OPC_MSA_I5_07:
28719         gen_msa_i5(env, ctx);
28720         break;
28721     case OPC_MSA_BIT_09:
28722     case OPC_MSA_BIT_0A:
28723         gen_msa_bit(env, ctx);
28724         break;
28725     case OPC_MSA_3R_0D:
28726     case OPC_MSA_3R_0E:
28727     case OPC_MSA_3R_0F:
28728     case OPC_MSA_3R_10:
28729     case OPC_MSA_3R_11:
28730     case OPC_MSA_3R_12:
28731     case OPC_MSA_3R_13:
28732     case OPC_MSA_3R_14:
28733     case OPC_MSA_3R_15:
28734         gen_msa_3r(env, ctx);
28735         break;
28736     case OPC_MSA_ELM:
28737         gen_msa_elm(env, ctx);
28738         break;
28739     case OPC_MSA_3RF_1A:
28740     case OPC_MSA_3RF_1B:
28741     case OPC_MSA_3RF_1C:
28742         gen_msa_3rf(env, ctx);
28743         break;
28744     case OPC_MSA_VEC:
28745         gen_msa_vec(env, ctx);
28746         break;
28747     case OPC_LD_B:
28748     case OPC_LD_H:
28749     case OPC_LD_W:
28750     case OPC_LD_D:
28751     case OPC_ST_B:
28752     case OPC_ST_H:
28753     case OPC_ST_W:
28754     case OPC_ST_D:
28755         {
28756             int32_t s10 = sextract32(ctx->opcode, 16, 10);
28757             uint8_t rs = (ctx->opcode >> 11) & 0x1f;
28758             uint8_t wd = (ctx->opcode >> 6) & 0x1f;
28759             uint8_t df = (ctx->opcode >> 0) & 0x3;
28760
28761             TCGv_i32 twd = tcg_const_i32(wd);
28762             TCGv taddr = tcg_temp_new();
28763             gen_base_offset_addr(ctx, taddr, rs, s10 << df);
28764
28765             switch (MASK_MSA_MINOR(opcode)) {
28766             case OPC_LD_B:
28767                 gen_helper_msa_ld_b(cpu_env, twd, taddr);
28768                 break;
28769             case OPC_LD_H:
28770                 gen_helper_msa_ld_h(cpu_env, twd, taddr);
28771                 break;
28772             case OPC_LD_W:
28773                 gen_helper_msa_ld_w(cpu_env, twd, taddr);
28774                 break;
28775             case OPC_LD_D:
28776                 gen_helper_msa_ld_d(cpu_env, twd, taddr);
28777                 break;
28778             case OPC_ST_B:
28779                 gen_helper_msa_st_b(cpu_env, twd, taddr);
28780                 break;
28781             case OPC_ST_H:
28782                 gen_helper_msa_st_h(cpu_env, twd, taddr);
28783                 break;
28784             case OPC_ST_W:
28785                 gen_helper_msa_st_w(cpu_env, twd, taddr);
28786                 break;
28787             case OPC_ST_D:
28788                 gen_helper_msa_st_d(cpu_env, twd, taddr);
28789                 break;
28790             }
28791
28792             tcg_temp_free_i32(twd);
28793             tcg_temp_free(taddr);
28794         }
28795         break;
28796     default:
28797         MIPS_INVAL("MSA instruction");
28798         generate_exception_end(ctx, EXCP_RI);
28799         break;
28800     }
28801
28802 }
28803
28804 static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
28805 {
28806     int32_t offset;
28807     int rs, rt, rd, sa;
28808     uint32_t op, op1;
28809     int16_t imm;
28810
28811     /* make sure instructions are on a word boundary */
28812     if (ctx->base.pc_next & 0x3) {
28813         env->CP0_BadVAddr = ctx->base.pc_next;
28814         generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
28815         return;
28816     }
28817
28818     /* Handle blikely not taken case */
28819     if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
28820         TCGLabel *l1 = gen_new_label();
28821
28822         tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
28823         tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
28824         gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
28825         gen_set_label(l1);
28826     }
28827
28828     op = MASK_OP_MAJOR(ctx->opcode);
28829     rs = (ctx->opcode >> 21) & 0x1f;
28830     rt = (ctx->opcode >> 16) & 0x1f;
28831     rd = (ctx->opcode >> 11) & 0x1f;
28832     sa = (ctx->opcode >> 6) & 0x1f;
28833     imm = (int16_t)ctx->opcode;
28834     switch (op) {
28835     case OPC_SPECIAL:
28836         decode_opc_special(env, ctx);
28837         break;
28838     case OPC_SPECIAL2:
28839         if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
28840             decode_mmi(env, ctx);
28841 #if !defined(TARGET_MIPS64)
28842         } else if (ctx->insn_flags & ASE_MXU) {
28843             decode_opc_mxu(env, ctx);
28844 #endif
28845         } else {
28846             decode_opc_special2_legacy(env, ctx);
28847         }
28848         break;
28849     case OPC_SPECIAL3:
28850         if (ctx->insn_flags & INSN_R5900) {
28851             decode_mmi_sq(env, ctx);    /* MMI_OPC_SQ */
28852         } else {
28853             decode_opc_special3(env, ctx);
28854         }
28855         break;
28856     case OPC_REGIMM:
28857         op1 = MASK_REGIMM(ctx->opcode);
28858         switch (op1) {
28859         case OPC_BLTZL: /* REGIMM branches */
28860         case OPC_BGEZL:
28861         case OPC_BLTZALL:
28862         case OPC_BGEZALL:
28863             check_insn(ctx, ISA_MIPS2);
28864             check_insn_opc_removed(ctx, ISA_MIPS32R6);
28865             /* Fallthrough */
28866         case OPC_BLTZ:
28867         case OPC_BGEZ:
28868             gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
28869             break;
28870         case OPC_BLTZAL:
28871         case OPC_BGEZAL:
28872             if (ctx->insn_flags & ISA_MIPS32R6) {
28873                 if (rs == 0) {
28874                     /* OPC_NAL, OPC_BAL */
28875                     gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
28876                 } else {
28877                     generate_exception_end(ctx, EXCP_RI);
28878                 }
28879             } else {
28880                 gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
28881             }
28882             break;
28883         case OPC_TGEI: /* REGIMM traps */
28884         case OPC_TGEIU:
28885         case OPC_TLTI:
28886         case OPC_TLTIU:
28887         case OPC_TEQI:
28888
28889         case OPC_TNEI:
28890             check_insn(ctx, ISA_MIPS2);
28891             check_insn_opc_removed(ctx, ISA_MIPS32R6);
28892             gen_trap(ctx, op1, rs, -1, imm);
28893             break;
28894         case OPC_SIGRIE:
28895             check_insn(ctx, ISA_MIPS32R6);
28896             generate_exception_end(ctx, EXCP_RI);
28897             break;
28898         case OPC_SYNCI:
28899             check_insn(ctx, ISA_MIPS32R2);
28900             /* Break the TB to be able to sync copied instructions
28901                immediately */
28902             ctx->base.is_jmp = DISAS_STOP;
28903             break;
28904         case OPC_BPOSGE32:    /* MIPS DSP branch */
28905 #if defined(TARGET_MIPS64)
28906         case OPC_BPOSGE64:
28907 #endif
28908             check_dsp(ctx);
28909             gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
28910             break;
28911 #if defined(TARGET_MIPS64)
28912         case OPC_DAHI:
28913             check_insn(ctx, ISA_MIPS32R6);
28914             check_mips_64(ctx);
28915             if (rs != 0) {
28916                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
28917             }
28918             break;
28919         case OPC_DATI:
28920             check_insn(ctx, ISA_MIPS32R6);
28921             check_mips_64(ctx);
28922             if (rs != 0) {
28923                 tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
28924             }
28925             break;
28926 #endif
28927         default:            /* Invalid */
28928             MIPS_INVAL("regimm");
28929             generate_exception_end(ctx, EXCP_RI);
28930             break;
28931         }
28932         break;
28933     case OPC_CP0:
28934         check_cp0_enabled(ctx);
28935         op1 = MASK_CP0(ctx->opcode);
28936         switch (op1) {
28937         case OPC_MFC0:
28938         case OPC_MTC0:
28939         case OPC_MFTR:
28940         case OPC_MTTR:
28941         case OPC_MFHC0:
28942         case OPC_MTHC0:
28943 #if defined(TARGET_MIPS64)
28944         case OPC_DMFC0:
28945         case OPC_DMTC0:
28946 #endif
28947 #ifndef CONFIG_USER_ONLY
28948             gen_cp0(env, ctx, op1, rt, rd);
28949 #endif /* !CONFIG_USER_ONLY */
28950             break;
28951         case OPC_C0:
28952         case OPC_C0_1:
28953         case OPC_C0_2:
28954         case OPC_C0_3:
28955         case OPC_C0_4:
28956         case OPC_C0_5:
28957         case OPC_C0_6:
28958         case OPC_C0_7:
28959         case OPC_C0_8:
28960         case OPC_C0_9:
28961         case OPC_C0_A:
28962         case OPC_C0_B:
28963         case OPC_C0_C:
28964         case OPC_C0_D:
28965         case OPC_C0_E:
28966         case OPC_C0_F:
28967 #ifndef CONFIG_USER_ONLY
28968             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
28969 #endif /* !CONFIG_USER_ONLY */
28970             break;
28971         case OPC_MFMC0:
28972 #ifndef CONFIG_USER_ONLY
28973             {
28974                 uint32_t op2;
28975                 TCGv t0 = tcg_temp_new();
28976
28977                 op2 = MASK_MFMC0(ctx->opcode);
28978                 switch (op2) {
28979                 case OPC_DMT:
28980                     check_cp0_mt(ctx);
28981                     gen_helper_dmt(t0);
28982                     gen_store_gpr(t0, rt);
28983                     break;
28984                 case OPC_EMT:
28985                     check_cp0_mt(ctx);
28986                     gen_helper_emt(t0);
28987                     gen_store_gpr(t0, rt);
28988                     break;
28989                 case OPC_DVPE:
28990                     check_cp0_mt(ctx);
28991                     gen_helper_dvpe(t0, cpu_env);
28992                     gen_store_gpr(t0, rt);
28993                     break;
28994                 case OPC_EVPE:
28995                     check_cp0_mt(ctx);
28996                     gen_helper_evpe(t0, cpu_env);
28997                     gen_store_gpr(t0, rt);
28998                     break;
28999                 case OPC_DVP:
29000                     check_insn(ctx, ISA_MIPS32R6);
29001                     if (ctx->vp) {
29002                         gen_helper_dvp(t0, cpu_env);
29003                         gen_store_gpr(t0, rt);
29004                     }
29005                     break;
29006                 case OPC_EVP:
29007                     check_insn(ctx, ISA_MIPS32R6);
29008                     if (ctx->vp) {
29009                         gen_helper_evp(t0, cpu_env);
29010                         gen_store_gpr(t0, rt);
29011                     }
29012                     break;
29013                 case OPC_DI:
29014                     check_insn(ctx, ISA_MIPS32R2);
29015                     save_cpu_state(ctx, 1);
29016                     gen_helper_di(t0, cpu_env);
29017                     gen_store_gpr(t0, rt);
29018                     /* Stop translation as we may have switched
29019                        the execution mode.  */
29020                     ctx->base.is_jmp = DISAS_STOP;
29021                     break;
29022                 case OPC_EI:
29023                     check_insn(ctx, ISA_MIPS32R2);
29024                     save_cpu_state(ctx, 1);
29025                     gen_helper_ei(t0, cpu_env);
29026                     gen_store_gpr(t0, rt);
29027                     /* DISAS_STOP isn't sufficient, we need to ensure we break
29028                        out of translated code to check for pending interrupts */
29029                     gen_save_pc(ctx->base.pc_next + 4);
29030                     ctx->base.is_jmp = DISAS_EXIT;
29031                     break;
29032                 default:            /* Invalid */
29033                     MIPS_INVAL("mfmc0");
29034                     generate_exception_end(ctx, EXCP_RI);
29035                     break;
29036                 }
29037                 tcg_temp_free(t0);
29038             }
29039 #endif /* !CONFIG_USER_ONLY */
29040             break;
29041         case OPC_RDPGPR:
29042             check_insn(ctx, ISA_MIPS32R2);
29043             gen_load_srsgpr(rt, rd);
29044             break;
29045         case OPC_WRPGPR:
29046             check_insn(ctx, ISA_MIPS32R2);
29047             gen_store_srsgpr(rt, rd);
29048             break;
29049         default:
29050             MIPS_INVAL("cp0");
29051             generate_exception_end(ctx, EXCP_RI);
29052             break;
29053         }
29054         break;
29055     case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
29056         if (ctx->insn_flags & ISA_MIPS32R6) {
29057             /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
29058             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29059         } else {
29060             /* OPC_ADDI */
29061             /* Arithmetic with immediate opcode */
29062             gen_arith_imm(ctx, op, rt, rs, imm);
29063         }
29064         break;
29065     case OPC_ADDIU:
29066          gen_arith_imm(ctx, op, rt, rs, imm);
29067          break;
29068     case OPC_SLTI: /* Set on less than with immediate opcode */
29069     case OPC_SLTIU:
29070          gen_slt_imm(ctx, op, rt, rs, imm);
29071          break;
29072     case OPC_ANDI: /* Arithmetic with immediate opcode */
29073     case OPC_LUI: /* OPC_AUI */
29074     case OPC_ORI:
29075     case OPC_XORI:
29076          gen_logic_imm(ctx, op, rt, rs, imm);
29077          break;
29078     case OPC_J: /* Jump */
29079     case OPC_JAL:
29080          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
29081          gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
29082          break;
29083     /* Branch */
29084     case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
29085         if (ctx->insn_flags & ISA_MIPS32R6) {
29086             if (rt == 0) {
29087                 generate_exception_end(ctx, EXCP_RI);
29088                 break;
29089             }
29090             /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
29091             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29092         } else {
29093             /* OPC_BLEZL */
29094             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29095         }
29096         break;
29097     case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
29098         if (ctx->insn_flags & ISA_MIPS32R6) {
29099             if (rt == 0) {
29100                 generate_exception_end(ctx, EXCP_RI);
29101                 break;
29102             }
29103             /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
29104             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29105         } else {
29106             /* OPC_BGTZL */
29107             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29108         }
29109         break;
29110     case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
29111         if (rt == 0) {
29112             /* OPC_BLEZ */
29113             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29114         } else {
29115             check_insn(ctx, ISA_MIPS32R6);
29116             /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
29117             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29118         }
29119         break;
29120     case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
29121         if (rt == 0) {
29122             /* OPC_BGTZ */
29123             gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29124         } else {
29125             check_insn(ctx, ISA_MIPS32R6);
29126             /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
29127             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29128         }
29129         break;
29130     case OPC_BEQL:
29131     case OPC_BNEL:
29132         check_insn(ctx, ISA_MIPS2);
29133          check_insn_opc_removed(ctx, ISA_MIPS32R6);
29134         /* Fallthrough */
29135     case OPC_BEQ:
29136     case OPC_BNE:
29137          gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
29138          break;
29139     case OPC_LL: /* Load and stores */
29140         check_insn(ctx, ISA_MIPS2);
29141         if (ctx->insn_flags & INSN_R5900) {
29142             check_insn_opc_user_only(ctx, INSN_R5900);
29143         }
29144         /* Fallthrough */
29145     case OPC_LWL:
29146     case OPC_LWR:
29147         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29148          /* Fallthrough */
29149     case OPC_LB:
29150     case OPC_LH:
29151     case OPC_LW:
29152     case OPC_LWPC:
29153     case OPC_LBU:
29154     case OPC_LHU:
29155          gen_ld(ctx, op, rt, rs, imm);
29156          break;
29157     case OPC_SWL:
29158     case OPC_SWR:
29159         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29160         /* fall through */
29161     case OPC_SB:
29162     case OPC_SH:
29163     case OPC_SW:
29164          gen_st(ctx, op, rt, rs, imm);
29165          break;
29166     case OPC_SC:
29167         check_insn(ctx, ISA_MIPS2);
29168          check_insn_opc_removed(ctx, ISA_MIPS32R6);
29169         if (ctx->insn_flags & INSN_R5900) {
29170             check_insn_opc_user_only(ctx, INSN_R5900);
29171         }
29172          gen_st_cond(ctx, op, rt, rs, imm);
29173          break;
29174     case OPC_CACHE:
29175         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29176         check_cp0_enabled(ctx);
29177         check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
29178         if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
29179             gen_cache_operation(ctx, rt, rs, imm);
29180         }
29181         /* Treat as NOP. */
29182         break;
29183     case OPC_PREF:
29184         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29185         if (ctx->insn_flags & INSN_R5900) {
29186             /* Treat as NOP. */
29187         } else {
29188             check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
29189             /* Treat as NOP. */
29190         }
29191         break;
29192
29193     /* Floating point (COP1). */
29194     case OPC_LWC1:
29195     case OPC_LDC1:
29196     case OPC_SWC1:
29197     case OPC_SDC1:
29198         gen_cop1_ldst(ctx, op, rt, rs, imm);
29199         break;
29200
29201     case OPC_CP1:
29202         op1 = MASK_CP1(ctx->opcode);
29203
29204         switch (op1) {
29205         case OPC_MFHC1:
29206         case OPC_MTHC1:
29207             check_cp1_enabled(ctx);
29208             check_insn(ctx, ISA_MIPS32R2);
29209             /* fall through */
29210         case OPC_MFC1:
29211         case OPC_CFC1:
29212         case OPC_MTC1:
29213         case OPC_CTC1:
29214             check_cp1_enabled(ctx);
29215             gen_cp1(ctx, op1, rt, rd);
29216             break;
29217 #if defined(TARGET_MIPS64)
29218         case OPC_DMFC1:
29219         case OPC_DMTC1:
29220             check_cp1_enabled(ctx);
29221             check_insn(ctx, ISA_MIPS3);
29222             check_mips_64(ctx);
29223             gen_cp1(ctx, op1, rt, rd);
29224             break;
29225 #endif
29226         case OPC_BC1EQZ: /* OPC_BC1ANY2 */
29227             check_cp1_enabled(ctx);
29228             if (ctx->insn_flags & ISA_MIPS32R6) {
29229                 /* OPC_BC1EQZ */
29230                 gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
29231                                        rt, imm << 2, 4);
29232             } else {
29233                 /* OPC_BC1ANY2 */
29234                 check_cop1x(ctx);
29235                 check_insn(ctx, ASE_MIPS3D);
29236                 gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29237                                     (rt >> 2) & 0x7, imm << 2);
29238             }
29239             break;
29240         case OPC_BC1NEZ:
29241             check_cp1_enabled(ctx);
29242             check_insn(ctx, ISA_MIPS32R6);
29243             gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
29244                                    rt, imm << 2, 4);
29245             break;
29246         case OPC_BC1ANY4:
29247             check_cp1_enabled(ctx);
29248             check_insn_opc_removed(ctx, ISA_MIPS32R6);
29249             check_cop1x(ctx);
29250             check_insn(ctx, ASE_MIPS3D);
29251             /* fall through */
29252         case OPC_BC1:
29253             check_cp1_enabled(ctx);
29254             check_insn_opc_removed(ctx, ISA_MIPS32R6);
29255             gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
29256                                 (rt >> 2) & 0x7, imm << 2);
29257             break;
29258         case OPC_PS_FMT:
29259             check_ps(ctx);
29260             /* fall through */
29261         case OPC_S_FMT:
29262         case OPC_D_FMT:
29263             check_cp1_enabled(ctx);
29264             gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29265                        (imm >> 8) & 0x7);
29266             break;
29267         case OPC_W_FMT:
29268         case OPC_L_FMT:
29269         {
29270             int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
29271             check_cp1_enabled(ctx);
29272             if (ctx->insn_flags & ISA_MIPS32R6) {
29273                 switch (r6_op) {
29274                 case R6_OPC_CMP_AF_S:
29275                 case R6_OPC_CMP_UN_S:
29276                 case R6_OPC_CMP_EQ_S:
29277                 case R6_OPC_CMP_UEQ_S:
29278                 case R6_OPC_CMP_LT_S:
29279                 case R6_OPC_CMP_ULT_S:
29280                 case R6_OPC_CMP_LE_S:
29281                 case R6_OPC_CMP_ULE_S:
29282                 case R6_OPC_CMP_SAF_S:
29283                 case R6_OPC_CMP_SUN_S:
29284                 case R6_OPC_CMP_SEQ_S:
29285                 case R6_OPC_CMP_SEUQ_S:
29286                 case R6_OPC_CMP_SLT_S:
29287                 case R6_OPC_CMP_SULT_S:
29288                 case R6_OPC_CMP_SLE_S:
29289                 case R6_OPC_CMP_SULE_S:
29290                 case R6_OPC_CMP_OR_S:
29291                 case R6_OPC_CMP_UNE_S:
29292                 case R6_OPC_CMP_NE_S:
29293                 case R6_OPC_CMP_SOR_S:
29294                 case R6_OPC_CMP_SUNE_S:
29295                 case R6_OPC_CMP_SNE_S:
29296                     gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29297                     break;
29298                 case R6_OPC_CMP_AF_D:
29299                 case R6_OPC_CMP_UN_D:
29300                 case R6_OPC_CMP_EQ_D:
29301                 case R6_OPC_CMP_UEQ_D:
29302                 case R6_OPC_CMP_LT_D:
29303                 case R6_OPC_CMP_ULT_D:
29304                 case R6_OPC_CMP_LE_D:
29305                 case R6_OPC_CMP_ULE_D:
29306                 case R6_OPC_CMP_SAF_D:
29307                 case R6_OPC_CMP_SUN_D:
29308                 case R6_OPC_CMP_SEQ_D:
29309                 case R6_OPC_CMP_SEUQ_D:
29310                 case R6_OPC_CMP_SLT_D:
29311                 case R6_OPC_CMP_SULT_D:
29312                 case R6_OPC_CMP_SLE_D:
29313                 case R6_OPC_CMP_SULE_D:
29314                 case R6_OPC_CMP_OR_D:
29315                 case R6_OPC_CMP_UNE_D:
29316                 case R6_OPC_CMP_NE_D:
29317                 case R6_OPC_CMP_SOR_D:
29318                 case R6_OPC_CMP_SUNE_D:
29319                 case R6_OPC_CMP_SNE_D:
29320                     gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
29321                     break;
29322                 default:
29323                     gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
29324                                rt, rd, sa, (imm >> 8) & 0x7);
29325
29326                     break;
29327                 }
29328             } else {
29329                 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
29330                            (imm >> 8) & 0x7);
29331             }
29332             break;
29333         }
29334         case OPC_BZ_V:
29335         case OPC_BNZ_V:
29336         case OPC_BZ_B:
29337         case OPC_BZ_H:
29338         case OPC_BZ_W:
29339         case OPC_BZ_D:
29340         case OPC_BNZ_B:
29341         case OPC_BNZ_H:
29342         case OPC_BNZ_W:
29343         case OPC_BNZ_D:
29344             check_insn(ctx, ASE_MSA);
29345             gen_msa_branch(env, ctx, op1);
29346             break;
29347         default:
29348             MIPS_INVAL("cp1");
29349             generate_exception_end(ctx, EXCP_RI);
29350             break;
29351         }
29352         break;
29353
29354     /* Compact branches [R6] and COP2 [non-R6] */
29355     case OPC_BC: /* OPC_LWC2 */
29356     case OPC_BALC: /* OPC_SWC2 */
29357         if (ctx->insn_flags & ISA_MIPS32R6) {
29358             /* OPC_BC, OPC_BALC */
29359             gen_compute_compact_branch(ctx, op, 0, 0,
29360                                        sextract32(ctx->opcode << 2, 0, 28));
29361         } else {
29362             /* OPC_LWC2, OPC_SWC2 */
29363             /* COP2: Not implemented. */
29364             generate_exception_err(ctx, EXCP_CpU, 2);
29365         }
29366         break;
29367     case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
29368     case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
29369         if (ctx->insn_flags & ISA_MIPS32R6) {
29370             if (rs != 0) {
29371                 /* OPC_BEQZC, OPC_BNEZC */
29372                 gen_compute_compact_branch(ctx, op, rs, 0,
29373                                            sextract32(ctx->opcode << 2, 0, 23));
29374             } else {
29375                 /* OPC_JIC, OPC_JIALC */
29376                 gen_compute_compact_branch(ctx, op, 0, rt, imm);
29377             }
29378         } else {
29379             /* OPC_LWC2, OPC_SWC2 */
29380             /* COP2: Not implemented. */
29381             generate_exception_err(ctx, EXCP_CpU, 2);
29382         }
29383         break;
29384     case OPC_CP2:
29385         check_insn(ctx, INSN_LOONGSON2F);
29386         /* Note that these instructions use different fields.  */
29387         gen_loongson_multimedia(ctx, sa, rd, rt);
29388         break;
29389
29390     case OPC_CP3:
29391         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29392         if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
29393             check_cp1_enabled(ctx);
29394             op1 = MASK_CP3(ctx->opcode);
29395             switch (op1) {
29396             case OPC_LUXC1:
29397             case OPC_SUXC1:
29398                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29399                 /* Fallthrough */
29400             case OPC_LWXC1:
29401             case OPC_LDXC1:
29402             case OPC_SWXC1:
29403             case OPC_SDXC1:
29404                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29405                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
29406                 break;
29407             case OPC_PREFX:
29408                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29409                 /* Treat as NOP. */
29410                 break;
29411             case OPC_ALNV_PS:
29412                 check_insn(ctx, ISA_MIPS5 | ISA_MIPS32R2);
29413                 /* Fallthrough */
29414             case OPC_MADD_S:
29415             case OPC_MADD_D:
29416             case OPC_MADD_PS:
29417             case OPC_MSUB_S:
29418             case OPC_MSUB_D:
29419             case OPC_MSUB_PS:
29420             case OPC_NMADD_S:
29421             case OPC_NMADD_D:
29422             case OPC_NMADD_PS:
29423             case OPC_NMSUB_S:
29424             case OPC_NMSUB_D:
29425             case OPC_NMSUB_PS:
29426                 check_insn(ctx, ISA_MIPS4 | ISA_MIPS32R2);
29427                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
29428                 break;
29429             default:
29430                 MIPS_INVAL("cp3");
29431                 generate_exception_end(ctx, EXCP_RI);
29432                 break;
29433             }
29434         } else {
29435             generate_exception_err(ctx, EXCP_CpU, 1);
29436         }
29437         break;
29438
29439 #if defined(TARGET_MIPS64)
29440     /* MIPS64 opcodes */
29441     case OPC_LLD:
29442         if (ctx->insn_flags & INSN_R5900) {
29443             check_insn_opc_user_only(ctx, INSN_R5900);
29444         }
29445         /* fall through */
29446     case OPC_LDL:
29447     case OPC_LDR:
29448         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29449         /* fall through */
29450     case OPC_LWU:
29451     case OPC_LD:
29452         check_insn(ctx, ISA_MIPS3);
29453         check_mips_64(ctx);
29454         gen_ld(ctx, op, rt, rs, imm);
29455         break;
29456     case OPC_SDL:
29457     case OPC_SDR:
29458         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29459         /* fall through */
29460     case OPC_SD:
29461         check_insn(ctx, ISA_MIPS3);
29462         check_mips_64(ctx);
29463         gen_st(ctx, op, rt, rs, imm);
29464         break;
29465     case OPC_SCD:
29466         check_insn_opc_removed(ctx, ISA_MIPS32R6);
29467         check_insn(ctx, ISA_MIPS3);
29468         if (ctx->insn_flags & INSN_R5900) {
29469             check_insn_opc_user_only(ctx, INSN_R5900);
29470         }
29471         check_mips_64(ctx);
29472         gen_st_cond(ctx, op, rt, rs, imm);
29473         break;
29474     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
29475         if (ctx->insn_flags & ISA_MIPS32R6) {
29476             /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
29477             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29478         } else {
29479             /* OPC_DADDI */
29480             check_insn(ctx, ISA_MIPS3);
29481             check_mips_64(ctx);
29482             gen_arith_imm(ctx, op, rt, rs, imm);
29483         }
29484         break;
29485     case OPC_DADDIU:
29486         check_insn(ctx, ISA_MIPS3);
29487         check_mips_64(ctx);
29488         gen_arith_imm(ctx, op, rt, rs, imm);
29489         break;
29490 #else
29491     case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
29492         if (ctx->insn_flags & ISA_MIPS32R6) {
29493             gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
29494         } else {
29495             MIPS_INVAL("major opcode");
29496             generate_exception_end(ctx, EXCP_RI);
29497         }
29498         break;
29499 #endif
29500     case OPC_DAUI: /* OPC_JALX */
29501         if (ctx->insn_flags & ISA_MIPS32R6) {
29502 #if defined(TARGET_MIPS64)
29503             /* OPC_DAUI */
29504             check_mips_64(ctx);
29505             if (rs == 0) {
29506                 generate_exception(ctx, EXCP_RI);
29507             } else if (rt != 0) {
29508                 TCGv t0 = tcg_temp_new();
29509                 gen_load_gpr(t0, rs);
29510                 tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
29511                 tcg_temp_free(t0);
29512             }
29513 #else
29514             generate_exception_end(ctx, EXCP_RI);
29515             MIPS_INVAL("major opcode");
29516 #endif
29517         } else {
29518             /* OPC_JALX */
29519             check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
29520             offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
29521             gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
29522         }
29523         break;
29524     case OPC_MSA: /* OPC_MDMX */
29525         if (ctx->insn_flags & INSN_R5900) {
29526             gen_mmi_lq(env, ctx);    /* MMI_OPC_LQ */
29527         } else {
29528             /* MDMX: Not implemented. */
29529             gen_msa(env, ctx);
29530         }
29531         break;
29532     case OPC_PCREL:
29533         check_insn(ctx, ISA_MIPS32R6);
29534         gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
29535         break;
29536     default:            /* Invalid */
29537         MIPS_INVAL("major opcode");
29538         generate_exception_end(ctx, EXCP_RI);
29539         break;
29540     }
29541 }
29542
29543 static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
29544 {
29545     DisasContext *ctx = container_of(dcbase, DisasContext, base);
29546     CPUMIPSState *env = cs->env_ptr;
29547
29548     ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
29549     ctx->saved_pc = -1;
29550     ctx->insn_flags = env->insn_flags;
29551     ctx->CP0_Config1 = env->CP0_Config1;
29552     ctx->CP0_Config2 = env->CP0_Config2;
29553     ctx->CP0_Config3 = env->CP0_Config3;
29554     ctx->CP0_Config5 = env->CP0_Config5;
29555     ctx->btarget = 0;
29556     ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
29557     ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
29558     ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
29559     ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
29560     ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
29561     ctx->PAMask = env->PAMask;
29562     ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
29563     ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
29564     ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
29565     ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
29566     ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
29567     /* Restore delay slot state from the tb context.  */
29568     ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
29569     ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
29570     ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
29571              (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
29572     ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
29573     ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
29574     ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
29575     ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
29576     restore_cpu_state(env, ctx);
29577 #ifdef CONFIG_USER_ONLY
29578         ctx->mem_idx = MIPS_HFLAG_UM;
29579 #else
29580         ctx->mem_idx = hflags_mmu_index(ctx->hflags);
29581 #endif
29582     ctx->default_tcg_memop_mask = (ctx->insn_flags & ISA_MIPS32R6) ?
29583                                   MO_UNALN : MO_ALIGN;
29584
29585     LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
29586               ctx->hflags);
29587 }
29588
29589 static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
29590 {
29591 }
29592
29593 static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
29594 {
29595     DisasContext *ctx = container_of(dcbase, DisasContext, base);
29596
29597     tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
29598                        ctx->btarget);
29599 }
29600
29601 static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
29602                                      const CPUBreakpoint *bp)
29603 {
29604     DisasContext *ctx = container_of(dcbase, DisasContext, base);
29605
29606     save_cpu_state(ctx, 1);
29607     ctx->base.is_jmp = DISAS_NORETURN;
29608     gen_helper_raise_exception_debug(cpu_env);
29609     /* The address covered by the breakpoint must be included in
29610        [tb->pc, tb->pc + tb->size) in order to for it to be
29611        properly cleared -- thus we increment the PC here so that
29612        the logic setting tb->size below does the right thing.  */
29613     ctx->base.pc_next += 4;
29614     return true;
29615 }
29616
29617 static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
29618 {
29619     CPUMIPSState *env = cs->env_ptr;
29620     DisasContext *ctx = container_of(dcbase, DisasContext, base);
29621     int insn_bytes;
29622     int is_slot;
29623
29624     is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
29625     if (ctx->insn_flags & ISA_NANOMIPS32) {
29626         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29627         insn_bytes = decode_nanomips_opc(env, ctx);
29628     } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
29629         ctx->opcode = cpu_ldl_code(env, ctx->base.pc_next);
29630         insn_bytes = 4;
29631         decode_opc(env, ctx);
29632     } else if (ctx->insn_flags & ASE_MICROMIPS) {
29633         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29634         insn_bytes = decode_micromips_opc(env, ctx);
29635     } else if (ctx->insn_flags & ASE_MIPS16) {
29636         ctx->opcode = cpu_lduw_code(env, ctx->base.pc_next);
29637         insn_bytes = decode_mips16_opc(env, ctx);
29638     } else {
29639         generate_exception_end(ctx, EXCP_RI);
29640         g_assert(ctx->base.is_jmp == DISAS_NORETURN);
29641         return;
29642     }
29643
29644     if (ctx->hflags & MIPS_HFLAG_BMASK) {
29645         if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
29646                              MIPS_HFLAG_FBNSLOT))) {
29647             /* force to generate branch as there is neither delay nor
29648                forbidden slot */
29649             is_slot = 1;
29650         }
29651         if ((ctx->hflags & MIPS_HFLAG_M16) &&
29652             (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
29653             /* Force to generate branch as microMIPS R6 doesn't restrict
29654                branches in the forbidden slot. */
29655             is_slot = 1;
29656         }
29657     }
29658     if (is_slot) {
29659         gen_branch(ctx, insn_bytes);
29660     }
29661     ctx->base.pc_next += insn_bytes;
29662
29663     if (ctx->base.is_jmp != DISAS_NEXT) {
29664         return;
29665     }
29666     /* Execute a branch and its delay slot as a single instruction.
29667        This is what GDB expects and is consistent with what the
29668        hardware does (e.g. if a delay slot instruction faults, the
29669        reported PC is the PC of the branch).  */
29670     if (ctx->base.singlestep_enabled &&
29671         (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
29672         ctx->base.is_jmp = DISAS_TOO_MANY;
29673     }
29674     if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
29675         ctx->base.is_jmp = DISAS_TOO_MANY;
29676     }
29677 }
29678
29679 static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
29680 {
29681     DisasContext *ctx = container_of(dcbase, DisasContext, base);
29682
29683     if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
29684         save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
29685         gen_helper_raise_exception_debug(cpu_env);
29686     } else {
29687         switch (ctx->base.is_jmp) {
29688         case DISAS_STOP:
29689             gen_save_pc(ctx->base.pc_next);
29690             tcg_gen_lookup_and_goto_ptr();
29691             break;
29692         case DISAS_NEXT:
29693         case DISAS_TOO_MANY:
29694             save_cpu_state(ctx, 0);
29695             gen_goto_tb(ctx, 0, ctx->base.pc_next);
29696             break;
29697         case DISAS_EXIT:
29698             tcg_gen_exit_tb(NULL, 0);
29699             break;
29700         case DISAS_NORETURN:
29701             break;
29702         default:
29703             g_assert_not_reached();
29704         }
29705     }
29706 }
29707
29708 static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
29709 {
29710     qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
29711     log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
29712 }
29713
29714 static const TranslatorOps mips_tr_ops = {
29715     .init_disas_context = mips_tr_init_disas_context,
29716     .tb_start           = mips_tr_tb_start,
29717     .insn_start         = mips_tr_insn_start,
29718     .breakpoint_check   = mips_tr_breakpoint_check,
29719     .translate_insn     = mips_tr_translate_insn,
29720     .tb_stop            = mips_tr_tb_stop,
29721     .disas_log          = mips_tr_disas_log,
29722 };
29723
29724 void gen_intermediate_code(CPUState *cs, struct TranslationBlock *tb)
29725 {
29726     DisasContext ctx;
29727
29728     translator_loop(&mips_tr_ops, &ctx.base, cs, tb);
29729 }
29730
29731 static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
29732                            int flags)
29733 {
29734     int i;
29735     int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
29736
29737 #define printfpr(fp)                                                    \
29738     do {                                                                \
29739         if (is_fpu64)                                                   \
29740             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
29741                         " fd:%13g fs:%13g psu: %13g\n",                 \
29742                         (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
29743                         (double)(fp)->fd,                               \
29744                         (double)(fp)->fs[FP_ENDIAN_IDX],                \
29745                         (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
29746         else {                                                          \
29747             fpr_t tmp;                                                  \
29748             tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
29749             tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
29750             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
29751                         " fd:%13g fs:%13g psu:%13g\n",                  \
29752                         tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
29753                         (double)tmp.fd,                                 \
29754                         (double)tmp.fs[FP_ENDIAN_IDX],                  \
29755                         (double)tmp.fs[!FP_ENDIAN_IDX]);                \
29756         }                                                               \
29757     } while(0)
29758
29759
29760     fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
29761                 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
29762                 get_float_exception_flags(&env->active_fpu.fp_status));
29763     for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
29764         fpu_fprintf(f, "%3s: ", fregnames[i]);
29765         printfpr(&env->active_fpu.fpr[i]);
29766     }
29767
29768 #undef printfpr
29769 }
29770
29771 void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
29772                          int flags)
29773 {
29774     MIPSCPU *cpu = MIPS_CPU(cs);
29775     CPUMIPSState *env = &cpu->env;
29776     int i;
29777
29778     cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
29779                 " LO=0x" TARGET_FMT_lx " ds %04x "
29780                 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
29781                 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
29782                 env->hflags, env->btarget, env->bcond);
29783     for (i = 0; i < 32; i++) {
29784         if ((i & 3) == 0)
29785             cpu_fprintf(f, "GPR%02d:", i);
29786         cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
29787         if ((i & 3) == 3)
29788             cpu_fprintf(f, "\n");
29789     }
29790
29791     cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
29792                 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
29793     cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
29794                 PRIx64 "\n",
29795                 env->CP0_Config0, env->CP0_Config1, env->lladdr);
29796     cpu_fprintf(f, "    Config2 0x%08x Config3 0x%08x\n",
29797                 env->CP0_Config2, env->CP0_Config3);
29798     cpu_fprintf(f, "    Config4 0x%08x Config5 0x%08x\n",
29799                 env->CP0_Config4, env->CP0_Config5);
29800     if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
29801         fpu_dump_state(env, f, cpu_fprintf, flags);
29802     }
29803 }
29804
29805 void mips_tcg_init(void)
29806 {
29807     int i;
29808
29809     cpu_gpr[0] = NULL;
29810     for (i = 1; i < 32; i++)
29811         cpu_gpr[i] = tcg_global_mem_new(cpu_env,
29812                                         offsetof(CPUMIPSState, active_tc.gpr[i]),
29813                                         regnames[i]);
29814
29815     for (i = 0; i < 32; i++) {
29816         int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
29817         msa_wr_d[i * 2] =
29818                 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2]);
29819         /* The scalar floating-point unit (FPU) registers are mapped on
29820          * the MSA vector registers. */
29821         fpu_f64[i] = msa_wr_d[i * 2];
29822         off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[1]);
29823         msa_wr_d[i * 2 + 1] =
29824                 tcg_global_mem_new_i64(cpu_env, off, msaregnames[i * 2 + 1]);
29825     }
29826
29827     cpu_PC = tcg_global_mem_new(cpu_env,
29828                                 offsetof(CPUMIPSState, active_tc.PC), "PC");
29829     for (i = 0; i < MIPS_DSP_ACC; i++) {
29830         cpu_HI[i] = tcg_global_mem_new(cpu_env,
29831                                        offsetof(CPUMIPSState, active_tc.HI[i]),
29832                                        regnames_HI[i]);
29833         cpu_LO[i] = tcg_global_mem_new(cpu_env,
29834                                        offsetof(CPUMIPSState, active_tc.LO[i]),
29835                                        regnames_LO[i]);
29836     }
29837     cpu_dspctrl = tcg_global_mem_new(cpu_env,
29838                                      offsetof(CPUMIPSState, active_tc.DSPControl),
29839                                      "DSPControl");
29840     bcond = tcg_global_mem_new(cpu_env,
29841                                offsetof(CPUMIPSState, bcond), "bcond");
29842     btarget = tcg_global_mem_new(cpu_env,
29843                                  offsetof(CPUMIPSState, btarget), "btarget");
29844     hflags = tcg_global_mem_new_i32(cpu_env,
29845                                     offsetof(CPUMIPSState, hflags), "hflags");
29846
29847     fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
29848                                       offsetof(CPUMIPSState, active_fpu.fcr0),
29849                                       "fcr0");
29850     fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
29851                                        offsetof(CPUMIPSState, active_fpu.fcr31),
29852                                        "fcr31");
29853
29854 #if defined(TARGET_MIPS64)
29855     cpu_mmr[0] = NULL;
29856     for (i = 1; i < 32; i++) {
29857         cpu_mmr[i] = tcg_global_mem_new_i64(cpu_env,
29858                                             offsetof(CPUMIPSState,
29859                                                      active_tc.mmr[i]),
29860                                             regnames[i]);
29861     }
29862 #endif
29863
29864 #if !defined(TARGET_MIPS64)
29865     for (i = 0; i < NUMBER_OF_MXU_REGISTERS - 1; i++) {
29866         mxu_gpr[i] = tcg_global_mem_new(cpu_env,
29867                                         offsetof(CPUMIPSState,
29868                                                  active_tc.mxu_gpr[i]),
29869                                         mxuregnames[i]);
29870     }
29871
29872     mxu_CR = tcg_global_mem_new(cpu_env,
29873                                 offsetof(CPUMIPSState, active_tc.mxu_cr),
29874                                 mxuregnames[NUMBER_OF_MXU_REGISTERS - 1]);
29875 #endif
29876 }
29877
29878 #include "translate_init.inc.c"
29879
29880 void cpu_mips_realize_env(CPUMIPSState *env)
29881 {
29882     env->exception_base = (int32_t)0xBFC00000;
29883
29884 #ifndef CONFIG_USER_ONLY
29885     mmu_init(env, env->cpu_model);
29886 #endif
29887     fpu_init(env, env->cpu_model);
29888     mvp_init(env, env->cpu_model);
29889 }
29890
29891 bool cpu_supports_cps_smp(const char *cpu_type)
29892 {
29893     const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
29894     return (mcc->cpu_def->CP0_Config3 & (1 << CP0C3_CMGCR)) != 0;
29895 }
29896
29897 bool cpu_supports_isa(const char *cpu_type, unsigned int isa)
29898 {
29899     const MIPSCPUClass *mcc = MIPS_CPU_CLASS(object_class_by_name(cpu_type));
29900     return (mcc->cpu_def->insn_flags & isa) != 0;
29901 }
29902
29903 void cpu_set_exception_base(int vp_index, target_ulong address)
29904 {
29905     MIPSCPU *vp = MIPS_CPU(qemu_get_cpu(vp_index));
29906     vp->env.exception_base = address;
29907 }
29908
29909 void cpu_state_reset(CPUMIPSState *env)
29910 {
29911     MIPSCPU *cpu = mips_env_get_cpu(env);
29912     CPUState *cs = CPU(cpu);
29913
29914     /* Reset registers to their default values */
29915     env->CP0_PRid = env->cpu_model->CP0_PRid;
29916     env->CP0_Config0 = env->cpu_model->CP0_Config0;
29917 #ifdef TARGET_WORDS_BIGENDIAN
29918     env->CP0_Config0 |= (1 << CP0C0_BE);
29919 #endif
29920     env->CP0_Config1 = env->cpu_model->CP0_Config1;
29921     env->CP0_Config2 = env->cpu_model->CP0_Config2;
29922     env->CP0_Config3 = env->cpu_model->CP0_Config3;
29923     env->CP0_Config4 = env->cpu_model->CP0_Config4;
29924     env->CP0_Config4_rw_bitmask = env->cpu_model->CP0_Config4_rw_bitmask;
29925     env->CP0_Config5 = env->cpu_model->CP0_Config5;
29926     env->CP0_Config5_rw_bitmask = env->cpu_model->CP0_Config5_rw_bitmask;
29927     env->CP0_Config6 = env->cpu_model->CP0_Config6;
29928     env->CP0_Config7 = env->cpu_model->CP0_Config7;
29929     env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
29930                                  << env->cpu_model->CP0_LLAddr_shift;
29931     env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
29932     env->SYNCI_Step = env->cpu_model->SYNCI_Step;
29933     env->CCRes = env->cpu_model->CCRes;
29934     env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
29935     env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
29936     env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
29937     env->current_tc = 0;
29938     env->SEGBITS = env->cpu_model->SEGBITS;
29939     env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
29940 #if defined(TARGET_MIPS64)
29941     if (env->cpu_model->insn_flags & ISA_MIPS3) {
29942         env->SEGMask |= 3ULL << 62;
29943     }
29944 #endif
29945     env->PABITS = env->cpu_model->PABITS;
29946     env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
29947     env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
29948     env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
29949     env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
29950     env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
29951     env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
29952     env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
29953     env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
29954     env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
29955     env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
29956     env->CP0_PageGrain_rw_bitmask = env->cpu_model->CP0_PageGrain_rw_bitmask;
29957     env->CP0_PageGrain = env->cpu_model->CP0_PageGrain;
29958     env->CP0_EBaseWG_rw_bitmask = env->cpu_model->CP0_EBaseWG_rw_bitmask;
29959     env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
29960     env->active_fpu.fcr31_rw_bitmask = env->cpu_model->CP1_fcr31_rw_bitmask;
29961     env->active_fpu.fcr31 = env->cpu_model->CP1_fcr31;
29962     env->msair = env->cpu_model->MSAIR;
29963     env->insn_flags = env->cpu_model->insn_flags;
29964
29965 #if defined(CONFIG_USER_ONLY)
29966     env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
29967 # ifdef TARGET_MIPS64
29968     /* Enable 64-bit register mode.  */
29969     env->CP0_Status |= (1 << CP0St_PX);
29970 # endif
29971 # ifdef TARGET_ABI_MIPSN64
29972     /* Enable 64-bit address mode.  */
29973     env->CP0_Status |= (1 << CP0St_UX);
29974 # endif
29975     /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
29976        hardware registers.  */
29977     env->CP0_HWREna |= 0x0000000F;
29978     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
29979         env->CP0_Status |= (1 << CP0St_CU1);
29980     }
29981     if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
29982         env->CP0_Status |= (1 << CP0St_MX);
29983     }
29984 # if defined(TARGET_MIPS64)
29985     /* For MIPS64, init FR bit to 1 if FPU unit is there and bit is writable. */
29986     if ((env->CP0_Config1 & (1 << CP0C1_FP)) &&
29987         (env->CP0_Status_rw_bitmask & (1 << CP0St_FR))) {
29988         env->CP0_Status |= (1 << CP0St_FR);
29989     }
29990 # endif
29991 #else
29992     if (env->hflags & MIPS_HFLAG_BMASK) {
29993         /* If the exception was raised from a delay slot,
29994            come back to the jump.  */
29995         env->CP0_ErrorEPC = (env->active_tc.PC
29996                              - (env->hflags & MIPS_HFLAG_B16 ? 2 : 4));
29997     } else {
29998         env->CP0_ErrorEPC = env->active_tc.PC;
29999     }
30000     env->active_tc.PC = env->exception_base;
30001     env->CP0_Random = env->tlb->nb_tlb - 1;
30002     env->tlb->tlb_in_use = env->tlb->nb_tlb;
30003     env->CP0_Wired = 0;
30004     env->CP0_GlobalNumber = (cs->cpu_index & 0xFF) << CP0GN_VPId;
30005     env->CP0_EBase = (cs->cpu_index & 0x3FF);
30006     if (mips_um_ksegs_enabled()) {
30007         env->CP0_EBase |= 0x40000000;
30008     } else {
30009         env->CP0_EBase |= (int32_t)0x80000000;
30010     }
30011     if (env->CP0_Config3 & (1 << CP0C3_CMGCR)) {
30012         env->CP0_CMGCRBase = 0x1fbf8000 >> 4;
30013     }
30014     env->CP0_EntryHi_ASID_mask = (env->CP0_Config4 & (1 << CP0C4_AE)) ?
30015                                  0x3ff : 0xff;
30016     env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
30017     /* vectored interrupts not implemented, timer on int 7,
30018        no performance counters. */
30019     env->CP0_IntCtl = 0xe0000000;
30020     {
30021         int i;
30022
30023         for (i = 0; i < 7; i++) {
30024             env->CP0_WatchLo[i] = 0;
30025             env->CP0_WatchHi[i] = 0x80000000;
30026         }
30027         env->CP0_WatchLo[7] = 0;
30028         env->CP0_WatchHi[7] = 0;
30029     }
30030     /* Count register increments in debug mode, EJTAG version 1 */
30031     env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
30032
30033     cpu_mips_store_count(env, 1);
30034
30035     if (env->CP0_Config3 & (1 << CP0C3_MT)) {
30036         int i;
30037
30038         /* Only TC0 on VPE 0 starts as active.  */
30039         for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
30040             env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
30041             env->tcs[i].CP0_TCHalt = 1;
30042         }
30043         env->active_tc.CP0_TCHalt = 1;
30044         cs->halted = 1;
30045
30046         if (cs->cpu_index == 0) {
30047             /* VPE0 starts up enabled.  */
30048             env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
30049             env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
30050
30051             /* TC0 starts up unhalted.  */
30052             cs->halted = 0;
30053             env->active_tc.CP0_TCHalt = 0;
30054             env->tcs[0].CP0_TCHalt = 0;
30055             /* With thread 0 active.  */
30056             env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
30057             env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
30058         }
30059     }
30060
30061     /*
30062      * Configure default legacy segmentation control. We use this regardless of
30063      * whether segmentation control is presented to the guest.
30064      */
30065     /* KSeg3 (seg0 0xE0000000..0xFFFFFFFF) */
30066     env->CP0_SegCtl0 =   (CP0SC_AM_MK << CP0SC_AM);
30067     /* KSeg2 (seg1 0xC0000000..0xDFFFFFFF) */
30068     env->CP0_SegCtl0 |= ((CP0SC_AM_MSK << CP0SC_AM)) << 16;
30069     /* KSeg1 (seg2 0xA0000000..0x9FFFFFFF) */
30070     env->CP0_SegCtl1 =   (0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
30071                          (2 << CP0SC_C);
30072     /* KSeg0 (seg3 0x80000000..0x9FFFFFFF) */
30073     env->CP0_SegCtl1 |= ((0 << CP0SC_PA) | (CP0SC_AM_UK << CP0SC_AM) |
30074                          (3 << CP0SC_C)) << 16;
30075     /* USeg (seg4 0x40000000..0x7FFFFFFF) */
30076     env->CP0_SegCtl2 =   (2 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30077                          (1 << CP0SC_EU) | (2 << CP0SC_C);
30078     /* USeg (seg5 0x00000000..0x3FFFFFFF) */
30079     env->CP0_SegCtl2 |= ((0 << CP0SC_PA) | (CP0SC_AM_MUSK << CP0SC_AM) |
30080                          (1 << CP0SC_EU) | (2 << CP0SC_C)) << 16;
30081     /* XKPhys (note, SegCtl2.XR = 0, so XAM won't be used) */
30082     env->CP0_SegCtl1 |= (CP0SC_AM_UK << CP0SC1_XAM);
30083 #endif
30084     if ((env->insn_flags & ISA_MIPS32R6) &&
30085         (env->active_fpu.fcr0 & (1 << FCR0_F64))) {
30086         /* Status.FR = 0 mode in 64-bit FPU not allowed in R6 */
30087         env->CP0_Status |= (1 << CP0St_FR);
30088     }
30089
30090     if (env->insn_flags & ISA_MIPS32R6) {
30091         /* PTW  =  1 */
30092         env->CP0_PWSize = 0x40;
30093         /* GDI  = 12 */
30094         /* UDI  = 12 */
30095         /* MDI  = 12 */
30096         /* PRI  = 12 */
30097         /* PTEI =  2 */
30098         env->CP0_PWField = 0x0C30C302;
30099     } else {
30100         /* GDI  =  0 */
30101         /* UDI  =  0 */
30102         /* MDI  =  0 */
30103         /* PRI  =  0 */
30104         /* PTEI =  2 */
30105         env->CP0_PWField = 0x02;
30106     }
30107
30108     if (env->CP0_Config3 & (1 << CP0C3_ISA) & (1 << (CP0C3_ISA + 1))) {
30109         /*  microMIPS on reset when Config3.ISA is 3 */
30110         env->hflags |= MIPS_HFLAG_M16;
30111     }
30112
30113     /* MSA */
30114     if (env->CP0_Config3 & (1 << CP0C3_MSAP)) {
30115         msa_reset(env);
30116     }
30117
30118     compute_hflags(env);
30119     restore_fp_status(env);
30120     restore_pamask(env);
30121     cs->exception_index = EXCP_NONE;
30122
30123     if (semihosting_get_argc()) {
30124         /* UHI interface can be used to obtain argc and argv */
30125         env->active_tc.gpr[4] = -1;
30126     }
30127 }
30128
30129 void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
30130                           target_ulong *data)
30131 {
30132     env->active_tc.PC = data[0];
30133     env->hflags &= ~MIPS_HFLAG_BMASK;
30134     env->hflags |= data[1];
30135     switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
30136     case MIPS_HFLAG_BR:
30137         break;
30138     case MIPS_HFLAG_BC:
30139     case MIPS_HFLAG_BL:
30140     case MIPS_HFLAG_B:
30141         env->btarget = data[2];
30142         break;
30143     }
30144 }
This page took 1.654044 seconds and 4 git commands to generate.